From cba6652c12bc9bcfc7f6f69e638b26b50c378464 Mon Sep 17 00:00:00 2001 From: Ke Li Date: Thu, 21 Nov 2024 12:49:07 +0800 Subject: [PATCH] removed duplicated entry in .clang-format and auto-format all source code --- .clang-format | 21 +- storage/ctc/ctc_cbo.cc | 173 +- storage/ctc/ctc_ddl_rewriter_plugin.cc | 609 +- storage/ctc/ctc_ddl_util.cc | 164 +- storage/ctc/ctc_error.cc | 150 +- storage/ctc/ctc_meta_data.cc | 472 +- storage/ctc/ctc_mysql_proxy.cc | 344 +- storage/ctc/ctc_proxy_util.cc | 90 +- storage/ctc/ctc_srv_mq_module.cc | 91 +- storage/ctc/ctc_srv_mq_stub.cc | 550 +- storage/ctc/ctc_stats.cc | 236 +- storage/ctc/ctc_util.cc | 178 +- storage/ctc/datatype_cnvrt_4_index_search.cc | 59 +- storage/ctc/datatype_cnvrtr.cc | 494 +- storage/ctc/decimal_convert.cc | 111 +- storage/ctc/ha_ctc.cc | 6184 +++++++++--------- storage/ctc/ha_ctc_ddl.cc | 896 +-- storage/ctc/ha_ctcpart.cc | 383 +- storage/ctc/mysql_cantian_plugin.cc | 55 +- 19 files changed, 5785 insertions(+), 5475 deletions(-) diff --git a/.clang-format b/.clang-format index 55ed2b2..7782373 100644 --- a/.clang-format +++ b/.clang-format @@ -43,7 +43,7 @@ BraceWrapping: SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None -BreakBeforeBraces: Attach +BreakBeforeBraces: WebKit BreakBeforeInheritanceComma: false BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: true @@ -51,7 +51,7 @@ BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true -ColumnLimit: 80 +ColumnLimit: 120 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: true @@ -59,7 +59,6 @@ ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DeriveLineEnding: true -DerivePointerAlignment: true DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true @@ -67,7 +66,6 @@ ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH -IncludeBlocks: Regroup IncludeCategories: - Regex: '^' Priority: 2 @@ -107,7 +105,6 @@ PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 -PointerAlignment: Left RawStringFormats: - Language: Cpp Delimiters: @@ -158,7 +155,6 @@ SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false SpaceBeforeSquareBrackets: false -Standard: Auto StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION @@ -171,8 +167,7 @@ UseTab: Never DerivePointerAlignment: false PointerAlignment: Right -# MySQL source code is allowed to use C++11 (and C++14) features. -Standard: Cpp11 +Standard: Latest # MySQL includes frequently are not order-independent (e.g. my_config.h needs # to go on top). This is unfortunate, but not something we can change easily, @@ -222,7 +217,7 @@ BraceWrapping: SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None -BreakBeforeBraces: Attach +BreakBeforeBraces: WebKit BreakBeforeInheritanceComma: false BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: false @@ -230,7 +225,7 @@ BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true -ColumnLimit: 80 +ColumnLimit: 120 CommentPragmas: '(taze:|^/[ ]*<|@see)' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: true @@ -238,7 +233,6 @@ ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DeriveLineEnding: true -DerivePointerAlignment: true DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true @@ -246,7 +240,6 @@ ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH -IncludeBlocks: Regroup IncludeCategories: - Regex: '^' Priority: 2 @@ -286,7 +279,6 @@ PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 -PointerAlignment: Left RawStringFormats: - Language: Cpp Delimiters: @@ -337,10 +329,9 @@ SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false SpaceBeforeSquareBrackets: false -Standard: Auto StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION TabWidth: 8 UseCRLF: false -UseTab: Never +UseTab: Never \ No newline at end of file diff --git a/storage/ctc/ctc_cbo.cc b/storage/ctc/ctc_cbo.cc index ba5a15c..c7349cf 100644 --- a/storage/ctc/ctc_cbo.cc +++ b/storage/ctc/ctc_cbo.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -15,14 +15,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Bon, MA 02110-1301 USA */ #include "ctc_cbo.h" -#include "ha_ctc.h" #include "ctc_log.h" -#include "sql/field.h" #include "ctc_srv_mq_module.h" -#include "datatype_cnvrtr.h" #include "ctc_util.h" +#include "datatype_cnvrtr.h" +#include "ha_ctc.h" +#include "sql/field.h" -static void convert_enum_key_to_variant(const uchar *enum_key, cache_variant_t *variant, capacity_usage cap_usage_of_enum_key) +static void convert_enum_key_to_variant(const uchar *enum_key, cache_variant_t *variant, + capacity_usage cap_usage_of_enum_key) { switch (cap_usage_of_enum_key) { case ONE_BYTE: @@ -36,7 +37,8 @@ static void convert_enum_key_to_variant(const uchar *enum_key, cache_variant_t * } } -static void convert_set_key_to_variant(const uchar *set_key, cache_variant_t *variant, capacity_usage cap_usage_of_set_key) +static void convert_set_key_to_variant(const uchar *set_key, cache_variant_t *variant, + capacity_usage cap_usage_of_set_key) { switch (cap_usage_of_set_key) { case ONE_BYTE: @@ -59,7 +61,8 @@ static void convert_set_key_to_variant(const uchar *set_key, cache_variant_t *va } } -void r_key2variant(ctc_key *rKey, KEY_PART_INFO *cur_index_part, cache_variant_t *ret_val, cache_variant_t * value, uint32_t key_offset) +void r_key2variant(ctc_key *rKey, KEY_PART_INFO *cur_index_part, cache_variant_t *ret_val, cache_variant_t *value, + uint32_t key_offset) { if (rKey->cmp_type == CMP_TYPE_NULL) { *ret_val = *value; @@ -71,7 +74,7 @@ void r_key2variant(ctc_key *rKey, KEY_PART_INFO *cur_index_part, cache_variant_t uint32_t offset = 0; if (cur_index_part->field->is_nullable()) { /* The first byte in the field tells if this is an SQL NULL value */ - if(*(rKey->key + key_offset) == 1) { + if (*(rKey->key + key_offset) == 1) { *ret_val = *value; rKey->cmp_type = CMP_TYPE_CLOSE_INTERNAL; return; @@ -84,13 +87,13 @@ void r_key2variant(ctc_key *rKey, KEY_PART_INFO *cur_index_part, cache_variant_t str_key_len = *(uint16_t *)const_cast(rKey->key + offset); } if (field->real_type() == MYSQL_TYPE_STRING) { - uint32_t data_len = field->key_length(); - while (data_len > 0 && rKey->key[data_len + offset - 1] == field->charset()->pad_char) { - data_len--; - } - str_key_len = data_len; + uint32_t data_len = field->key_length(); + while (data_len > 0 && rKey->key[data_len + offset - 1] == field->charset()->pad_char) { + data_len--; + } + str_key_len = data_len; } - uint32_t str_copy_len = str_key_len > CBO_STRING_MAX_LEN-1 ? CBO_STRING_MAX_LEN-1 : str_key_len; + uint32_t str_copy_len = str_key_len > CBO_STRING_MAX_LEN - 1 ? CBO_STRING_MAX_LEN - 1 : str_key_len; key_offset += field->real_type() == MYSQL_TYPE_VARCHAR ? OFFSET_VARCHAR_TYPE : 0; const uchar *key = rKey->key + key_offset + offset; @@ -133,11 +136,13 @@ void r_key2variant(ctc_key *rKey, KEY_PART_INFO *cur_index_part, cache_variant_t ret_val->v_date = *(date_t *)const_cast(key); break; case MYSQL_TYPE_DATETIME2: - cnvrt_datetime_decimal(const_cast(key), cur_index_part->field->decimals(), tmp_ptr, DATETIME_MAX_DECIMALS, CTC_BYTE_8); + cnvrt_datetime_decimal(const_cast(key), cur_index_part->field->decimals(), tmp_ptr, + DATETIME_MAX_DECIMALS, CTC_BYTE_8); ret_val->v_date = *(date_t *)tmp_ptr; break; case MYSQL_TYPE_TIME2: - cnvrt_time_decimal(const_cast(key), cur_index_part->field->decimals(), tmp_ptr, DATETIME_MAX_DECIMALS, CTC_BYTE_8); + cnvrt_time_decimal(const_cast(key), cur_index_part->field->decimals(), tmp_ptr, DATETIME_MAX_DECIMALS, + CTC_BYTE_8); ret_val->v_date = *(date_t *)tmp_ptr; break; case MYSQL_TYPE_DECIMAL: @@ -177,14 +182,18 @@ double datetime_compare(const uchar *datetime1, const uchar *datetime2) } template -static inline en_ctc_compare_type two_nums_compare(T a, T b) { - if (a > b) { return GREAT; } - if (a < b) { return LESS; } +static inline en_ctc_compare_type two_nums_compare(T a, T b) +{ + if (a > b) { + return GREAT; + } + if (a < b) { + return LESS; + } return EQUAL; } -static en_ctc_compare_type compare(cache_variant_t *right, cache_variant_t *left, Field *field, - const CHARSET_INFO *cs) +static en_ctc_compare_type compare(cache_variant_t *right, cache_variant_t *left, Field *field, const CHARSET_INFO *cs) { double compare_value = 0; switch (field->real_type()) { @@ -209,7 +218,7 @@ static en_ctc_compare_type compare(cache_variant_t *right, cache_variant_t *left compare_value = (right->v_real - left->v_real); break; case MYSQL_TYPE_LONGLONG: - compare_value = (right->v_bigint - left->v_bigint); + compare_value = (right->v_bigint - left->v_bigint); break; case MYSQL_TYPE_YEAR: case MYSQL_TYPE_TIMESTAMP2: @@ -228,7 +237,7 @@ static en_ctc_compare_type compare(cache_variant_t *right, cache_variant_t *left case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: compare_value = cs->coll->strnncollsp(cs, (const uchar *)right->v_str, strlen(right->v_str), - (const uchar *)left->v_str, strlen(left->v_str)); + (const uchar *)left->v_str, strlen(left->v_str)); break; default: return UNCOMPARABLE; @@ -244,24 +253,24 @@ static en_ctc_compare_type compare(cache_variant_t *right, cache_variant_t *left double eval_density_result(double density) { /* - * key range is beyond the actual index range, - * don't have any records in this range - */ + * key range is beyond the actual index range, + * don't have any records in this range + */ if (density < 0) { return 0; } /* - * key range is larger than the actual index range, - * any key with this range shoule be deemed as not selective - */ + * key range is larger than the actual index range, + * any key with this range shoule be deemed as not selective + */ if (density > 1) { return 1; } return density; } -static double calc_frequency_hist_equal_density(ctc_cbo_stats_column_t *col_stat, cache_variant_t *val, - Field *field, const CHARSET_INFO *cs) +static double calc_frequency_hist_equal_density(ctc_cbo_stats_column_t *col_stat, cache_variant_t *val, Field *field, + const CHARSET_INFO *cs) { en_ctc_compare_type cmp_result; int64 result = 0; @@ -271,10 +280,10 @@ static double calc_frequency_hist_equal_density(ctc_cbo_stats_column_t *col_stat cmp_result = compare(&hist_infos[i].ep_value, val, field, cs); if (cmp_result == EQUAL) { - result = (i == 0) ? hist_infos[i].ep_number : hist_infos[i].ep_number - hist_infos[i - 1].ep_number; - break; + result = (i == 0) ? hist_infos[i].ep_number : hist_infos[i].ep_number - hist_infos[i - 1].ep_number; + break; } else if (cmp_result == GREAT) { - break; + break; } } @@ -283,13 +292,13 @@ static double calc_frequency_hist_equal_density(ctc_cbo_stats_column_t *col_stat density = (double)result / hist_infos[end_pos].ep_number; } else if (result == 0) { density = 0; - //calc_density_by_sample_rate(stmt, entity, &density); + // calc_density_by_sample_rate(stmt, entity, &density); } return density; } -static double calc_balance_hist_equal_density(ctc_cbo_stats_column_t *col_stat, cache_variant_t *val, - Field *field, const CHARSET_INFO *cs) +static double calc_balance_hist_equal_density(ctc_cbo_stats_column_t *col_stat, cache_variant_t *val, Field *field, + const CHARSET_INFO *cs) { uint32 popular_count = 0; en_ctc_compare_type cmp_result; @@ -298,9 +307,9 @@ static double calc_balance_hist_equal_density(ctc_cbo_stats_column_t *col_stat, cmp_result = compare(&hist_infos[i].ep_value, val, field, cs); if (cmp_result == EQUAL) { - // ep_number is different from oracle, when compress balance histogram, need to change this + // ep_number is different from oracle, when compress balance histogram, need to change this popular_count++; - } else if (cmp_result == GREAT) { + } else if (cmp_result == GREAT) { break; } } @@ -317,11 +326,11 @@ static double calc_equal_null_density(ctc_cbo_stats_table_t *cbo_stats, uint32 c if (cbo_stats->estimate_rows > 0) { density = (double)col_stat->num_null / cbo_stats->estimate_rows; } - return density ; + return density; } -double calc_hist_equal_density(ctc_cbo_stats_table_t *cbo_stats, cache_variant_t *val, - uint32 col_id, Field *field, const CHARSET_INFO *cs) +double calc_hist_equal_density(ctc_cbo_stats_table_t *cbo_stats, cache_variant_t *val, uint32 col_id, Field *field, + const CHARSET_INFO *cs) { ctc_cbo_stats_column_t *col_stat = &cbo_stats->columns[col_id]; double density = col_stat->density; @@ -346,8 +355,8 @@ double calc_hist_equal_density(ctc_cbo_stats_table_t *cbo_stats, cache_variant_t return density; } -static double calc_hist_between_frequency(ctc_cbo_stats_table_t *cbo_stats, field_stats_val stats_val, - Field *field, uint32 col_id, const CHARSET_INFO *cs) +static double calc_hist_between_frequency(ctc_cbo_stats_table_t *cbo_stats, field_stats_val stats_val, Field *field, + uint32 col_id, const CHARSET_INFO *cs) { ctc_cbo_stats_column_t *col_stat = &cbo_stats->columns[col_id]; double density = col_stat->density; @@ -361,39 +370,35 @@ static double calc_hist_between_frequency(ctc_cbo_stats_table_t *cbo_stats, fie // HISTOGRAM_FREQUNCEY for (uint32 i = 0; i < hist_count; i++) { - cmp_result = compare(&hist_infos[i].ep_value, stats_val.min_key_val, field, cs); - if ((stats_val.min_type == CMP_TYPE_CLOSE_INTERNAL && (cmp_result == GREAT || cmp_result == EQUAL)) - || (stats_val.min_type == CMP_TYPE_OPEN_INTERNAL && cmp_result == GREAT)) { - if (i > 0) { - low_nums = hist_infos[i - 1].ep_number; - } + if ((stats_val.min_type == CMP_TYPE_CLOSE_INTERNAL && (cmp_result == GREAT || cmp_result == EQUAL)) || + (stats_val.min_type == CMP_TYPE_OPEN_INTERNAL && cmp_result == GREAT)) { + if (i > 0) { + low_nums = hist_infos[i - 1].ep_number; + } low_nums = total_nums - low_nums; break; } } for (uint32 i = 0; i < hist_count; i++) { - cmp_result = compare(&hist_infos[i].ep_value, stats_val.max_key_val, field, cs); - if ((stats_val.max_type == CMP_TYPE_OPEN_INTERNAL && (cmp_result == GREAT || cmp_result == EQUAL)) - || (stats_val.max_type == CMP_TYPE_CLOSE_INTERNAL && cmp_result == GREAT)) { + if ((stats_val.max_type == CMP_TYPE_OPEN_INTERNAL && (cmp_result == GREAT || cmp_result == EQUAL)) || + (stats_val.max_type == CMP_TYPE_CLOSE_INTERNAL && cmp_result == GREAT)) { high_nums = (i == 0) ? 0 : hist_infos[i - 1].ep_number; break; } } - if (total_nums > 0) { - return ((double)(low_nums + high_nums - total_nums) / total_nums) ; - } else { - return density; - } - + if (total_nums > 0) { + return ((double)(low_nums + high_nums - total_nums) / total_nums); + } else { + return density; + } } -static double percent_in_bucket(ctc_cbo_stats_column_t *col_stat, uint32 high, - cache_variant_t *key, Field *field) +static double percent_in_bucket(ctc_cbo_stats_column_t *col_stat, uint32 high, cache_variant_t *key, Field *field) { double percent = 0.0D; ctc_cbo_column_hist_t *hist_infos = col_stat->column_hist; @@ -525,8 +530,8 @@ static int calc_hist_range_boundary(field_stats_val stats_val, Field *field, ctc return hi_pos - lo_pos; } -static double calc_hist_between_balance(ctc_cbo_stats_table_t *cbo_stats, field_stats_val stats_val, - Field *field, uint32 col_id, const CHARSET_INFO *cs) +static double calc_hist_between_balance(ctc_cbo_stats_table_t *cbo_stats, field_stats_val stats_val, Field *field, + uint32 col_id, const CHARSET_INFO *cs) { ctc_cbo_stats_column_t *col_stat = &cbo_stats->columns[col_id]; double density = col_stat->density; @@ -542,8 +547,8 @@ static double calc_hist_between_balance(ctc_cbo_stats_table_t *cbo_stats, field_ return density; } -static double calc_hist_between_density(ctc_cbo_stats_table_t *cbo_stats, - uint32 col_id, Field *field, field_stats_val stats_val, const CHARSET_INFO *cs) +static double calc_hist_between_density(ctc_cbo_stats_table_t *cbo_stats, uint32 col_id, Field *field, + field_stats_val stats_val, const CHARSET_INFO *cs) { double density; ctc_cbo_stats_column_t *col_stat = &cbo_stats->columns[col_id]; @@ -579,11 +584,11 @@ double calc_density_by_cond(ctc_cbo_stats_table_t *cbo_stats, KEY_PART_INFO cur_ low_val = &cbo_stats->columns[col_id].low_value; high_val = &cbo_stats->columns[col_id].high_value; - cache_variant_t min_key_val = { 0 }; - cache_variant_t max_key_val = { 0 }; + cache_variant_t min_key_val = {0}; + cache_variant_t max_key_val = {0}; enum_field_types field_type = cur_index_part.field->real_type(); - char v_str_min[CBO_STRING_MAX_LEN] = { 0 }; - char v_str_max[CBO_STRING_MAX_LEN] = { 0 }; + char v_str_min[CBO_STRING_MAX_LEN] = {0}; + char v_str_max[CBO_STRING_MAX_LEN] = {0}; if (field_type == MYSQL_TYPE_VARCHAR || field_type == MYSQL_TYPE_VAR_STRING || field_type == MYSQL_TYPE_STRING) { min_key_val.v_str = v_str_min; max_key_val.v_str = v_str_max; @@ -610,7 +615,7 @@ double calc_density_by_cond(ctc_cbo_stats_table_t *cbo_stats, KEY_PART_INFO cur_ return density; } -void calc_accumulate_gcol_num(uint num_fields, Field** field, uint32_t *acc_gcol_num) +void calc_accumulate_gcol_num(uint num_fields, Field **field, uint32_t *acc_gcol_num) { uint32_t count = 0; for (uint i = 0; i < num_fields; i++) { @@ -621,10 +626,9 @@ void calc_accumulate_gcol_num(uint num_fields, Field** field, uint32_t *acc_gcol } } -double calc_density_one_table(uint16_t idx_id, ctc_range_key *key, - ctc_cbo_stats_table_t *cbo_stats, const TABLE &table) +double calc_density_one_table(uint16_t idx_id, ctc_range_key *key, ctc_cbo_stats_table_t *cbo_stats, const TABLE &table) { - if (cbo_stats->estimate_rows == 0) { // no stats or empty table + if (cbo_stats->estimate_rows == 0) { // no stats or empty table return 0; } double density = 1.0; @@ -632,14 +636,14 @@ double calc_density_one_table(uint16_t idx_id, ctc_range_key *key, uint32_t ct_col_id; uint32_t acc_gcol_num[CTC_MAX_COLUMNS] = {0}; calc_accumulate_gcol_num(table.s->fields, table.s->field, acc_gcol_num); - uint32_t key_offset = 0;//列在索引中的偏移量 + uint32_t key_offset = 0; // 列在索引中的偏移量 uint64_t col_map = max(key->min_key->col_map, key->max_key->col_map); KEY cur_index = table.key_info[idx_id]; /* - * For all columns in used index, - * density = 1.0 / (column[0]->num_distinct * ... * column[n]->num_distinct) - */ + * For all columns in used index, + * density = 1.0 / (column[0]->num_distinct * ... * column[n]->num_distinct) + */ for (uint32_t idx_col_num = 0; idx_col_num < cur_index.actual_key_parts; idx_col_num++) { double col_product = 1.0; if (col_map & ((uint64_t)1 << idx_col_num)) { @@ -657,7 +661,8 @@ double calc_density_one_table(uint16_t idx_id, ctc_range_key *key, // select * from table where col is null col_product = calc_equal_null_density(cbo_stats, ct_col_id); } else { - col_product = calc_density_by_cond(cbo_stats, cur_index_part, key, key_offset, ct_col_id, table.field[my_col_id]->charset()); + col_product = calc_density_by_cond(cbo_stats, cur_index_part, key, key_offset, ct_col_id, + table.field[my_col_id]->charset()); } col_product = eval_density_result(col_product); key_offset += (offset + cur_index_part.field->key_length()); @@ -666,10 +671,10 @@ double calc_density_one_table(uint16_t idx_id, ctc_range_key *key, } /* - * This is a safe-guard logic since we don't handle ctc call error in this method, - * we need this to make sure that our optimizer continue to work even when we - * miscalculated the density, and it's still prefer index read - */ + * This is a safe-guard logic since we don't handle ctc call error in this method, + * we need this to make sure that our optimizer continue to work even when we + * miscalculated the density, and it's still prefer index read + */ if (density < 0.0 || density > 1.0) { density = PREFER_RANGE_DENSITY; } @@ -703,10 +708,10 @@ void ctc_index_stats_update(TABLE *table, ctc_cbo_stats_t *cbo_stats) do { if (!n_diff_part) { break; - } + } rec_per_key += static_cast(records) / static_cast(n_diff_part + has_null); all_n_diff_is_zero = false; - } while(0); + } while (0); } // if all n_diff(s) values 0, take records itself as rec_per_key diff --git a/storage/ctc/ctc_ddl_rewriter_plugin.cc b/storage/ctc/ctc_ddl_rewriter_plugin.cc index d83c69e..c03f384 100644 --- a/storage/ctc/ctc_ddl_rewriter_plugin.cc +++ b/storage/ctc/ctc_ddl_rewriter_plugin.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -15,60 +15,58 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include #include #include #include #include #include +#include +#include +#include +#include #include +#include +#include #include -#include -#include "my_inttypes.h" -#include "my_psi_config.h" -#include "my_thread.h" // my_thread_handle needed by mysql_memory.h -#include "sql/sql_class.h" -#include "sql/sql_lex.h" -#include "sql/sql_error.h" +#include "ctc_error.h" #include "ctc_log.h" +#include "ctc_proxy_util.h" #include "ctc_srv.h" #include "ctc_util.h" -#include "ctc_proxy_util.h" -#include "ctc_error.h" #include "ha_ctc.h" #include "ha_ctc_ddl.h" -#include "sql/sql_initialize.h" // opt_initialize_insecure -#include "sql/sql_list.h" -#include "sql/set_var.h" -#include "sql/dd/types/schema.h" +#include "my_inttypes.h" +#include "my_psi_config.h" +#include "my_thread.h" // my_thread_handle needed by mysql_memory.h +#include "mysql/plugin_auth.h" +#include "sql/auth/auth_common.h" +#include "sql/auth/auth_internal.h" +#include "sql/auth/sql_auth_cache.h" #include "sql/dd/cache/dictionary_client.h" +#include "sql/dd/types/schema.h" #include "sql/lock.h" -#include "sql/auth/auth_common.h" -#include -#include -#include "sql/sql_tablespace.h" -#include "sql/sql_lex.h" -#include "sql/sql_db.h" // check_schema_readonly +#include "sql/set_var.h" #include "sql/sql_backup_lock.h" -#include "mysql/plugin_auth.h" -#include "sql/auth/sql_auth_cache.h" -#include "sql/auth/auth_internal.h" +#include "sql/sql_class.h" +#include "sql/sql_db.h" // check_schema_readonly +#include "sql/sql_error.h" +#include "sql/sql_initialize.h" // opt_initialize_insecure +#include "sql/sql_lex.h" +#include "sql/sql_list.h" #include "sql/sql_parse.h" +#include "sql/sql_tablespace.h" #ifdef FEATURE_X_FOR_MYSQL_32 #include "sql/sys_vars_shared.h" // intern_find_sys_var #endif using namespace std; -static SYS_VAR *ctc_rewriter_system_variables[] = { - nullptr -}; +static SYS_VAR *ctc_rewriter_system_variables[] = {nullptr}; extern uint32_t ctc_instance_id; -static bool is_current_system_var(set_var *setvar) { +static bool is_current_system_var(set_var *setvar) +{ Item_func_get_system_var *itemFunc = dynamic_cast(setvar->value); if (setvar->value == nullptr || itemFunc) { return true; @@ -78,9 +76,10 @@ static bool is_current_system_var(set_var *setvar) { typedef int (*check_variable_fn)(set_var *setvar, bool &need_forward, string user_val_str); -int check_default_engine(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unused)), string user_val_str) { +int check_default_engine(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unused)), string user_val_str) +{ if (is_current_system_var(setvar)) { - return 0; + return 0; } if (setvar->value->item_name.ptr() == nullptr) { @@ -92,65 +91,71 @@ int check_default_engine(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unuse if (user_val_str == "ctc" || user_val_str == "default") { return 0; } - + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Once the CTC is loaded, it must be set as the default engine. To modify the setting, uninstall the CTC first."); + "Once the CTC is loaded, it must be set as the default engine. To modify the setting, uninstall " + "the CTC first."); return -1; } if (strcasecmp(setvar->value->item_name.ptr(), ctc_hton_name) != 0) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Once the CTC is loaded, it must be set as the default engine. To modify the setting, uninstall the CTC first."); + "Once the CTC is loaded, it must be set as the default engine. To modify the setting, uninstall " + "the CTC first."); return -1; } return 0; } -int check_session_pool_volume(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unused)), string user_val_str) { - if (is_current_system_var(setvar)) { +int check_session_pool_volume(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unused)), string user_val_str) +{ + if (is_current_system_var(setvar)) { + return 0; + } + + uint max_sessions; + if (ctc_get_max_sessions_per_node(&max_sessions)) { + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "Get max connections in Cantian failed"); + return -1; + } + + if (setvar->value->item_name.ptr() == nullptr) { + if (user_val_str == "") { return 0; } - uint max_sessions; - if (ctc_get_max_sessions_per_node(&max_sessions)) { - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "Get max connections in Cantian failed"); + if (!isdigit(*user_val_str.c_str())) { + my_printf_error(ER_DISALLOWED_OPERATION, "[CTC]:Please make sure value is digits.", MYF(0)); return -1; } - if (setvar->value->item_name.ptr() == nullptr) { - if (user_val_str == "") { - return 0; - } - - if (!isdigit(*user_val_str.c_str())) { - my_printf_error(ER_DISALLOWED_OPERATION, "[CTC]:Please make sure value is digits.", MYF(0)); - return -1; - } - - int tmp_max_connection = atoi(user_val_str.c_str()); - if (tmp_max_connection > (int)max_sessions) { - my_printf_error(ER_DISALLOWED_OPERATION, "Current SE can only provide %d connections for one mysql-server", MYF(0), max_sessions); - return -1; - } else if (tmp_max_connection < 1) { - my_printf_error(ER_DISALLOWED_OPERATION, "Current SE cannot provide less than one connection.", MYF(0)); - return -1; - } - return 0; - } - - int num_max_conns = atoi(setvar->value->item_name.ptr()); - if (num_max_conns > (int)max_sessions) { - my_printf_error(ER_DISALLOWED_OPERATION, "Current SE can only provide %d connections for one mysql-server", MYF(0), max_sessions); + int tmp_max_connection = atoi(user_val_str.c_str()); + if (tmp_max_connection > (int)max_sessions) { + my_printf_error(ER_DISALLOWED_OPERATION, "Current SE can only provide %d connections for one mysql-server", + MYF(0), max_sessions); return -1; - } else if (num_max_conns < 1) { + } else if (tmp_max_connection < 1) { my_printf_error(ER_DISALLOWED_OPERATION, "Current SE cannot provide less than one connection.", MYF(0)); return -1; } return 0; + } + + int num_max_conns = atoi(setvar->value->item_name.ptr()); + if (num_max_conns > (int)max_sessions) { + my_printf_error(ER_DISALLOWED_OPERATION, "Current SE can only provide %d connections for one mysql-server", MYF(0), + max_sessions); + return -1; + } else if (num_max_conns < 1) { + my_printf_error(ER_DISALLOWED_OPERATION, "Current SE cannot provide less than one connection.", MYF(0)); + return -1; + } + return 0; } int not_allow_modify(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unused)), - string user_val_str MY_ATTRIBUTE((unused))) { + string user_val_str MY_ATTRIBUTE((unused))) +{ if (is_current_system_var(setvar)) { return 0; } @@ -163,11 +168,12 @@ int not_allow_modify(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unused)), 参考 Sys_var_transaction_isolation::session_update 和 Sys_var_typelib::do_check(). transaction_isolation 只支持设置为READ_COMMITTED */ -int unsupport_tx_isolation_level(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unused)), string user_val_str) { +int unsupport_tx_isolation_level(set_var *setvar, bool &need_forward MY_ATTRIBUTE((unused)), string user_val_str) +{ if (is_current_system_var(setvar)) { return 0; } - + if (setvar->value->result_type() == STRING_RESULT) { // 对应 SET @@global.transaction_isolation = @global_start_value;的写法 if (setvar->value->item_name.ptr() == nullptr) { @@ -181,7 +187,7 @@ int unsupport_tx_isolation_level(set_var *setvar, bool &need_forward MY_ATTRIBUT } my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "CTC STORAGE ENGINE ONLY SUPPORT READ_COMMITTED TRANSACTION ISOLATION LEVEL."); + "CTC STORAGE ENGINE ONLY SUPPORT READ_COMMITTED TRANSACTION ISOLATION LEVEL."); return -1; } @@ -190,7 +196,7 @@ int unsupport_tx_isolation_level(set_var *setvar, bool &need_forward MY_ATTRIBUT return 0; } else if (strcasecmp(setvar->value->item_name.ptr(), "repeatable-read") == 0) { push_warning_printf(current_thd, Sql_condition::SL_WARNING, ER_DISALLOWED_OPERATION, - "CTC: The Function of REPEATABLE READ transaction isolation is in progress."); + "CTC: The Function of REPEATABLE READ transaction isolation is in progress."); return 0; } } else { @@ -200,23 +206,23 @@ int unsupport_tx_isolation_level(set_var *setvar, bool &need_forward MY_ATTRIBUT return 0; } else if (tx_isol == ISO_REPEATABLE_READ) { push_warning_printf(current_thd, Sql_condition::SL_WARNING, ER_DISALLOWED_OPERATION, - "CTC: The Function of REPEATABLE READ transaction isolation is in progress."); + "CTC: The Function of REPEATABLE READ transaction isolation is in progress."); return 0; } } my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "CTC STORAGE ENGINE ONLY SUPPORT READ_COMMITTED TRANSACTION ISOLATION LEVEL."); + "CTC STORAGE ENGINE ONLY SUPPORT READ_COMMITTED TRANSACTION ISOLATION LEVEL."); return -1; } static std::unordered_map set_variable_rules_map = { - {"default_storage_engine", check_default_engine}, - {"max_connections", check_session_pool_volume}, - {"transaction_isolation", unsupport_tx_isolation_level} -}; + {"default_storage_engine", check_default_engine}, + {"max_connections", check_session_pool_volume}, + {"transaction_isolation", unsupport_tx_isolation_level}}; -static int ctc_get_user_var_string(MYSQL_THD thd, Item_func_get_user_var *itemFunc, string &user_val_str) { +static int ctc_get_user_var_string(MYSQL_THD thd, Item_func_get_user_var *itemFunc, string &user_val_str) +{ mysql_mutex_lock(&thd->LOCK_thd_data); String str; @@ -224,11 +230,12 @@ static int ctc_get_user_var_string(MYSQL_THD thd, Item_func_get_user_var *itemFu var_entry = find_or_nullptr(thd->user_vars, itemFunc->name.ptr()); if (var_entry == nullptr) { ctc_log_system("user var:%s have no value. no need to broadcast.", itemFunc->name.ptr()); - my_printf_error(ER_DISALLOWED_OPERATION, "[CTC]:Please make sure %s has value in it.", MYF(0), itemFunc->name.ptr()); + my_printf_error(ER_DISALLOWED_OPERATION, "[CTC]:Please make sure %s has value in it.", MYF(0), + itemFunc->name.ptr()); mysql_mutex_unlock(&thd->LOCK_thd_data); return -1; } - + bool is_var_null; String *var_value = var_entry->val_str(&is_var_null, &str, DECIMAL_NOT_SPECIFIED); @@ -241,10 +248,11 @@ static int ctc_get_user_var_string(MYSQL_THD thd, Item_func_get_user_var *itemFu return 0; } -static int allow_sqlcmd(MYSQL_THD thd, string session_var_name) { +static int allow_sqlcmd(MYSQL_THD thd, string session_var_name) +{ String str; user_var_entry *var_entry = find_or_nullptr(thd->user_vars, session_var_name); - if(var_entry == nullptr || var_entry->ptr() == nullptr) { + if (var_entry == nullptr || var_entry->ptr() == nullptr) { return 0; } bool is_var_null; @@ -258,10 +266,10 @@ static int allow_sqlcmd(MYSQL_THD thd, string session_var_name) { return 0; } -static int ctc_check_dcl(string &, MYSQL_THD thd, bool &need_forward) { +static int ctc_check_dcl(string &, MYSQL_THD thd, bool &need_forward) +{ if (check_readonly(thd, false) || - (thd->lex->query_tables != nullptr && - check_schema_readonly(thd, thd->lex->query_tables->table_name))) { + (thd->lex->query_tables != nullptr && check_schema_readonly(thd, thd->lex->query_tables->table_name))) { need_forward = false; } if (allow_sqlcmd(thd, "ctc_dcl_disabled") != 0) { @@ -272,7 +280,8 @@ static int ctc_check_dcl(string &, MYSQL_THD thd, bool &need_forward) { } // reference for 'validate_password_require_current' function -int ctc_verify_password4existed_user(MYSQL_THD thd, const LEX_USER *existed_user, bool &res) { +int ctc_verify_password4existed_user(MYSQL_THD thd, const LEX_USER *existed_user, bool &res) +{ ACL_USER *acl_user = nullptr; plugin_ref plugin = nullptr; int is_error = 0; @@ -288,7 +297,8 @@ int ctc_verify_password4existed_user(MYSQL_THD thd, const LEX_USER *existed_user } plugin = my_plugin_lock_by_name(nullptr, acl_user->plugin, MYSQL_AUTHENTICATION_PLUGIN); if (!plugin) { - ctc_log_error("ctc_verify_password failed, lock plugin %s failed", acl_user->plugin.str ? acl_user->plugin.str : ""); + ctc_log_error("ctc_verify_password failed, lock plugin %s failed", + acl_user->plugin.str ? acl_user->plugin.str : ""); return -1; } st_mysql_auth *auth = (st_mysql_auth *)plugin_decl(plugin)->info; @@ -296,9 +306,11 @@ int ctc_verify_password4existed_user(MYSQL_THD thd, const LEX_USER *existed_user if (acl_user->credentials[PRIMARY_CRED].m_auth_string.length == 0 && existed_user->current_auth.length > 0) { res = false; } else if ((auth->authentication_flags & AUTH_FLAG_USES_INTERNAL_STORAGE) && auth->compare_password_with_hash && - auth->compare_password_with_hash(acl_user->credentials[PRIMARY_CRED].m_auth_string.str, - (unsigned long)acl_user->credentials[PRIMARY_CRED].m_auth_string.length, existed_user->current_auth.str, - (unsigned long)existed_user->current_auth.length, &is_error) && !is_error) { + auth->compare_password_with_hash(acl_user->credentials[PRIMARY_CRED].m_auth_string.str, + (unsigned long)acl_user->credentials[PRIMARY_CRED].m_auth_string.length, + existed_user->current_auth.str, + (unsigned long)existed_user->current_auth.length, &is_error) && + !is_error) { res = false; } res = true; @@ -306,7 +318,8 @@ int ctc_verify_password4existed_user(MYSQL_THD thd, const LEX_USER *existed_user return 0; } -void ctc_remove_replace_clause4sql(string &sql_str) { +void ctc_remove_replace_clause4sql(string &sql_str) +{ // match: replace "xxx" | replace 'xxx' regex replace_pattern(" \\s*replace \\s*(\".*\"|'.*')", std::regex_constants::icase); sql_str = regex_replace(sql_str, replace_pattern, " "); @@ -317,7 +330,8 @@ void ctc_remove_replace_clause4sql(string &sql_str) { 1. alter user current_user() -> alter user 'user'@'host' 2. alter user current user && replace 'old password', we need check the old password to remove the 'replace clause' */ -static int ctc_rewrite_alter_user4update_passwd(MYSQL_THD thd, string &sql_str) { +static int ctc_rewrite_alter_user4update_passwd(MYSQL_THD thd, string &sql_str) +{ List_iterator user_list(thd->lex->users_list); LEX_USER *tmp_user; LEX_USER *user; @@ -365,7 +379,8 @@ static int ctc_rewrite_alter_user4update_passwd(MYSQL_THD thd, string &sql_str) return 0; } -static int ctc_check_alter_user(string &sql_str, MYSQL_THD thd, bool &need_forward) { +static int ctc_check_alter_user(string &sql_str, MYSQL_THD thd, bool &need_forward) +{ if (ctc_check_dcl(sql_str, thd, need_forward) != 0) { return -1; } @@ -373,9 +388,12 @@ static int ctc_check_alter_user(string &sql_str, MYSQL_THD thd, bool &need_forwa return ctc_rewrite_alter_user4update_passwd(thd, sql_str); } -static int ctc_rewrite_setpasswd(MYSQL_THD thd, string &sql_str) { - // match: set password = | set password to | set password for current_user(),but 'to' and '=' dont match for replacing - regex add_or_rewrite_for_pattern("^set \\s*password\\s*((?=to|=)|for \\s*current_user[(][)])", regex_constants::icase); +static int ctc_rewrite_setpasswd(MYSQL_THD thd, string &sql_str) +{ + // match: set password = | set password to | set password for current_user(),but 'to' and '=' dont match for + // replacing + regex add_or_rewrite_for_pattern("^set \\s*password\\s*((?=to|=)|for \\s*current_user[(][)])", + regex_constants::icase); string rw_query_sql = sql_str; string user2host(""); @@ -411,7 +429,8 @@ static int ctc_rewrite_setpasswd(MYSQL_THD thd, string &sql_str) { return 0; } -static int ctc_check_set_password(SENSI_INFO string &sql_str, MYSQL_THD thd, bool &need_forward) { +static int ctc_check_set_password(SENSI_INFO string &sql_str, MYSQL_THD thd, bool &need_forward) +{ if (ctc_check_dcl(sql_str, thd, need_forward) != 0) { return -1; } @@ -419,13 +438,14 @@ static int ctc_check_set_password(SENSI_INFO string &sql_str, MYSQL_THD thd, boo return ctc_rewrite_setpasswd(thd, sql_str); } -static int ctc_check_flush(string &, MYSQL_THD thd, bool &need_forward) { +static int ctc_check_flush(string &, MYSQL_THD thd, bool &need_forward) +{ need_forward = thd->lex->type & (REFRESH_FOR_EXPORT | REFRESH_READ_LOCK | REFRESH_GRANT); return 0; } -static uint32_t ctc_set_var_option(bool is_null_value, bool is_set_default_value, - set_var *setvar) { +static uint32_t ctc_set_var_option(bool is_null_value, bool is_set_default_value, set_var *setvar) +{ uint32_t options = 0; if (is_null_value) { options |= CTC_SET_VARIABLE_TO_NULL; @@ -442,15 +462,16 @@ static uint32_t ctc_set_var_option(bool is_null_value, bool is_set_default_value return options; } -static int ctc_set_var_meta(MYSQL_THD thd, uint32_t options, const char* base_name, - string var_name, string var_value, bool var_real_type) { +static int ctc_set_var_meta(MYSQL_THD thd, uint32_t options, const char *base_name, string var_name, string var_value, + bool var_real_type) +{ ctc_handler_t tch; tch.inst_id = ctc_instance_id; - handlerton* hton = get_ctc_hton(); + handlerton *hton = get_ctc_hton(); CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); - ctc_ddl_broadcast_request broadcast_req {{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; + ctc_ddl_broadcast_request broadcast_req{{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; broadcast_req.options |= CTC_NOT_NEED_CANTIAN_EXECUTE; broadcast_req.options |= (thd->lex->contains_plaintext_password ? CTC_CURRENT_SQL_CONTAIN_PLAINTEXT_PASSWORD : 0); string sql = string(thd->query().str).substr(0, thd->query().length); @@ -459,9 +480,9 @@ static int ctc_set_var_meta(MYSQL_THD thd, uint32_t options, const char* base_na broadcast_req.user_ip[0] |= 1; } // user_name存变量名,user_ip存变量值 - FILL_BROADCAST_BASE_REQ(broadcast_req, var_value.c_str(), var_name.c_str(), - broadcast_req.user_ip, ctc_instance_id, SQLCOM_SET_OPTION); - if(base_name != nullptr) { + FILL_BROADCAST_BASE_REQ(broadcast_req, var_value.c_str(), var_name.c_str(), broadcast_req.user_ip, ctc_instance_id, + SQLCOM_SET_OPTION); + if (base_name != nullptr) { strncpy(broadcast_req.db_name, base_name, SMALL_RECORD_SIZE - 1); } broadcast_req.options |= options; @@ -475,8 +496,9 @@ static int ctc_set_var_meta(MYSQL_THD thd, uint32_t options, const char* base_na return ret; } -static int ctc_get_variables_value_string(MYSQL_THD thd, string &sql_str, set_var* setvar, string& val_str, - bool& is_null_value, bool &need_forward) { +static int ctc_get_variables_value_string(MYSQL_THD thd, string &sql_str, set_var *setvar, string &val_str, + bool &is_null_value, bool &need_forward) +{ Item_func_get_user_var *itemFunc = dynamic_cast(setvar->value); Item_func_get_system_var *itemFuncSys = dynamic_cast(setvar->value); @@ -496,7 +518,7 @@ static int ctc_get_variables_value_string(MYSQL_THD thd, string &sql_str, set_va } } else if (itemFuncSys) { // 从系统变量取值 - String* new_str; + String *new_str; String str; ctc_log_system("[CTC_DDL_REWRITE]:get system var value. %s", sql_str.c_str()); #ifdef FEATURE_X_FOR_MYSQL_26 @@ -518,7 +540,7 @@ static int ctc_get_variables_value_string(MYSQL_THD thd, string &sql_str, set_va } } else { // 其他变量类型 - String* new_str; + String *new_str; String str; if (!(new_str = setvar->value->val_str(&str))) { is_null_value = true; @@ -530,7 +552,8 @@ static int ctc_get_variables_value_string(MYSQL_THD thd, string &sql_str, set_va return 0; } -static int ctc_check_set_opt_rule(set_var *setvar, string& name_str, string& user_val_str, bool& need_forward) { +static int ctc_check_set_opt_rule(set_var *setvar, string &name_str, string &user_val_str, bool &need_forward) +{ int ret = 0; transform(name_str.begin(), name_str.end(), name_str.begin(), ::tolower); auto it = set_variable_rules_map.find(name_str); @@ -544,8 +567,9 @@ static int ctc_check_set_opt_rule(set_var *setvar, string& name_str, string& use return ret; } -static int ctc_set_user_var_flag(MYSQL_THD thd, string name, string value) { - handlerton* hton = get_ctc_hton(); +static int ctc_set_user_var_flag(MYSQL_THD thd, string name, string value) +{ + handlerton *hton = get_ctc_hton(); thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(hton, thd); if (sess_ctx == nullptr) { return HA_ERR_OUT_OF_MEM; @@ -559,15 +583,16 @@ static int ctc_set_user_var_flag(MYSQL_THD thd, string name, string value) { } else if (is_flag_unset) { sess_ctx->set_flag &= ~it->second; } else { - my_printf_error(ER_UNKNOWN_COM_ERROR, "Invalid variable value for '%s': '%s'", MYF(0), - name.c_str(), value.c_str()); + my_printf_error(ER_UNKNOWN_COM_ERROR, "Invalid variable value for '%s': '%s'", MYF(0), name.c_str(), + value.c_str()); return -1; } } return 0; } -static int check_non_system_var(set_var_base *var, bool& need_forward, MYSQL_THD thd) { +static int check_non_system_var(set_var_base *var, bool &need_forward, MYSQL_THD thd) +{ need_forward = false; if (typeid(*var) != typeid(set_var_user)) { return 0; @@ -587,25 +612,26 @@ static int check_non_system_var(set_var_base *var, bool& need_forward, MYSQL_THD string str(set_str.ptr(), set_str.length()); size_t pos = str.find("@"); if (pos != str.npos) { - size_t end_pos = str.find(":=", pos); - if (end_pos != str.npos) { - size_t name_start = pos + 1; - size_t name_len = end_pos - name_start; - var_name = str.substr(name_start, name_len); - } + size_t end_pos = str.find(":=", pos); + if (end_pos != str.npos) { + size_t name_start = pos + 1; + size_t name_len = end_pos - name_start; + var_name = str.substr(name_start, name_len); + } } size_t value_pos = str.find(":="); if (value_pos != str.npos) { - size_t value_start = value_pos + 2; - size_t value_len = str.length() - value_start; - var_value = str.substr(value_start, value_len); + size_t value_start = value_pos + 2; + size_t value_len = str.length() - value_start; + var_value = str.substr(value_start, value_len); } return ctc_set_user_var_flag(thd, var_name, var_value); } -static int check_system_var(set_var_base *var, string &sql_str, MYSQL_THD thd, - bool& need_forward, bool& contain_subselect) { +static int check_system_var(set_var_base *var, string &sql_str, MYSQL_THD thd, bool &need_forward, + bool &contain_subselect) +{ set_var *setvar = dynamic_cast(var); bool is_set_default_value = false; bool is_null_value = false; @@ -613,63 +639,62 @@ static int check_system_var(set_var_base *var, string &sql_str, MYSQL_THD thd, string name_str; string val_str; #ifdef FEATURE_X_FOR_MYSQL_32 - if (setvar) { - std::function f = [&thd, &need_forward, setvar] - (const System_variable_tracker &, sys_var *system_var) { - if (system_var) { - need_forward = !system_var->is_readonly() && setvar->is_global_persist(); - } - return true; - }; - setvar->m_var_tracker.access_system_variable(thd, f).value_or(true); - name_str = setvar->m_var_tracker.get_var_name(); + if (setvar) { + std::function f = + [&thd, &need_forward, setvar](const System_variable_tracker &, sys_var *system_var) { + if (system_var) { + need_forward = !system_var->is_readonly() && setvar->is_global_persist(); + } + return true; + }; + setvar->m_var_tracker.access_system_variable(thd, f).value_or(true); + name_str = setvar->m_var_tracker.get_var_name(); #elif defined(FEATURE_X_FOR_MYSQL_26) - if (setvar && setvar->var) { - need_forward = !setvar->var->is_readonly() && setvar->is_global_persist() - && setvar->var->check_scope(OPT_GLOBAL); - name_str = setvar->var->name.str; + if (setvar && setvar->var) { + need_forward = !setvar->var->is_readonly() && setvar->is_global_persist() && setvar->var->check_scope(OPT_GLOBAL); + name_str = setvar->var->name.str; #endif - - if (!contain_subselect) { - /* get user value (@xxxxx) as string */ - if (!setvar->value) { - is_set_default_value = true; - val_str = ""; - } else { - ret = ctc_get_variables_value_string(thd, sql_str, setvar, val_str, is_null_value, need_forward); - } - ret |= ctc_check_set_opt_rule(setvar, name_str, val_str, need_forward); + + if (!contain_subselect) { + /* get user value (@xxxxx) as string */ + if (!setvar->value) { + is_set_default_value = true; + val_str = ""; + } else { + ret = ctc_get_variables_value_string(thd, sql_str, setvar, val_str, is_null_value, need_forward); } + ret |= ctc_check_set_opt_rule(setvar, name_str, val_str, need_forward); } - if (need_forward && allow_sqlcmd(thd, "ctc_setopt_disabled") != 0) { - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Set global variable query is not allowed (ctc_setopt_disabled = true)"); - return -1; - } + } + if (need_forward && allow_sqlcmd(thd, "ctc_setopt_disabled") != 0) { + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), + "Set global variable query is not allowed (ctc_setopt_disabled = true)"); + return -1; + } - if (IS_METADATA_NORMALIZATION() && !contain_subselect && need_forward && setvar) { - if (setvar->check(thd) == 0) { - bool var_real_type = false; - if (setvar->value && setvar->value->result_type() == INT_RESULT) { - var_real_type = true; - } - uint32_t options = ctc_set_var_option(is_null_value, is_set_default_value, setvar); + if (IS_METADATA_NORMALIZATION() && !contain_subselect && need_forward && setvar) { + if (setvar->check(thd) == 0) { + bool var_real_type = false; + if (setvar->value && setvar->value->result_type() == INT_RESULT) { + var_real_type = true; + } + uint32_t options = ctc_set_var_option(is_null_value, is_set_default_value, setvar); #ifdef FEATURE_X_FOR_MYSQL_26 - ret = ctc_set_var_meta(thd, options, setvar->base.str, name_str, val_str, var_real_type); + ret = ctc_set_var_meta(thd, options, setvar->base.str, name_str, val_str, var_real_type); #elif defined(FEATURE_X_FOR_MYSQL_32) - ret = ctc_set_var_meta(thd, options, setvar->m_var_tracker.get_var_name(), - name_str, val_str, var_real_type); + ret = ctc_set_var_meta(thd, options, setvar->m_var_tracker.get_var_name(), name_str, val_str, var_real_type); #endif - } else { - thd->clear_error(); - need_forward = false; // 值校验失败, ctc不进行广播并返回成功, 后续报错由MySQL完成 - } + } else { + thd->clear_error(); + need_forward = false; // 值校验失败, ctc不进行广播并返回成功, 后续报错由MySQL完成 } - return ret; + } + return ret; } /* 参考set_var.cc: sql_set_variables */ -static int ctc_check_set_opt(string &sql_str, MYSQL_THD thd, bool &need_forward) { +static int ctc_check_set_opt(string &sql_str, MYSQL_THD thd, bool &need_forward) +{ List_iterator_fast var_it(thd->lex->var_list); set_var_base *var = nullptr; @@ -695,17 +720,20 @@ static int ctc_check_set_opt(string &sql_str, MYSQL_THD thd, bool &need_forward) return ret; } -static int is_system_db(const char *ddl_db) { +static int is_system_db(const char *ddl_db) +{ if (mysql_system_db.find(ddl_db) != mysql_system_db.end()) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Once the CTC is loaded, it must be used as the default engine. To specify other engine for table, uninstall the CTC first."); + "Once the CTC is loaded, it must be used as the default engine. To specify other engine for table, " + "uninstall the CTC first."); return -1; } return 0; } -static int ctc_check_ddl_engine(string &, MYSQL_THD thd, bool &need_forward) { - need_forward = false; // broadcast by storage engine +static int ctc_check_ddl_engine(string &, MYSQL_THD thd, bool &need_forward) +{ + need_forward = false; // broadcast by storage engine LEX_CSTRING ctc_name; ctc_name.str = ctc_hton_name; ctc_name.length = strlen(ctc_hton_name); @@ -717,23 +745,19 @@ static int ctc_check_ddl_engine(string &, MYSQL_THD thd, bool &need_forward) { } // 检查ddl语句是否显示指定非CTC - if (thd->lex->create_info != nullptr && - thd->lex->create_info->db_type != nullptr && - thd->lex->create_info->db_type != ctc_handlerton && - !(thd->lex->create_info->options & HA_LEX_CREATE_TMP_TABLE)) { + if (thd->lex->create_info != nullptr && thd->lex->create_info->db_type != nullptr && + thd->lex->create_info->db_type != ctc_handlerton && !(thd->lex->create_info->options & HA_LEX_CREATE_TMP_TABLE)) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Once the CTC is loaded, it must be used as the default engine. To specify other engine for table, uninstall the CTC first."); + "Once the CTC is loaded, it must be used as the default engine. To specify other engine for table, " + "uninstall the CTC first."); return -1; } if (!IS_METADATA_NORMALIZATION()) { // create like table 检查是否是系统库 - if (thd->lex->query_tables != nullptr && - thd->lex->query_tables->next_global != nullptr && - thd->lex->create_info != nullptr && - thd->lex->create_info->options & HA_LEX_CREATE_TABLE_LIKE && - !(thd->lex->create_info->options & HA_LEX_CREATE_TMP_TABLE) && - !thd->lex->drop_temporary) { + if (thd->lex->query_tables != nullptr && thd->lex->query_tables->next_global != nullptr && + thd->lex->create_info != nullptr && thd->lex->create_info->options & HA_LEX_CREATE_TABLE_LIKE && + !(thd->lex->create_info->options & HA_LEX_CREATE_TMP_TABLE) && !thd->lex->drop_temporary) { const char *ddl_db = thd->lex->query_tables->next_global->db; return is_system_db(ddl_db); } @@ -742,11 +766,11 @@ static int ctc_check_ddl_engine(string &, MYSQL_THD thd, bool &need_forward) { // create tablespace 检查是否为engine=Innodb情况 if (thd->lex->sql_command == SQLCOM_ALTER_TABLESPACE) { const Sql_cmd_tablespace *sct = dynamic_cast(thd->lex->m_sql_cmd); - if (sct != nullptr && - sct->get_options().engine_name.str != nullptr && + if (sct != nullptr && sct->get_options().engine_name.str != nullptr && strcmp(sct->get_options().engine_name.str, ctc_name.str) != 0) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Once the CTC is loaded, it must be used as the default engine. To specify other engine for table, uninstall the CTC first."); + "Once the CTC is loaded, it must be used as the default engine. To specify other engine for " + "table, uninstall the CTC first."); return -1; } } @@ -764,28 +788,31 @@ static int ctc_check_ddl_engine(string &, MYSQL_THD thd, bool &need_forward) { return 0; } -static int ctc_check_ddl(string &, MYSQL_THD, bool &need_forward) { - need_forward = false; // broadcast by storage engine +static int ctc_check_ddl(string &, MYSQL_THD, bool &need_forward) +{ + need_forward = false; // broadcast by storage engine return 0; } -static int ctc_check_unspport_ddl(string &, MYSQL_THD, bool &) { +static int ctc_check_unspport_ddl(string &, MYSQL_THD, bool &) +{ my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "Cantian doesn't support current operation"); return -1; } -static int ctc_read_only_ddl(string &, MYSQL_THD thd, bool &need_forward) { +static int ctc_read_only_ddl(string &, MYSQL_THD thd, bool &need_forward) +{ if (check_readonly(thd, true) || - (thd->lex->query_tables != nullptr && - check_schema_readonly(thd, thd->lex->query_tables->table_name))) { + (thd->lex->query_tables != nullptr && check_schema_readonly(thd, thd->lex->query_tables->table_name))) { need_forward = false; } return 0; } -static int ctc_lock_tables_ddl(string &, MYSQL_THD thd, bool &) { +static int ctc_lock_tables_ddl(string &, MYSQL_THD thd, bool &) +{ int ret = 0; - vector ticket_list; + vector ticket_list; int pre_lock_ret = ctc_lock_table_pre(thd, ticket_list, MDL_SHARED_NO_READ_WRITE); if (pre_lock_ret != 0) { ctc_lock_table_post(thd, ticket_list); @@ -801,7 +828,7 @@ static int ctc_lock_tables_ddl(string &, MYSQL_THD thd, bool &) { #endif ctc_handler_t tch; tch.inst_id = ctc_instance_id; - handlerton* hton = get_ctc_hton(); + handlerton *hton = get_ctc_hton(); CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); int32_t mdl_type = 0; @@ -828,13 +855,13 @@ static int ctc_lock_tables_ddl(string &, MYSQL_THD thd, bool &) { if (ret != 0) { #ifdef FEATURE_X_FOR_MYSQL_32 - for (Table_ref *table = tables; table != NULL; table = table->next_global) { + for (Table_ref *table = tables; table != NULL; table = table->next_global) { #elif defined(FEATURE_X_FOR_MYSQL_26) - for (TABLE_LIST *table = tables; table != NULL; table = table->next_global) { + for (TABLE_LIST *table = tables; table != NULL; table = table->next_global) { #endif ctc_handler_t tch; tch.inst_id = ctc_instance_id; - handlerton* hton = get_ctc_hton(); + handlerton *hton = get_ctc_hton(); CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); ctc_lock_table_info lock_info = {{0}, {0}, {0}, {0}, SQLCOM_LOCK_TABLES, (int32_t)TL_UNLOCK}; @@ -850,12 +877,13 @@ static int ctc_lock_tables_ddl(string &, MYSQL_THD thd, bool &) { return ret; } -static int ctc_unlock_tables_ddl(string &, MYSQL_THD thd, bool &) { +static int ctc_unlock_tables_ddl(string &, MYSQL_THD thd, bool &) +{ int ret = 0; ctc_handler_t tch; tch.inst_id = ctc_instance_id; - handlerton* hton = get_ctc_hton(); + handlerton *hton = get_ctc_hton(); CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); @@ -868,14 +896,12 @@ static int ctc_unlock_tables_ddl(string &, MYSQL_THD thd, bool &) { return ret; } -typedef struct ddl_broadcast_cmd_s -{ - bool need_select_db; // 需要指定数据库 - int (*pre_func)(string &sql_str, MYSQL_THD thd, bool &need_forward); //转发之前的预处理函数,为空则不调用 +typedef struct ddl_broadcast_cmd_s { + bool need_select_db; // 需要指定数据库 + int (*pre_func)(string &sql_str, MYSQL_THD thd, bool &need_forward); // 转发之前的预处理函数,为空则不调用 } ddl_broadcast_cmd; -static unordered_map - ddl_cmds = { +static unordered_map ddl_cmds = { // DCL,broadcast on !ctc_dcl_disabled {SQLCOM_GRANT, {true, ctc_check_dcl}}, {SQLCOM_REVOKE, {false, ctc_check_dcl}}, @@ -990,21 +1016,20 @@ static unordered_map }; -bool is_ddl_sql_cmd(enum_sql_command sql_cmd) { +bool is_ddl_sql_cmd(enum_sql_command sql_cmd) +{ if (ddl_cmds.find(sql_cmd) != ddl_cmds.end()) { return true; } return false; } -bool is_dcl_sql_cmd(enum_sql_command sql_cmd) { - - if (sql_cmd == SQLCOM_GRANT || sql_cmd == SQLCOM_REVOKE || - sql_cmd == SQLCOM_CREATE_USER || sql_cmd == SQLCOM_DROP_USER || - sql_cmd == SQLCOM_RENAME_USER || sql_cmd == SQLCOM_REVOKE_ALL || - sql_cmd == SQLCOM_ALTER_USER || sql_cmd == SQLCOM_ALTER_USER_DEFAULT_ROLE || - sql_cmd == SQLCOM_CREATE_ROLE || sql_cmd == SQLCOM_DROP_ROLE || - sql_cmd == SQLCOM_SET_ROLE || sql_cmd ==SQLCOM_GRANT_ROLE || +bool is_dcl_sql_cmd(enum_sql_command sql_cmd) +{ + if (sql_cmd == SQLCOM_GRANT || sql_cmd == SQLCOM_REVOKE || sql_cmd == SQLCOM_CREATE_USER || + sql_cmd == SQLCOM_DROP_USER || sql_cmd == SQLCOM_RENAME_USER || sql_cmd == SQLCOM_REVOKE_ALL || + sql_cmd == SQLCOM_ALTER_USER || sql_cmd == SQLCOM_ALTER_USER_DEFAULT_ROLE || sql_cmd == SQLCOM_CREATE_ROLE || + sql_cmd == SQLCOM_DROP_ROLE || sql_cmd == SQLCOM_SET_ROLE || sql_cmd == SQLCOM_GRANT_ROLE || sql_cmd == SQLCOM_REVOKE_ROLE) { return true; } @@ -1018,7 +1043,8 @@ static PSI_memory_key key_memory_ctc_ddl_rewriter; static PSI_memory_info all_rewrite_memory[] = { {&key_memory_ctc_ddl_rewriter, "ctc_ddl_rewriter", 0, 0, PSI_DOCUMENT_ME}}; -static int plugin_init(MYSQL_PLUGIN) { +static int plugin_init(MYSQL_PLUGIN) +{ const char *category = "rewriter"; int count = static_cast(array_elements(all_rewrite_memory)); mysql_memory_register(category, all_rewrite_memory, count); @@ -1030,19 +1056,24 @@ static int plugin_init(MYSQL_PLUGIN) { #define key_memory_ctc_ddl_rewriter PSI_NOT_INSTRUMENTED #endif /* HAVE_PSI_INTERFACE */ -static void ctc_ddl_rewrite_handle_error(MYSQL_THD thd, int ret, ctc_ddl_broadcast_request &broadcast_req, uint8_t sql_cmd) { +static void ctc_ddl_rewrite_handle_error(MYSQL_THD thd, int ret, ctc_ddl_broadcast_request &broadcast_req, + uint8_t sql_cmd) +{ if (ret == CTC_DDL_VERSION_NOT_MATCH) { broadcast_req.err_code = ER_DISALLOWED_OPERATION; - my_printf_error(ER_DISALLOWED_OPERATION, "Version not match. Please make sure cluster on the same version.", MYF(0)); - ctc_log_system("[CTC_DDL_REWRITE]: Version not match, sql=%s", sql_without_plaintext_password(&broadcast_req).c_str()); + my_printf_error(ER_DISALLOWED_OPERATION, "Version not match. Please make sure cluster on the same version.", + MYF(0)); + ctc_log_system("[CTC_DDL_REWRITE]: Version not match, sql=%s", + sql_without_plaintext_password(&broadcast_req).c_str()); return; } my_printf_error(broadcast_req.err_code, "Got error(err_code:%d, err_msg:%s) on remote mysql.", MYF(0), - broadcast_req.err_code, broadcast_req.err_msg); + broadcast_req.err_code, broadcast_req.err_msg); ctc_log_error("[CTC_DDL_REWRITE]:Got error on remote mysql, query:%s, user_name:%s, err_code:%d, err_msg:%s", - sql_without_plaintext_password(&broadcast_req).c_str(), broadcast_req.user_name, broadcast_req.err_code, broadcast_req.err_msg); + sql_without_plaintext_password(&broadcast_req).c_str(), broadcast_req.user_name, broadcast_req.err_code, + broadcast_req.err_msg); // unlock when lock instance failed if (sql_cmd == SQLCOM_LOCK_INSTANCE) { @@ -1052,18 +1083,17 @@ static void ctc_ddl_rewrite_handle_error(MYSQL_THD thd, int ret, ctc_ddl_broadca return; } -int ddl_broadcast_and_wait(MYSQL_THD thd, string &query_str, - uint8_t sql_cmd, ddl_broadcast_cmd &broadcast_cmd) { +int ddl_broadcast_and_wait(MYSQL_THD thd, string &query_str, uint8_t sql_cmd, ddl_broadcast_cmd &broadcast_cmd) +{ ctc_handler_t tch; memset(&tch, 0, sizeof(tch)); tch.inst_id = ctc_instance_id; handlerton *hton = get_ctc_hton(); update_member_tch(tch, hton, thd); - ctc_ddl_broadcast_request broadcast_req {{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; + ctc_ddl_broadcast_request broadcast_req{{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; - if (thd->db().str != NULL && strlen(thd->db().str) > 0 && - broadcast_cmd.need_select_db) { + if (thd->db().str != NULL && strlen(thd->db().str) > 0 && broadcast_cmd.need_select_db) { strncpy(broadcast_req.db_name, thd->db().str, SMALL_RECORD_SIZE - 1); } @@ -1074,9 +1104,9 @@ int ddl_broadcast_and_wait(MYSQL_THD thd, string &query_str, broadcast_req.options |= CTC_NOT_NEED_CANTIAN_EXECUTE; broadcast_req.options |= (thd->lex->contains_plaintext_password ? CTC_CURRENT_SQL_CONTAIN_PLAINTEXT_PASSWORD : 0); FILL_BROADCAST_BASE_REQ(broadcast_req, query_str.c_str(), thd->m_main_security_ctx.priv_user().str, - thd->m_main_security_ctx.priv_host().str, ctc_instance_id, sql_cmd); - - vector ticket_list; + thd->m_main_security_ctx.priv_host().str, ctc_instance_id, sql_cmd); + + vector ticket_list; if (sql_cmd == SQLCOM_LOCK_TABLES) { int pre_lock_ret = ctc_lock_table_pre(thd, ticket_list, MDL_SHARED_NO_READ_WRITE); if (pre_lock_ret != 0) { @@ -1093,22 +1123,27 @@ int ddl_broadcast_and_wait(MYSQL_THD thd, string &query_str, ctc_lock_table_post(thd, ticket_list); } - DBUG_EXECUTE_IF("ctc_ddl_rewrite_broadcast_fail", { ret = CTC_DDL_VERSION_NOT_MATCH;broadcast_req.err_code = ER_DISALLOWED_OPERATION; }); + DBUG_EXECUTE_IF("ctc_ddl_rewrite_broadcast_fail", { + ret = CTC_DDL_VERSION_NOT_MATCH; + broadcast_req.err_code = ER_DISALLOWED_OPERATION; + }); if (ret != 0 && broadcast_req.err_code != 0) { ctc_ddl_rewrite_handle_error(thd, ret, broadcast_req, sql_cmd); return broadcast_req.err_code; } - ctc_log_system("[CTC_DDL_REWRITE]:ret:%d, query:%s, user_name:%s, err_code:%d, broadcast_inst_id:%u, " - "conn_id:%u, ctc_inst_id:%u", ret, sql_without_plaintext_password(&broadcast_req).c_str(), broadcast_req.user_name, - broadcast_req.err_code, broadcast_req.mysql_inst_id, tch.thd_id, tch.inst_id); + ctc_log_system( + "[CTC_DDL_REWRITE]:ret:%d, query:%s, user_name:%s, err_code:%d, broadcast_inst_id:%u, " + "conn_id:%u, ctc_inst_id:%u", + ret, sql_without_plaintext_password(&broadcast_req).c_str(), broadcast_req.user_name, broadcast_req.err_code, + broadcast_req.mysql_inst_id, tch.thd_id, tch.inst_id); update_sess_ctx_by_tch(tch, hton, thd); return convert_ctc_error_code_to_mysql((ct_errno_t)ret); } -bool plugin_ddl_passthru(MYSQL_THD thd, - unordered_map::iterator &it) { +bool plugin_ddl_passthru(MYSQL_THD thd, unordered_map::iterator &it) +{ if (it == ddl_cmds.end()) { return true; } @@ -1129,24 +1164,22 @@ bool plugin_ddl_passthru(MYSQL_THD thd, return false; } -bool check_agent_connection(MYSQL_THD thd) { +bool check_agent_connection(MYSQL_THD thd) +{ // Only user from localhost/127.0.0.1 or % can be proxied remotely if (strcmp(thd->m_main_security_ctx.priv_host().str, my_localhost) != 0 && strcmp(thd->m_main_security_ctx.priv_host().str, "127.0.0.1") != 0 && strcmp(thd->m_main_security_ctx.priv_host().str, "%") != 0 && strcmp(thd->m_main_security_ctx.priv_host().str, "skip-grants host") != 0) { - my_printf_error(ER_DISALLOWED_OPERATION, - "%s@%s is not allowed for DDL remote execution!", MYF(0), - thd->m_main_security_ctx.priv_user().str, - thd->m_main_security_ctx.priv_host().str); + my_printf_error(ER_DISALLOWED_OPERATION, "%s@%s is not allowed for DDL remote execution!", MYF(0), + thd->m_main_security_ctx.priv_user().str, thd->m_main_security_ctx.priv_host().str); return true; } MYSQL *agent_conn = NULL; // 连接mysql server失败,不允许执行ddl操作 if (ctc_init_agent_client(agent_conn) != 0) { - my_printf_error(ER_DISALLOWED_OPERATION, - "Failed to establish connection for DDL remote execution!", MYF(0)); + my_printf_error(ER_DISALLOWED_OPERATION, "Failed to establish connection for DDL remote execution!", MYF(0)); ctc_close_mysql_conn(&agent_conn); return true; } @@ -1155,14 +1188,15 @@ bool check_agent_connection(MYSQL_THD thd) { return false; } -int ctc_record_sql(MYSQL_THD thd, bool need_select_db) { +int ctc_record_sql(MYSQL_THD thd, bool need_select_db) +{ ctc_handler_t tch; tch.inst_id = ctc_instance_id; - handlerton* hton = get_ctc_hton(); + handlerton *hton = get_ctc_hton(); CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); - ctc_ddl_broadcast_request broadcast_req {{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; + ctc_ddl_broadcast_request broadcast_req{{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; if (thd->db().str != NULL && strlen(thd->db().str) > 0 && need_select_db) { strncpy(broadcast_req.db_name, thd->db().str, SMALL_RECORD_SIZE - 1); @@ -1173,8 +1207,8 @@ int ctc_record_sql(MYSQL_THD thd, bool need_select_db) { string sql = string(thd->query().str).substr(0, thd->query().length); FILL_BROADCAST_BASE_REQ(broadcast_req, sql.c_str(), thd->m_main_security_ctx.priv_user().str, - thd->m_main_security_ctx.priv_host().str, ctc_instance_id, (uint8_t)thd->lex->sql_command); - + thd->m_main_security_ctx.priv_host().str, ctc_instance_id, (uint8_t)thd->lex->sql_command); + int ret = ctc_record_sql_for_cantian(&tch, &broadcast_req, false); update_sess_ctx_by_tch(tch, hton, thd); @@ -1183,16 +1217,14 @@ int ctc_record_sql(MYSQL_THD thd, bool need_select_db) { return ret; } -bool plugin_ddl_block(MYSQL_THD thd, - unordered_map::iterator &it, - string &query_str, - bool &need_forward) { +bool plugin_ddl_block(MYSQL_THD thd, unordered_map::iterator &it, + string &query_str, bool &need_forward) +{ ddl_broadcast_cmd broadcast_cmd = it->second; if (broadcast_cmd.pre_func != NULL) { int ret = broadcast_cmd.pre_func(query_str, thd, need_forward); if (ret != 0) { - ctc_log_system("pre_func execute failed,ret:%d,cmd:%d, sql:%s", - ret, it->first, query_str.c_str()); + ctc_log_system("pre_func execute failed,ret:%d,cmd:%d, sql:%s", ret, it->first, query_str.c_str()); return true; } } @@ -1219,7 +1251,8 @@ bool plugin_ddl_block(MYSQL_THD thd, } // disallow ddl query if ctc_concurrent_ddl=OFF and ctc_enable_ddl not set if (!ddl_enabled_normal(thd)) { - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "DDL not allowed in this mode, Please check the value of @@ctc_concurrent_ddl."); + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), + "DDL not allowed in this mode, Please check the value of @@ctc_concurrent_ddl."); return true; } @@ -1229,26 +1262,29 @@ bool plugin_ddl_block(MYSQL_THD thd, return false; } -// due to MDL_key::BACKUP_LOCK`s MDL_INTENTION_EXCLUSIVE comflicts with MDL_key::BACKUP_LOCK`s MDL_SHARED (user execute STMT `lock instance for backup`) -static bool ctc_is_instance_locked_by_backup(MYSQL_THD thd) { +// due to MDL_key::BACKUP_LOCK`s MDL_INTENTION_EXCLUSIVE comflicts with MDL_key::BACKUP_LOCK`s MDL_SHARED (user execute +// STMT `lock instance for backup`) +static bool ctc_is_instance_locked_by_backup(MYSQL_THD thd) +{ MDL_request mdl_request; MDL_key key(MDL_key::BACKUP_LOCK, "", ""); // check this conn whether has backup S lock if (thd->mdl_context.owns_equal_or_stronger_lock(&key, MDL_SHARED)) { - return true; + return true; } // check other conn whether has backup S lock MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP_LOCK, "", "", MDL_INTENTION_EXCLUSIVE, MDL_EXPLICIT); if (thd->mdl_context.acquire_lock(&mdl_request, 0)) { - thd->clear_error(); // clear lock failed error + thd->clear_error(); // clear lock failed error return true; } else { - thd->mdl_context.release_lock(mdl_request.ticket); // MDL_EXPLICIT need us to release when locked succeed + thd->mdl_context.release_lock(mdl_request.ticket); // MDL_EXPLICIT need us to release when locked succeed return false; } } -static bool ctc_is_have_global_read_lock(MYSQL_THD thd) { +static bool ctc_is_have_global_read_lock(MYSQL_THD thd) +{ // check if current connetion hold global read lock, let it go if (thd->global_read_lock.is_acquired()) { return false; @@ -1262,18 +1298,20 @@ static bool ctc_is_have_global_read_lock(MYSQL_THD thd) { return false; } -static inline bool ctc_is_broadcast_by_storage_engine(ddl_broadcast_cmd broadcast_cmd) { +static inline bool ctc_is_broadcast_by_storage_engine(ddl_broadcast_cmd broadcast_cmd) +{ return broadcast_cmd.pre_func == ctc_check_ddl || broadcast_cmd.pre_func == ctc_check_ddl_engine; } -static bool ctc_is_set_session_var(MYSQL_THD thd, string &query_str) { +static bool ctc_is_set_session_var(MYSQL_THD thd, string &query_str) +{ if (thd->lex->sql_command != SQLCOM_SET_OPTION) { return false; } set_var_base *var = nullptr; List_iterator_fast var_it(thd->lex->var_list); - + while ((var = var_it++)) { // identify SET statement other than GLOBAL scop set_var *setvar = dynamic_cast(var); @@ -1293,7 +1331,8 @@ static bool ctc_is_set_session_var(MYSQL_THD thd, string &query_str) { return false; } -static int ctc_check_metadata_switch() { +static int ctc_check_metadata_switch() +{ metadata_switchs metadata_switch = (metadata_switchs)ctc_get_metadata_switch(); switch (metadata_switch) { case metadata_switchs::MATCH_META: { @@ -1316,17 +1355,15 @@ static int ctc_check_metadata_switch() { } } -static int ctc_ddl_rewrite(MYSQL_THD thd, mysql_event_class_t event_class, - const void *event) { +static int ctc_ddl_rewrite(MYSQL_THD thd, mysql_event_class_t event_class, const void *event) +{ if (is_meta_version_initialize()) { return 0; } /* We can exit early if this is not a pre-parse event. */ - const struct mysql_event_parse *event_parse = - static_cast(event); - assert(event_class == MYSQL_AUDIT_PARSE_CLASS && - event_parse->event_subclass == MYSQL_AUDIT_PARSE_POSTPARSE); + const struct mysql_event_parse *event_parse = static_cast(event); + assert(event_class == MYSQL_AUDIT_PARSE_CLASS && event_parse->event_subclass == MYSQL_AUDIT_PARSE_POSTPARSE); if (event_class != MYSQL_AUDIT_PARSE_CLASS || event_parse->event_subclass != MYSQL_AUDIT_PARSE_POSTPARSE) { return 1; } @@ -1343,7 +1380,7 @@ static int ctc_ddl_rewrite(MYSQL_THD thd, mysql_event_class_t event_class, if (plugin_ddl_block(thd, it, query_str, need_forward)) { return -1; } - + int check_metadata_switch_result = ctc_check_metadata_switch(); // for non-metadata-normalization's gate test DBUG_EXECUTE_IF("non_metadata_normalization", { check_metadata_switch_result = 1; }); @@ -1351,7 +1388,7 @@ static int ctc_ddl_rewrite(MYSQL_THD thd, mysql_event_class_t event_class, if (check_metadata_switch_result != 1 && !(need_forward && sql_cmd == SQLCOM_SET_OPTION)) { return check_metadata_switch_result; } - + if (sql_cmd == SQLCOM_LOCK_INSTANCE) { if (ctc_check_lock_instance(thd, need_forward)) { return -1; @@ -1361,7 +1398,6 @@ static int ctc_ddl_rewrite(MYSQL_THD thd, mysql_event_class_t event_class, } else if (!IS_METADATA_NORMALIZATION() && (need_forward || ctc_is_broadcast_by_storage_engine(it->second))) { // block ddl when instance has exclusive backup lock (LOCK INSTANCE FOR BACKUP), ref sql_backup_lock.cc if (ctc_is_instance_locked_by_backup(thd)) { - // don't block SET session variable after "lock instance for backup" if (ctc_is_set_session_var(thd, query_str)) { return 0; @@ -1380,19 +1416,20 @@ static int ctc_ddl_rewrite(MYSQL_THD thd, mysql_event_class_t event_class, } ddl_broadcast_cmd broadcast_cmd = it->second; - return need_forward && ddl_broadcast_and_wait(thd, query_str, (uint8_t)sql_cmd, broadcast_cmd); // 0: success other: fail + return need_forward && + ddl_broadcast_and_wait(thd, query_str, (uint8_t)sql_cmd, broadcast_cmd); // 0: success other: fail } /* Audit plugin descriptor. */ static struct st_mysql_audit ctc_ddl_rewriter_descriptor = { - MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */ - nullptr, /* release_thd() */ - ctc_ddl_rewrite, /* event_notify() */ - { - 0, - 0, - (unsigned long)MYSQL_AUDIT_PARSE_POSTPARSE, - } /* class mask */ + MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */ + nullptr, /* release_thd() */ + ctc_ddl_rewrite, /* event_notify() */ + { + 0, + 0, + (unsigned long)MYSQL_AUDIT_PARSE_POSTPARSE, + } /* class mask */ }; #if !defined __STRICT_ANSI__ && defined __GNUC__ && !defined __clang__ diff --git a/storage/ctc/ctc_ddl_util.cc b/storage/ctc/ctc_ddl_util.cc index df91e4d..07a4c5a 100644 --- a/storage/ctc/ctc_ddl_util.cc +++ b/storage/ctc/ctc_ddl_util.cc @@ -13,8 +13,8 @@ #include "ctc_ddl_util.h" #include "ctc_log.h" -#include "sql/sql_class.h" #include "sql/create_field.h" +#include "sql/sql_class.h" #include "sql/sql_lex.h" #include "sql/sql_table.h" @@ -22,8 +22,8 @@ using namespace std; const char *ibd_suffix = ".ibd"; -void *ctc_ddl_alloc_mem(char **mem_start, char *mem_end, - size_t malloc_size) { +void *ctc_ddl_alloc_mem(char **mem_start, char *mem_end, size_t malloc_size) +{ assert(mem_start != NULL && *mem_start != NULL && mem_end != NULL); if (*mem_start + malloc_size >= mem_end) { ctc_log_error("alloc ddl mem failed,size:%u", (uint32_t)malloc_size); @@ -34,7 +34,8 @@ void *ctc_ddl_alloc_mem(char **mem_start, char *mem_end, return ptr; } -int check_ctc_identifier_name(const char *in_name) { +int check_ctc_identifier_name(const char *in_name) +{ if (in_name == nullptr) { return 0; } @@ -45,7 +46,8 @@ int check_ctc_identifier_name(const char *in_name) { return 0; } -bool check_file_name_has_suffix(const char *file_name, const char *suffix) { +bool check_file_name_has_suffix(const char *file_name, const char *suffix) +{ size_t suffix_len = strlen(suffix); size_t file_name_len = strlen(file_name); if (file_name_len <= suffix_len || (strcmp(file_name + file_name_len - suffix_len, suffix) != 0)) { @@ -54,14 +56,16 @@ bool check_file_name_has_suffix(const char *file_name, const char *suffix) { return false; } -bool check_file_name_prefix(const char *file_name) { +bool check_file_name_prefix(const char *file_name) +{ if (file_name[0] == ' ' || file_name[0] == '/') { return true; } return false; } -bool check_data_file_name(const char *data_file_name) { +bool check_data_file_name(const char *data_file_name) +{ if (data_file_name == nullptr || data_file_name[0] == '\0') { my_printf_error(ER_WRONG_FILE_NAME, "The ADD DATAFILE filepath does not have a proper filename", MYF(0)); return true; @@ -69,26 +73,27 @@ bool check_data_file_name(const char *data_file_name) { // The datafile name can not start with '/' or ' ' if (check_file_name_prefix(data_file_name)) { - my_printf_error(ER_WRONG_FILE_NAME, "The DATAFILE location must be in a known directory.", MYF(0)); - return true; + my_printf_error(ER_WRONG_FILE_NAME, "The DATAFILE location must be in a known directory.", MYF(0)); + return true; } // The datafile name must be suffixed with '.ibd' if (check_file_name_has_suffix(data_file_name, ibd_suffix)) { - my_printf_error(ER_WRONG_FILE_NAME, "The ADD DATAFILE filepath must end with '%s'.", MYF(0), ibd_suffix); - return true; + my_printf_error(ER_WRONG_FILE_NAME, "The ADD DATAFILE filepath must end with '%s'.", MYF(0), ibd_suffix); + return true; } // the datafile name is too long (Maximum value: 128 byte). if (strlen(data_file_name) > SMALL_RECORD_SIZE) { - my_printf_error(ER_WRONG_FILE_NAME, "The ADD DATAFILE filename is too long (Maximum value: 128 byte).", MYF(0)); - return true; + my_printf_error(ER_WRONG_FILE_NAME, "The ADD DATAFILE filename is too long (Maximum value: 128 byte).", MYF(0)); + return true; } return false; } -Field *ctc_get_field_by_name(TABLE *form, const char *name) { +Field *ctc_get_field_by_name(TABLE *form, const char *name) +{ if (name == nullptr) { return nullptr; } @@ -100,14 +105,15 @@ Field *ctc_get_field_by_name(TABLE *form, const char *name) { return nullptr; } -const Create_field *ctc_get_create_field_by_column_name(THD *thd, const char* field_name) { +const Create_field *ctc_get_create_field_by_column_name(THD *thd, const char *field_name) +{ // 处理普通建表 Alter_info *alter_info = thd->lex->alter_info; const Create_field *field = NULL; if (alter_info != nullptr) { List_iterator_fast field_it(alter_info->create_list); while ((field = field_it++)) { - if(strcmp(field->field_name, field_name) == 0) { + if (strcmp(field->field_name, field_name) == 0) { return field; } } @@ -116,12 +122,12 @@ const Create_field *ctc_get_create_field_by_column_name(THD *thd, const char* fi // 此时alter_info->create_list为空,需生成Create_field TABLE tmp_table MY_ATTRIBUTE((unused)); // lex execution is not started, item->field cannot be got. - if(!thd->lex->is_exec_started()) { + if (!thd->lex->is_exec_started()) { return nullptr; } mem_root_deque *items = thd->lex->unit->get_unit_column_types(); for (Item *item : VisibleFields(*items)) { - if(strcmp(item->item_name.ptr(), field_name) == 0) { + if (strcmp(item->item_name.ptr(), field_name) == 0) { Create_field *cr_field = generate_create_field(thd, item, &tmp_table); if (cr_field == nullptr) { break; @@ -155,21 +161,21 @@ const Create_field *ctc_get_create_field_by_column_name(THD *thd, const char* fi create_info.init_create_options_from_share(table_list->table->s, create_info.used_fields); // Prepare Create_field and Key_spec objects for ALTER and upgrade. - prepare_fields_and_keys(thd, src_table, table_list->table, &create_info, &local_alter_info, - &local_alter_ctx, create_info.used_fields); + prepare_fields_and_keys(thd, src_table, table_list->table, &create_info, &local_alter_info, &local_alter_ctx, + create_info.used_fields); List_iterator_fast field_like_it(local_alter_info.create_list); while ((field = field_like_it++)) { - if(strcmp(field->field_name, field_name) == 0) { + if (strcmp(field->field_name, field_name) == 0) { return field; } } } - + return nullptr; } -ctc_alter_table_drop_type ctc_ddl_get_drop_type_from_mysql_type( - Alter_drop::drop_type drop_type) { +ctc_alter_table_drop_type ctc_ddl_get_drop_type_from_mysql_type(Alter_drop::drop_type drop_type) +{ switch (drop_type) { case Alter_drop::drop_type::KEY: return CTC_ALTER_TABLE_DROP_KEY; @@ -186,9 +192,9 @@ ctc_alter_table_drop_type ctc_ddl_get_drop_type_from_mysql_type( } } -ctc_alter_column_type ctc_ddl_get_alter_column_type_from_mysql_type( - Alter_column::Type alter_column_type) { - switch (alter_column_type) {// SET_DEFAULT, DROP_DEFAULT, RENAME_COLUMN +ctc_alter_column_type ctc_ddl_get_alter_column_type_from_mysql_type(Alter_column::Type alter_column_type) +{ + switch (alter_column_type) { // SET_DEFAULT, DROP_DEFAULT, RENAME_COLUMN case Alter_column::Type::SET_DEFAULT: return CTC_ALTER_COLUMN_SET_DEFAULT; case Alter_column::Type::DROP_DEFAULT: @@ -204,7 +210,8 @@ ctc_alter_column_type ctc_ddl_get_alter_column_type_from_mysql_type( } } -bool get_ctc_key_type(const KEY *key_info, int32_t *ret_type) { +bool get_ctc_key_type(const KEY *key_info, int32_t *ret_type) +{ *ret_type = CTC_KEYTYPE_UNKNOW; if (key_info->flags & HA_SPATIAL) { *ret_type = CTC_KEYTYPE_SPATIAL; @@ -236,7 +243,8 @@ bool get_ctc_key_type(const KEY *key_info, int32_t *ret_type) { return true; } -bool get_ctc_key_algorithm(ha_key_alg algorithm, int32_t *ret_algorithm) { +bool get_ctc_key_algorithm(ha_key_alg algorithm, int32_t *ret_algorithm) +{ *ret_algorithm = (int32_t)CTC_HA_KEY_ALG_BTREE; switch (algorithm) { case HA_KEY_ALG_RTREE: @@ -255,13 +263,12 @@ bool get_ctc_key_algorithm(ha_key_alg algorithm, int32_t *ret_algorithm) { break; } // mysql字符序和cantian的参数对接 - static map - g_ctc_key_algorithm_map = { - {HA_KEY_ALG_SE_SPECIFIC, CTC_HA_KEY_ALG_SE_SPECIFIC}, - {HA_KEY_ALG_BTREE, CTC_HA_KEY_ALG_BTREE}, - {HA_KEY_ALG_RTREE, CTC_HA_KEY_ALG_RTREE}, - {HA_KEY_ALG_HASH, CTC_HA_KEY_ALG_HASH}, - {HA_KEY_ALG_FULLTEXT, CTC_HA_KEY_ALG_FULLTEXT}}; + static map g_ctc_key_algorithm_map = { + {HA_KEY_ALG_SE_SPECIFIC, CTC_HA_KEY_ALG_SE_SPECIFIC}, + {HA_KEY_ALG_BTREE, CTC_HA_KEY_ALG_BTREE}, + {HA_KEY_ALG_RTREE, CTC_HA_KEY_ALG_RTREE}, + {HA_KEY_ALG_HASH, CTC_HA_KEY_ALG_HASH}, + {HA_KEY_ALG_FULLTEXT, CTC_HA_KEY_ALG_FULLTEXT}}; auto it = g_ctc_key_algorithm_map.find(algorithm); if (it != g_ctc_key_algorithm_map.end()) { *ret_algorithm = (int32_t)it->second; @@ -270,8 +277,8 @@ bool get_ctc_key_algorithm(ha_key_alg algorithm, int32_t *ret_algorithm) { return false; } -bool ctc_ddl_get_data_type_from_mysql_type(Field *field, - const enum_field_types &mysql_type, int32_t *ret_type) { +bool ctc_ddl_get_data_type_from_mysql_type(Field *field, const enum_field_types &mysql_type, int32_t *ret_type) +{ if (field != nullptr) { const field_cnvrt_aux_t *mysql_info = get_auxiliary_for_field_convert(field, mysql_type); if (mysql_info != nullptr) { @@ -287,7 +294,8 @@ bool ctc_ddl_get_data_type_from_mysql_type(Field *field, // SET类型最多只能包含64个成员, 1~8成员的集合占1个字节 ,9~16成员的集合占2个字节 // 17~24成员的集合占3个字节, 25~32成员的集合占4个字节, 33~64成员的集合占8个字节 -bool set_column_datatype(size_t set_num, TcDb__CtcDDLColumnDef *column) { +bool set_column_datatype(size_t set_num, TcDb__CtcDDLColumnDef *column) +{ if (set_num < 9) { column->datatype->datatype = CTC_DDL_TYPE_TINY; return true; @@ -305,13 +313,14 @@ bool set_column_datatype(size_t set_num, TcDb__CtcDDLColumnDef *column) { return false; } -bool ctc_is_with_default_value(Field *field, const dd::Column *col_obj) { +bool ctc_is_with_default_value(Field *field, const dd::Column *col_obj) +{ bool has_default_value = false; if (col_obj != nullptr) { - const bool has_default = ((!field->is_flag_set(NO_DEFAULT_VALUE_FLAG) && - !(field->auto_flags & Field::NEXT_NUMBER)) && - !col_obj->is_default_value_null()) || - field->m_default_val_expr; + const bool has_default = + ((!field->is_flag_set(NO_DEFAULT_VALUE_FLAG) && !(field->auto_flags & Field::NEXT_NUMBER)) && + !col_obj->is_default_value_null()) || + field->m_default_val_expr; has_default_value = has_default && (col_obj->default_value_utf8().data()) != NULL; } const bool has_default_timestamp = field->has_insert_default_datetime_value_expression(); @@ -321,7 +330,8 @@ bool ctc_is_with_default_value(Field *field, const dd::Column *col_obj) { return false; } -ctc_ddl_fk_rule ctc_ddl_get_foreign_key_rule(fk_option rule) { +ctc_ddl_fk_rule ctc_ddl_get_foreign_key_rule(fk_option rule) +{ switch (rule) { case FK_OPTION_UNDEF: case FK_OPTION_NO_ACTION: @@ -340,7 +350,8 @@ ctc_ddl_fk_rule ctc_ddl_get_foreign_key_rule(fk_option rule) { return CTC_DDL_FK_RULE_UNKNOW; } -ctc_ddl_fk_rule ctc_ddl_get_foreign_key_rule(dd::Foreign_key::enum_rule rule) { +ctc_ddl_fk_rule ctc_ddl_get_foreign_key_rule(dd::Foreign_key::enum_rule rule) +{ switch (rule) { case dd::Foreign_key::enum_rule::RULE_NO_ACTION: case dd::Foreign_key::enum_rule::RULE_RESTRICT: @@ -358,8 +369,8 @@ ctc_ddl_fk_rule ctc_ddl_get_foreign_key_rule(dd::Foreign_key::enum_rule rule) { return CTC_DDL_FK_RULE_UNKNOW; } -const dd::Index *ctc_ddl_get_index_by_name(const dd::Table *tab_obj, - const char *index_name) { +const dd::Index *ctc_ddl_get_index_by_name(const dd::Table *tab_obj, const char *index_name) +{ for (const dd::Index *index : tab_obj->indexes()) { if (strcmp(index->name().data(), index_name) == 0) { return index; @@ -368,17 +379,18 @@ const dd::Index *ctc_ddl_get_index_by_name(const dd::Table *tab_obj, return nullptr; } -const dd::Column *ctc_ddl_get_column_by_name(const dd::Table *table_def, - const char *col_name) { +const dd::Column *ctc_ddl_get_column_by_name(const dd::Table *table_def, const char *col_name) +{ for (auto iter : table_def->columns()) { if (my_strcasecmp(system_charset_info, iter->name().data(), col_name) == 0) { - return iter; + return iter; } } return nullptr; } -bool ctc_ddl_get_create_key_type(dd::Index::enum_index_type type, int32_t *ret_type) { +bool ctc_ddl_get_create_key_type(dd::Index::enum_index_type type, int32_t *ret_type) +{ *ret_type = CTC_KEYTYPE_UNKNOW; switch (type) { case dd::Index::enum_index_type::IT_PRIMARY: @@ -402,8 +414,8 @@ bool ctc_ddl_get_create_key_type(dd::Index::enum_index_type type, int32_t *ret_t return true; } -bool ctc_ddl_get_create_key_algorithm(dd::Index::enum_index_algorithm algorithm, - int32_t *ret_algorithm) { +bool ctc_ddl_get_create_key_algorithm(dd::Index::enum_index_algorithm algorithm, int32_t *ret_algorithm) +{ *ret_algorithm = (int32_t)CTC_HA_KEY_ALG_BTREE; switch (algorithm) { case dd::Index::enum_index_algorithm::IA_RTREE: @@ -422,33 +434,29 @@ bool ctc_ddl_get_create_key_algorithm(dd::Index::enum_index_algorithm algorithm, break; } - static map - g_ctc_create_key_algorithm_map = { - {dd::Index::enum_index_algorithm::IA_SE_SPECIFIC, CTC_HA_KEY_ALG_SE_SPECIFIC}, - {dd::Index::enum_index_algorithm::IA_BTREE, CTC_HA_KEY_ALG_BTREE}, - {dd::Index::enum_index_algorithm::IA_RTREE, CTC_HA_KEY_ALG_RTREE}, - {dd::Index::enum_index_algorithm::IA_HASH, CTC_HA_KEY_ALG_HASH}, - {dd::Index::enum_index_algorithm::IA_FULLTEXT, CTC_HA_KEY_ALG_FULLTEXT}}; + static map g_ctc_create_key_algorithm_map = { + {dd::Index::enum_index_algorithm::IA_SE_SPECIFIC, CTC_HA_KEY_ALG_SE_SPECIFIC}, + {dd::Index::enum_index_algorithm::IA_BTREE, CTC_HA_KEY_ALG_BTREE}, + {dd::Index::enum_index_algorithm::IA_RTREE, CTC_HA_KEY_ALG_RTREE}, + {dd::Index::enum_index_algorithm::IA_HASH, CTC_HA_KEY_ALG_HASH}, + {dd::Index::enum_index_algorithm::IA_FULLTEXT, CTC_HA_KEY_ALG_FULLTEXT}}; auto it = g_ctc_create_key_algorithm_map.find(algorithm); if (it != g_ctc_create_key_algorithm_map.end()) { *ret_algorithm = (int32_t)it->second; return true; } - my_printf_error(ER_DISALLOWED_OPERATION, - "get index algorithm failed, unsuported index algorithm", MYF(0)); + my_printf_error(ER_DISALLOWED_OPERATION, "get index algorithm failed, unsuported index algorithm", MYF(0)); return false; } -uint16 get_prefix_index_len(const Field *field, const uint16 key_length) { +uint16 get_prefix_index_len(const Field *field, const uint16 key_length) +{ uint16 prefix_len = 0; /* No prefix index on multi-value field */ if (!field->is_array() && - (field->is_flag_set(BLOB_FLAG)|| - (key_length < field->pack_length() && - field->type() == MYSQL_TYPE_STRING) || - (field->type() == MYSQL_TYPE_VARCHAR && - key_length < field->pack_length() - field->get_length_bytes()))) { + (field->is_flag_set(BLOB_FLAG) || (key_length < field->pack_length() && field->type() == MYSQL_TYPE_STRING) || + (field->type() == MYSQL_TYPE_VARCHAR && key_length < field->pack_length() - field->get_length_bytes()))) { prefix_len = key_length; prefix_len /= field->charset()->mbmaxlen; assert(!field->gcol_info); @@ -456,7 +464,8 @@ uint16 get_prefix_index_len(const Field *field, const uint16 key_length) { return prefix_len; } -int convert_ctc_part_type(dd::Table::enum_partition_type mysql_part_type, uint32_t *ctc_part_type) { +int convert_ctc_part_type(dd::Table::enum_partition_type mysql_part_type, uint32_t *ctc_part_type) +{ *ctc_part_type = CTC_PART_TYPE_INVALID; switch (mysql_part_type) { case dd::Table::PT_RANGE: @@ -475,16 +484,18 @@ int convert_ctc_part_type(dd::Table::enum_partition_type mysql_part_type, uint32 case dd::Table::PT_LINEAR_KEY_55: *ctc_part_type = CTC_PART_TYPE_HASH; break; - default : - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Partition tables support only hash partitions, range partitions, list partitions, and columns partitions."); + default: + my_printf_error( + ER_DISALLOWED_OPERATION, "%s", MYF(0), + "Partition tables support only hash partitions, range partitions, list partitions, and columns partitions."); ctc_log_system("unsupported partition type : %d.", mysql_part_type); return 1; } return 0; } -int convert_ctc_subpart_type(dd::Table::enum_subpartition_type mysql_subpart_type, uint32_t *ctc_part_type) { +int convert_ctc_subpart_type(dd::Table::enum_subpartition_type mysql_subpart_type, uint32_t *ctc_part_type) +{ *ctc_part_type = CTC_PART_TYPE_INVALID; switch (mysql_subpart_type) { case dd::Table::ST_NONE: @@ -498,9 +509,8 @@ int convert_ctc_subpart_type(dd::Table::enum_subpartition_type mysql_subpart_typ case dd::Table::ST_LINEAR_KEY_55: *ctc_part_type = CTC_PART_TYPE_HASH; break; - default : - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "SubPartition tables support only hash partitions"); + default: + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "SubPartition tables support only hash partitions"); ctc_log_system("unsupported partition type : %d.", mysql_subpart_type); return 1; } diff --git a/storage/ctc/ctc_error.cc b/storage/ctc/ctc_error.cc index 9c618be..37b189a 100644 --- a/storage/ctc/ctc_error.cc +++ b/storage/ctc/ctc_error.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -14,70 +14,71 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include "ctc_error.h" -#include "my_base.h" +#include #include "ctc_log.h" +#include "my_base.h" static std::unordered_map err_code_lookup_map = { - {ERR_OAMAP_DUP_KEY_ERROR, HA_ERR_GENERIC}, - {ERR_OAMAP_INSERTION_FAILED, HA_ERR_GENERIC}, - {ERR_OAMAP_FETCH_FAILED, HA_ERR_GENERIC}, - {ERR_GENERIC_INTERNAL_ERROR, HA_ERR_GENERIC}, - {ERR_NOT_SUPPORT, HA_ERR_WRONG_COMMAND}, - {ERR_OPERATIONS_NOT_SUPPORT, HA_ERR_WRONG_COMMAND}, - /* Since we rolled back the whole transaction, we must - tell it also to MySQL so that MySQL knows to empty the - cached binlog for this transaction */ - {ERR_DEAD_LOCK, HA_ERR_LOCK_DEADLOCK}, - /* The CANTIAN serialization isolation level is stricter than the MySQL - repeatable read isolation level. If two transactions conflict: - - The cantian is locked, including lock timeout and transaction area conflict. - - MySQL will be locked, including lock timeout and success. - Therefore, the cantian transaction conflict error code is temporarily - classified as lock timeout. */ - {ERR_SERIALIZE_ACCESS, HA_ERR_RECORD_CHANGED}, - /* Starting from 5.0.13, we let MySQL just roll back the - latest SQL statement in a lock wait timeout. Previously, we - rolled back the whole transaction. */ - {ERR_LOCK_TIMEOUT, HA_ERR_LOCK_WAIT_TIMEOUT}, - /* If prefix is true then a 768-byte prefix is stored - locally for BLOB fields. Refer to dict_table_get_format(). - We limit max record size to 16k for 64k page size. */ - {ERR_RECORD_SIZE_OVERFLOW, HA_ERR_TOO_BIG_ROW}, - /* Be cautious with returning this error, since - mysql could re-enter the storage layer to get - duplicated key info, the operation requires a - valid table handle and/or transaction information, - which might not always be available in the error - handling stage. */ - {ERR_DUPLICATE_KEY, HA_ERR_FOUND_DUPP_KEY}, - {ERR_CONSTRAINT_VIOLATED_NO_FOUND, HA_ERR_NO_REFERENCED_ROW}, - {ERR_ROW_IS_REFERENCED, HA_ERR_ROW_IS_REFERENCED}, - {ERR_DEF_CHANGED, HA_ERR_TABLE_DEF_CHANGED}, - {ERR_SAVEPOINT_NOT_EXIST, HA_ERR_NO_SAVEPOINT}, - {ERR_NO_MORE_LOCKS, HA_ERR_LOCK_TABLE_FULL}, - {ERR_FILE_NOT_EXIST, HA_ERR_WRONG_FILE_NAME}, - {ERR_SPACE_NOT_EXIST, HA_ERR_TABLESPACE_MISSING}, - {ERR_SPACE_ALREADY_EXIST, HA_ERR_TABLESPACE_EXISTS}, - {ERR_BTREE_LEVEL_EXCEEDED, HA_ERR_INTERNAL_ERROR}, - {ERR_TABLE_OR_VIEW_NOT_EXIST, HA_ERR_NO_SUCH_TABLE}, - {ERR_DC_INVALIDATED, HA_ERR_NO_SUCH_TABLE}, - {ERR_INDEX_INVALID, HA_ERR_WRONG_INDEX}, - {ERR_CONNECTION_FAILED, HA_ERR_NO_CONNECTION}, - {ERR_ALLOC_MEMORY, HA_ERR_SE_OUT_OF_MEMORY}, - {ERR_ROW_LOCKED_NOWAIT, HA_ERR_NO_WAIT_LOCK}, - {ERR_OPERATION_CANCELED, HA_ERR_QUERY_INTERRUPTED}, - {ERR_SEM_FAULT, HA_ERR_INTERNAL_ERROR}, - {ERR_BATCH_DATA_HANDLE_FAILED, HA_ERR_INTERNAL_ERROR}, - {ERR_SHM_SEND_MSG_FAILED, HA_ERR_NO_CONNECTION}, - {ERR_INSTANCE_REG_FAILED, HA_ERR_INTERNAL_ERROR}, - {ERR_AUTOINC_READ_FAILED, HA_ERR_AUTOINC_READ_FAILED}, - {ERR_OBJECT_ALREADY_DROPPED, HA_ERR_TABLE_CORRUPT}, - {ERR_PAGE_CORRUPTED, HA_ERR_TABLE_CORRUPT}, + {ERR_OAMAP_DUP_KEY_ERROR, HA_ERR_GENERIC}, + {ERR_OAMAP_INSERTION_FAILED, HA_ERR_GENERIC}, + {ERR_OAMAP_FETCH_FAILED, HA_ERR_GENERIC}, + {ERR_GENERIC_INTERNAL_ERROR, HA_ERR_GENERIC}, + {ERR_NOT_SUPPORT, HA_ERR_WRONG_COMMAND}, + {ERR_OPERATIONS_NOT_SUPPORT, HA_ERR_WRONG_COMMAND}, + /* Since we rolled back the whole transaction, we must + tell it also to MySQL so that MySQL knows to empty the + cached binlog for this transaction */ + {ERR_DEAD_LOCK, HA_ERR_LOCK_DEADLOCK}, + /* The CANTIAN serialization isolation level is stricter than the MySQL + repeatable read isolation level. If two transactions conflict: + - The cantian is locked, including lock timeout and transaction area conflict. + - MySQL will be locked, including lock timeout and success. + Therefore, the cantian transaction conflict error code is temporarily + classified as lock timeout. */ + {ERR_SERIALIZE_ACCESS, HA_ERR_RECORD_CHANGED}, + /* Starting from 5.0.13, we let MySQL just roll back the + latest SQL statement in a lock wait timeout. Previously, we + rolled back the whole transaction. */ + {ERR_LOCK_TIMEOUT, HA_ERR_LOCK_WAIT_TIMEOUT}, + /* If prefix is true then a 768-byte prefix is stored + locally for BLOB fields. Refer to dict_table_get_format(). + We limit max record size to 16k for 64k page size. */ + {ERR_RECORD_SIZE_OVERFLOW, HA_ERR_TOO_BIG_ROW}, + /* Be cautious with returning this error, since + mysql could re-enter the storage layer to get + duplicated key info, the operation requires a + valid table handle and/or transaction information, + which might not always be available in the error + handling stage. */ + {ERR_DUPLICATE_KEY, HA_ERR_FOUND_DUPP_KEY}, + {ERR_CONSTRAINT_VIOLATED_NO_FOUND, HA_ERR_NO_REFERENCED_ROW}, + {ERR_ROW_IS_REFERENCED, HA_ERR_ROW_IS_REFERENCED}, + {ERR_DEF_CHANGED, HA_ERR_TABLE_DEF_CHANGED}, + {ERR_SAVEPOINT_NOT_EXIST, HA_ERR_NO_SAVEPOINT}, + {ERR_NO_MORE_LOCKS, HA_ERR_LOCK_TABLE_FULL}, + {ERR_FILE_NOT_EXIST, HA_ERR_WRONG_FILE_NAME}, + {ERR_SPACE_NOT_EXIST, HA_ERR_TABLESPACE_MISSING}, + {ERR_SPACE_ALREADY_EXIST, HA_ERR_TABLESPACE_EXISTS}, + {ERR_BTREE_LEVEL_EXCEEDED, HA_ERR_INTERNAL_ERROR}, + {ERR_TABLE_OR_VIEW_NOT_EXIST, HA_ERR_NO_SUCH_TABLE}, + {ERR_DC_INVALIDATED, HA_ERR_NO_SUCH_TABLE}, + {ERR_INDEX_INVALID, HA_ERR_WRONG_INDEX}, + {ERR_CONNECTION_FAILED, HA_ERR_NO_CONNECTION}, + {ERR_ALLOC_MEMORY, HA_ERR_SE_OUT_OF_MEMORY}, + {ERR_ROW_LOCKED_NOWAIT, HA_ERR_NO_WAIT_LOCK}, + {ERR_OPERATION_CANCELED, HA_ERR_QUERY_INTERRUPTED}, + {ERR_SEM_FAULT, HA_ERR_INTERNAL_ERROR}, + {ERR_BATCH_DATA_HANDLE_FAILED, HA_ERR_INTERNAL_ERROR}, + {ERR_SHM_SEND_MSG_FAILED, HA_ERR_NO_CONNECTION}, + {ERR_INSTANCE_REG_FAILED, HA_ERR_INTERNAL_ERROR}, + {ERR_AUTOINC_READ_FAILED, HA_ERR_AUTOINC_READ_FAILED}, + {ERR_OBJECT_ALREADY_DROPPED, HA_ERR_TABLE_CORRUPT}, + {ERR_PAGE_CORRUPTED, HA_ERR_TABLE_CORRUPT}, }; -int convert_cantian_err_to_mysql(ct_errno_t error) { +int convert_cantian_err_to_mysql(ct_errno_t error) +{ int err_code = 0; switch (error) { case ERR_CAPABILITY_NOT_SUPPORT: @@ -85,7 +86,8 @@ int convert_cantian_err_to_mysql(ct_errno_t error) { err_code = ER_DISALLOWED_OPERATION; break; case ERR_WRITE_OPT_IN_READONLY: - my_printf_error(ER_OPEN_AS_READONLY, "%s", MYF(0), "Cantian does not support this operation under readonly mode."); + my_printf_error(ER_OPEN_AS_READONLY, "%s", MYF(0), + "Cantian does not support this operation under readonly mode."); err_code = ER_OPEN_AS_READONLY; break; case ERR_DATABASE_ROLE: @@ -102,8 +104,8 @@ int convert_cantian_err_to_mysql(ct_errno_t error) { break; case ERR_ROW_SELF_UPDATED: my_printf_error(ER_MULTI_UPDATE_KEY_CONFLICT, - "Primary key/partition key update is not allowed since the table is updated both.", MYF(0)); - err_code = ER_MULTI_UPDATE_KEY_CONFLICT; + "Primary key/partition key update is not allowed since the table is updated both.", MYF(0)); + err_code = ER_MULTI_UPDATE_KEY_CONFLICT; break; case ERR_COLUMN_HAS_NULL: my_error(ER_INVALID_USE_OF_NULL, MYF(0)); @@ -119,7 +121,7 @@ int convert_cantian_err_to_mysql(ct_errno_t error) { break; case ERR_CHILD_DUPLICATE_KEY: my_printf_error(ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO, - "Foreign key constraint would lead to a duplicate entry in child table", MYF(0)); + "Foreign key constraint would lead to a duplicate entry in child table", MYF(0)); err_code = ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO; break; case ERR_FK_NO_INDEX_PAREN_4MYSQL: @@ -132,16 +134,17 @@ int convert_cantian_err_to_mysql(ct_errno_t error) { break; case ERR_SNAPSHOT_TOO_OLD: my_printf_error(HA_ERR_TOO_MANY_CONCURRENT_TRXS, - "snapshot too old, it is advised to modify the parameters _undo_active_segments in Cantian", MYF(0)); + "snapshot too old, it is advised to modify the parameters _undo_active_segments in Cantian", + MYF(0)); err_code = HA_ERR_TOO_MANY_CONCURRENT_TRXS; break; case ERR_CHILD_ROW_CANNOT_ADD_OR_UPDATE: - my_printf_error(ER_NO_REFERENCED_ROW_2, - "Cannot add or update a child row: a foreign key constraint fails", MYF(0)); + my_printf_error(ER_NO_REFERENCED_ROW_2, "Cannot add or update a child row: a foreign key constraint fails", + MYF(0)); err_code = ER_NO_REFERENCED_ROW_2; break; case ERR_LOCK_TIMEOUT: - my_error(ER_LOCK_WAIT_TIMEOUT,MYF(0)); + my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); err_code = ER_LOCK_WAIT_TIMEOUT; break; default: @@ -150,11 +153,12 @@ int convert_cantian_err_to_mysql(ct_errno_t error) { return err_code; } -void ctc_alter_table_handle_fault(ct_errno_t error) { +void ctc_alter_table_handle_fault(ct_errno_t error) +{ switch (error) { case ERR_CONSTRAINT_VIOLATED_NO_FOUND: - my_printf_error(ER_NO_REFERENCED_ROW_2, - "Cannot add or update a child row: a foreign key constraint fails.", MYF(0)); + my_printf_error(ER_NO_REFERENCED_ROW_2, "Cannot add or update a child row: a foreign key constraint fails.", + MYF(0)); break; default: my_error(ER_GET_ERRNO, MYF(0), error, "Cantian error"); @@ -162,8 +166,8 @@ void ctc_alter_table_handle_fault(ct_errno_t error) { } } - -int convert_ctc_error_code_to_mysql_impl(ct_errno_t error, const char* funcName, const int line) { +int convert_ctc_error_code_to_mysql_impl(ct_errno_t error, const char *funcName, const int line) +{ if (error == CT_SUCCESS) { return 0; } @@ -187,7 +191,7 @@ int convert_ctc_error_code_to_mysql_impl(ct_errno_t error, const char* funcName, if (iter != err_code_lookup_map.end()) { ret = iter->second; } else { - ctc_log_system("func %s(line%d) returned with unknown err, cantian ret %d", funcName, line, (int)error); + ctc_log_system("func %s(line%d) returned with unknown err, cantian ret %d", funcName, line, (int)error); } ctc_log_note("func %s(line%d) returned with errCode %d, cantian ret %d", funcName, line, ret, (int)error); return ret; diff --git a/storage/ctc/ctc_meta_data.cc b/storage/ctc/ctc_meta_data.cc index dd96415..5365069 100644 --- a/storage/ctc/ctc_meta_data.cc +++ b/storage/ctc/ctc_meta_data.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -15,53 +15,53 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ctc_meta_data.h" -#include +#include +#include +#include #include +#include #include #include -#include -#include -#include -#include "mysql.h" -#include "sql/mysqld.h" // mysql_port, my_localhost #include "ctc_log.h" +#include "ctc_proxy_util.h" #include "ctc_srv.h" #include "ctc_util.h" -#include "ctc_proxy_util.h" -#include "sql/sql_table.h" #include "my_dir.h" -#include "sql/sql_handler.h" -#include "sql/sql_base.h" -#include "sql/sql_class.h" +#include "mysql.h" +#include "mysql_com.h" +#include "sql/auth/auth_acls.h" +#include "sql/auth/auth_common.h" #include "sql/dd/cache/dictionary_client.h" -#include "sql/mysqld_thd_manager.h" -#include "sql/dd/types/procedure.h" -#include "sql/dd/types/function.h" -#include "sql/dd/types/routine.h" -#include "sql/mdl.h" +#include "sql/dd/impl/cache/shared_dictionary_cache.h" +#include "sql/dd/impl/utils.h" #include "sql/dd/types/event.h" +#include "sql/dd/types/function.h" +#include "sql/dd/types/procedure.h" #include "sql/dd/types/resource_group.h" +#include "sql/dd/types/routine.h" #include "sql/dd/types/trigger.h" -#include "sql/auth/auth_common.h" -#include "sql/sys_vars_shared.h" // intern_find_sys_var -#include "sql/sql_lex.h" // lex_start/lex_end -#include "sql/handler.h" // ha_ctc_commit -#include "sql/auth/auth_acls.h" -#include "sql/sp_cache.h" // sp_cache_invalidate -#include "sql/sp_head.h" // Stored_program_creation_ctx -#include "sql/sp_pcontext.h" // sp_pcontext -#include "sql/dd/impl/cache/shared_dictionary_cache.h" -#include "sql/dd/impl/utils.h" -#include "sql/sql_reload.h" +#include "sql/handler.h" // ha_ctc_commit +#include "sql/mdl.h" +#include "sql/mysqld.h" // mysql_port, my_localhost +#include "sql/mysqld_thd_manager.h" +#include "sql/sp_cache.h" // sp_cache_invalidate +#include "sql/sp_head.h" // Stored_program_creation_ctx +#include "sql/sp_pcontext.h" // sp_pcontext +#include "sql/sql_base.h" +#include "sql/sql_class.h" +#include "sql/sql_handler.h" +#include "sql/sql_lex.h" // lex_start/lex_end #include "sql/sql_plugin.h" -#include "mysql_com.h" +#include "sql/sql_reload.h" +#include "sql/sql_table.h" +#include "sql/sys_vars_shared.h" // intern_find_sys_var #include "sql/transaction.h" using namespace std; extern uint32_t ctc_instance_id; -static map g_ctc_mdl_thd_map; +static map g_ctc_mdl_thd_map; static mutex m_ctc_mdl_thd_mutex; static map *> g_ctc_mdl_ticket_maps; static map *> g_ctc_invalidate_routine_maps; @@ -72,32 +72,35 @@ bool no_create_dir = true; class Release_all_ctc_explicit_locks : public MDL_release_locks_visitor { public: - bool release(MDL_ticket *ticket) override { + bool release(MDL_ticket *ticket) override + { const MDL_key *mdl_key = ticket->get_key(); ctc_log_system("[CTC_MDL_THD]: Release ticket info, db_name:%s, name:%s, namespace:%d, ticket_type:%d", - mdl_key->db_name(), mdl_key->name(), mdl_key->mdl_namespace(), ticket->get_type()); + mdl_key->db_name(), mdl_key->name(), mdl_key->mdl_namespace(), ticket->get_type()); return ticket->get_type() == MDL_EXCLUSIVE || ((ticket->get_type() == MDL_SHARED_READ_ONLY || ticket->get_type() == MDL_SHARED_NO_READ_WRITE) && - mdl_key->mdl_namespace() == MDL_key::TABLE); + mdl_key->mdl_namespace() == MDL_key::TABLE); } }; - -static void release_ctc_thd_and_explicit_locks(THD *thd) { + +static void release_ctc_thd_and_explicit_locks(THD *thd) +{ my_thread_init(); thd->store_globals(); - + Release_all_ctc_explicit_locks lock_visitor; thd->mdl_context.release_locks(&lock_visitor); - + thd->release_resources(); delete thd; - + my_thread_end(); } static void release_routine_and_schema(THD *thd, bool *error); -static void release_ctc_thd_tickets(THD *thd) { +static void release_ctc_thd_tickets(THD *thd) +{ lock_guard lock(m_ctc_mdl_ticket_mutex); auto ticket_map_iter = g_ctc_mdl_ticket_maps.find(thd); if (ticket_map_iter == g_ctc_mdl_ticket_maps.end()) { @@ -115,7 +118,8 @@ static void release_ctc_thd_tickets(THD *thd) { g_ctc_mdl_ticket_maps.erase(thd); } -static void release_ctc_mdl_thd_by_key(uint64_t mdl_thd_key) { +static void release_ctc_mdl_thd_by_key(uint64_t mdl_thd_key) +{ /* 存在并发场景 map操作加锁 */ lock_guard lock(m_ctc_mdl_thd_mutex); auto iter = g_ctc_mdl_thd_map.find(mdl_thd_key); @@ -129,15 +133,16 @@ static void release_ctc_mdl_thd_by_key(uint64_t mdl_thd_key) { release_routine_and_schema(thd, &error); release_ctc_thd_tickets(thd); release_ctc_thd_and_explicit_locks(thd); - + ctc_log_system("[CTC_MDL_THD]: Close mdl thd by key=%lu", mdl_thd_key); - + g_ctc_mdl_thd_map.erase(mdl_thd_key); } -static void release_ctc_mdl_thd_by_cantian_id(uint16_t cantian_inst_id) { +static void release_ctc_mdl_thd_by_cantian_id(uint16_t cantian_inst_id) +{ lock_guard lock(m_ctc_mdl_thd_mutex); - for (auto iter = g_ctc_mdl_thd_map.begin(); iter != g_ctc_mdl_thd_map.end(); ) { + for (auto iter = g_ctc_mdl_thd_map.begin(); iter != g_ctc_mdl_thd_map.end();) { if (ctc_get_cantian_id_from_conn_key(iter->first) == cantian_inst_id) { THD *thd = iter->second; assert(thd); @@ -153,9 +158,10 @@ static void release_ctc_mdl_thd_by_cantian_id(uint16_t cantian_inst_id) { } } -static void release_ctc_mdl_thd_by_inst_id(uint32_t mysql_inst_id) { +static void release_ctc_mdl_thd_by_inst_id(uint32_t mysql_inst_id) +{ lock_guard lock(m_ctc_mdl_thd_mutex); - for (auto iter = g_ctc_mdl_thd_map.begin(); iter != g_ctc_mdl_thd_map.end(); ) { + for (auto iter = g_ctc_mdl_thd_map.begin(); iter != g_ctc_mdl_thd_map.end();) { if (ctc_get_inst_id_from_conn_key(iter->first) == mysql_inst_id) { THD *thd = iter->second; assert(thd); @@ -171,7 +177,8 @@ static void release_ctc_mdl_thd_by_inst_id(uint32_t mysql_inst_id) { } } -static void ctc_init_thd(THD **thd, uint64_t thd_key) { +static void ctc_init_thd(THD **thd, uint64_t thd_key) +{ lock_guard lock(m_ctc_mdl_thd_mutex); if (g_ctc_mdl_thd_map.find(thd_key) != g_ctc_mdl_thd_map.end()) { (*thd) = g_ctc_mdl_thd_map[thd_key]; @@ -179,7 +186,7 @@ static void ctc_init_thd(THD **thd, uint64_t thd_key) { (*thd)->thread_stack = (char *)thd; (*thd)->store_globals(); } else { - THD* new_thd = new (std::nothrow) THD; + THD *new_thd = new (std::nothrow) THD; my_thread_init(); new_thd->set_new_thread_id(); new_thd->thread_stack = (char *)thd; @@ -191,7 +198,8 @@ static void ctc_init_thd(THD **thd, uint64_t thd_key) { } #ifdef METADATA_NORMALIZED -static void ctc_insert_schema(THD *thd, invalidate_obj_entry_t *obj) { +static void ctc_insert_schema(THD *thd, invalidate_obj_entry_t *obj) +{ lock_guard lock(m_ctc_invalidate_dd_cache_mutex); auto it = g_ctc_invalidate_schema_maps.find(thd); vector *invalidate_schema_list = nullptr; @@ -205,7 +213,8 @@ static void ctc_insert_schema(THD *thd, invalidate_obj_entry_t *obj) { #endif #ifdef METADATA_NORMALIZED -static void ctc_insert_routine(THD *thd, invalidate_obj_entry_t *obj) { +static void ctc_insert_routine(THD *thd, invalidate_obj_entry_t *obj) +{ lock_guard lock(m_ctc_invalidate_dd_cache_mutex); auto it = g_ctc_invalidate_routine_maps.find(thd); vector *invalidate_routine_list = nullptr; @@ -219,17 +228,19 @@ static void ctc_insert_routine(THD *thd, invalidate_obj_entry_t *obj) { #endif template -typename std::enable_if::type - invalidate_routine(T *thd, const char *schema_name, const char *routine_name, uint8 type) { +typename std::enable_if::type invalidate_routine(T *thd, + const char *schema_name, + const char *routine_name, + uint8 type) +{ MDL_ticket *schema_ticket = nullptr; MDL_ticket *routine_ticket = nullptr; - - ctc_log_system("[INVALIDATE_ROUTINE]: enter invalidate_routine. schema_name:%s, routine_name:%s", schema_name, routine_name); - if(!thd->mdl_context.owns_equal_or_stronger_lock( - MDL_key::SCHEMA, schema_name, "", MDL_INTENTION_EXCLUSIVE)) { + + ctc_log_system("[INVALIDATE_ROUTINE]: enter invalidate_routine. schema_name:%s, routine_name:%s", schema_name, + routine_name); + if (!thd->mdl_context.owns_equal_or_stronger_lock(MDL_key::SCHEMA, schema_name, "", MDL_INTENTION_EXCLUSIVE)) { MDL_request mdl_request; - MDL_REQUEST_INIT(&mdl_request, MDL_key::SCHEMA, schema_name, "", - MDL_INTENTION_EXCLUSIVE, MDL_EXPLICIT); + MDL_REQUEST_INIT(&mdl_request, MDL_key::SCHEMA, schema_name, "", MDL_INTENTION_EXCLUSIVE, MDL_EXPLICIT); if (thd->mdl_context.acquire_lock(&mdl_request, CTC_MDL_TIMEOUT)) { assert(thd->killed || thd->is_error()); return true; @@ -247,17 +258,19 @@ typename std::enable_if::type sptype = enum_sp_type::FUNCTION; } - if(!thd->mdl_context.owns_equal_or_stronger_lock(&mdl_key, MDL_EXCLUSIVE)) { + if (!thd->mdl_context.owns_equal_or_stronger_lock(&mdl_key, MDL_EXCLUSIVE)) { MDL_request mdl_request; MDL_REQUEST_INIT_BY_KEY(&mdl_request, &mdl_key, MDL_EXCLUSIVE, MDL_EXPLICIT); if (thd->mdl_context.acquire_lock(&mdl_request, CTC_MDL_TIMEOUT)) { assert(thd->killed || thd->is_error()); - ctc_log_error("[INVALIDATE_ROUTINE]: Failed to acquire routine/procedure mdl of schema_name:%s and routine_name:%s", schema_name, routine_name); + ctc_log_error( + "[INVALIDATE_ROUTINE]: Failed to acquire routine/procedure mdl of schema_name:%s and routine_name:%s", + schema_name, routine_name); return true; } routine_ticket = mdl_request.ticket; } - + dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client()); const dd::Routine *routine = nullptr; bool ignored MY_ATTRIBUTE((unused)); @@ -269,14 +282,13 @@ typename std::enable_if::type if (routine) { thd->dd_client()->invalidate(routine); } - + // Invalidate routine cache. - LEX_STRING lex_routine_name = { const_cast(routine_name), strlen(routine_name) }; + LEX_STRING lex_routine_name = {const_cast(routine_name), strlen(routine_name)}; sp_name *name = new (thd->mem_root) sp_name(to_lex_cstring(schema_name), lex_routine_name, true); sp_cache_invalidate(); sp_head *sp; - sp_cache **spc = (sptype == enum_sp_type::FUNCTION ? &thd->sp_func_cache - : &thd->sp_proc_cache); + sp_cache **spc = (sptype == enum_sp_type::FUNCTION ? &thd->sp_func_cache : &thd->sp_proc_cache); sp = sp_cache_lookup(spc, name); if (sp) { sp_cache_flush_obsolete(spc, &sp); @@ -284,128 +296,133 @@ typename std::enable_if::type if (routine_ticket) thd->mdl_context.release_lock(routine_ticket); if (schema_ticket) thd->mdl_context.release_lock(schema_ticket); - - ctc_log_system("[INVALIDATE_ROUTINE]: leave invalidate_routine. schema_name:%s, routine_name:%s", schema_name, routine_name); + + ctc_log_system("[INVALIDATE_ROUTINE]: leave invalidate_routine. schema_name:%s, routine_name:%s", schema_name, + routine_name); return false; } template -typename std::enable_if::type - invalidate_routine(T *thd MY_ATTRIBUTE((unused)), const char *schema_name MY_ATTRIBUTE((unused)), - const char *routine_name MY_ATTRIBUTE((unused)), uint8 type MY_ATTRIBUTE((unused))) { +typename std::enable_if::type invalidate_routine( + T *thd MY_ATTRIBUTE((unused)), const char *schema_name MY_ATTRIBUTE((unused)), + const char *routine_name MY_ATTRIBUTE((unused)), uint8 type MY_ATTRIBUTE((unused))) +{ return false; } template -typename std::enable_if::type - invalidate_table(T *thd, const char *schema_name, const char *table_name) { +typename std::enable_if::type invalidate_table(T *thd, + const char *schema_name, + const char *table_name) +{ MDL_ticket *schema_ticket = nullptr; MDL_ticket *table_ticket = nullptr; - + ctc_log_system("[INVALIDATE_TABLE]: enter invalidate_table, schema:%s, table:%s", schema_name, table_name); - if(!thd->mdl_context.owns_equal_or_stronger_lock( - MDL_key::SCHEMA, schema_name, "", MDL_INTENTION_EXCLUSIVE)) { + if (!thd->mdl_context.owns_equal_or_stronger_lock(MDL_key::SCHEMA, schema_name, "", MDL_INTENTION_EXCLUSIVE)) { MDL_request mdl_request; - MDL_REQUEST_INIT(&mdl_request, MDL_key::SCHEMA, schema_name, "", - MDL_INTENTION_EXCLUSIVE, MDL_EXPLICIT); + MDL_REQUEST_INIT(&mdl_request, MDL_key::SCHEMA, schema_name, "", MDL_INTENTION_EXCLUSIVE, MDL_EXPLICIT); if (thd->mdl_context.acquire_lock(&mdl_request, CTC_MDL_TIMEOUT)) { assert(thd->killed || thd->is_error()); - ctc_log_error("[INVALIDATE_TABLE]: Failed to acquire schema mdl lock of schema:%s and table:%s ", schema_name, table_name); + ctc_log_error("[INVALIDATE_TABLE]: Failed to acquire schema mdl lock of schema:%s and table:%s ", schema_name, + table_name); return true; } schema_ticket = mdl_request.ticket; } ctc_log_system("[INVALIDATE_TABLE]: enter invalidate_table table, schema:%s, table:%s", schema_name, table_name); - if(!thd->mdl_context.owns_equal_or_stronger_lock( - MDL_key::TABLE, schema_name, table_name, MDL_EXCLUSIVE)) { + if (!thd->mdl_context.owns_equal_or_stronger_lock(MDL_key::TABLE, schema_name, table_name, MDL_EXCLUSIVE)) { MDL_request mdl_request; - MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLE, schema_name, table_name, - MDL_EXCLUSIVE, MDL_EXPLICIT); + MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLE, schema_name, table_name, MDL_EXCLUSIVE, MDL_EXPLICIT); if (thd->mdl_context.acquire_lock(&mdl_request, CTC_MDL_TIMEOUT)) { assert(thd->killed || thd->is_error()); - ctc_log_error("[INVALIDATE_TABLE]: Failed to acquire table mdl lock of schema:%s and table:%s ", schema_name, table_name); + ctc_log_error("[INVALIDATE_TABLE]: Failed to acquire table mdl lock of schema:%s and table:%s ", schema_name, + table_name); return true; } table_ticket = mdl_request.ticket; } - + dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client()); tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, schema_name, table_name, false); - + bool ignored MY_ATTRIBUTE((unused)); ignored = thd->dd_client()->invalidate(schema_name, table_name); - + if (schema_ticket) thd->mdl_context.release_lock(schema_ticket); if (table_ticket) thd->mdl_context.release_lock(table_ticket); - + ctc_log_system("[INVALIDATE_TABLE]: leave invalidate_table, schema:%s, table:%s", schema_name, table_name); return false; } template -typename std::enable_if::type - invalidate_table(T *thd MY_ATTRIBUTE((unused)), const char *schema_name MY_ATTRIBUTE((unused)), - const char *table_name MY_ATTRIBUTE((unused))) { +typename std::enable_if::type invalidate_table( + T *thd MY_ATTRIBUTE((unused)), const char *schema_name MY_ATTRIBUTE((unused)), + const char *table_name MY_ATTRIBUTE((unused))) +{ return false; } template -typename std::enable_if::type - invalidate_schema(T *thd, const char *schema_name) { +typename std::enable_if::type invalidate_schema(T *thd, + const char *schema_name) +{ MDL_ticket *schema_ticket = nullptr; - + ctc_log_system("[INVALIDATE_SCHEMA]:enter invalidate_schema, schema:%s", schema_name); MDL_request mdl_request; - MDL_REQUEST_INIT(&mdl_request, MDL_key::SCHEMA, schema_name, "", - MDL_EXCLUSIVE, MDL_EXPLICIT); - + MDL_REQUEST_INIT(&mdl_request, MDL_key::SCHEMA, schema_name, "", MDL_EXCLUSIVE, MDL_EXPLICIT); + if (thd->mdl_context.acquire_lock(&mdl_request, CTC_MDL_TIMEOUT)) { assert(thd->killed || thd->is_error()); ctc_log_error("[INVALIDATE_SCHEMA]: Failed to acquire schema(%s) mdl lock .", schema_name); return true; } schema_ticket = mdl_request.ticket; - + dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client()); - + const dd::Schema *schema = nullptr; bool ignored MY_ATTRIBUTE((unused)); ignored = thd->dd_client()->acquire(schema_name, &schema); if (schema) { thd->dd_client()->invalidate(schema); } - + if (schema_ticket) thd->mdl_context.release_lock(schema_ticket); - + ctc_log_system("leave invalidate_schema, schema:%s", schema_name); return false; } template -typename std::enable_if::type - invalidate_schema(T *thd, const char *schema_name) { +typename std::enable_if::type invalidate_schema(T *thd, + const char *schema_name) +{ return false; } template -typename std::enable_if::type - invalidate_tablespace(T *thd, const char *tablespace_name) { +typename std::enable_if::type invalidate_tablespace( + T *thd, const char *tablespace_name) +{ MDL_ticket *tablespace_ticket = nullptr; - + ctc_log_system("[INVALIDATE_TABLESPACE]: enter invalidate_tablespace, tablespace_name:%s", tablespace_name); MDL_request mdl_request; - MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLESPACE, tablespace_name, "", - MDL_EXCLUSIVE, MDL_EXPLICIT); - + MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLESPACE, tablespace_name, "", MDL_EXCLUSIVE, MDL_EXPLICIT); + if (thd->mdl_context.acquire_lock(&mdl_request, CTC_MDL_TIMEOUT)) { assert(thd->killed || thd->is_error()); - ctc_log_error("[INVALIDATE_TABLESPACE]: Failed to acquire tablespace mdl lock of tablespace_name:%s", tablespace_name); + ctc_log_error("[INVALIDATE_TABLESPACE]: Failed to acquire tablespace mdl lock of tablespace_name:%s", + tablespace_name); return true; } tablespace_ticket = mdl_request.ticket; - + dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client()); - + const dd::Tablespace *tablespace = nullptr; bool ignored MY_ATTRIBUTE((unused)); ignored = thd->dd_client()->acquire(tablespace_name, &tablespace); @@ -413,34 +430,37 @@ typename std::enable_if::type thd->dd_client()->invalidate(tablespace); } thd->dd_client()->template dump(); - + if (tablespace_ticket) thd->mdl_context.release_lock(tablespace_ticket); - + ctc_log_system("[INVALIDATE_TABLESPACE]:leave invalidate_tablespace, tablespace_name:%s", tablespace_name); return false; } template -typename std::enable_if::type - invalidate_tablespace(T *thd MY_ATTRIBUTE((unused)), const char *tablespace_name MY_ATTRIBUTE((unused))) { +typename std::enable_if::type invalidate_tablespace( + T *thd MY_ATTRIBUTE((unused)), const char *tablespace_name MY_ATTRIBUTE((unused))) +{ return false; } template -static typename std::enable_if::type - ctc_invalidate_mysql_dd_cache_impl(ctc_handler_t *tch, ctc_invalidate_broadcast_request *broadcast_req, int *err_code) { +static typename std::enable_if::type ctc_invalidate_mysql_dd_cache_impl( + ctc_handler_t *tch, ctc_invalidate_broadcast_request *broadcast_req, int *err_code) +{ UNUSED_PARAM(err_code); // 相同节点不用执行 - if(broadcast_req->mysql_inst_id == ctc_instance_id) { - ctc_log_note("ctc_invalidate_mysql_dd_cache curnode not need execute,mysql_inst_id:%u", broadcast_req->mysql_inst_id); + if (broadcast_req->mysql_inst_id == ctc_instance_id) { + ctc_log_note("ctc_invalidate_mysql_dd_cache curnode not need execute,mysql_inst_id:%u", + broadcast_req->mysql_inst_id); return 0; } - + bool error = false; T *thd = nullptr; uint64_t thd_key = ctc_get_conn_key(tch->inst_id, tch->thd_id, true); ctc_init_thd(&thd, thd_key); - + if (broadcast_req->is_dcl == true) { error = reload_acl_caches(thd, false); ctc_log_system("[CTC_INVALID_DD]: remote invalidate acl cache, mysql_inst_id=%u", broadcast_req->mysql_inst_id); @@ -454,23 +474,25 @@ static typename std::enable_if::type obj = (invalidate_obj_entry_t *)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(invalidate_obj_entry_t), MYF(MY_WME)); assert(obj); memcpy(obj, buff + offset, sizeof(invalidate_obj_entry_t)); - printf("\n[ctc_invalidate_mysql_dd_cache_impl] type: %u, first: %s, second: %s\n", obj->type, obj->first, obj->second); fflush(stdout); + printf("\n[ctc_invalidate_mysql_dd_cache_impl] type: %u, first: %s, second: %s\n", obj->type, obj->first, + obj->second); + fflush(stdout); switch (obj->type) { case T::OBJ_ABSTRACT_TABLE: - error = invalidate_table(thd, obj->first, obj->second); - my_free(obj); - break; + error = invalidate_table(thd, obj->first, obj->second); + my_free(obj); + break; case T::OBJ_RT_PROCEDURE: case T::OBJ_RT_FUNCTION: - ctc_insert_routine(thd, obj); - break; + ctc_insert_routine(thd, obj); + break; case T::OBJ_SCHEMA: - ctc_insert_schema(thd, obj); - break; + ctc_insert_schema(thd, obj); + break; case T::OBJ_TABLESPACE: - error = invalidate_tablespace(thd, obj->first); - my_free(obj); - break; + error = invalidate_tablespace(thd, obj->first); + my_free(obj); + break; case T::OBJ_EVENT: case T::OBJ_COLUMN_STATISTICS: case T::OBJ_RESOURCE_GROUP: @@ -478,7 +500,7 @@ static typename std::enable_if::type case T::OBJ_CHARSET: case T::OBJ_COLLATION: default: - break; + break; } offset += sizeof(invalidate_obj_entry_t); } @@ -487,22 +509,22 @@ static typename std::enable_if::type release_routine_and_schema(thd, &error); } } - + thd->restore_globals(); my_thread_end(); - - ctc_log_system("[CTC_INVALID_DD]: remote invalidate dd cache success, mysql_inst_id=%u", broadcast_req->mysql_inst_id); + + ctc_log_system("[CTC_INVALID_DD]: remote invalidate dd cache success, mysql_inst_id=%u", + broadcast_req->mysql_inst_id); return error; } #ifndef METADATA_NORMALIZED -static void release_routine_and_schema(THD *thd MY_ATTRIBUTE((unused)), bool *error MY_ATTRIBUTE((unused))) { - return; -} +static void release_routine_and_schema(THD *thd MY_ATTRIBUTE((unused)), bool *error MY_ATTRIBUTE((unused))) { return; } #endif #ifdef METADATA_NORMALIZED -static void release_routine_and_schema(THD *thd, bool *error) { +static void release_routine_and_schema(THD *thd, bool *error) +{ lock_guard lock(m_ctc_invalidate_dd_cache_mutex); auto it_routine = g_ctc_invalidate_routine_maps.find(thd); auto it_schema = g_ctc_invalidate_schema_maps.find(thd); @@ -512,7 +534,9 @@ static void release_routine_and_schema(THD *thd, bool *error) { for (auto invalidate_it : *invalidate_routine_list) { *error = invalidate_routine(thd, invalidate_it->first, invalidate_it->second, invalidate_it->type); if (*error) { - printf("\n[invalidate_routine] error.type: %u, first: %s, second: %s\n", invalidate_it->type, invalidate_it->first, invalidate_it->second); fflush(stdout); + printf("\n[invalidate_routine] error.type: %u, first: %s, second: %s\n", invalidate_it->type, + invalidate_it->first, invalidate_it->second); + fflush(stdout); } my_free(invalidate_it); invalidate_it = nullptr; @@ -523,14 +547,16 @@ static void release_routine_and_schema(THD *thd, bool *error) { } g_ctc_invalidate_routine_maps.erase(thd); } - + if (it_schema != g_ctc_invalidate_schema_maps.end()) { vector *invalidate_schema_list = it_schema->second; if (invalidate_schema_list != nullptr) { for (auto invalidate_it : *invalidate_schema_list) { *error = invalidate_schema(thd, invalidate_it->first); if (*error) { - printf("\n[invalidate_schema] error.type: %u, first: %s, second: %s\n", invalidate_it->type, invalidate_it->first, invalidate_it->second); fflush(stdout); + printf("\n[invalidate_schema] error.type: %u, first: %s, second: %s\n", invalidate_it->type, + invalidate_it->first, invalidate_it->second); + fflush(stdout); } my_free(invalidate_it); invalidate_it = nullptr; @@ -545,23 +571,25 @@ static void release_routine_and_schema(THD *thd, bool *error) { #endif template -static typename std::enable_if::type - ctc_invalidate_mysql_dd_cache_impl(ctc_handler_t *tch MY_ATTRIBUTE((unused)), - ctc_invalidate_broadcast_request *broadcast_req MY_ATTRIBUTE((unused)), - int *err_code MY_ATTRIBUTE((unused))) { +static typename std::enable_if::type ctc_invalidate_mysql_dd_cache_impl( + ctc_handler_t *tch MY_ATTRIBUTE((unused)), ctc_invalidate_broadcast_request *broadcast_req MY_ATTRIBUTE((unused)), + int *err_code MY_ATTRIBUTE((unused))) +{ return 0; } -int ctc_invalidate_mysql_dd_cache(ctc_handler_t *tch, ctc_invalidate_broadcast_request *broadcast_req, int *err_code) { +int ctc_invalidate_mysql_dd_cache(ctc_handler_t *tch, ctc_invalidate_broadcast_request *broadcast_req, int *err_code) +{ return (int)ctc_invalidate_mysql_dd_cache_impl(tch, broadcast_req, err_code); } -static void ctc_init_mdl_request(ctc_lock_table_info *lock_info, MDL_request *mdl_request) { +static void ctc_init_mdl_request(ctc_lock_table_info *lock_info, MDL_request *mdl_request) +{ MDL_key mdl_key; dd::String_type schema_name = dd::String_type(lock_info->db_name); dd::String_type name = dd::String_type(lock_info->table_name); MDL_key::enum_mdl_namespace ctc_mdl_namespace = (MDL_key::enum_mdl_namespace)lock_info->mdl_namespace; - + switch (ctc_mdl_namespace) { case MDL_key::FUNCTION: dd::Function::create_mdl_key(schema_name, name, &mdl_key); @@ -584,14 +612,16 @@ static void ctc_init_mdl_request(ctc_lock_table_info *lock_info, MDL_request *md MDL_REQUEST_INIT_BY_KEY(mdl_request, &mdl_key, MDL_EXCLUSIVE, MDL_EXPLICIT); break; default: - MDL_REQUEST_INIT(mdl_request, ctc_mdl_namespace, lock_info->db_name, lock_info->table_name, - MDL_EXCLUSIVE, MDL_EXPLICIT); + MDL_REQUEST_INIT(mdl_request, ctc_mdl_namespace, lock_info->db_name, lock_info->table_name, MDL_EXCLUSIVE, + MDL_EXPLICIT); break; } return; } -static void ctc_init_mdl_request(ctc_lock_table_info *lock_info, MDL_request *mdl_request, MDL_key::enum_mdl_namespace ctc_mdl_namespace) { +static void ctc_init_mdl_request(ctc_lock_table_info *lock_info, MDL_request *mdl_request, + MDL_key::enum_mdl_namespace ctc_mdl_namespace) +{ MDL_key mdl_key; dd::String_type schema_name = dd::String_type(lock_info->db_name); dd::String_type name = dd::String_type(lock_info->table_name); @@ -599,21 +629,22 @@ static void ctc_init_mdl_request(ctc_lock_table_info *lock_info, MDL_request *md (enum_mdl_type)lock_info->mdl_namespace, MDL_EXPLICIT); return; } - -int ctc_mdl_lock_thd(ctc_handler_t *tch, ctc_lock_table_info *lock_info, int *err_code) { + +int ctc_mdl_lock_thd(ctc_handler_t *tch, ctc_lock_table_info *lock_info, int *err_code) +{ bool is_same_node = (tch->inst_id == ctc_instance_id); uint64_t mdl_thd_key = ctc_get_conn_key(tch->inst_id, tch->thd_id, true); - + if (is_same_node) { return false; } - + THD *thd = nullptr; ctc_init_thd(&thd, mdl_thd_key); - + MDL_request ctc_mdl_request; ctc_init_mdl_request(lock_info, &ctc_mdl_request); - + if (thd->mdl_context.acquire_lock(&ctc_mdl_request, 10)) { *err_code = ER_LOCK_WAIT_TIMEOUT; ctc_log_error("[CTC_MDL_LOCK]:Failed to get mdl lock of namespace:%d , db_name:%s and table_name:%s", @@ -631,7 +662,7 @@ int ctc_mdl_lock_thd(ctc_handler_t *tch, ctc_lock_table_info *lock_info, int *er ctc_mdl_ticket_map = g_ctc_mdl_ticket_maps[thd]; } string mdl_ticket_key; - mdl_ticket_key.assign(((const char*)(ctc_mdl_request.key.ptr())), ctc_mdl_request.key.length()); + mdl_ticket_key.assign(((const char *)(ctc_mdl_request.key.ptr())), ctc_mdl_request.key.length()); assert(mdl_ticket_key.length() > 0); ctc_mdl_ticket_map->insert(map::value_type(mdl_ticket_key, ctc_mdl_request.ticket)); @@ -641,7 +672,8 @@ int ctc_mdl_lock_thd(ctc_handler_t *tch, ctc_lock_table_info *lock_info, int *er return false; } -void ctc_mdl_unlock_thd_by_ticket(THD* thd, MDL_request *ctc_release_request) { +void ctc_mdl_unlock_thd_by_ticket(THD *thd, MDL_request *ctc_release_request) +{ lock_guard lock(m_ctc_mdl_ticket_mutex); auto ticket_map_iter = g_ctc_mdl_ticket_maps.find(thd); if (ticket_map_iter == g_ctc_mdl_ticket_maps.end()) { @@ -655,7 +687,7 @@ void ctc_mdl_unlock_thd_by_ticket(THD* thd, MDL_request *ctc_release_request) { } string mdl_ticket_key; - mdl_ticket_key.assign(((const char*)(ctc_release_request->key.ptr())), ctc_release_request->key.length()); + mdl_ticket_key.assign(((const char *)(ctc_release_request->key.ptr())), ctc_release_request->key.length()); auto ticket_iter = ctc_mdl_ticket_map->find(mdl_ticket_key); if (ticket_iter == ctc_mdl_ticket_map->end()) { return; @@ -670,7 +702,8 @@ void ctc_mdl_unlock_thd_by_ticket(THD* thd, MDL_request *ctc_release_request) { } } -void ctc_mdl_unlock_tables_thd(ctc_handler_t *tch) { +void ctc_mdl_unlock_tables_thd(ctc_handler_t *tch) +{ bool is_same_node = (tch->inst_id == ctc_instance_id); uint64_t mdl_thd_key = ctc_get_conn_key(tch->inst_id, tch->thd_id, true); @@ -682,7 +715,7 @@ void ctc_mdl_unlock_tables_thd(ctc_handler_t *tch) { if (iter == g_ctc_mdl_thd_map.end()) { return; } - THD* thd = iter->second; + THD *thd = iter->second; assert(thd); my_thread_init(); @@ -721,7 +754,8 @@ void ctc_mdl_unlock_tables_thd(ctc_handler_t *tch) { return; } -void ctc_mdl_unlock_thd(ctc_handler_t *tch, ctc_lock_table_info *lock_info) { +void ctc_mdl_unlock_thd(ctc_handler_t *tch, ctc_lock_table_info *lock_info) +{ bool is_same_node = (tch->inst_id == ctc_instance_id); uint64_t mdl_thd_key = ctc_get_conn_key(tch->inst_id, tch->thd_id, true); @@ -733,7 +767,7 @@ void ctc_mdl_unlock_thd(ctc_handler_t *tch, ctc_lock_table_info *lock_info) { if (iter == g_ctc_mdl_thd_map.end()) { return; } - THD* thd = iter->second; + THD *thd = iter->second; assert(thd); my_thread_init(); thd->store_globals(); @@ -747,12 +781,13 @@ void ctc_mdl_unlock_thd(ctc_handler_t *tch, ctc_lock_table_info *lock_info) { return; } -int close_ctc_mdl_thd(uint32_t thd_id, uint32_t mysql_inst_id) { +int close_ctc_mdl_thd(uint32_t thd_id, uint32_t mysql_inst_id) +{ if (thd_id == 0) { if ((uint16_t)mysql_inst_id == (uint16_t)CANTIAN_DOWN_MASK) { /* 清理整个参天节点相关的THD */ ctc_log_system("[CTC_MDL_THD]:Close All MDL THD on bad node by cantian_instance_id:%u", - (uint16_t)(mysql_inst_id >> 16)); + (uint16_t)(mysql_inst_id >> 16)); release_ctc_mdl_thd_by_cantian_id((uint16_t)(mysql_inst_id >> 16)); } else { /* 清理整个mysqld节点相关的THD */ @@ -762,64 +797,54 @@ int close_ctc_mdl_thd(uint32_t thd_id, uint32_t mysql_inst_id) { } else { /* 通过把mysql_inst_id左移32位 与 thd_id拼接在一起 用来唯一标识一个THD */ uint64_t mdl_thd_key = ctc_get_conn_key(mysql_inst_id, thd_id, true); - ctc_log_note("[CTC_MDL_THD]: Close THD by conn_id=%u, ctc_instance_id=%u, proxy_conn_map_key=%lu", - thd_id, mysql_inst_id, mdl_thd_key); + ctc_log_note("[CTC_MDL_THD]: Close THD by conn_id=%u, ctc_instance_id=%u, proxy_conn_map_key=%lu", thd_id, + mysql_inst_id, mdl_thd_key); release_ctc_mdl_thd_by_key(mdl_thd_key); } return 0; } -static void ctc_get_set_var_item(THD* new_thd, sys_var* sysvar, Item** res MY_ATTRIBUTE((unused)), string& var_value, - bool is_null_value, bool var_is_int) { +static void ctc_get_set_var_item(THD *new_thd, sys_var *sysvar, Item **res MY_ATTRIBUTE((unused)), string &var_value, + bool is_null_value, bool var_is_int) +{ switch (sysvar->show_type()) { case SHOW_INT: case SHOW_LONG: case SHOW_LONGLONG: case SHOW_HA_ROWS: if (var_value.c_str()[0] != '-') { - *res = new (new_thd->mem_root) - Item_uint(var_value.c_str(), (uint)var_value.length()); + *res = new (new_thd->mem_root) Item_uint(var_value.c_str(), (uint)var_value.length()); break; } case SHOW_SIGNED_INT: case SHOW_SIGNED_LONG: case SHOW_SIGNED_LONGLONG: - *res = new (new_thd->mem_root) - Item_int(var_value.c_str(), (uint)var_value.length()); + *res = new (new_thd->mem_root) Item_int(var_value.c_str(), (uint)var_value.length()); break; case SHOW_BOOL: case SHOW_MY_BOOL: - if(var_value == "1" || var_value == "0") { - *res = new (new_thd->mem_root) - Item_int(var_value.c_str(), (uint)var_value.length()); + if (var_value == "1" || var_value == "0") { + *res = new (new_thd->mem_root) Item_int(var_value.c_str(), (uint)var_value.length()); } else { - *res = new (new_thd->mem_root) - Item_string(var_value.c_str(), var_value.length(), - &my_charset_utf8mb4_bin); + *res = new (new_thd->mem_root) Item_string(var_value.c_str(), var_value.length(), &my_charset_utf8mb4_bin); } break; case SHOW_CHAR: case SHOW_LEX_STRING: if (var_is_int) { - *res = new (new_thd->mem_root) - Item_int(var_value.c_str(), (uint)var_value.length()); + *res = new (new_thd->mem_root) Item_int(var_value.c_str(), (uint)var_value.length()); } else { - *res = new (new_thd->mem_root) - Item_string(var_value.c_str(), var_value.length(), - &my_charset_utf8mb4_bin); + *res = new (new_thd->mem_root) Item_string(var_value.c_str(), var_value.length(), &my_charset_utf8mb4_bin); } break; case SHOW_CHAR_PTR: if (is_null_value) *res = new (new_thd->mem_root) Item_null(); else - *res = new (new_thd->mem_root) - Item_string(var_value.c_str(), var_value.length(), - &my_charset_utf8mb4_bin); + *res = new (new_thd->mem_root) Item_string(var_value.c_str(), var_value.length(), &my_charset_utf8mb4_bin); break; case SHOW_DOUBLE: - *res = new (new_thd->mem_root) - Item_float(var_value.c_str(), (uint)var_value.length()); + *res = new (new_thd->mem_root) Item_float(var_value.c_str(), (uint)var_value.length()); break; default: my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), sysvar->name.str); @@ -827,7 +852,8 @@ static void ctc_get_set_var_item(THD* new_thd, sys_var* sysvar, Item** res MY_AT } #ifdef FEATURE_X_FOR_MYSQL_26 -static void ctc_set_var_type(uint32_t option, set_var *var) { +static void ctc_set_var_type(uint32_t option, set_var *var) +{ if ((option & CTC_SET_VARIABLE_PERSIST) > 0) { var->type = OPT_PERSIST; } @@ -837,27 +863,26 @@ static void ctc_set_var_type(uint32_t option, set_var *var) { } #endif -static void ctc_init_thd_priv(THD** thd, Sctx_ptr *ctx) { +static void ctc_init_thd_priv(THD **thd, Sctx_ptr *ctx) +{ my_thread_init(); - THD* new_thd = new (std::nothrow) THD; + THD *new_thd = new (std::nothrow) THD; new_thd->set_new_thread_id(); new_thd->thread_stack = (char *)&new_thd; new_thd->store_globals(); lex_start(new_thd); new_thd->security_context()->skip_grants(); new_thd->set_query("ctc_mdl_thd_notify", 18); - - const std::vector priv_list = { - "ENCRYPTION_KEY_ADMIN", "ROLE_ADMIN", "SYSTEM_VARIABLES_ADMIN", - "AUDIT_ADMIN", "PERSIST_RO_VARIABLES_ADMIN"}; + + const std::vector priv_list = {"ENCRYPTION_KEY_ADMIN", "ROLE_ADMIN", "SYSTEM_VARIABLES_ADMIN", + "AUDIT_ADMIN", "PERSIST_RO_VARIABLES_ADMIN"}; const ulong static_priv_list = (SUPER_ACL | FILE_ACL); - - Security_context_factory default_factory( - new_thd, "bootstrap", "localhost", Default_local_authid(new_thd), - Grant_temporary_dynamic_privileges(new_thd, priv_list), - Grant_temporary_static_privileges(new_thd, static_priv_list), - Drop_temporary_dynamic_privileges(priv_list)); - + + Security_context_factory default_factory(new_thd, "bootstrap", "localhost", Default_local_authid(new_thd), + Grant_temporary_dynamic_privileges(new_thd, priv_list), + Grant_temporary_static_privileges(new_thd, static_priv_list), + Drop_temporary_dynamic_privileges(priv_list)); + (*ctx) = default_factory.create(); /* attach this auth id to current security_context */ new_thd->set_security_context(ctx->get()); @@ -867,7 +892,8 @@ static void ctc_init_thd_priv(THD** thd, Sctx_ptr *ctx) { (*thd) = new_thd; } -int ctc_set_sys_var(ctc_ddl_broadcast_request *broadcast_req) { +int ctc_set_sys_var(ctc_ddl_broadcast_request *broadcast_req) +{ Sctx_ptr ctx; THD *new_thd = nullptr; ctc_init_thd_priv(&new_thd, &ctx); @@ -880,7 +906,7 @@ int ctc_set_sys_var(ctc_ddl_broadcast_request *broadcast_req) { // variable value is too long and exceeds the range of user_ip string var_value = broadcast_req->sql_str; List tmp_var_list; - + bool is_default_value = ((broadcast_req->options) & (CTC_SET_VARIABLE_TO_DEFAULT)) > 0; bool is_null_value = ((broadcast_req->options) & (CTC_SET_VARIABLE_TO_NULL)) > 0; bool var_is_int = ((broadcast_req->user_ip[0] & 1) != 0); @@ -904,7 +930,7 @@ int ctc_set_sys_var(ctc_ddl_broadcast_request *broadcast_req) { return ER_UNKNOWN_SYSTEM_VARIABLE; } ctc_get_set_var_item(new_thd, sysvar, &res, var_value, is_null_value, var_is_int); - + if (is_default_value) { if (res) { res->cleanup(); @@ -915,8 +941,7 @@ int ctc_set_sys_var(ctc_ddl_broadcast_request *broadcast_req) { var = new (new_thd->mem_root) set_var(type, sysvar, base_name, res); ctc_set_var_type(broadcast_req->options, var); #elif defined(FEATURE_X_FOR_MYSQL_32) - System_variable_tracker var_tracker = - System_variable_tracker::make_tracker(var_name.c_str()); + System_variable_tracker var_tracker = System_variable_tracker::make_tracker(var_name.c_str()); var = new (new_thd->mem_root) set_var(type, var_tracker, res); #endif tmp_var_list.push_back(var); @@ -924,8 +949,8 @@ int ctc_set_sys_var(ctc_ddl_broadcast_request *broadcast_req) { if (ret != 0) { uint err_code = new_thd->get_stmt_da()->mysql_errno(); strncpy(broadcast_req->err_msg, new_thd->get_stmt_da()->message_text(), ERROR_MESSAGE_LEN - 1); - ctc_log_error("[ctc_set_sys_var]:set global opt fail; err_code: %u, var_name: %s, var_value: %s", - err_code, var_name.c_str(), var_value.c_str()); + ctc_log_error("[ctc_set_sys_var]:set global opt fail; err_code: %u, var_name: %s, var_value: %s", err_code, + var_name.c_str(), var_value.c_str()); return err_code; } @@ -939,31 +964,32 @@ int ctc_set_sys_var(ctc_ddl_broadcast_request *broadcast_req) { delete new_thd; my_thread_end(); - + return ret; } -int ctc_ddl_execute_lock_tables_by_req(ctc_handler_t *tch, ctc_lock_table_info *lock_info, int *err_code) { -// unlock tables before locking tables +int ctc_ddl_execute_lock_tables_by_req(ctc_handler_t *tch, ctc_lock_table_info *lock_info, int *err_code) +{ + // unlock tables before locking tables ctc_mdl_unlock_tables_thd(tch); bool is_same_node = (tch->inst_id == ctc_instance_id); uint64_t mdl_thd_key = ctc_get_conn_key(tch->inst_id, tch->thd_id, true); - + if (is_same_node) { return false; } - + THD *thd = nullptr; ctc_init_thd(&thd, mdl_thd_key); - + MDL_request ctc_mdl_request; ctc_init_mdl_request(lock_info, &ctc_mdl_request, MDL_key::TABLE); - + if (thd->mdl_context.acquire_lock(&ctc_mdl_request, 10)) { *err_code = ER_LOCK_WAIT_TIMEOUT; - ctc_log_error("[CTC_MDL_LOCK]:Get mdl lock fail. namespace:%d, db_name:%s, table_name:%s", - lock_info->mdl_namespace, lock_info->db_name, lock_info->table_name); + ctc_log_error("[CTC_MDL_LOCK]:Get mdl lock fail. namespace:%d, db_name:%s, table_name:%s", lock_info->mdl_namespace, + lock_info->db_name, lock_info->table_name); return true; } @@ -977,7 +1003,7 @@ int ctc_ddl_execute_lock_tables_by_req(ctc_handler_t *tch, ctc_lock_table_info * ctc_mdl_ticket_map = g_ctc_mdl_ticket_maps[thd]; } string mdl_ticket_key; - mdl_ticket_key.assign(((const char*)(ctc_mdl_request.key.ptr())), ctc_mdl_request.key.length()); + mdl_ticket_key.assign(((const char *)(ctc_mdl_request.key.ptr())), ctc_mdl_request.key.length()); assert(mdl_ticket_key.length() > 0); ctc_mdl_ticket_map->insert(map::value_type(mdl_ticket_key, ctc_mdl_request.ticket)); diff --git a/storage/ctc/ctc_mysql_proxy.cc b/storage/ctc/ctc_mysql_proxy.cc index 32a0e54..4283d47 100644 --- a/storage/ctc/ctc_mysql_proxy.cc +++ b/storage/ctc/ctc_mysql_proxy.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -14,55 +14,56 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include +#include +#include #include +#include #include #include -#include -#include -#include -#include "my_md5.h" -#include "my_md5_size.h" -#include "mysql.h" -#include "sql/mysqld.h" // mysql_port, my_localhost #include "ctc_log.h" +#include "ctc_meta_data.h" +#include "ctc_proxy_util.h" #include "ctc_srv.h" #include "ctc_util.h" #include "ha_ctc.h" -#include "ctc_meta_data.h" -#include "ctc_proxy_util.h" -#include "sql/sql_table.h" #include "my_dir.h" -#include "sql/sql_handler.h" -#include "sql/sql_base.h" -#include "sql/sql_class.h" +#include "my_md5.h" +#include "my_md5_size.h" +#include "mysql.h" +#include "sql/auth/auth_common.h" #include "sql/dd/cache/dictionary_client.h" -#include "sql/mysqld_thd_manager.h" -#include "sql/dd/types/procedure.h" -#include "sql/dd/types/function.h" -#include "sql/dd/types/routine.h" -#include "sql/mdl.h" #include "sql/dd/types/event.h" +#include "sql/dd/types/function.h" +#include "sql/dd/types/procedure.h" #include "sql/dd/types/resource_group.h" +#include "sql/dd/types/routine.h" #include "sql/dd/types/trigger.h" -#include "sql/auth/auth_common.h" +#include "sql/handler.h" // ha_ctc_commit +#include "sql/mdl.h" +#include "sql/mysqld.h" // mysql_port, my_localhost +#include "sql/mysqld_thd_manager.h" +#include "sql/sql_base.h" +#include "sql/sql_class.h" +#include "sql/sql_handler.h" +#include "sql/sql_lex.h" // lex_start/lex_end +#include "sql/sql_table.h" #include "sql/sys_vars_shared.h" // intern_find_sys_var -#include "sql/sql_lex.h" // lex_start/lex_end -#include "sql/handler.h" // ha_ctc_commit using namespace std; struct ctc_mysql_conn_info { - MYSQL* conn; - set> table_lock_info; // 连接上已存在的表锁 (db, table) - bool has_explicit_table_lock; // 连接上是否存在显式的表锁 - uint32_t name_locks; // 连接上持有的命名锁数量 + MYSQL *conn; + set> table_lock_info; // 连接上已存在的表锁 (db, table) + bool has_explicit_table_lock; // 连接上是否存在显式的表锁 + uint32_t name_locks; // 连接上持有的命名锁数量 }; -static map g_mysql_conn_map; +static map g_mysql_conn_map; static mutex m_ctc_mysql_proxy_mutex; -static ctc_mysql_conn_info* init_ctc_mysql_conn(MYSQL* curr_conn) { +static ctc_mysql_conn_info *init_ctc_mysql_conn(MYSQL *curr_conn) +{ ctc_mysql_conn_info *ctc_conn_info = new ctc_mysql_conn_info(); ctc_conn_info->conn = curr_conn; ctc_conn_info->table_lock_info = set>(); @@ -71,7 +72,8 @@ static ctc_mysql_conn_info* init_ctc_mysql_conn(MYSQL* curr_conn) { return ctc_conn_info; } -static void set_explicit_table_lock(uint64_t conn_map_key, uint8_t sql_command) { +static void set_explicit_table_lock(uint64_t conn_map_key, uint8_t sql_command) +{ lock_guard lock(m_ctc_mysql_proxy_mutex); if (sql_command == SQLCOM_LOCK_TABLES) { g_mysql_conn_map[conn_map_key]->has_explicit_table_lock = true; @@ -81,7 +83,8 @@ static void set_explicit_table_lock(uint64_t conn_map_key, uint8_t sql_command) return; } -int ctc_select_db(MYSQL *curr_conn, const char *db) { +int ctc_select_db(MYSQL *curr_conn, const char *db) +{ if (CM_IS_EMPTY_STR(db)) { return 0; } @@ -90,11 +93,11 @@ int ctc_select_db(MYSQL *curr_conn, const char *db) { if (ret != 0) { ctc_log_error("ctc_select_db: mysql server has gone. db:%s error_code:%d, reconnecting.", db, ret); } - + ret = mysql_select_db(curr_conn, db); if (ret != 0) { - ctc_log_error("select db:%s failed,ret:%d, error_code:%d,desc:%s", db, ret, - mysql_errno(curr_conn), mysql_error(curr_conn)); + ctc_log_error("select db:%s failed,ret:%d, error_code:%d,desc:%s", db, ret, mysql_errno(curr_conn), + mysql_error(curr_conn)); return mysql_errno(curr_conn); } return 0; @@ -103,28 +106,29 @@ int ctc_select_db(MYSQL *curr_conn, const char *db) { static void ctc_drop_proxy_user(MYSQL *agent_conn, const string &proxy_user_name) { string drop_user_sql = "drop user if exists '" + proxy_user_name + "';"; - + if (ctc_mysql_query(agent_conn, drop_user_sql.c_str())) { - ctc_log_error("ctc_drop_proxy_user failed, drop user=%s, sql=%s, err_code=%d, err_msg=%s", - proxy_user_name.c_str(), drop_user_sql.c_str(), mysql_errno(agent_conn), mysql_error(agent_conn)); + ctc_log_error("ctc_drop_proxy_user failed, drop user=%s, sql=%s, err_code=%d, err_msg=%s", proxy_user_name.c_str(), + drop_user_sql.c_str(), mysql_errno(agent_conn), mysql_error(agent_conn)); assert(0); } } -static int ctc_create_proxy_user(MYSQL *agent_conn, const char*user_name, const char*user_ip, - string &proxy_user_name, string &proxy_user_password) +static int ctc_create_proxy_user(MYSQL *agent_conn, const char *user_name, const char *user_ip, string &proxy_user_name, + string &proxy_user_password) { - string create_user_sql = "CREATE USER '" + proxy_user_name + \ - "' IDENTIFIED WITH 'mysql_native_password' BY RANDOM PASSWORD;"; + string create_user_sql = + "CREATE USER '" + proxy_user_name + "' IDENTIFIED WITH 'mysql_native_password' BY RANDOM PASSWORD;"; int ret = ctc_mysql_query(agent_conn, create_user_sql.c_str()); // ret: success: 0, fail: 1 - + int err_code = mysql_errno(agent_conn); char err_msg[ERROR_MESSAGE_LEN] = {0}; strncpy(err_msg, mysql_error(agent_conn), ERROR_MESSAGE_LEN - 1); if (ret != 0 || err_code != 0) { - ctc_log_error("ctc_create_proxy_user failed to create user %s, " - "sql=%s, ret=%d, err_code=%d, err_msg=%s", - proxy_user_name.c_str(), create_user_sql.c_str(), ret, err_code, err_msg); + ctc_log_error( + "ctc_create_proxy_user failed to create user %s, " + "sql=%s, ret=%d, err_code=%d, err_msg=%s", + proxy_user_name.c_str(), create_user_sql.c_str(), ret, err_code, err_msg); return err_code; } @@ -134,38 +138,37 @@ static int ctc_create_proxy_user(MYSQL *agent_conn, const char*user_name, const ctc_drop_proxy_user(agent_conn, proxy_user_name); return -1; } - + MYSQL_ROW row = mysql_fetch_row(result); if (row == nullptr) { ctc_log_error("ctc_create_proxy_user mysql_fetch_row failed, user name:%s", user_name); ctc_drop_proxy_user(agent_conn, proxy_user_name); return -1; } - + proxy_user_password = row[2]; mysql_free_result(result); - + string username(user_name); username = ctc_escape_single_quotation_str(username); - string grant_user_sql = "grant proxy on '" + username + - "'@'" + string(user_ip) + "' to '" + proxy_user_name + "';"; + string grant_user_sql = "grant proxy on '" + username + "'@'" + string(user_ip) + "' to '" + proxy_user_name + "';"; ret = ctc_mysql_query(agent_conn, grant_user_sql.c_str()); - + err_code = mysql_errno(agent_conn); strncpy(err_msg, mysql_error(agent_conn), ERROR_MESSAGE_LEN - 1); if (ret != 0 || err_code != 0) { - ctc_log_error("ctc_create_proxy_user failed to grant %s to %s, " - "sql=%s, ret=%d, err_code=%d, err_msg=%s", - user_name, proxy_user_name.c_str(), grant_user_sql.c_str(), ret, err_code, err_msg); + ctc_log_error( + "ctc_create_proxy_user failed to grant %s to %s, " + "sql=%s, ret=%d, err_code=%d, err_msg=%s", + user_name, proxy_user_name.c_str(), grant_user_sql.c_str(), ret, err_code, err_msg); ctc_drop_proxy_user(agent_conn, proxy_user_name); return err_code; } return 0; } -static int ctc_init_proxy_client(MYSQL *&curr_conn, uint64_t conn_map_key, - const char *user_name, const char *user_ip) +static int ctc_init_proxy_client(MYSQL *&curr_conn, uint64_t conn_map_key, const char *user_name, const char *user_ip) { MYSQL *agent_conn = NULL; int ret = ctc_init_agent_client(agent_conn); @@ -200,7 +203,8 @@ static int ctc_init_proxy_client(MYSQL *&curr_conn, uint64_t conn_map_key, return ret; } -static void get_ctc_mysql_conn(uint64_t conn_map_key, MYSQL *&curr_conn) { +static void get_ctc_mysql_conn(uint64_t conn_map_key, MYSQL *&curr_conn) +{ lock_guard lock(m_ctc_mysql_proxy_mutex); auto iter = g_mysql_conn_map.find(conn_map_key); if (iter != g_mysql_conn_map.end()) { @@ -208,9 +212,9 @@ static void get_ctc_mysql_conn(uint64_t conn_map_key, MYSQL *&curr_conn) { } } -int ctc_init_mysql_client(uint64_t conn_map_key, const char *db, MYSQL *&curr_conn, - const char *user_name, const char *user_ip, bool use_proxy) { - +int ctc_init_mysql_client(uint64_t conn_map_key, const char *db, MYSQL *&curr_conn, const char *user_name, + const char *user_ip, bool use_proxy) +{ if (opt_noacl && strcmp(user_name, "skip-grants user") == 0) { use_proxy = false; } @@ -224,8 +228,8 @@ int ctc_init_mysql_client(uint64_t conn_map_key, const char *db, MYSQL *&curr_co return 0; } - ctc_log_error("ctc_init_mysql_client select db failed, err_code=%d, err_msg=%s.", - mysql_errno(curr_conn), mysql_error(curr_conn)); + ctc_log_error("ctc_init_mysql_client select db failed, err_code=%d, err_msg=%s.", mysql_errno(curr_conn), + mysql_error(curr_conn)); lock_guard lock(m_ctc_mysql_proxy_mutex); delete g_mysql_conn_map[conn_map_key]; g_mysql_conn_map.erase(conn_map_key); @@ -233,7 +237,7 @@ int ctc_init_mysql_client(uint64_t conn_map_key, const char *db, MYSQL *&curr_co } assert(curr_conn == nullptr); - while(!mysqld_server_started) { + while (!mysqld_server_started) { ctc_log_system("[CTC_INIT]:ctc_init_mysql_client wait mysql server start!!!!"); sleep(1); } @@ -243,7 +247,7 @@ int ctc_init_mysql_client(uint64_t conn_map_key, const char *db, MYSQL *&curr_co } else { ret = ctc_init_agent_client(curr_conn); } - + if (ret) { ctc_log_error("init mysql client failed ret=%d", ret); return ret; @@ -251,14 +255,14 @@ int ctc_init_mysql_client(uint64_t conn_map_key, const char *db, MYSQL *&curr_co ret = ctc_mysql_query(curr_conn, "set lock_wait_timeout = 1;"); if (ret != 0 || mysql_errno(curr_conn) != 0) { - ctc_log_error("set lock_wait_timeout = 1 failed. err_code:%u, err_msg:%s", - mysql_errno(curr_conn), mysql_error(curr_conn)); + ctc_log_error("set lock_wait_timeout = 1 failed. err_code:%u, err_msg:%s", mysql_errno(curr_conn), + mysql_error(curr_conn)); } ret = ctc_select_db(curr_conn, db); if (ret != 0) { - ctc_log_error("ctc_init_mysql_client select db failed, err_code=%d, err_msg=%s.", - mysql_errno(curr_conn), mysql_error(curr_conn)); + ctc_log_error("ctc_init_mysql_client select db failed, err_code=%d, err_msg=%s.", mysql_errno(curr_conn), + mysql_error(curr_conn)); ctc_close_mysql_conn(&curr_conn); return ret; } @@ -270,11 +274,12 @@ int ctc_init_mysql_client(uint64_t conn_map_key, const char *db, MYSQL *&curr_co return 0; } -static void close_mysql_conn_by_key(uint64_t conn_map_key) { +static void close_mysql_conn_by_key(uint64_t conn_map_key) +{ /* 存在并发场景 map操作加锁 */ lock_guard lock(m_ctc_mysql_proxy_mutex); auto iter = g_mysql_conn_map.find(conn_map_key); - + if (iter == g_mysql_conn_map.end()) { ctc_log_system("[CTC_CLOSE_CONN]: Connection has already been closed or not exists (key=%lu)", conn_map_key); return; @@ -285,16 +290,17 @@ static void close_mysql_conn_by_key(uint64_t conn_map_key) { uint32_t name_locks = sub_g_name_locks(iter->second->name_locks); ctc_log_system("[CTC_CLOSE_CONN]: Close connect by key=%lu, current global name locks=%u", conn_map_key, name_locks); - + delete g_mysql_conn_map[conn_map_key]; g_mysql_conn_map.erase(conn_map_key); } -static MYSQL* get_mysql_conn_by_key(uint64_t conn_map_key) { +static MYSQL *get_mysql_conn_by_key(uint64_t conn_map_key) +{ /* 存在并发场景 map操作加锁 */ lock_guard lock(m_ctc_mysql_proxy_mutex); auto iter = g_mysql_conn_map.find(conn_map_key); - + if (iter == g_mysql_conn_map.end()) { ctc_log_system("get mysql Connection has already been closed or not exists (key=%lu)", conn_map_key); return NULL; @@ -302,39 +308,46 @@ static MYSQL* get_mysql_conn_by_key(uint64_t conn_map_key) { return iter->second->conn; } -static void close_mysql_conn_by_inst_id(uint32_t inst_id, bool by_mysql_inst) { +static void close_mysql_conn_by_inst_id(uint32_t inst_id, bool by_mysql_inst) +{ lock_guard lock(m_ctc_mysql_proxy_mutex); - for (auto iter = g_mysql_conn_map.begin(); iter != g_mysql_conn_map.end(); ) { - uint32_t find_id = by_mysql_inst ? ctc_get_inst_id_from_conn_key(iter->first) : - ctc_get_cantian_id_from_conn_key(iter->first); + for (auto iter = g_mysql_conn_map.begin(); iter != g_mysql_conn_map.end();) { + uint32_t find_id = + by_mysql_inst ? ctc_get_inst_id_from_conn_key(iter->first) : ctc_get_cantian_id_from_conn_key(iter->first); if (find_id == inst_id) { - MYSQL *mysql_conn = iter->second->conn; - ctc_close_mysql_conn(&mysql_conn); - uint32_t name_locks = sub_g_name_locks(iter->second->name_locks); - ctc_log_system("[CTC_CLOSE_CONN]: Close connects by mysql_id/cantian_id = %d, instance_id=%u, key=%lu," - "current global name locks=%u", by_mysql_inst, inst_id, iter->first, name_locks); - - delete g_mysql_conn_map[iter->first]; - iter = g_mysql_conn_map.erase(iter); + MYSQL *mysql_conn = iter->second->conn; + ctc_close_mysql_conn(&mysql_conn); + uint32_t name_locks = sub_g_name_locks(iter->second->name_locks); + ctc_log_system( + "[CTC_CLOSE_CONN]: Close connects by mysql_id/cantian_id = %d, instance_id=%u, key=%lu," + "current global name locks=%u", + by_mysql_inst, inst_id, iter->first, name_locks); + + delete g_mysql_conn_map[iter->first]; + iter = g_mysql_conn_map.erase(iter); } else { ++iter; } } } -static inline bool is_backup_lock_op(uint8_t sql_command) { - return sql_command == SQLCOM_LOCK_INSTANCE || - sql_command == SQLCOM_UNLOCK_INSTANCE; +static inline bool is_backup_lock_op(uint8_t sql_command) +{ + return sql_command == SQLCOM_LOCK_INSTANCE || sql_command == SQLCOM_UNLOCK_INSTANCE; } -static inline bool ctc_use_proxy(uint8_t sql_command) { +static inline bool ctc_use_proxy(uint8_t sql_command) +{ bool is_slave = ctc_get_cluster_role() == (int32_t)dis_cluster_role::STANDBY; - ctc_log_system("[Disaster Recovery] is_slave: %d, sql_command=%d, use_proxy:%d", is_slave, sql_command, (!is_slave && !is_backup_lock_op(sql_command))); + ctc_log_system("[Disaster Recovery] is_slave: %d, sql_command=%d, use_proxy:%d", is_slave, sql_command, + (!is_slave && !is_backup_lock_op(sql_command))); return !is_slave && !is_backup_lock_op(sql_command); } extern uint32_t ctc_instance_id; -__attribute__((visibility("default"))) int ctc_execute_rewrite_open_conn(uint32_t thd_id, ctc_ddl_broadcast_request *broadcast_req) { +__attribute__((visibility("default"))) int ctc_execute_rewrite_open_conn(uint32_t thd_id, + ctc_ddl_broadcast_request *broadcast_req) +{ // 相同节点不用执行 if (broadcast_req->mysql_inst_id == ctc_instance_id) { return 0; @@ -344,26 +357,31 @@ __attribute__((visibility("default"))) int ctc_execute_rewrite_open_conn(uint32_ uint64_t conn_map_key = ctc_get_conn_key(broadcast_req->mysql_inst_id, thd_id, use_proxy); MYSQL *curr_conn = NULL; - int ret = ctc_init_mysql_client(conn_map_key, broadcast_req->db_name, curr_conn, - broadcast_req->user_name, broadcast_req->user_ip, use_proxy); + int ret = ctc_init_mysql_client(conn_map_key, broadcast_req->db_name, curr_conn, broadcast_req->user_name, + broadcast_req->user_ip, use_proxy); if (ret != 0) { broadcast_req->err_code = ret; ctc_log_error("[CTC_REWRITE_CONN]:init_mysql_client failed, ret:%d, conn_map_key:%lu, sql:%s", ret, conn_map_key, - sql_without_plaintext_password(broadcast_req).c_str()); + sql_without_plaintext_password(broadcast_req).c_str()); return ret; } - ctc_log_system("[CTC_REWRITE_CONN]: remote open conn for sql=%s, user_name:%s, success, mysql_inst_id=%u," - "conn_map_key:%lu", sql_without_plaintext_password(broadcast_req).c_str(), broadcast_req->user_name, - broadcast_req->mysql_inst_id, conn_map_key); - + ctc_log_system( + "[CTC_REWRITE_CONN]: remote open conn for sql=%s, user_name:%s, success, mysql_inst_id=%u," + "conn_map_key:%lu", + sql_without_plaintext_password(broadcast_req).c_str(), broadcast_req->user_name, broadcast_req->mysql_inst_id, + conn_map_key); + mysql_free_result(mysql_store_result(curr_conn)); return 0; } -__attribute__((visibility("default"))) int ctc_ddl_execute_update(uint32_t thd_id, ctc_ddl_broadcast_request *broadcast_req, bool *allow_fail) { +__attribute__((visibility("default"))) int ctc_ddl_execute_update(uint32_t thd_id, + ctc_ddl_broadcast_request *broadcast_req, + bool *allow_fail) +{ // 相同节点不用执行 - if(broadcast_req->mysql_inst_id == ctc_instance_id) { + if (broadcast_req->mysql_inst_id == ctc_instance_id) { ctc_log_note("ctc_ddl_execute_update curnode not need execute,mysql_inst_id:%u", broadcast_req->mysql_inst_id); return 0; } @@ -371,8 +389,8 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_update(uint32_t thd_i bool is_meta_normalization = IS_METADATA_NORMALIZATION(); if (is_meta_normalization && broadcast_req->sql_command != SQLCOM_SET_OPTION) { return 0; - } else if (is_meta_normalization && broadcast_req->sql_command == SQLCOM_SET_OPTION - && (broadcast_req->options & CTC_SET_VARIABLE_WITH_SUBSELECT) == 0){ + } else if (is_meta_normalization && broadcast_req->sql_command == SQLCOM_SET_OPTION && + (broadcast_req->options & CTC_SET_VARIABLE_WITH_SUBSELECT) == 0) { return ctc_set_sys_var(broadcast_req); } @@ -380,18 +398,19 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_update(uint32_t thd_i uint64_t conn_map_key = ctc_get_conn_key(broadcast_req->mysql_inst_id, thd_id, use_proxy); MYSQL *curr_conn = NULL; - int ret = ctc_init_mysql_client(conn_map_key, broadcast_req->db_name, curr_conn, - broadcast_req->user_name, broadcast_req->user_ip, use_proxy); + int ret = ctc_init_mysql_client(conn_map_key, broadcast_req->db_name, curr_conn, broadcast_req->user_name, + broadcast_req->user_ip, use_proxy); if (ret != 0) { broadcast_req->err_code = ret; ctc_log_error("[CTC_DDL]:init_mysql_client failed, ret:%d, conn_id:%u, sql_str:%s", ret, thd_id, - sql_without_plaintext_password(broadcast_req).c_str()); + sql_without_plaintext_password(broadcast_req).c_str()); return ret; } // 设置随机密码seed - if (broadcast_req->sql_command == SQLCOM_CREATE_USER || broadcast_req->sql_command == SQLCOM_ALTER_USER || broadcast_req->sql_command == SQLCOM_SET_PASSWORD) { + if (broadcast_req->sql_command == SQLCOM_CREATE_USER || broadcast_req->sql_command == SQLCOM_ALTER_USER || + broadcast_req->sql_command == SQLCOM_SET_PASSWORD) { ret = ctc_mysql_query(curr_conn, ("set @random_password_seed = " + std::to_string(thd_id) + ";").c_str()); if (ret != 0) { ctc_log_error("ctc_init_proxy_client set @random_password_seed failed, error_code:%d", mysql_errno(curr_conn)); @@ -401,7 +420,8 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_update(uint32_t thd_i if (broadcast_req->options & CTC_OPEN_NO_CHECK_FK_FOR_CURRENT_SQL) { if (ctc_mysql_query(curr_conn, "SET SESSION foreign_key_checks = 0;")) { - ctc_log_error("ctc_init_proxy_client SET SESSION foreign_key_checks = 0; failed, error_code:%d,error:%s", mysql_errno(curr_conn), mysql_error(curr_conn)); + ctc_log_error("ctc_init_proxy_client SET SESSION foreign_key_checks = 0; failed, error_code:%d,error:%s", + mysql_errno(curr_conn), mysql_error(curr_conn)); broadcast_req->err_code = mysql_errno(curr_conn); ctc_close_mysql_conn(&curr_conn); return broadcast_req->err_code; @@ -412,15 +432,18 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_update(uint32_t thd_i if (ret != 0 || error_code != 0) { broadcast_req->err_code = error_code; strncpy(broadcast_req->err_msg, mysql_error(curr_conn), ERROR_MESSAGE_LEN - 1); - ctc_log_error("[CTC_DDL]:mysql query exectue failed. err_code:%d, err_msg:%s, sql_str:%s, user_name:%s," - " conn_id:%u, allow_fail:%d",error_code, broadcast_req->err_msg, - sql_without_plaintext_password(broadcast_req).c_str(), broadcast_req->user_name, thd_id, *allow_fail); + ctc_log_error( + "[CTC_DDL]:mysql query exectue failed. err_code:%d, err_msg:%s, sql_str:%s, user_name:%s," + " conn_id:%u, allow_fail:%d", + error_code, broadcast_req->err_msg, sql_without_plaintext_password(broadcast_req).c_str(), + broadcast_req->user_name, thd_id, *allow_fail); return broadcast_req->err_code; } if (broadcast_req->options & CTC_OPEN_NO_CHECK_FK_FOR_CURRENT_SQL) { if (ctc_mysql_query(curr_conn, "SET SESSION foreign_key_checks = 1;")) { - ctc_log_error("ctc_init_proxy_client SET SESSION foreign_key_checks = 1; failed, error_code:%d,error:%s", mysql_errno(curr_conn), mysql_error(curr_conn)); + ctc_log_error("ctc_init_proxy_client SET SESSION foreign_key_checks = 1; failed, error_code:%d,error:%s", + mysql_errno(curr_conn), mysql_error(curr_conn)); broadcast_req->err_code = mysql_errno(curr_conn); ctc_close_mysql_conn(&curr_conn); return broadcast_req->err_code; @@ -428,7 +451,8 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_update(uint32_t thd_i } ctc_log_system("[CTC_DDL]: remote execute sql=%s, user_name:%s, success, mysql_inst_id=%u, conn_map_key:%lu", - sql_without_plaintext_password(broadcast_req).c_str(), broadcast_req->user_name, broadcast_req->mysql_inst_id, conn_map_key); + sql_without_plaintext_password(broadcast_req).c_str(), broadcast_req->user_name, + broadcast_req->mysql_inst_id, conn_map_key); set_explicit_table_lock(conn_map_key, broadcast_req->sql_command); @@ -438,7 +462,8 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_update(uint32_t thd_i return 0; } -static int ctc_ddl_get_lock(MYSQL *curr_conn, const uint64_t &conn_map_key, const char *lock_name, int *err_code) { +static int ctc_ddl_get_lock(MYSQL *curr_conn, const uint64_t &conn_map_key, const char *lock_name, int *err_code) +{ uchar digest[MD5_HASH_SIZE]; compute_md5_hash(pointer_cast(digest), lock_name, strlen(lock_name)); @@ -451,16 +476,17 @@ static int ctc_ddl_get_lock(MYSQL *curr_conn, const uint64_t &conn_map_key, cons int ret = ctc_mysql_query(curr_conn, lock_function_str.c_str()); *err_code = mysql_errno(curr_conn); if (ret != 0 || *err_code != 0) { - ctc_log_error("[CTC_LOCK_TABLE]:execute GET_LOCK() failed, " - "return_err: %d, err_code:%d, err_msg:%s, lock_function_str:%s", - ret, *err_code, mysql_error(curr_conn), lock_function_str.c_str()); + ctc_log_error( + "[CTC_LOCK_TABLE]:execute GET_LOCK() failed, " + "return_err: %d, err_code:%d, err_msg:%s, lock_function_str:%s", + ret, *err_code, mysql_error(curr_conn), lock_function_str.c_str()); return *err_code; } MYSQL_RES *query_res = mysql_store_result(curr_conn); if (query_res == nullptr) { - ctc_log_error("[CTC_LOCK_TABLE]:execute GET_LOCK() failed to store result, lock_name:%s, err_msg:%s", - lock_name, mysql_error(curr_conn)); + ctc_log_error("[CTC_LOCK_TABLE]:execute GET_LOCK() failed to store result, lock_name:%s, err_msg:%s", lock_name, + mysql_error(curr_conn)); return 1; } @@ -479,14 +505,15 @@ static int ctc_ddl_get_lock(MYSQL *curr_conn, const uint64_t &conn_map_key, cons if (iter != g_mysql_conn_map.end()) { iter->second->name_locks++; uint32_t name_locks = add_g_name_locks(1); - ctc_log_note("[CTC_LOCK_TABLE]: conn key=%lu, its name locks=%u, current global name locks=%u", - conn_map_key, iter->second->name_locks, name_locks); + ctc_log_note("[CTC_LOCK_TABLE]: conn key=%lu, its name locks=%u, current global name locks=%u", conn_map_key, + iter->second->name_locks, name_locks); } } return 0; } -int32_t ctc_check_table_exist(MYSQL *curr_conn_proxy, const char *db_name, const char *table_name, int *err_code) { +int32_t ctc_check_table_exist(MYSQL *curr_conn_proxy, const char *db_name, const char *table_name, int *err_code) +{ string sql_str = "SELECT EXISTS (SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA LIKE '" + string(db_name) + "' AND TABLE_NAME = '" + string(table_name) + "');"; @@ -504,8 +531,9 @@ int32_t ctc_check_table_exist(MYSQL *curr_conn_proxy, const char *db_name, const return res; } -__attribute__((visibility("default"))) int ctc_ddl_execute_lock_tables(ctc_handler_t *tch, char *db_name, ctc_lock_table_info *lock_info, int *err_code) { - +__attribute__((visibility("default"))) int ctc_ddl_execute_lock_tables(ctc_handler_t *tch, char *db_name, + ctc_lock_table_info *lock_info, int *err_code) +{ if (IS_METADATA_NORMALIZATION()) { if (lock_info->sql_type == SQLCOM_LOCK_TABLES) { if (ctc_ddl_execute_lock_tables_by_req(tch, lock_info, err_code)) { @@ -521,11 +549,12 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_lock_tables(ctc_handl uint64_t conn_map_key = ctc_get_conn_key(tch->inst_id, tch->thd_id, !is_same_node); MYSQL *curr_conn = NULL; - int ret = ctc_init_mysql_client(conn_map_key, db_name, curr_conn, lock_info->user_name, lock_info->user_ip, !is_same_node); + int ret = + ctc_init_mysql_client(conn_map_key, db_name, curr_conn, lock_info->user_name, lock_info->user_ip, !is_same_node); if (ret != 0) { *err_code = ret; - ctc_log_error("[CTC_LOCK_TABLE]:ctc_init_mysql_client failed, ret:%d, conn_id:%u, ctc_instance_id:%u", - ret, tch->thd_id, tch->inst_id); + ctc_log_error("[CTC_LOCK_TABLE]:ctc_init_mysql_client failed, ret:%d, conn_id:%u, ctc_instance_id:%u", ret, + tch->thd_id, tch->inst_id); return ret; } @@ -533,7 +562,7 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_lock_tables(ctc_handl if (strlen(lock_info->table_name) == 0) { return ctc_ddl_get_lock(curr_conn, conn_map_key, lock_info->db_name, err_code); } - + string lock_name_str; lock_name_str.append(lock_info->db_name); lock_name_str.append("."); @@ -544,21 +573,21 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_lock_tables(ctc_handl } /* Do not run lock_table on the same node. */ - if(is_same_node) { + if (is_same_node) { ctc_log_note("[CTC_LOCK_TABLE]:curnode not need execute, mysql_inst_id:%u", tch->inst_id); return 0; } - if (lock_info->sql_type == SQLCOM_CREATE_TABLE || - lock_info->sql_type == SQLCOM_DROP_VIEW || + if (lock_info->sql_type == SQLCOM_CREATE_TABLE || lock_info->sql_type == SQLCOM_DROP_VIEW || lock_info->sql_type == SQLCOM_CREATE_VIEW) { ctc_log_note("[CTC_LOCK_TABLE]:Skip lock_table. sql_cmd:%d", lock_info->sql_type); return 0; } if (g_mysql_conn_map[conn_map_key]->has_explicit_table_lock) { - ctc_log_system("[CTC_LOCK_TABLE]: curnode doesn't need execute, conn_map_key=%lu, mysql_thd_id=%u, mysql_inst_id=%u", - conn_map_key, tch->thd_id, tch->inst_id); + ctc_log_system( + "[CTC_LOCK_TABLE]: curnode doesn't need execute, conn_map_key=%lu, mysql_thd_id=%u, mysql_inst_id=%u", + conn_map_key, tch->thd_id, tch->inst_id); return ret; } @@ -574,7 +603,8 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_lock_tables(ctc_handl for (auto iter : g_mysql_conn_map[conn_map_key]->table_lock_info) { row_res = ctc_check_table_exist(curr_conn, iter.first.c_str(), iter.second.c_str(), err_code); if (row_res <= 0) { - ctc_log_warning("[CTC_LOCK_TABLE]:Table not exist. row_res:%d, db:%s, table:%s", row_res, iter.first.c_str(), iter.second.c_str()); + ctc_log_warning("[CTC_LOCK_TABLE]:Table not exist. row_res:%d, db:%s, table:%s", row_res, iter.first.c_str(), + iter.second.c_str()); return 0; } @@ -590,16 +620,18 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_lock_tables(ctc_handl ret = ctc_mysql_query(curr_conn, lock_str.c_str()); if (ret != 0 || mysql_errno(curr_conn) != 0) { *err_code = mysql_errno(curr_conn); - ctc_log_error("[CTC_LOCK_TABLE]:return_err:%d, err_code:%d, err_msg:%s, lock_sql_str:%s, conn_id:%u, ctc_instance_id:%u", - ret, *err_code, mysql_error(curr_conn), lock_str.c_str(), tch->thd_id, tch->inst_id); + ctc_log_error( + "[CTC_LOCK_TABLE]:return_err:%d, err_code:%d, err_msg:%s, lock_sql_str:%s, conn_id:%u, ctc_instance_id:%u", + ret, *err_code, mysql_error(curr_conn), lock_str.c_str(), tch->thd_id, tch->inst_id); } } return ret; } -__attribute__((visibility("default"))) int ctc_ddl_execute_unlock_tables(ctc_handler_t *tch, uint32_t mysql_inst_id, ctc_lock_table_info *lock_info) - { +__attribute__((visibility("default"))) int ctc_ddl_execute_unlock_tables(ctc_handler_t *tch, uint32_t mysql_inst_id, + ctc_lock_table_info *lock_info) +{ if (IS_METADATA_NORMALIZATION()) { UNUSED_PARAM(mysql_inst_id); if (lock_info->sql_type == SQLCOM_UNLOCK_TABLES) { @@ -627,7 +659,7 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_unlock_tables(ctc_han } mysql_free_result(mysql_store_result(curr_conn)); - + { // 清空加锁信息 lock_guard lock(m_ctc_mysql_proxy_mutex); @@ -637,21 +669,24 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_unlock_tables(ctc_han if (iter->second->name_locks > 0) { iter->second->name_locks--; uint32_t name_locks = sub_g_name_locks(1); - ctc_log_note("[CTC_LOCK_TABLE]: conn key=%lu, its name locks=%u, current global name locks=%u", - conn_map_key, iter->second->name_locks, name_locks); + ctc_log_note("[CTC_LOCK_TABLE]: conn key=%lu, its name locks=%u, current global name locks=%u", conn_map_key, + iter->second->name_locks, name_locks); } } } /* Do not run unlock_table on the same node. */ - if(is_same_node) { + if (is_same_node) { close_mysql_conn_by_key(conn_map_key); - ctc_log_note("[CTC_UNLOCK_TABLE]: curnode doesn't need execute, conn_map_key=%lu, mysql_inst_id=%u", conn_map_key, tch->inst_id); + ctc_log_note("[CTC_UNLOCK_TABLE]: curnode doesn't need execute, conn_map_key=%lu, mysql_inst_id=%u", conn_map_key, + tch->inst_id); return 0; } if (g_mysql_conn_map[conn_map_key]->has_explicit_table_lock) { - ctc_log_system("[CTC_UNLOCK_TABLE]: curnode doesn't need execute, conn_map_key=%lu, mysql_thd_id=%u, mysql_inst_id=%u", conn_map_key, tch->thd_id, tch->inst_id); + ctc_log_system( + "[CTC_UNLOCK_TABLE]: curnode doesn't need execute, conn_map_key=%lu, mysql_thd_id=%u, mysql_inst_id=%u", + conn_map_key, tch->thd_id, tch->inst_id); return 0; } @@ -666,11 +701,12 @@ __attribute__((visibility("default"))) int ctc_ddl_execute_unlock_tables(ctc_han } /* thd_id为0时,关闭实例id为mysql_inst_id的所有连接 -* mysql_inst_id: 高16位 ---> 参天实例id -* 低16位 ---> mysqld实例id, 由当前节点参天分配,取值范围(2-19) -* 低16位全为1代表整个参天节点故障,清理与参天实例id相关的资源 -*/ -__attribute__((visibility("default"))) int close_mysql_connection(uint32_t thd_id, uint32_t mysql_inst_id) { + * mysql_inst_id: 高16位 ---> 参天实例id + * 低16位 ---> mysqld实例id, 由当前节点参天分配,取值范围(2-19) + * 低16位全为1代表整个参天节点故障,清理与参天实例id相关的资源 + */ +__attribute__((visibility("default"))) int close_mysql_connection(uint32_t thd_id, uint32_t mysql_inst_id) +{ if (IS_METADATA_NORMALIZATION()) { close_ctc_mdl_thd(thd_id, mysql_inst_id); return 0; @@ -680,7 +716,7 @@ __attribute__((visibility("default"))) int close_mysql_connection(uint32_t thd_i if ((uint16_t)mysql_inst_id == (uint16_t)CANTIAN_DOWN_MASK) { /* 清理整个参天节点相关的连接 */ ctc_log_system("[CTC_CLOSE_SESSION]:Close All connects on bad node by cantian_instance_id:%u", - (mysql_inst_id >> 16)); + (mysql_inst_id >> 16)); close_mysql_conn_by_inst_id((mysql_inst_id >> 16), false); } else { /* 清理整个mysqld节点相关的连接 */ @@ -690,13 +726,13 @@ __attribute__((visibility("default"))) int close_mysql_connection(uint32_t thd_i } else { /* 通过把mysql_inst_id左移32位 与 thd_id拼接在一起 用来唯一标识一个连接 */ uint64_t proxy_conn_map_key = ctc_get_conn_key(mysql_inst_id, thd_id, true); - ctc_log_note("[CTC_CLOSE_SESSION]: Close connect by conn_id=%u, ctc_instance_id=%u, proxy_conn_map_key=%lu", - thd_id, mysql_inst_id, proxy_conn_map_key); + ctc_log_note("[CTC_CLOSE_SESSION]: Close connect by conn_id=%u, ctc_instance_id=%u, proxy_conn_map_key=%lu", thd_id, + mysql_inst_id, proxy_conn_map_key); close_mysql_conn_by_key(proxy_conn_map_key); - + uint64_t agent_conn_map_key = ctc_get_conn_key(mysql_inst_id, thd_id, false); - ctc_log_note("[CTC_CLOSE_SESSION]: Close connect by conn_id=%u, ctc_instance_id=%u, agent_conn_map_key=%lu", - thd_id, mysql_inst_id, agent_conn_map_key); + ctc_log_note("[CTC_CLOSE_SESSION]: Close connect by conn_id=%u, ctc_instance_id=%u, agent_conn_map_key=%lu", thd_id, + mysql_inst_id, agent_conn_map_key); close_mysql_conn_by_key(agent_conn_map_key); } return 0; diff --git a/storage/ctc/ctc_proxy_util.cc b/storage/ctc/ctc_proxy_util.cc index 1d93b1e..66b203d 100644 --- a/storage/ctc/ctc_proxy_util.cc +++ b/storage/ctc/ctc_proxy_util.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -17,13 +17,13 @@ #include "ctc_proxy_util.h" #include -#include "ctc_log.h" -#include "sql/sql_connect.h" -#include "sql/conn_handler/connection_handler_manager.h" // Connection_handler_manager #include "compression.h" +#include "ctc_log.h" +#include "ctc_meta_data.h" #include "ha_ctc.h" +#include "sql/conn_handler/connection_handler_manager.h" // Connection_handler_manager #include "sql/mysqld.h" -#include "ctc_meta_data.h" +#include "sql/sql_connect.h" #define CTC_CONN_MAX_RETRY_TIMES 10 #define CTC_PASSWORD_BUFFER_SIZE (uint32)512 @@ -34,27 +34,27 @@ static atomic g_name_locks(0); // 实例持有的命名锁总数,用于标记当前是否有 DDL 正在执行 -uint32_t get_g_name_locks(void) { - return g_name_locks.load(); -} +uint32_t get_g_name_locks(void) { return g_name_locks.load(); } -uint32_t add_g_name_locks(uint32_t num) { - uint32_t name_locks = g_name_locks.fetch_add(num); - return name_locks + num; +uint32_t add_g_name_locks(uint32_t num) +{ + uint32_t name_locks = g_name_locks.fetch_add(num); + return name_locks + num; } -uint32_t sub_g_name_locks(uint32_t num) { - uint32_t name_locks = g_name_locks.fetch_sub(num); - return name_locks - num; +uint32_t sub_g_name_locks(uint32_t num) +{ + uint32_t name_locks = g_name_locks.fetch_sub(num); + return name_locks - num; } -static bool is_dangerous_pwd(const char *password) { - +static bool is_dangerous_pwd(const char *password) +{ bool danger_pwd_flag = false; - for(int i = 0; password[i] != '\0'; i++) { + for (int i = 0; password[i] != '\0'; i++) { if (!isalnum(password[i]) && password[i] != '+' && password[i] != '/' && password[i] != '=' && - !(password[i] == '\n' && password[i+1] == '\0')) { + !(password[i] == '\n' && password[i + 1] == '\0')) { danger_pwd_flag = true; break; } @@ -62,7 +62,8 @@ static bool is_dangerous_pwd(const char *password) { return danger_pwd_flag; } -static int ctc_get_agent_info(char *password, uint password_size) { +static int ctc_get_agent_info(char *password, uint password_size) +{ char *user_password = getenv("MYSQL_AGENT_PASSWORD"); if (user_password == NULL) { return -1; @@ -83,7 +84,7 @@ static int ctc_get_agent_info(char *password, uint password_size) { if (fgets(password, password_size, fp) == NULL) { ctc_log_error("get password failed"); - pclose (fp); + pclose(fp); return -1; } @@ -94,11 +95,11 @@ static int ctc_get_agent_info(char *password, uint password_size) { } // remove \n from the passwd - if(passwd_len > 0 && password[passwd_len -1] == '\n' ) { - password[passwd_len -1] = '\0'; + if (passwd_len > 0 && password[passwd_len - 1] == '\n') { + password[passwd_len - 1] = '\0'; } - pclose (fp); + pclose(fp); return 0; } @@ -108,19 +109,24 @@ static void ctc_inc_conn_count(int &dec_conn_count) conn_manager->check_and_incr_conn_count(true); Connection_handler_manager::reset_max_used_connections(); dec_conn_count--; - ctc_log_warning("[CTC_CONN_INC]:connection_count:%u, max_used_connections:%lu, max_connections:%lu, dec_conn_count:%d", - Connection_handler_manager::connection_count, Connection_handler_manager::max_used_connections, max_connections, dec_conn_count); + ctc_log_warning( + "[CTC_CONN_INC]:connection_count:%u, max_used_connections:%lu, max_connections:%lu, dec_conn_count:%d", + Connection_handler_manager::connection_count, Connection_handler_manager::max_used_connections, max_connections, + dec_conn_count); } static void ctc_dec_conn_count(int &dec_conn_count) { Connection_handler_manager::dec_connection_count(); dec_conn_count++; - ctc_log_warning("[CTC_CONN_DEC]:connection_count:%u, max_used_connections:%lu, max_connections:%lu, dec_conn_count:%d", - Connection_handler_manager::connection_count, Connection_handler_manager::max_used_connections, max_connections, dec_conn_count); + ctc_log_warning( + "[CTC_CONN_DEC]:connection_count:%u, max_used_connections:%lu, max_connections:%lu, dec_conn_count:%d", + Connection_handler_manager::connection_count, Connection_handler_manager::max_used_connections, max_connections, + dec_conn_count); } -int ctc_mysql_conn(MYSQL *&con, const char *host, const char *user, const char *passwd) { +int ctc_mysql_conn(MYSQL *&con, const char *host, const char *user, const char *passwd) +{ con = mysql_init(NULL); if (con == nullptr) { ctc_log_error("ctc_mysql_conn mysql_init failed, error_code:%d,error:%s", mysql_errno(con), mysql_error(con)); @@ -136,7 +142,8 @@ int ctc_mysql_conn(MYSQL *&con, const char *host, const char *user, const char * (void)mysql_options(con, MYSQL_DEFAULT_AUTH, "mysql_native_password"); // do init sql commands for new con. - // for ddl do not go to ctc SE. this command should be first executed. it should be placed firstly at mysql_options MYSQL_INIT_COMMAND. + // for ddl do not go to ctc SE. this command should be first executed. it should be placed firstly at mysql_options + // MYSQL_INIT_COMMAND. (void)mysql_options(con, MYSQL_INIT_COMMAND, "set @ctc_ddl_local_enabled = true;"); /* proxy的连接强制解除只读属性 proxy的连接应该永远都是没有只读状态才对的,因为如果发起端连接只读,ddl不会转到远端, @@ -152,16 +159,19 @@ int ctc_mysql_conn(MYSQL *&con, const char *host, const char *user, const char * int retry_time = CTC_CONN_MAX_RETRY_TIMES; int dec_conn_count = 0; - while (!mysql_real_connect(con, host, user, passwd, NULL, mysqld_port, mysqld_unix_port, CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS | CLIENT_INTERACTIVE) && retry_time > 0) { + while (!mysql_real_connect( + con, host, user, passwd, NULL, mysqld_port, mysqld_unix_port, + CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS | CLIENT_INTERACTIVE) && + retry_time > 0) { int err = mysql_errno(con); if (err == ER_CON_COUNT_ERROR) { ctc_dec_conn_count(dec_conn_count); } // 3922 errcode, server has open compress conn, client need to open. if (err == ER_WRONG_COMPRESSION_ALGORITHM_CLIENT) { - if ((con->server_capabilities & CLIENT_COMPRESS)) { // server open zlib conn + if ((con->server_capabilities & CLIENT_COMPRESS)) { // server open zlib conn mysql_options(con, MYSQL_OPT_COMPRESSION_ALGORITHMS, COMPRESSION_ALGORITHM_ZLIB); - } else if((con->server_capabilities & CLIENT_ZSTD_COMPRESSION_ALGORITHM)) { // server open zstd conn + } else if ((con->server_capabilities & CLIENT_ZSTD_COMPRESSION_ALGORITHM)) { // server open zstd conn mysql_options(con, MYSQL_OPT_COMPRESSION_ALGORITHMS, COMPRESSION_ALGORITHM_ZSTD); } retry_time--; @@ -179,7 +189,8 @@ int ctc_mysql_conn(MYSQL *&con, const char *host, const char *user, const char * return con == nullptr; } -int ctc_init_agent_client(MYSQL *&curr_conn) { +int ctc_init_agent_client(MYSQL *&curr_conn) +{ SENSI_INFO char agent_password[CTC_PASSWORD_BUFFER_SIZE] = {0}; string agent_user = "root"; if (!ctc_get_agent_info(agent_password, CTC_PASSWORD_BUFFER_SIZE)) { @@ -189,8 +200,8 @@ int ctc_init_agent_client(MYSQL *&curr_conn) { int ret = ctc_mysql_conn(curr_conn, my_localhost, agent_user.c_str(), password); memset(agent_password, 0, CTC_PASSWORD_BUFFER_SIZE); if (ret) { - ctc_log_error("ctc_init_agent_client ctc_mysql_conn failed, err_code=%d, err_msg=%s.", - mysql_errno(curr_conn), mysql_error(curr_conn)); + ctc_log_error("ctc_init_agent_client ctc_mysql_conn failed, err_code=%d, err_msg=%s.", mysql_errno(curr_conn), + mysql_error(curr_conn)); ctc_close_mysql_conn(&curr_conn); return ret; } @@ -198,7 +209,8 @@ int ctc_init_agent_client(MYSQL *&curr_conn) { return 0; } -int ctc_mysql_query(MYSQL *mysql, const char *query) { +int ctc_mysql_query(MYSQL *mysql, const char *query) +{ reset_mqh(nullptr, nullptr, 0); int ret = mysql_ping(mysql); @@ -227,13 +239,15 @@ int ctc_mysql_query(MYSQL *mysql, const char *query) { ctc_set_mysql_read_only(); } if (ret != 0) { - ctc_log_error("[CTC_MYSQL_QUERY]:ret:%d, err_code=%d, err_msg=%s, query_str:%s.", ret, mysql_errno(mysql), mysql_error(mysql), query); + ctc_log_error("[CTC_MYSQL_QUERY]:ret:%d, err_code=%d, err_msg=%s, query_str:%s.", ret, mysql_errno(mysql), + mysql_error(mysql), query); } return ret; // success: 0, fail: other } -void ctc_close_mysql_conn(MYSQL **curr_conn) { +void ctc_close_mysql_conn(MYSQL **curr_conn) +{ mysql_close(*curr_conn); *curr_conn = NULL; } \ No newline at end of file diff --git a/storage/ctc/ctc_srv_mq_module.cc b/storage/ctc/ctc_srv_mq_module.cc index 19ac683..c92a3d8 100644 --- a/storage/ctc/ctc_srv_mq_module.cc +++ b/storage/ctc/ctc_srv_mq_module.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -15,7 +15,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "srv_mq_msg.h" #include "ctc_srv_mq_module.h" #include #include @@ -24,24 +23,24 @@ #include "assert.h" #include "ctc_error.h" #include "ctc_log.h" -#include "message_queue/dsw_shm.h" #include "ctc_stats.h" #include "ha_ctc.h" +#include "message_queue/dsw_shm.h" +#include "srv_mq_msg.h" #define MQ_THD_NUM 1 #define MAX_DDL_THD_NUM 1024 #define SHM_MAX_SEG_NUM 8 using namespace std; -#define CTC_IGNORE_ERROR_WHEN_MYSQL_SHUTDOWN(req, tag) \ - do { \ - if ((req)->result != 0 && get_server_state() == SERVER_SHUTTING_DOWN) { \ - ctc_log_error("%s failed,server will shutdown:result:%d", (tag), \ - (req)->result); \ - (req)->result = 0; \ - } \ +#define CTC_IGNORE_ERROR_WHEN_MYSQL_SHUTDOWN(req, tag) \ + do { \ + if ((req)->result != 0 && get_server_state() == SERVER_SHUTTING_DOWN) { \ + ctc_log_error("%s failed,server will shutdown:result:%d", (tag), (req)->result); \ + (req)->result = 0; \ + } \ } while (0) -#define CTC_GET_CLIENT_ID(inst_id) ((int) ((inst_id) & 0xFFFF)) +#define CTC_GET_CLIENT_ID(inst_id) ((int)((inst_id) & 0xFFFF)) // the last shm seg g_shm_segs[SHM_MAX_SEG_NUM] is for upstream, served by mysqld uint32_t g_shm_file_num = 1; @@ -50,7 +49,8 @@ shm_seg_s *g_upstream_shm_seg = nullptr; atomic_int g_ddl_thd_num(0); int g_shm_client_id(-1); -static void* mq_msg_handler(void *arg) { +static void *mq_msg_handler(void *arg) +{ pthread_detach(pthread_self()); dsw_message_block_t *message_block = (dsw_message_block_t *)arg; ctc_log_note("recv msg ! cmd:%d", message_block->head.cmd_type); @@ -63,11 +63,10 @@ static void* mq_msg_handler(void *arg) { break; } case CTC_FUNC_TYPE_MYSQL_EXECUTE_UPDATE: { - execute_ddl_mysql_sql_request *req = - (execute_ddl_mysql_sql_request *)message_block->seg_buf[0]; + execute_ddl_mysql_sql_request *req = (execute_ddl_mysql_sql_request *)message_block->seg_buf[0]; req->result = ctc_ddl_execute_update(req->thd_id, &req->broadcast_req, &req->allow_fail); - ctc_log_system("[Disaster Recovery] execute_ddl_mysql_sql : db:%s, sql_txt:%s,result:%d", req->broadcast_req.db_name, - req->broadcast_req.sql_str, req->result); + ctc_log_system("[Disaster Recovery] execute_ddl_mysql_sql : db:%s, sql_txt:%s,result:%d", + req->broadcast_req.db_name, req->broadcast_req.sql_str, req->result); ctc_log_note("execute_ddl_mysql_sql : db:%s, sql_txt:%s,result:%d", req->broadcast_req.db_name, req->broadcast_req.sql_str, req->result); CTC_IGNORE_ERROR_WHEN_MYSQL_SHUTDOWN(req, "ctc_ddl_execute_update"); @@ -100,12 +99,13 @@ static void* mq_msg_handler(void *arg) { struct invalidate_mysql_dd_request *req = (struct invalidate_mysql_dd_request *)message_block->seg_buf[0]; req->result = ctc_invalidate_mysql_dd_cache(&(req->tch), &req->broadcast_req, &(req->err_code)); ctc_log_note("invalidate dd cache: thd_id : %d, inst_id : %d, ret : %d.", req->tch.thd_id, req->tch.inst_id, - req->result); + req->result); CTC_IGNORE_ERROR_WHEN_MYSQL_SHUTDOWN(req, "ctc_invalidate_mysql_dd_cache"); break; } case CTC_FUNC_SET_CLUSTER_ROLE_BY_CANTIAN: { - struct set_cluster_role_by_cantian_request *req = (struct set_cluster_role_by_cantian_request *)message_block->seg_buf[0]; + struct set_cluster_role_by_cantian_request *req = + (struct set_cluster_role_by_cantian_request *)message_block->seg_buf[0]; req->result = ctc_set_cluster_role_by_cantian(req->is_slave); ctc_log_note("[Disaster Recovery] Set cluster role by cantian, is_slave:%d", req->is_slave); CTC_IGNORE_ERROR_WHEN_MYSQL_SHUTDOWN(req, "ctc_set_cluster_role_by_cantian"); @@ -135,7 +135,7 @@ int mq_recv_msg(struct shm_seg_s *shm_seg, dsw_message_block_t *message_block) ctc_log_error("ddl thd has reach max limit: %d", MAX_DDL_THD_NUM); assert(0); } - result = pthread_create(&thd, NULL, mq_msg_handler, (void*)message_block); + result = pthread_create(&thd, NULL, mq_msg_handler, (void *)message_block); if (result != 0) { ctc_log_error("pthread_create failed, result:%d.", result); } @@ -181,7 +181,7 @@ bool init_shm_segment(int shm_num, int *inst_id) ctc_log_error("shm client connect failed, shm_name(%s)", shm_key.shm_name); return false; } - ha_ctc_set_inst_id((uint32_t) *inst_id); + ha_ctc_set_inst_id((uint32_t)*inst_id); g_shm_client_id = CTC_GET_CLIENT_ID(*inst_id); } @@ -258,13 +258,10 @@ void *get_one_shm_inst(ctc_handler_t *tch) pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask); tch->bind_core = 1; } - return (void *)g_shm_segs[hashSeed % g_shm_file_num]; + return (void *)g_shm_segs[hashSeed % g_shm_file_num]; } -void *alloc_share_mem(void *seg, uint32_t mem_size) -{ - return shm_alloc((shm_seg_s *)seg, mem_size); -} +void *alloc_share_mem(void *seg, uint32_t mem_size) { return shm_alloc((shm_seg_s *)seg, mem_size); } void free_share_mem(void *seg, void *shm_mem) { @@ -272,7 +269,7 @@ void free_share_mem(void *seg, void *shm_mem) shm_free(nullptr, shm_mem); } -void batch_free_shm_buf(void *seg, dsw_message_block_t* msg) +void batch_free_shm_buf(void *seg, dsw_message_block_t *msg) { UNUSED_PARAM(seg); for (uint16_t i = 0; i < msg->head.seg_num; ++i) { @@ -314,7 +311,7 @@ static void set_cpu_mask() static void ctc_log_reg_error_by_code(int error_code) { - switch(error_code) { + switch (error_code) { case ERR_CONNECTION_FAILED: #ifdef WITH_CANTIAN ctc_log_error("connection failed"); @@ -331,8 +328,8 @@ static void ctc_log_reg_error_by_code(int error_code) } } -EXTER_ATTACK int ctc_mq_deal_func(void *shm_inst, CTC_FUNC_TYPE func_type, - void *request, void* msg_buf, uint32_t server_id, uint32_t wait_sec) +EXTER_ATTACK int ctc_mq_deal_func(void *shm_inst, CTC_FUNC_TYPE func_type, void *request, void *msg_buf, + uint32_t server_id, uint32_t wait_sec) { uint64_t start_time = 0; if (ctc_stats::get_instance().get_statistics_enabled()) { @@ -343,12 +340,12 @@ EXTER_ATTACK int ctc_mq_deal_func(void *shm_inst, CTC_FUNC_TYPE func_type, dsw_message_block_t *msg; bool is_alloc = false; if (msg_buf != nullptr) { - msg = (dsw_message_block_t *)msg_buf; + msg = (dsw_message_block_t *)msg_buf; } else { msg = (dsw_message_block_t *)shm_alloc(seg, sizeof(dsw_message_block_t)); is_alloc = true; } - + if (msg == nullptr) { ctc_log_error("alloc shm failed, len:%lu.", sizeof(dsw_message_block_t)); return ERR_ALLOC_MEMORY; @@ -357,7 +354,7 @@ EXTER_ATTACK int ctc_mq_deal_func(void *shm_inst, CTC_FUNC_TYPE func_type, if (is_alloc) { ret = sem_init(&msg->head.sem, 1, 0); } - + if (ret != CT_SUCCESS) { if (is_alloc) { shm_free(nullptr, msg); @@ -373,7 +370,7 @@ EXTER_ATTACK int ctc_mq_deal_func(void *shm_inst, CTC_FUNC_TYPE func_type, msg->head.seg_desc[0].length = REQUEST_SIZE; msg->head.cmd_type = (uint32_t)func_type; msg->seg_buf[0] = request; - + ct_errno_t result = CT_SUCCESS; do { ret = shm_send_msg(seg, server_id, msg); @@ -382,12 +379,12 @@ EXTER_ATTACK int ctc_mq_deal_func(void *shm_inst, CTC_FUNC_TYPE func_type, ctc_log_error("send msg failed, ret:%d, func_type:%d.", ret, func_type); break; } - + // register funcs won't relinquish the processor if (func_type < CTC_FUNC_TYPE_REGISTER_INSTANCE) { sched_yield(); } - + if (wait_sec > 0) { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); @@ -411,7 +408,6 @@ EXTER_ATTACK int ctc_mq_deal_func(void *shm_inst, CTC_FUNC_TYPE func_type, } shm_free(nullptr, msg); } - if (ctc_stats::get_instance().get_statistics_enabled()) { ctc_stats::get_instance().gather_stats(func_type, my_getsystime() / 10 - start_time); @@ -423,20 +419,23 @@ EXTER_ATTACK int ctc_mq_deal_func(void *shm_inst, CTC_FUNC_TYPE func_type, int ctc_mq_register_func(void) { mq_srv_start(g_shm_client_id); - + shm_seg_s *shm_inst = (shm_seg_s *)get_one_shm_inst(nullptr); - register_instance_request *req = (register_instance_request *)alloc_share_mem(shm_inst, sizeof(register_instance_request)); + register_instance_request *req = + (register_instance_request *)alloc_share_mem(shm_inst, sizeof(register_instance_request)); if (req == NULL) { - ctc_log_error("[CTC_INIT]: alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(register_instance_request)); + ctc_log_error("[CTC_INIT]: alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, + sizeof(register_instance_request)); return ERR_ALLOC_MEMORY; } req->ctc_version = (uint32_t)CTC_CLIENT_VERSION_NUMBER; int result = ERR_CONNECTION_FAILED; - if (ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_REGISTER_INSTANCE, req, nullptr, SERVER_REGISTER_PROC_ID) == CT_SUCCESS) { + if (ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_REGISTER_INSTANCE, req, nullptr, SERVER_REGISTER_PROC_ID) == + CT_SUCCESS) { result = req->result; } - + if (result == CT_SUCCESS) { set_cpu_info(req); set_cpu_mask(); @@ -473,12 +472,12 @@ int ctc_mq_get_batch_data(dsw_message_block_t *message_block, uint8_t *buf_data, return CT_SUCCESS; } -static int ctc_mq_fill_batch_data(shm_seg_s *seg, dsw_message_block_t* msg, uint8_t* data_buf, - uint32_t data_len, uint32_t buf_size) +static int ctc_mq_fill_batch_data(shm_seg_s *seg, dsw_message_block_t *msg, uint8_t *data_buf, uint32_t data_len, + uint32_t buf_size) { assert(data_len <= buf_size); - uint8_t* buf_tmp = data_buf; + uint8_t *buf_tmp = data_buf; msg->head.seg_num = 0; uint16_t i; uint32_t tmp_len = buf_size; @@ -512,7 +511,7 @@ static int ctc_mq_fill_batch_data(shm_seg_s *seg, dsw_message_block_t* msg, uint return CT_SUCCESS; } -EXTER_ATTACK int ctc_mq_batch_send_message(void *shm_inst, CTC_FUNC_TYPE func_type, uint8_t* data_buf, +EXTER_ATTACK int ctc_mq_batch_send_message(void *shm_inst, CTC_FUNC_TYPE func_type, uint8_t *data_buf, uint32_t send_data_len, uint32_t buf_size) { if (buf_size > CTC_MQ_MESSAGE_SLICE_LEN * DSW_MESSAGE_SEGMENT_NUM_MAX) { @@ -521,7 +520,7 @@ EXTER_ATTACK int ctc_mq_batch_send_message(void *shm_inst, CTC_FUNC_TYPE func_ty } shm_seg_s *seg = (shm_seg_s *)shm_inst; - dsw_message_block_t* msg = (dsw_message_block_t*)shm_alloc(seg, sizeof(dsw_message_block_t)); + dsw_message_block_t *msg = (dsw_message_block_t *)shm_alloc(seg, sizeof(dsw_message_block_t)); if (msg == nullptr) { ctc_log_error("alloc shm failed, len:%lu.", sizeof(dsw_message_block_t)); return ERR_ALLOC_MEMORY; diff --git a/storage/ctc/ctc_srv_mq_stub.cc b/storage/ctc/ctc_srv_mq_stub.cc index ad2f03b..cbb8c58 100644 --- a/storage/ctc/ctc_srv_mq_stub.cc +++ b/storage/ctc/ctc_srv_mq_stub.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -15,34 +15,34 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "srv_mq_msg.h" -#include "ctc_srv_mq_module.h" -#include "message_queue/dsw_shm.h" +#include #include "ctc_error.h" #include "ctc_log.h" #include "ctc_srv.h" +#include "ctc_srv_mq_module.h" #include "ctc_util.h" #include "ha_ctc.h" +#include "message_queue/dsw_shm.h" #include "protobuf/tc_db.pb-c.h" -#include +#include "srv_mq_msg.h" #define OUTLINE_LOB_LOCATOR_SIZE 44 // 行外LOB数据结构体长度 // 双进程模式在 ctc_init 中已经提前获取 inst_id -int ctc_alloc_inst_id(uint32_t *inst_id) { +int ctc_alloc_inst_id(uint32_t *inst_id) +{ *inst_id = ha_ctc_get_inst_id(); return ctc_mq_register_func(); } // 双进程模式在 clean_up_for_bad_mysql_proc 中释放 inst_id -int ctc_release_inst_id(uint32_t ) { - return CT_SUCCESS; -} +int ctc_release_inst_id(uint32_t) { return CT_SUCCESS; } -int ctc_open_table(ctc_handler_t *tch, const char *table_name, const char *user_name) { +int ctc_open_table(ctc_handler_t *tch, const char *table_name, const char *user_name) +{ void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(open_table_request); - open_table_request *req = (open_table_request*)alloc_share_mem(shm_inst, len); + open_table_request *req = (open_table_request *)alloc_share_mem(shm_inst, len); DBUG_EXECUTE_IF("open_table_shm_oom", { req = NULL; }); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); @@ -56,7 +56,7 @@ int ctc_open_table(ctc_handler_t *tch, const char *table_name, const char *user_ int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_OPEN_TABLE, req, tch->msg_buf); - *tch = req->tch; // 此处不管参天处理成功与否,都需要拷贝一次,避免session泄漏 + *tch = req->tch; // 此处不管参天处理成功与否,都需要拷贝一次,避免session泄漏 if (ret == CT_SUCCESS) { result = req->result; } @@ -64,12 +64,14 @@ int ctc_open_table(ctc_handler_t *tch, const char *table_name, const char *user_ return result; } -int ctc_close_session(ctc_handler_t *tch) { +int ctc_close_session(ctc_handler_t *tch) +{ ctc_log_note("close session"); void *shm_inst = get_one_shm_inst(tch); - close_session_request *req = (close_session_request*)alloc_share_mem(shm_inst, sizeof(close_session_request)); + close_session_request *req = (close_session_request *)alloc_share_mem(shm_inst, sizeof(close_session_request)); if (req == NULL) { - ctc_log_error("[CTC_CLOSE_SESSION]:alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(close_session_request)); + ctc_log_error("[CTC_CLOSE_SESSION]:alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, + sizeof(close_session_request)); return ERR_ALLOC_MEMORY; } req->tch = *tch; @@ -84,12 +86,14 @@ int ctc_close_session(ctc_handler_t *tch) { return result; } -void ctc_kill_session(ctc_handler_t *tch) { +void ctc_kill_session(ctc_handler_t *tch) +{ ctc_log_note("kill session"); void *shm_inst = get_one_shm_inst(tch); - close_session_request *req = (close_session_request*)alloc_share_mem(shm_inst, sizeof(close_session_request)); + close_session_request *req = (close_session_request *)alloc_share_mem(shm_inst, sizeof(close_session_request)); if (req == NULL) { - ctc_log_error("[CTC_KILL_SESSION]:alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(close_session_request)); + ctc_log_error("[CTC_KILL_SESSION]:alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, + sizeof(close_session_request)); return; } req->tch = *tch; @@ -101,9 +105,10 @@ void ctc_kill_session(ctc_handler_t *tch) { free_share_mem(shm_inst, req); } -int ctc_close_table(ctc_handler_t *tch) { +int ctc_close_table(ctc_handler_t *tch) +{ void *shm_inst = get_one_shm_inst(tch); - close_table_request *req = (close_table_request*)alloc_share_mem(shm_inst, sizeof(close_table_request)); + close_table_request *req = (close_table_request *)alloc_share_mem(shm_inst, sizeof(close_table_request)); DBUG_EXECUTE_IF("close_table_shm_oom", { req = NULL; }); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(close_table_request)); @@ -121,10 +126,11 @@ int ctc_close_table(ctc_handler_t *tch) { return result; } -int ctc_write_row(ctc_handler_t *tch, const record_info_t *record_info, - uint16_t serial_column_offset, uint64_t *last_insert_id, dml_flag_t flag) { +int ctc_write_row(ctc_handler_t *tch, const record_info_t *record_info, uint16_t serial_column_offset, + uint64_t *last_insert_id, dml_flag_t flag) +{ void *shm_inst = get_one_shm_inst(tch); - write_row_request *req = (write_row_request*)alloc_share_mem(shm_inst, sizeof(write_row_request)); + write_row_request *req = (write_row_request *)alloc_share_mem(shm_inst, sizeof(write_row_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(write_row_request)); return ERR_ALLOC_MEMORY; @@ -147,11 +153,12 @@ int ctc_write_row(ctc_handler_t *tch, const record_info_t *record_info, return result; } -int ctc_bulk_write(ctc_handler_t *tch, const record_info_t *record_info, uint64_t rec_num, - uint32_t *err_pos, dml_flag_t flag, ctc_part_t *part_ids) { +int ctc_bulk_write(ctc_handler_t *tch, const record_info_t *record_info, uint64_t rec_num, uint32_t *err_pos, + dml_flag_t flag, ctc_part_t *part_ids) +{ void *shm_inst = get_one_shm_inst(tch); assert(record_info->record_len * rec_num <= MAX_RECORD_SIZE); - bulk_write_request *req = (bulk_write_request*)alloc_share_mem(shm_inst, sizeof(bulk_write_request)); + bulk_write_request *req = (bulk_write_request *)alloc_share_mem(shm_inst, sizeof(bulk_write_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(bulk_write_request)); return ERR_ALLOC_MEMORY; @@ -164,7 +171,7 @@ int ctc_bulk_write(ctc_handler_t *tch, const record_info_t *record_info, uint64_ if (part_ids != nullptr) { memcpy(req->part_ids, part_ids, rec_num * sizeof(ctc_part_t)); } - + int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_BULK_INSERT, req, tch->msg_buf); *tch = req->tch; @@ -178,12 +185,13 @@ int ctc_bulk_write(ctc_handler_t *tch, const record_info_t *record_info, uint64_ return result; } -int ctc_update_row(ctc_handler_t *tch, uint16_t new_record_len, const uint8_t *new_record, - const uint16_t *upd_cols, uint16_t col_num, dml_flag_t flag) { +int ctc_update_row(ctc_handler_t *tch, uint16_t new_record_len, const uint8_t *new_record, const uint16_t *upd_cols, + uint16_t col_num, dml_flag_t flag) +{ assert(new_record_len < BIG_RECORD_SIZE); assert(col_num <= CTC_MAX_COLUMNS); void *shm_inst = get_one_shm_inst(tch); - update_row_request *req = (update_row_request*)alloc_share_mem(shm_inst, sizeof(update_row_request)); + update_row_request *req = (update_row_request *)alloc_share_mem(shm_inst, sizeof(update_row_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(update_row_request)); return ERR_ALLOC_MEMORY; @@ -204,10 +212,11 @@ int ctc_update_row(ctc_handler_t *tch, uint16_t new_record_len, const uint8_t *n return result; } -int ctc_delete_row(ctc_handler_t *tch, uint16_t record_len, dml_flag_t flag) { +int ctc_delete_row(ctc_handler_t *tch, uint16_t record_len, dml_flag_t flag) +{ assert(record_len < BIG_RECORD_SIZE); void *shm_inst = get_one_shm_inst(tch); - delete_row_request *req = (delete_row_request*)alloc_share_mem(shm_inst, sizeof(delete_row_request)); + delete_row_request *req = (delete_row_request *)alloc_share_mem(shm_inst, sizeof(delete_row_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(delete_row_request)); return ERR_ALLOC_MEMORY; @@ -225,10 +234,11 @@ int ctc_delete_row(ctc_handler_t *tch, uint16_t record_len, dml_flag_t flag) { return result; } -int ctc_scan_records(ctc_handler_t *tch, uint64_t *num_rows, char *index_name) { +int ctc_scan_records(ctc_handler_t *tch, uint64_t *num_rows, char *index_name) +{ void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(scan_records_request); - scan_records_request *req = (scan_records_request*)alloc_share_mem(shm_inst, len); + scan_records_request *req = (scan_records_request *)alloc_share_mem(shm_inst, len); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); return ERR_ALLOC_MEMORY; @@ -252,9 +262,10 @@ int ctc_scan_records(ctc_handler_t *tch, uint64_t *num_rows, char *index_name) { return result; } -int ctc_rnd_next(ctc_handler_t *tch, record_info_t *record_info) { +int ctc_rnd_next(ctc_handler_t *tch, record_info_t *record_info) +{ void *shm_inst = get_one_shm_inst(tch); - rnd_next_request *req = (rnd_next_request*)alloc_share_mem(shm_inst, sizeof(rnd_next_request)); + rnd_next_request *req = (rnd_next_request *)alloc_share_mem(shm_inst, sizeof(rnd_next_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(rnd_next_request)); return ERR_ALLOC_MEMORY; @@ -265,7 +276,7 @@ int ctc_rnd_next(ctc_handler_t *tch, record_info_t *record_info) { int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_RND_NEXT, req, tch->msg_buf); *tch = req->tch; if (ret == CT_SUCCESS) { - if(req->result == CT_SUCCESS) { + if (req->result == CT_SUCCESS) { record_info->record_len = req->record_len; assert(record_info->record_len < BIG_RECORD_SIZE); } @@ -275,11 +286,11 @@ int ctc_rnd_next(ctc_handler_t *tch, record_info_t *record_info) { return result; } -int ctc_rnd_prefetch(ctc_handler_t *tch, uint8_t *records, uint16_t *record_lens, - uint32_t *recNum, uint64_t *rowids, int32_t max_row_size) +int ctc_rnd_prefetch(ctc_handler_t *tch, uint8_t *records, uint16_t *record_lens, uint32_t *recNum, uint64_t *rowids, + int32_t max_row_size) { void *shm_inst = get_one_shm_inst(tch); - rnd_prefetch_request *req = (rnd_prefetch_request*)alloc_share_mem(shm_inst, sizeof(rnd_prefetch_request)); + rnd_prefetch_request *req = (rnd_prefetch_request *)alloc_share_mem(shm_inst, sizeof(rnd_prefetch_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(rnd_prefetch_request)); return ERR_ALLOC_MEMORY; @@ -295,7 +306,7 @@ int ctc_rnd_prefetch(ctc_handler_t *tch, uint8_t *records, uint16_t *record_lens *recNum = *(req->recNum); if (*recNum != 0) { uint32_t record_len = 0; - for(uint8_t i = 0; i < *recNum; i ++){ + for (uint8_t i = 0; i < *recNum; i++) { record_len += req->record_lens[i]; } memcpy(records, req->records, record_len); @@ -309,9 +320,10 @@ int ctc_rnd_prefetch(ctc_handler_t *tch, uint8_t *records, uint16_t *record_lens return result; } -int ctc_rnd_init(ctc_handler_t *tch, expected_cursor_action_t action, ctc_select_mode_t mode, ctc_conds *cond) { +int ctc_rnd_init(ctc_handler_t *tch, expected_cursor_action_t action, ctc_select_mode_t mode, ctc_conds *cond) +{ void *shm_inst = get_one_shm_inst(tch); - rnd_init_request *req = (rnd_init_request*)alloc_share_mem(shm_inst, sizeof(rnd_init_request)); + rnd_init_request *req = (rnd_init_request *)alloc_share_mem(shm_inst, sizeof(rnd_init_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(rnd_init_request)); return ERR_ALLOC_MEMORY; @@ -332,9 +344,10 @@ int ctc_rnd_init(ctc_handler_t *tch, expected_cursor_action_t action, ctc_select return result; } -int ctc_rnd_end(ctc_handler_t *tch) { +int ctc_rnd_end(ctc_handler_t *tch) +{ void *shm_inst = get_one_shm_inst(tch); - rnd_end_request *req = (rnd_end_request*)alloc_share_mem(shm_inst, sizeof(rnd_end_request)); + rnd_end_request *req = (rnd_end_request *)alloc_share_mem(shm_inst, sizeof(rnd_end_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(rnd_end_request)); return ERR_ALLOC_MEMORY; @@ -351,10 +364,11 @@ int ctc_rnd_end(ctc_handler_t *tch) { return result; } -int ctc_position(ctc_handler_t *tch, uint8_t *position, uint16_t pos_length) { +int ctc_position(ctc_handler_t *tch, uint8_t *position, uint16_t pos_length) +{ assert(pos_length < SMALL_RECORD_SIZE); void *shm_inst = get_one_shm_inst(tch); - position_request *req = (position_request*)alloc_share_mem(shm_inst, sizeof(position_request)); + position_request *req = (position_request *)alloc_share_mem(shm_inst, sizeof(position_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(position_request)); return ERR_ALLOC_MEMORY; @@ -373,10 +387,11 @@ int ctc_position(ctc_handler_t *tch, uint8_t *position, uint16_t pos_length) { return result; } -int ctc_rnd_pos(ctc_handler_t *tch, uint16_t pos_length, uint8_t *position, record_info_t *record_info) { +int ctc_rnd_pos(ctc_handler_t *tch, uint16_t pos_length, uint8_t *position, record_info_t *record_info) +{ assert(pos_length < SMALL_RECORD_SIZE); void *shm_inst = get_one_shm_inst(tch); - rnd_pos_request *req = (rnd_pos_request*)alloc_share_mem(shm_inst, sizeof(rnd_pos_request)); + rnd_pos_request *req = (rnd_pos_request *)alloc_share_mem(shm_inst, sizeof(rnd_pos_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(rnd_pos_request)); return ERR_ALLOC_MEMORY; @@ -390,7 +405,7 @@ int ctc_rnd_pos(ctc_handler_t *tch, uint16_t pos_length, uint8_t *position, reco int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_RND_POS, req, tch->msg_buf); if (ret == CT_SUCCESS) { - if(req->result == CT_SUCCESS) { + if (req->result == CT_SUCCESS) { record_info->record_len = req->record_len; assert(record_info->record_len < BIG_RECORD_SIZE); } @@ -400,9 +415,10 @@ int ctc_rnd_pos(ctc_handler_t *tch, uint16_t pos_length, uint8_t *position, reco return result; } -int ctc_delete_all_rows(ctc_handler_t *tch, dml_flag_t flag) { +int ctc_delete_all_rows(ctc_handler_t *tch, dml_flag_t flag) +{ void *shm_inst = get_one_shm_inst(tch); - delete_all_rows_request *req = (delete_all_rows_request*)alloc_share_mem(shm_inst, sizeof(delete_all_rows_request)); + delete_all_rows_request *req = (delete_all_rows_request *)alloc_share_mem(shm_inst, sizeof(delete_all_rows_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(delete_all_rows_request)); return ERR_ALLOC_MEMORY; @@ -419,9 +435,10 @@ int ctc_delete_all_rows(ctc_handler_t *tch, dml_flag_t flag) { return result; } -int ctc_index_end(ctc_handler_t *tch) { +int ctc_index_end(ctc_handler_t *tch) +{ void *shm_inst = get_one_shm_inst(tch); - index_end_request *req = (index_end_request*)alloc_share_mem(shm_inst, sizeof(index_end_request)); + index_end_request *req = (index_end_request *)alloc_share_mem(shm_inst, sizeof(index_end_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(index_end_request)); return ERR_ALLOC_MEMORY; @@ -438,7 +455,8 @@ int ctc_index_end(ctc_handler_t *tch) { return result; } -static void copy_index_info_to_req(const index_key_info_t *index_info, index_read_request *req) { +static void copy_index_info_to_req(const index_key_info_t *index_info, index_read_request *req) +{ uint32_t left_offset = 0; uint32_t right_offset = 0; uint8_t *pLeft = req->left_key_record; @@ -460,7 +478,7 @@ static void copy_index_info_to_req(const index_key_info_t *index_info, index_rea req->left_key_info.key_lens[i] = 0; req->left_key_info.key_offsets[i] = 0; } - + if (index_info->key_info[i].right_key != nullptr) { assert(right_offset + index_info->key_info[i].right_key_len <= INDEX_KEY_SIZE); memcpy(pRight, index_info->key_info[i].right_key, index_info->key_info[i].right_key_len); @@ -485,19 +503,20 @@ static void copy_index_info_to_req(const index_key_info_t *index_info, index_rea return; } -int ctc_index_read(ctc_handler_t *tch, record_info_t *record_info, index_key_info_t *index_info, - ctc_select_mode_t mode, ctc_conds *cond, const bool is_replace) { +int ctc_index_read(ctc_handler_t *tch, record_info_t *record_info, index_key_info_t *index_info, ctc_select_mode_t mode, + ctc_conds *cond, const bool is_replace) +{ if (index_info == NULL) { return ERR_GENERIC_INTERNAL_ERROR; } void *shm_inst = get_one_shm_inst(tch); - index_read_request *req = (index_read_request*)alloc_share_mem(shm_inst, sizeof(index_read_request)); + index_read_request *req = (index_read_request *)alloc_share_mem(shm_inst, sizeof(index_read_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(index_read_request)); return ERR_ALLOC_MEMORY; } - + copy_index_info_to_req(index_info, req); req->tch = *tch; @@ -513,7 +532,7 @@ int ctc_index_read(ctc_handler_t *tch, record_info_t *record_info, index_key_inf *tch = req->tch; tch->sql_stat_start = req->tch.sql_stat_start; if (ret == CT_SUCCESS) { - if(req->result == CT_SUCCESS) { + if (req->result == CT_SUCCESS) { record_info->record_len = req->record_len; assert(record_info->record_len < BIG_RECORD_SIZE); } @@ -526,9 +545,10 @@ int ctc_index_read(ctc_handler_t *tch, record_info_t *record_info, index_key_inf return result; } -int ctc_trx_begin(ctc_handler_t *tch, ctc_trx_context_t trx_context, bool is_mysql_local) { +int ctc_trx_begin(ctc_handler_t *tch, ctc_trx_context_t trx_context, bool is_mysql_local) +{ void *shm_inst = get_one_shm_inst(tch); - trx_begin_request *req = (trx_begin_request*)alloc_share_mem(shm_inst, sizeof(trx_begin_request)); + trx_begin_request *req = (trx_begin_request *)alloc_share_mem(shm_inst, sizeof(trx_begin_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(trx_begin_request)); return ERR_ALLOC_MEMORY; @@ -539,7 +559,7 @@ int ctc_trx_begin(ctc_handler_t *tch, ctc_trx_context_t trx_context, bool is_mys int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_TRX_BEGIN, req, tch->msg_buf); - *tch = req->tch; // 此处不管参天处理成功与否,都需要拷贝一次,避免session泄漏 + *tch = req->tch; // 此处不管参天处理成功与否,都需要拷贝一次,避免session泄漏 if (ret == CT_SUCCESS) { result = req->result; } @@ -547,9 +567,10 @@ int ctc_trx_begin(ctc_handler_t *tch, ctc_trx_context_t trx_context, bool is_mys return result; } -int ctc_trx_commit(ctc_handler_t *tch, uint64_t *cursors, int32_t csize, bool *is_ddl_commit) { +int ctc_trx_commit(ctc_handler_t *tch, uint64_t *cursors, int32_t csize, bool *is_ddl_commit) +{ void *shm_inst = get_one_shm_inst(tch); - trx_commit_request *req = (trx_commit_request*)alloc_share_mem(shm_inst, sizeof(trx_commit_request)); + trx_commit_request *req = (trx_commit_request *)alloc_share_mem(shm_inst, sizeof(trx_commit_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(trx_commit_request)); return ERR_ALLOC_MEMORY; @@ -568,9 +589,10 @@ int ctc_trx_commit(ctc_handler_t *tch, uint64_t *cursors, int32_t csize, bool *i return result; } -int ctc_trx_rollback(ctc_handler_t *tch, uint64_t *cursors, int32_t csize) { +int ctc_trx_rollback(ctc_handler_t *tch, uint64_t *cursors, int32_t csize) +{ void *shm_inst = get_one_shm_inst(tch); - trx_rollback_request *req = (trx_rollback_request*)alloc_share_mem(shm_inst, sizeof(trx_rollback_request)); + trx_rollback_request *req = (trx_rollback_request *)alloc_share_mem(shm_inst, sizeof(trx_rollback_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(trx_rollback_request)); return ERR_ALLOC_MEMORY; @@ -588,13 +610,14 @@ int ctc_trx_rollback(ctc_handler_t *tch, uint64_t *cursors, int32_t csize) { return result; } -int ctc_srv_set_savepoint(ctc_handler_t *tch, const char *name) { +int ctc_srv_set_savepoint(ctc_handler_t *tch, const char *name) +{ void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(srv_set_savepoint_request); - srv_set_savepoint_request *req = (srv_set_savepoint_request*)alloc_share_mem(shm_inst, len); + srv_set_savepoint_request *req = (srv_set_savepoint_request *)alloc_share_mem(shm_inst, len); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); + return ERR_ALLOC_MEMORY; } memset(req, 0, len); strncpy(req->name, name, SMALL_RECORD_SIZE - 1); @@ -602,18 +625,20 @@ int ctc_srv_set_savepoint(ctc_handler_t *tch, const char *name) { int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_SRV_SET_SAVEPOINT, req, tch->msg_buf); if (ret == CT_SUCCESS) { - result = req->result; + result = req->result; } free_share_mem(shm_inst, req); return result; } -int ctc_srv_rollback_savepoint(ctc_handler_t *tch, uint64_t *cursors, int32_t csize, const char *name) { +int ctc_srv_rollback_savepoint(ctc_handler_t *tch, uint64_t *cursors, int32_t csize, const char *name) +{ void *shm_inst = get_one_shm_inst(tch); - srv_rollback_savepoint_request *req = (srv_rollback_savepoint_request*)alloc_share_mem(shm_inst, sizeof(srv_rollback_savepoint_request)); + srv_rollback_savepoint_request *req = + (srv_rollback_savepoint_request *)alloc_share_mem(shm_inst, sizeof(srv_rollback_savepoint_request)); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(srv_rollback_savepoint_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(srv_rollback_savepoint_request)); + return ERR_ALLOC_MEMORY; } memset(req->name, 0, SMALL_RECORD_SIZE); strncpy(req->name, name, SMALL_RECORD_SIZE - 1); @@ -624,19 +649,20 @@ int ctc_srv_rollback_savepoint(ctc_handler_t *tch, uint64_t *cursors, int32_t cs int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_SRV_ROLLBACK_SAVEPOINT, req, tch->msg_buf); if (ret == CT_SUCCESS) { - result = req->result; + result = req->result; } free_share_mem(shm_inst, req); return result; } -int ctc_srv_release_savepoint(ctc_handler_t *tch, const char *name) { +int ctc_srv_release_savepoint(ctc_handler_t *tch, const char *name) +{ void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(srv_release_savepoint_request); - srv_release_savepoint_request *req = (srv_release_savepoint_request*)alloc_share_mem(shm_inst, len); + srv_release_savepoint_request *req = (srv_release_savepoint_request *)alloc_share_mem(shm_inst, len); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); + return ERR_ALLOC_MEMORY; } memset(req, 0, len); strncpy(req->name, name, SMALL_RECORD_SIZE - 1); @@ -644,15 +670,16 @@ int ctc_srv_release_savepoint(ctc_handler_t *tch, const char *name) { int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_SRV_RELEASE_SAVEPOINT, req, tch->msg_buf); if (ret == CT_SUCCESS) { - result = req->result; + result = req->result; } free_share_mem(shm_inst, req); return result; } -int ctc_general_fetch(ctc_handler_t *tch, record_info_t *record_info) { +int ctc_general_fetch(ctc_handler_t *tch, record_info_t *record_info) +{ void *shm_inst = get_one_shm_inst(tch); - general_fetch_request *req = (general_fetch_request*)alloc_share_mem(shm_inst, sizeof(general_fetch_request)); + general_fetch_request *req = (general_fetch_request *)alloc_share_mem(shm_inst, sizeof(general_fetch_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(general_fetch_request)); return ERR_ALLOC_MEMORY; @@ -673,9 +700,11 @@ int ctc_general_fetch(ctc_handler_t *tch, record_info_t *record_info) { return result; } -int ctc_free_session_cursors(ctc_handler_t *tch, uint64_t *cursors, int32_t csize) { +int ctc_free_session_cursors(ctc_handler_t *tch, uint64_t *cursors, int32_t csize) +{ void *shm_inst = get_one_shm_inst(tch); - free_session_cursors_request *req = (free_session_cursors_request*)alloc_share_mem(shm_inst, sizeof(free_session_cursors_request)); + free_session_cursors_request *req = + (free_session_cursors_request *)alloc_share_mem(shm_inst, sizeof(free_session_cursors_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(free_session_cursors_request)); return ERR_ALLOC_MEMORY; @@ -683,7 +712,7 @@ int ctc_free_session_cursors(ctc_handler_t *tch, uint64_t *cursors, int32_t csiz req->tch = *tch; req->csize = csize; req->cursors = cursors; - + int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_FREE_CURSORS, req, tch->msg_buf); *tch = req->tch; @@ -694,9 +723,10 @@ int ctc_free_session_cursors(ctc_handler_t *tch, uint64_t *cursors, int32_t csiz return result; } -int ctc_get_max_sessions_per_node(uint32_t *max_sessions) { +int ctc_get_max_sessions_per_node(uint32_t *max_sessions) +{ void *shm_inst = get_one_shm_inst(NULL); - get_max_session_request *req = (get_max_session_request*)alloc_share_mem(shm_inst, sizeof(get_max_session_request)); + get_max_session_request *req = (get_max_session_request *)alloc_share_mem(shm_inst, sizeof(get_max_session_request)); DBUG_EXECUTE_IF("ctc_get_max_sessions_shm_oom", { req = NULL; }); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(get_max_session_request)); @@ -709,10 +739,11 @@ int ctc_get_max_sessions_per_node(uint32_t *max_sessions) { return ret; } -int ctc_analyze_table(ctc_handler_t *tch, const char *db_name, const char *table_name, double sampling_ratio) { +int ctc_analyze_table(ctc_handler_t *tch, const char *db_name, const char *table_name, double sampling_ratio) +{ void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(analyze_table_request); - analyze_table_request *req = (analyze_table_request*)alloc_share_mem(shm_inst, len); + analyze_table_request *req = (analyze_table_request *)alloc_share_mem(shm_inst, len); DBUG_EXECUTE_IF("ctc_analyze_table_shm_oom", { req = NULL; }); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); @@ -735,61 +766,60 @@ int ctc_analyze_table(ctc_handler_t *tch, const char *db_name, const char *table } void ctc_cbo_stats_columns_copy(ctc_cbo_stats_column_t *dst_columns, ctc_cbo_stats_column_t *src_columns, - ctc_cbo_stats_t *stats, uint num_columns) { + ctc_cbo_stats_t *stats, uint num_columns) +{ for (uint j = 0; j < num_columns; j++) { dst_columns[j].num_null = src_columns[j].num_null; dst_columns[j].density = src_columns[j].density; dst_columns[j].hist_type = src_columns[j].hist_type; dst_columns[j].hist_count = src_columns[j].hist_count; if (stats->col_type[j] == true) { - memcpy(dst_columns[j].high_value.v_str, - src_columns[j].high_value.v_str, CBO_STRING_MAX_LEN); - memcpy(dst_columns[j].low_value.v_str, - src_columns[j].low_value.v_str, CBO_STRING_MAX_LEN); + memcpy(dst_columns[j].high_value.v_str, src_columns[j].high_value.v_str, CBO_STRING_MAX_LEN); + memcpy(dst_columns[j].low_value.v_str, src_columns[j].low_value.v_str, CBO_STRING_MAX_LEN); } else { - memcpy(&dst_columns[j].high_value, - &src_columns[j].high_value, sizeof(cache_variant_t)); - memcpy(&dst_columns[j].low_value, - &src_columns[j].low_value, sizeof(cache_variant_t)); + memcpy(&dst_columns[j].high_value, &src_columns[j].high_value, sizeof(cache_variant_t)); + memcpy(&dst_columns[j].low_value, &src_columns[j].low_value, sizeof(cache_variant_t)); } uint hist_count = src_columns[j].hist_count; for (uint k = 0; k < hist_count; k++) { dst_columns[j].column_hist[k].ep_number = src_columns[j].column_hist[k].ep_number; if (stats->col_type[j] == true) { - memcpy(dst_columns[j].column_hist[k].ep_value.v_str, - src_columns[j].column_hist[k].ep_value.v_str, CBO_STRING_MAX_LEN); + memcpy(dst_columns[j].column_hist[k].ep_value.v_str, src_columns[j].column_hist[k].ep_value.v_str, + CBO_STRING_MAX_LEN); } else { - memcpy(&dst_columns[j].column_hist[k].ep_value, - &src_columns[j].column_hist[k].ep_value, sizeof(cache_variant_t)); + memcpy(&dst_columns[j].column_hist[k].ep_value, &src_columns[j].column_hist[k].ep_value, + sizeof(cache_variant_t)); } } } } void ctc_cbo_stats_copy_from_shm(ctc_handler_t *tch, ctc_cbo_stats_table_t *ctc_cbo_stats_table, - get_cbo_stats_request *req, ctc_cbo_stats_t *stats) { + get_cbo_stats_request *req, ctc_cbo_stats_t *stats) +{ bool is_part_table = stats->part_cnt ? true : false; stats->is_updated = req->stats->is_updated; stats->records = req->stats->records; memcpy(stats->ndv_keys, req->stats->ndv_keys, stats->key_len); uint num_columns = req->stats->msg_len / sizeof(ctc_cbo_stats_column_t); if (!is_part_table) { - *tch = req->tch; - ctc_cbo_stats_table->estimate_rows = req->ctc_cbo_stats_table->estimate_rows; - ctc_cbo_stats_columns_copy(ctc_cbo_stats_table->columns, - req->ctc_cbo_stats_table->columns, stats, num_columns); + *tch = req->tch; + ctc_cbo_stats_table->estimate_rows = req->ctc_cbo_stats_table->estimate_rows; + ctc_cbo_stats_columns_copy(ctc_cbo_stats_table->columns, req->ctc_cbo_stats_table->columns, stats, num_columns); } else { for (uint i = 0; i < req->num_part_fetch; i++) { ctc_cbo_stats_table[i].estimate_rows = req->ctc_cbo_stats_table[i].estimate_rows; - ctc_cbo_stats_columns_copy(ctc_cbo_stats_table[i].columns, - req->ctc_cbo_stats_table[i].columns, stats, num_columns); + ctc_cbo_stats_columns_copy(ctc_cbo_stats_table[i].columns, req->ctc_cbo_stats_table[i].columns, stats, + num_columns); } } } -int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_table_t *ctc_cbo_stats_table, uint32_t first_partid, uint32_t num_part_fetch) { +int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_table_t *ctc_cbo_stats_table, + uint32_t first_partid, uint32_t num_part_fetch) +{ void *shm_inst_4_req = get_one_shm_inst(tch); - get_cbo_stats_request *req = (get_cbo_stats_request*)alloc_share_mem(shm_inst_4_req, sizeof(get_cbo_stats_request)); + get_cbo_stats_request *req = (get_cbo_stats_request *)alloc_share_mem(shm_inst_4_req, sizeof(get_cbo_stats_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst_4_req, sizeof(get_cbo_stats_request)); @@ -813,8 +843,8 @@ int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_ void *shm_inst_4_table = get_one_shm_inst(tch); void *shm_inst_4_str_stats = get_one_shm_inst(tch); char *shm_mem_4_str_stats_begin; - ctc_cbo_stats_column_t* part_columns = nullptr; - req->stats->ndv_keys = (uint32_t*)alloc_share_mem(shm_inst_4_keys, stats->key_len); + ctc_cbo_stats_column_t *part_columns = nullptr; + req->stats->ndv_keys = (uint32_t *)alloc_share_mem(shm_inst_4_keys, stats->key_len); if (req->stats->ndv_keys == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%u)", shm_inst_4_keys, stats->key_len); free_share_mem(shm_inst_4_stats, req->stats); @@ -823,7 +853,7 @@ int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_ } if (!is_part_table) { req->ctc_cbo_stats_table = - (ctc_cbo_stats_table_t*)alloc_share_mem(shm_inst_4_table, sizeof(ctc_cbo_stats_table_t)); + (ctc_cbo_stats_table_t *)alloc_share_mem(shm_inst_4_table, sizeof(ctc_cbo_stats_table_t)); if (req->ctc_cbo_stats_table == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst_4_table, sizeof(ctc_cbo_stats_table_t)); free_share_mem(shm_inst_4_keys, req->stats->ndv_keys); @@ -831,7 +861,8 @@ int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_ free_share_mem(shm_inst_4_req, req); return ERR_ALLOC_MEMORY; } - req->ctc_cbo_stats_table->columns = (ctc_cbo_stats_column_t*)alloc_share_mem(shm_inst_4_columns, req->stats->msg_len); + req->ctc_cbo_stats_table->columns = + (ctc_cbo_stats_column_t *)alloc_share_mem(shm_inst_4_columns, req->stats->msg_len); if (req->ctc_cbo_stats_table->columns == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%u)", shm_inst_4_columns, req->stats->msg_len); free_share_mem(shm_inst_4_table, req->ctc_cbo_stats_table); @@ -842,11 +873,11 @@ int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_ } memset(req->ctc_cbo_stats_table->columns, 0, req->stats->msg_len); - shm_mem_4_str_stats_begin = (char*)alloc_share_mem(shm_inst_4_str_stats, - stats->num_str_cols * (STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN); + shm_mem_4_str_stats_begin = (char *)alloc_share_mem( + shm_inst_4_str_stats, stats->num_str_cols * (STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN); if (shm_mem_4_str_stats_begin == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%u)", shm_inst_4_str_stats, - stats->num_str_cols * (STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN); + stats->num_str_cols * (STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN); free_share_mem(shm_inst_4_columns, req->ctc_cbo_stats_table->columns); free_share_mem(shm_inst_4_table, req->ctc_cbo_stats_table); free_share_mem(shm_inst_4_keys, req->stats->ndv_keys); @@ -868,15 +899,16 @@ int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_ } } else { req->ctc_cbo_stats_table = - (ctc_cbo_stats_table_t*)alloc_share_mem(shm_inst_4_table, num_part_fetch * sizeof(ctc_cbo_stats_table_t)); + (ctc_cbo_stats_table_t *)alloc_share_mem(shm_inst_4_table, num_part_fetch * sizeof(ctc_cbo_stats_table_t)); if (req->ctc_cbo_stats_table == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst_4_table, num_part_fetch * sizeof(ctc_cbo_stats_table_t)); + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst_4_table, + num_part_fetch * sizeof(ctc_cbo_stats_table_t)); free_share_mem(shm_inst_4_keys, req->stats->ndv_keys); free_share_mem(shm_inst_4_stats, req->stats); free_share_mem(shm_inst_4_req, req); return ERR_ALLOC_MEMORY; } - part_columns = (ctc_cbo_stats_column_t*)alloc_share_mem(shm_inst_4_columns, stats->msg_len * num_part_fetch); + part_columns = (ctc_cbo_stats_column_t *)alloc_share_mem(shm_inst_4_columns, stats->msg_len * num_part_fetch); if (part_columns == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%u)", shm_inst_4_columns, stats->msg_len * num_part_fetch); free_share_mem(shm_inst_4_table, req->ctc_cbo_stats_table); @@ -890,8 +922,9 @@ int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_ req->ctc_cbo_stats_table[i].columns = part_columns + i * (stats->msg_len / sizeof(ctc_cbo_stats_column_t)); } - shm_mem_4_str_stats_begin = (char *)alloc_share_mem(shm_inst_4_str_stats, - stats->num_str_cols * num_part_fetch * ((STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN)); + shm_mem_4_str_stats_begin = + (char *)alloc_share_mem(shm_inst_4_str_stats, stats->num_str_cols * num_part_fetch * + ((STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN)); if (shm_mem_4_str_stats_begin == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%u)", shm_inst_4_str_stats, stats->num_str_cols * num_part_fetch * ((STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN)); @@ -940,10 +973,11 @@ int ctc_get_cbo_stats(ctc_handler_t *tch, ctc_cbo_stats_t *stats, ctc_cbo_stats_ return result; } -int ctc_get_index_name(ctc_handler_t *tch, char *index_name) { +int ctc_get_index_name(ctc_handler_t *tch, char *index_name) +{ void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(get_index_slot_request); - get_index_slot_request *req = (get_index_slot_request*)alloc_share_mem(shm_inst, len); + get_index_slot_request *req = (get_index_slot_request *)alloc_share_mem(shm_inst, len); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); return ERR_ALLOC_MEMORY; @@ -966,15 +1000,17 @@ int ctc_get_index_name(ctc_handler_t *tch, char *index_name) { return result; } -uint8_t* ctc_alloc_buf(ctc_handler_t *tch, uint32_t buf_size) { +uint8_t *ctc_alloc_buf(ctc_handler_t *tch, uint32_t buf_size) +{ if (buf_size == 0) { return nullptr; } void *shm_inst = get_one_shm_inst(tch); - return (uint8_t*)alloc_share_mem(shm_inst, buf_size); + return (uint8_t *)alloc_share_mem(shm_inst, buf_size); } -void ctc_free_buf(ctc_handler_t *tch, uint8_t *buf) { +void ctc_free_buf(ctc_handler_t *tch, uint8_t *buf) +{ if (buf == nullptr) { return; } @@ -982,10 +1018,12 @@ void ctc_free_buf(ctc_handler_t *tch, uint8_t *buf) { free_share_mem(shm_inst, buf); } -int ctc_general_prefetch(ctc_handler_t *tch, uint8_t *records, uint16_t *record_lens, - uint32_t *recNum, uint64_t *rowids, int32_t max_row_size) { +int ctc_general_prefetch(ctc_handler_t *tch, uint8_t *records, uint16_t *record_lens, uint32_t *recNum, + uint64_t *rowids, int32_t max_row_size) +{ void *shm_inst = get_one_shm_inst(tch); - general_prefetch_request *req = (general_prefetch_request*)alloc_share_mem(shm_inst, sizeof(general_prefetch_request)); + general_prefetch_request *req = + (general_prefetch_request *)alloc_share_mem(shm_inst, sizeof(general_prefetch_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(general_prefetch_request)); return ERR_ALLOC_MEMORY; @@ -1001,7 +1039,7 @@ int ctc_general_prefetch(ctc_handler_t *tch, uint8_t *records, uint16_t *record_ *recNum = *(req->recNum); if (*recNum != 0) { uint32_t record_len = 0; - for(uint8_t i = 0; i < *recNum; i ++){ + for (uint8_t i = 0; i < *recNum; i++) { record_len += req->record_lens[i]; } memcpy(records, req->records, record_len); @@ -1018,21 +1056,16 @@ int ctc_general_prefetch(ctc_handler_t *tch, uint8_t *records, uint16_t *record_ return result; } -int ctc_drop_tablespace_and_user(ctc_handler_t *tch, - const char *db_name, - const char *sql_str, - const char *user_name, - const char *user_ip, - int *error_code, - char *error_message) +int ctc_drop_tablespace_and_user(ctc_handler_t *tch, const char *db_name, const char *sql_str, const char *user_name, + const char *user_ip, int *error_code, char *error_message) { void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(drop_tablespace_and_user_request); - drop_tablespace_and_user_request *req = (drop_tablespace_and_user_request*)alloc_share_mem(shm_inst, len); + drop_tablespace_and_user_request *req = (drop_tablespace_and_user_request *)alloc_share_mem(shm_inst, len); DBUG_EXECUTE_IF("drop_tablespace_and_user_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); + return ERR_ALLOC_MEMORY; } memset(req, 0, len); strncpy(req->db_name, db_name, SMALL_RECORD_SIZE - 1); @@ -1042,7 +1075,7 @@ int ctc_drop_tablespace_and_user(ctc_handler_t *tch, req->tch = *tch; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_DROP_TABLESPACE_AND_USER, req, tch->msg_buf); *tch = req->tch; - if(req->error_message != NULL && strlen(req->error_message) > 0) { + if (req->error_message != NULL && strlen(req->error_message) > 0) { *error_code = req->error_code; strncpy(error_message, req->error_message, ERROR_MESSAGE_LEN); } @@ -1054,13 +1087,14 @@ int ctc_drop_tablespace_and_user(ctc_handler_t *tch, return result; } -int ctc_drop_db_pre_check(ctc_handler_t *tch, const char *db_name, int *error_code, char *error_message) { +int ctc_drop_db_pre_check(ctc_handler_t *tch, const char *db_name, int *error_code, char *error_message) +{ void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(drop_db_pre_check_request); - drop_db_pre_check_request *req = (drop_db_pre_check_request*)alloc_share_mem(shm_inst, len); + drop_db_pre_check_request *req = (drop_db_pre_check_request *)alloc_share_mem(shm_inst, len); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); + return ERR_ALLOC_MEMORY; } memset(req, 0, len); req->tch = *tch; @@ -1071,23 +1105,23 @@ int ctc_drop_db_pre_check(ctc_handler_t *tch, const char *db_name, int *error_co *error_code = req->error_code; strncpy(error_message, req->error_message, ERROR_MESSAGE_LEN); if (ret == CT_SUCCESS) { - result = req->result; + result = req->result; } free_share_mem(shm_inst, req); return result; } -int ctc_lock_table(ctc_handler_t *tch, const char *db_name, ctc_lock_table_info *lock_info, - int *error_code) { +int ctc_lock_table(ctc_handler_t *tch, const char *db_name, ctc_lock_table_info *lock_info, int *error_code) +{ void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(lock_table_request); - lock_table_request *req = (lock_table_request*)alloc_share_mem(shm_inst, len); + lock_table_request *req = (lock_table_request *)alloc_share_mem(shm_inst, len); DBUG_EXECUTE_IF("lock_table_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); + return ERR_ALLOC_MEMORY; } - + memset(req, 0, len); if (db_name != nullptr) { strncpy(req->db_name, db_name, SMALL_RECORD_SIZE - 1); @@ -1100,22 +1134,22 @@ int ctc_lock_table(ctc_handler_t *tch, const char *db_name, ctc_lock_table_info *tch = req->tch; *error_code = req->error_code; if (ret == CT_SUCCESS) { - result = req->result; + result = req->result; } free_share_mem(shm_inst, req); return result; } -int ctc_pre_create_db(ctc_handler_t *tch, const char *sql_str, ctc_db_infos_t *db_infos, - int *error_code, char *error_message) +int ctc_pre_create_db(ctc_handler_t *tch, const char *sql_str, ctc_db_infos_t *db_infos, int *error_code, + char *error_message) { void *shm_inst = get_one_shm_inst(tch); uint64_t len = sizeof(pre_create_db_request); - pre_create_db_request *req = (pre_create_db_request*)alloc_share_mem(shm_inst, len); + pre_create_db_request *req = (pre_create_db_request *)alloc_share_mem(shm_inst, len); DBUG_EXECUTE_IF("create_tablespace_and_user_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); + return ERR_ALLOC_MEMORY; } memset(req, 0, len); strncpy(req->sql_str, sql_str, MAX_DDL_SQL_LEN - 1); @@ -1127,7 +1161,7 @@ int ctc_pre_create_db(ctc_handler_t *tch, const char *sql_str, ctc_db_infos_t *d req->tch = *tch; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_PRE_CREATE_DB, req, tch->msg_buf); *tch = req->tch; - if(req->error_message != NULL && strlen(req->error_message) > 0) { + if (req->error_message != NULL && strlen(req->error_message) > 0) { *error_code = req->error_code; strncpy(error_message, req->error_message, ERROR_MESSAGE_LEN); } @@ -1139,13 +1173,15 @@ int ctc_pre_create_db(ctc_handler_t *tch, const char *sql_str, ctc_db_infos_t *d return result; } -int ctc_unlock_table(ctc_handler_t *tch, uint32_t mysql_insert_id, ctc_lock_table_info *lock_info) { +int ctc_unlock_table(ctc_handler_t *tch, uint32_t mysql_insert_id, ctc_lock_table_info *lock_info) +{ void *shm_inst = get_one_shm_inst(tch); - ctc_unlock_tables_request *req = (ctc_unlock_tables_request*)alloc_share_mem(shm_inst, sizeof(ctc_unlock_tables_request)); + ctc_unlock_tables_request *req = + (ctc_unlock_tables_request *)alloc_share_mem(shm_inst, sizeof(ctc_unlock_tables_request)); DBUG_EXECUTE_IF("unlock_table_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(ctc_unlock_tables_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(ctc_unlock_tables_request)); + return ERR_ALLOC_MEMORY; } req->tch = *tch; req->mysql_inst_id = mysql_insert_id; @@ -1160,12 +1196,12 @@ int ctc_unlock_table(ctc_handler_t *tch, uint32_t mysql_insert_id, ctc_lock_tabl return result; } -int ctc_knl_write_lob(ctc_handler_t *tch, char* locator, uint32_t locator_size, int column_id, - void* data, uint32_t data_len, bool force_outline) +int ctc_knl_write_lob(ctc_handler_t *tch, char *locator, uint32_t locator_size, int column_id, void *data, + uint32_t data_len, bool force_outline) { void *shm_inst = get_one_shm_inst(tch); int reqSize = sizeof(knl_write_lob_request) + data_len; - uchar* reqBuf = new uchar[reqSize]; + uchar *reqBuf = new uchar[reqSize]; knl_write_lob_request *req = (knl_write_lob_request *)reqBuf; if (req == NULL) { return ERR_ALLOC_MEMORY; @@ -1192,11 +1228,11 @@ int ctc_knl_write_lob(ctc_handler_t *tch, char* locator, uint32_t locator_size, return result; } -int ctc_knl_read_lob(ctc_handler_t *tch, char* locator, uint32_t offset, void *buf, uint32_t size, uint32_t *read_size) +int ctc_knl_read_lob(ctc_handler_t *tch, char *locator, uint32_t offset, void *buf, uint32_t size, uint32_t *read_size) { void *shm_inst = get_one_shm_inst(tch); int reqSize = sizeof(knl_read_lob_request) + size; - uchar* reqBuf = new uchar[reqSize]; + uchar *reqBuf = new uchar[reqSize]; knl_read_lob_request *req = (knl_read_lob_request *)reqBuf; if (req == NULL) { return ERR_ALLOC_MEMORY; @@ -1211,7 +1247,7 @@ int ctc_knl_read_lob(ctc_handler_t *tch, char* locator, uint32_t offset, void *b if (ret != CT_SUCCESS) { ctc_log_error("ctc_mq_batch_send_message failed in read lob: %d", ret); } else { - if(req->result == CT_SUCCESS) { + if (req->result == CT_SUCCESS) { *read_size = (uint32_t)(req->read_size); assert(*read_size <= size); memcpy(buf, req->buf, *read_size); @@ -1230,15 +1266,17 @@ int srv_wait_instance_startuped(void) ctc_log_error("alloc shm mem error, shm_inst(%p), size(%d)", shm_inst, 0); return ERR_ALLOC_MEMORY; } - int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_WAIT_CONNETOR_STARTUPED, req_mem, nullptr, SERVER_REGISTER_PROC_ID, 5); + int ret = + ctc_mq_deal_func(shm_inst, CTC_FUNC_TYPE_WAIT_CONNETOR_STARTUPED, req_mem, nullptr, SERVER_REGISTER_PROC_ID, 5); free_share_mem(shm_inst, req_mem); return ret; } -int ctc_create_table(void *table_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_create_table(void *table_def, ddl_ctrl_t *ddl_ctrl) +{ void *shm_inst = get_one_shm_inst(&ddl_ctrl->tch); int result = ERR_CONNECTION_FAILED; - int ret = ctc_mq_batch_send_message(shm_inst, CTC_FUNC_TYPE_CREATE_TABLE, (uint8_t*)table_def, ddl_ctrl->msg_len, + int ret = ctc_mq_batch_send_message(shm_inst, CTC_FUNC_TYPE_CREATE_TABLE, (uint8_t *)table_def, ddl_ctrl->msg_len, ddl_ctrl->msg_len); memcpy(ddl_ctrl, table_def, sizeof(ddl_ctrl_t)); if (ret == CT_SUCCESS) { @@ -1247,7 +1285,8 @@ int ctc_create_table(void *table_def, ddl_ctrl_t *ddl_ctrl) { return result; } -int ctc_truncate_table(void *table_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_truncate_table(void *table_def, ddl_ctrl_t *ddl_ctrl) +{ assert(ddl_ctrl->msg_len + sizeof(ddl_ctrl_t) < REQUEST_SIZE); void *shm_inst = get_one_shm_inst(NULL); void *req_mem = alloc_share_mem(shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); @@ -1268,11 +1307,12 @@ int ctc_truncate_table(void *table_def, ddl_ctrl_t *ddl_ctrl) { return result; } -int ctc_truncate_partition(void *table_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_truncate_partition(void *table_def, ddl_ctrl_t *ddl_ctrl) +{ void *shm_inst = get_one_shm_inst(&ddl_ctrl->tch); int result = ERR_CONNECTION_FAILED; - int ret = ctc_mq_batch_send_message(shm_inst, CTC_FUNC_TYPE_TRUNCATE_PARTITION, (uint8_t*)table_def, ddl_ctrl->msg_len, - ddl_ctrl->msg_len); + int ret = ctc_mq_batch_send_message(shm_inst, CTC_FUNC_TYPE_TRUNCATE_PARTITION, (uint8_t *)table_def, + ddl_ctrl->msg_len, ddl_ctrl->msg_len); memcpy(ddl_ctrl, table_def, sizeof(ddl_ctrl_t)); if (ret == CT_SUCCESS) { result = ddl_ctrl->error_code; @@ -1280,10 +1320,11 @@ int ctc_truncate_partition(void *table_def, ddl_ctrl_t *ddl_ctrl) { return result; } -int ctc_alter_table(void *alter_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_alter_table(void *alter_def, ddl_ctrl_t *ddl_ctrl) +{ void *shm_inst = get_one_shm_inst(&ddl_ctrl->tch); int result = ERR_CONNECTION_FAILED; - int ret = ctc_mq_batch_send_message(shm_inst, CTC_FUNC_TYPE_ALTER_TABLE, (uint8_t*)alter_def, ddl_ctrl->msg_len, + int ret = ctc_mq_batch_send_message(shm_inst, CTC_FUNC_TYPE_ALTER_TABLE, (uint8_t *)alter_def, ddl_ctrl->msg_len, ddl_ctrl->msg_len); memcpy(ddl_ctrl, alter_def, sizeof(ddl_ctrl_t)); if (ret == CT_SUCCESS) { @@ -1292,7 +1333,8 @@ int ctc_alter_table(void *alter_def, ddl_ctrl_t *ddl_ctrl) { return result; } -int ctc_rename_table(void *alter_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_rename_table(void *alter_def, ddl_ctrl_t *ddl_ctrl) +{ assert(ddl_ctrl->msg_len + sizeof(ddl_ctrl_t) < REQUEST_SIZE); void *shm_inst = get_one_shm_inst(NULL); void *req_mem = alloc_share_mem(shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); @@ -1316,7 +1358,7 @@ int ctc_rename_table(void *alter_def, ddl_ctrl_t *ddl_ctrl) { int ctc_update_job(update_job_info info) { void *shm_inst = get_one_shm_inst(NULL); - update_job_request *req = (update_job_request*)alloc_share_mem(shm_inst, sizeof(update_job_request)); + update_job_request *req = (update_job_request *)alloc_share_mem(shm_inst, sizeof(update_job_request)); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(update_job_request)); return ERR_ALLOC_MEMORY; @@ -1331,13 +1373,15 @@ int ctc_update_job(update_job_info info) return result; } -int ctc_execute_mysql_ddl_sql(ctc_handler_t *tch, ctc_ddl_broadcast_request *broadcast_req, bool allow_fail) { +int ctc_execute_mysql_ddl_sql(ctc_handler_t *tch, ctc_ddl_broadcast_request *broadcast_req, bool allow_fail) +{ void *shm_inst = get_one_shm_inst(tch); - execute_mysql_ddl_sql_request *req = (execute_mysql_ddl_sql_request*)alloc_share_mem(shm_inst, sizeof(execute_mysql_ddl_sql_request)); + execute_mysql_ddl_sql_request *req = + (execute_mysql_ddl_sql_request *)alloc_share_mem(shm_inst, sizeof(execute_mysql_ddl_sql_request)); DBUG_EXECUTE_IF("xcute_general_ddl_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(execute_mysql_ddl_sql_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(execute_mysql_ddl_sql_request)); + return ERR_ALLOC_MEMORY; } memcpy(&req->broadcast_req, broadcast_req, sizeof(ctc_ddl_broadcast_request)); req->tch = *tch; @@ -1354,13 +1398,15 @@ int ctc_execute_mysql_ddl_sql(ctc_handler_t *tch, ctc_ddl_broadcast_request *bro return result; } -int ctc_broadcast_mysql_dd_invalidate(ctc_handler_t *tch, ctc_invalidate_broadcast_request *broadcast_req) { +int ctc_broadcast_mysql_dd_invalidate(ctc_handler_t *tch, ctc_invalidate_broadcast_request *broadcast_req) +{ void *shm_inst = get_one_shm_inst(tch); - invalidate_mysql_dd_request *req = (invalidate_mysql_dd_request *)alloc_share_mem(shm_inst, sizeof(invalidate_mysql_dd_request)); + invalidate_mysql_dd_request *req = + (invalidate_mysql_dd_request *)alloc_share_mem(shm_inst, sizeof(invalidate_mysql_dd_request)); DBUG_EXECUTE_IF("xcute_general_ddl_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(invalidate_mysql_dd_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(invalidate_mysql_dd_request)); + return ERR_ALLOC_MEMORY; } memcpy(&req->broadcast_req, broadcast_req, sizeof(ctc_invalidate_broadcast_request)); req->tch = *tch; @@ -1375,12 +1421,14 @@ int ctc_broadcast_mysql_dd_invalidate(ctc_handler_t *tch, ctc_invalidate_broadca return result; } -int ctc_broadcast_rewrite_sql(ctc_handler_t *tch, ctc_ddl_broadcast_request *broadcast_req, bool allow_fail) { +int ctc_broadcast_rewrite_sql(ctc_handler_t *tch, ctc_ddl_broadcast_request *broadcast_req, bool allow_fail) +{ void *shm_inst = get_one_shm_inst(tch); - execute_mysql_ddl_sql_request *req = (execute_mysql_ddl_sql_request*)alloc_share_mem(shm_inst, sizeof(execute_mysql_ddl_sql_request)); + execute_mysql_ddl_sql_request *req = + (execute_mysql_ddl_sql_request *)alloc_share_mem(shm_inst, sizeof(execute_mysql_ddl_sql_request)); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(execute_mysql_ddl_sql_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(execute_mysql_ddl_sql_request)); + return ERR_ALLOC_MEMORY; } memcpy(&req->broadcast_req, broadcast_req, sizeof(ctc_ddl_broadcast_request)); @@ -1398,9 +1446,10 @@ int ctc_broadcast_rewrite_sql(ctc_handler_t *tch, ctc_ddl_broadcast_request *bro return result; } -int ctc_get_serial_value(ctc_handler_t *tch, uint64_t *value, dml_flag_t flag) { +int ctc_get_serial_value(ctc_handler_t *tch, uint64_t *value, dml_flag_t flag) +{ void *shm_inst = get_one_shm_inst(tch); - get_serial_val_request *req = (get_serial_val_request*)alloc_share_mem(shm_inst, sizeof(get_serial_val_request)); + get_serial_val_request *req = (get_serial_val_request *)alloc_share_mem(shm_inst, sizeof(get_serial_val_request)); DBUG_EXECUTE_IF("get_serial_val_ddl_shm_oom", { req = NULL; }); if (req == NULL) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(get_serial_val_request)); @@ -1422,7 +1471,8 @@ int ctc_get_serial_value(ctc_handler_t *tch, uint64_t *value, dml_flag_t flag) { return result; } -int ctc_drop_table(void *drop_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_drop_table(void *drop_def, ddl_ctrl_t *ddl_ctrl) +{ assert(ddl_ctrl->msg_len + sizeof(ddl_ctrl_t) < REQUEST_SIZE); void *shm_inst = get_one_shm_inst(NULL); void *req_mem = alloc_share_mem(shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); @@ -1443,7 +1493,8 @@ int ctc_drop_table(void *drop_def, ddl_ctrl_t *ddl_ctrl) { return result; } -int ctc_create_tablespace(void *space_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_create_tablespace(void *space_def, ddl_ctrl_t *ddl_ctrl) +{ assert(ddl_ctrl->msg_len + sizeof(ddl_ctrl_t) < REQUEST_SIZE); void *shm_inst = get_one_shm_inst(NULL); void *req_mem = alloc_share_mem(shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); @@ -1464,14 +1515,15 @@ int ctc_create_tablespace(void *space_def, ddl_ctrl_t *ddl_ctrl) { return result; } -int ctc_alter_tablespace(void *space_alter_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_alter_tablespace(void *space_alter_def, ddl_ctrl_t *ddl_ctrl) +{ assert(ddl_ctrl->msg_len + sizeof(ddl_ctrl_t) < REQUEST_SIZE); void *shm_inst = get_one_shm_inst(NULL); void *req_mem = alloc_share_mem(shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); DBUG_EXECUTE_IF("alter_tablespace_shm_oom", { req_mem = NULL; }); if (req_mem == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); + return ERR_ALLOC_MEMORY; } memcpy((char *)req_mem, ddl_ctrl, sizeof(ddl_ctrl_t)); memcpy((char *)req_mem + sizeof(ddl_ctrl_t), space_alter_def, ddl_ctrl->msg_len); @@ -1485,14 +1537,15 @@ int ctc_alter_tablespace(void *space_alter_def, ddl_ctrl_t *ddl_ctrl) { return result; } -int ctc_drop_tablespace(void *space_drop_def, ddl_ctrl_t *ddl_ctrl) { +int ctc_drop_tablespace(void *space_drop_def, ddl_ctrl_t *ddl_ctrl) +{ assert(ddl_ctrl->msg_len + sizeof(ddl_ctrl_t) < REQUEST_SIZE); void *shm_inst = get_one_shm_inst(NULL); void *req_mem = alloc_share_mem(shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); DBUG_EXECUTE_IF("drop_tablespace_shm_oom", { req_mem = NULL; }); if (req_mem == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, ddl_ctrl->msg_len + sizeof(ddl_ctrl_t)); + return ERR_ALLOC_MEMORY; } memcpy((char *)req_mem, ddl_ctrl, sizeof(ddl_ctrl_t)); memcpy((char *)req_mem + sizeof(ddl_ctrl_t), space_drop_def, ddl_ctrl->msg_len); @@ -1506,13 +1559,14 @@ int ctc_drop_tablespace(void *space_drop_def, ddl_ctrl_t *ddl_ctrl) { return result; } -int ctc_lock_instance(bool *is_mysqld_starting, ctc_lock_table_mode_t lock_type, ctc_handler_t *tch) { +int ctc_lock_instance(bool *is_mysqld_starting, ctc_lock_table_mode_t lock_type, ctc_handler_t *tch) +{ void *shm_inst = get_one_shm_inst(tch); - lock_instance_request *req = (lock_instance_request*)alloc_share_mem(shm_inst, sizeof(lock_instance_request)); + lock_instance_request *req = (lock_instance_request *)alloc_share_mem(shm_inst, sizeof(lock_instance_request)); DBUG_EXECUTE_IF("lock_instance_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(lock_instance_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(lock_instance_request)); + return ERR_ALLOC_MEMORY; } req->tch = *tch; @@ -1522,19 +1576,20 @@ int ctc_lock_instance(bool *is_mysqld_starting, ctc_lock_table_mode_t lock_type, int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_LOCK_INSTANCE, req, tch->msg_buf); *tch = req->tch; if (ret == CT_SUCCESS) { - result = req->result; + result = req->result; } free_share_mem(shm_inst, req); return result; } -int ctc_unlock_instance(bool *is_mysqld_starting, ctc_handler_t *tch) { +int ctc_unlock_instance(bool *is_mysqld_starting, ctc_handler_t *tch) +{ void *shm_inst = get_one_shm_inst(tch); - unlock_instance_request *req = (unlock_instance_request*)alloc_share_mem(shm_inst, sizeof(unlock_instance_request)); + unlock_instance_request *req = (unlock_instance_request *)alloc_share_mem(shm_inst, sizeof(unlock_instance_request)); DBUG_EXECUTE_IF("unlock_instance_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(unlock_instance_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(unlock_instance_request)); + return ERR_ALLOC_MEMORY; } req->tch = *tch; @@ -1543,41 +1598,44 @@ int ctc_unlock_instance(bool *is_mysqld_starting, ctc_handler_t *tch) { int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_UNLOCK_INSTANCE, req, tch->msg_buf); *tch = req->tch; if (ret == CT_SUCCESS) { - result = req->result; + result = req->result; } free_share_mem(shm_inst, req); return result; } -int ctc_search_metadata_status(bool *cantian_metadata_switch, bool *cantian_cluster_ready) { +int ctc_search_metadata_status(bool *cantian_metadata_switch, bool *cantian_cluster_ready) +{ void *shm_inst = get_one_shm_inst(NULL); - search_metadata_status_request *req = (search_metadata_status_request*)alloc_share_mem(shm_inst, sizeof(search_metadata_status_request)); + search_metadata_status_request *req = + (search_metadata_status_request *)alloc_share_mem(shm_inst, sizeof(search_metadata_status_request)); DBUG_EXECUTE_IF("check_init_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(search_metadata_status_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(search_metadata_status_request)); + return ERR_ALLOC_MEMORY; } - + int result = ERR_CONNECTION_FAILED; int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_SEARCH_METADATA_SWITCH, req, nullptr); if (ret == CT_SUCCESS) { - result = req->result; - *cantian_metadata_switch = req->metadata_switch; - *cantian_cluster_ready = req->cluster_ready; + result = req->result; + *cantian_metadata_switch = req->metadata_switch; + *cantian_cluster_ready = req->cluster_ready; } free_share_mem(shm_inst, req); - + return result; } - -int ctc_check_db_table_exists(const char *db, const char *name, bool *is_exists) { + +int ctc_check_db_table_exists(const char *db, const char *name, bool *is_exists) +{ void *shm_inst = get_one_shm_inst(NULL); uint64_t len = sizeof(check_table_exists_request); - check_table_exists_request *req = (check_table_exists_request*)alloc_share_mem(shm_inst, len); + check_table_exists_request *req = (check_table_exists_request *)alloc_share_mem(shm_inst, len); DBUG_EXECUTE_IF("check_init_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, len); + return ERR_ALLOC_MEMORY; } memset(req, 0, len); int result = ERR_CONNECTION_FAILED; @@ -1585,20 +1643,22 @@ int ctc_check_db_table_exists(const char *db, const char *name, bool *is_exists) strncpy(req->name, name, SMALL_RECORD_SIZE - 1); int ret = ctc_mq_deal_func(shm_inst, CTC_FUNC_CHECK_TABLE_EXIST, req, nullptr); if (ret == CT_SUCCESS) { - result = req->result; - *is_exists = (bool)req->is_exists; + result = req->result; + *is_exists = (bool)req->is_exists; } free_share_mem(shm_inst, req); - + return result; } -int ctc_record_sql_for_cantian(ctc_handler_t *tch, ctc_ddl_broadcast_request *broadcast_req, bool allow_fail) { +int ctc_record_sql_for_cantian(ctc_handler_t *tch, ctc_ddl_broadcast_request *broadcast_req, bool allow_fail) +{ void *shm_inst = get_one_shm_inst(tch); - execute_mysql_ddl_sql_request *req = (execute_mysql_ddl_sql_request*)alloc_share_mem(shm_inst, sizeof(execute_mysql_ddl_sql_request)); + execute_mysql_ddl_sql_request *req = + (execute_mysql_ddl_sql_request *)alloc_share_mem(shm_inst, sizeof(execute_mysql_ddl_sql_request)); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(execute_mysql_ddl_sql_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(execute_mysql_ddl_sql_request)); + return ERR_ALLOC_MEMORY; } memcpy(&req->broadcast_req, broadcast_req, sizeof(ctc_ddl_broadcast_request)); @@ -1616,13 +1676,15 @@ int ctc_record_sql_for_cantian(ctc_handler_t *tch, ctc_ddl_broadcast_request *br return result; } -int ctc_query_cluster_role(bool *is_slave, bool *cantian_cluster_ready) { +int ctc_query_cluster_role(bool *is_slave, bool *cantian_cluster_ready) +{ void *shm_inst = get_one_shm_inst(NULL); - query_cluster_role_request *req = (query_cluster_role_request*) alloc_share_mem(shm_inst, sizeof(query_cluster_role_request)); + query_cluster_role_request *req = + (query_cluster_role_request *)alloc_share_mem(shm_inst, sizeof(query_cluster_role_request)); DBUG_EXECUTE_IF("check_init_shm_oom", { req = NULL; }); if (req == NULL) { - ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(query_cluster_role_request)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(query_cluster_role_request)); + return ERR_ALLOC_MEMORY; } int result = ERR_CONNECTION_FAILED; @@ -1640,8 +1702,8 @@ int ctc_query_cluster_role(bool *is_slave, bool *cantian_cluster_ready) { int ctc_query_shm_file_num(uint32_t *shm_file_num) { void *shm_inst = get_one_shm_inst(NULL); - query_shm_file_num_request *req = (query_shm_file_num_request*) - alloc_share_mem(shm_inst, sizeof(query_shm_file_num_request)); + query_shm_file_num_request *req = + (query_shm_file_num_request *)alloc_share_mem(shm_inst, sizeof(query_shm_file_num_request)); if (req == nullptr) { ctc_log_error("alloc shm mem error, shm_inst(%p), size(%lu)", shm_inst, sizeof(query_shm_file_num_request)); return ERR_ALLOC_MEMORY; diff --git a/storage/ctc/ctc_stats.cc b/storage/ctc/ctc_stats.cc index 20e8a91..8798eaa 100644 --- a/storage/ctc/ctc_stats.cc +++ b/storage/ctc/ctc_stats.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -15,147 +15,126 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ctc_stats.h" -#include "ctc_log.h" #include +#include "ctc_log.h" const char *ctc_interface_strs[] = { - "CTC_FUNC_TYPE_OPEN_TABLE", - "CTC_FUNC_TYPE_CLOSE_TABLE", - "CTC_FUNC_TYPE_CLOSE_SESSION", - "CTC_FUNC_TYPE_WRITE_ROW", - "CTC_FUNC_TYPE_UPDATE_JOB", - "CTC_FUNC_TYPE_UPDATE_ROW", - "CTC_FUNC_TYPE_DELETE_ROW", - "CTC_FUNC_TYPE_RND_INIT", - "CTC_FUNC_TYPE_RND_END", - "CTC_FUNC_TYPE_RND_NEXT", - "CTC_FUNC_TYPE_RND_PREFETCH", - "CTC_FUNC_TYPE_SCAN_RECORDS", - "CTC_FUNC_TYPE_TRX_COMMIT", - "CTC_FUNC_TYPE_TRX_ROLLBACK", - "CTC_FUNC_TYPE_TRX_BEGIN", - "CTC_FUNC_TYPE_LOCK_TABLE", - "CTC_FUNC_TYPE_UNLOCK_TABLE", - "CTC_FUNC_TYPE_INDEX_END", - "CTC_FUNC_TYPE_SRV_SET_SAVEPOINT", - "CTC_FUNC_TYPE_SRV_ROLLBACK_SAVEPOINT", - "CTC_FUNC_TYPE_SRV_RELEASE_SAVEPOINT", - "CTC_FUNC_TYPE_GENERAL_FETCH", - "CTC_FUNC_TYPE_GENERAL_PREFETCH", - "CTC_FUNC_TYPE_FREE_CURSORS", - "CTC_FUNC_TYPE_GET_INDEX_NAME", - "CTC_FUNC_TYPE_INDEX_READ", - "CTC_FUNC_TYPE_RND_POS", - "CTC_FUNC_TYPE_POSITION", - "CTC_FUNC_TYPE_DELETE_ALL_ROWS", - "CTC_FUNC_TYPE_GET_CBO_STATS", - "CTC_FUNC_TYPE_WRITE_LOB", - "CTC_FUNC_TYPE_READ_LOB", - "CTC_FUNC_TYPE_CREATE_TABLE", - "CTC_FUNC_TYPE_TRUNCATE_TABLE", - "CTC_FUNC_TYPE_TRUNCATE_PARTITION", - "CTC_FUNC_TYPE_RENAME_TABLE", - "CTC_FUNC_TYPE_ALTER_TABLE", - "CTC_FUNC_TYPE_GET_SERIAL_VALUE", - "CTC_FUNC_TYPE_DROP_TABLE", - "CTC_FUNC_TYPE_EXCUTE_MYSQL_DDL_SQL", - "CTC_FUNC_TYPE_BROADCAST_REWRITE_SQL", - "CTC_FUNC_TYPE_CREATE_TABLESPACE", - "CTC_FUNC_TYPE_ALTER_TABLESPACE", - "CTC_FUNC_TYPE_DROP_TABLESPACE", - "CTC_FUNC_TYPE_BULK_INSERT", - "CTC_FUNC_TYPE_ANALYZE", - "CTC_FUNC_TYPE_GET_MAX_SESSIONS", - "CTC_FUNC_LOCK_INSTANCE", - "CTC_FUNC_UNLOCK_INSTANCE", - "CTC_FUNC_CHECK_TABLE_EXIST", - "CTC_FUNC_SEARCH_METADATA_SWITCH", - "CTC_FUNC_QUERY_SHM_USAGE", - "CTC_FUNC_QUERY_CLUSTER_ROLE", - "CTC_FUNC_SET_CLUSTER_ROLE_BY_CANTIAN", - "CTC_FUNC_PRE_CREATE_DB", - "CTC_FUNC_TYPE_DROP_TABLESPACE_AND_USER", - "CTC_FUNC_DROP_DB_PRE_CHECK", - "CTC_FUNC_KILL_CONNECTION", - "CTC_FUNC_TYPE_INVALIDATE_OBJECT", - "CTC_FUNC_TYPE_RECORD_SQL", - "CTC_FUNC_TYPE_REGISTER_INSTANCE", - "CTC_FUNC_QUERY_SHM_FILE_NUM", - "CTC_FUNC_TYPE_WAIT_CONNETOR_STARTUPED", - "CTC_FUNC_TYPE_MYSQL_EXECUTE_UPDATE", - "CTC_FUNC_TYPE_CLOSE_MYSQL_CONNECTION", - "CTC_FUNC_TYPE_LOCK_TABLES", - "CTC_FUNC_TYPE_UNLOCK_TABLES", - "CTC_FUNC_TYPE_EXECUTE_REWRITE_OPEN_CONN", - "CTC_FUNC_TYPE_INVALIDATE_OBJECTS", - "CTC_FUNC_TYPE_INVALIDATE_ALL_OBJECTS", - "CTC_FUNC_TYPE_UPDATE_DDCACHE", + "CTC_FUNC_TYPE_OPEN_TABLE", + "CTC_FUNC_TYPE_CLOSE_TABLE", + "CTC_FUNC_TYPE_CLOSE_SESSION", + "CTC_FUNC_TYPE_WRITE_ROW", + "CTC_FUNC_TYPE_UPDATE_JOB", + "CTC_FUNC_TYPE_UPDATE_ROW", + "CTC_FUNC_TYPE_DELETE_ROW", + "CTC_FUNC_TYPE_RND_INIT", + "CTC_FUNC_TYPE_RND_END", + "CTC_FUNC_TYPE_RND_NEXT", + "CTC_FUNC_TYPE_RND_PREFETCH", + "CTC_FUNC_TYPE_SCAN_RECORDS", + "CTC_FUNC_TYPE_TRX_COMMIT", + "CTC_FUNC_TYPE_TRX_ROLLBACK", + "CTC_FUNC_TYPE_TRX_BEGIN", + "CTC_FUNC_TYPE_LOCK_TABLE", + "CTC_FUNC_TYPE_UNLOCK_TABLE", + "CTC_FUNC_TYPE_INDEX_END", + "CTC_FUNC_TYPE_SRV_SET_SAVEPOINT", + "CTC_FUNC_TYPE_SRV_ROLLBACK_SAVEPOINT", + "CTC_FUNC_TYPE_SRV_RELEASE_SAVEPOINT", + "CTC_FUNC_TYPE_GENERAL_FETCH", + "CTC_FUNC_TYPE_GENERAL_PREFETCH", + "CTC_FUNC_TYPE_FREE_CURSORS", + "CTC_FUNC_TYPE_GET_INDEX_NAME", + "CTC_FUNC_TYPE_INDEX_READ", + "CTC_FUNC_TYPE_RND_POS", + "CTC_FUNC_TYPE_POSITION", + "CTC_FUNC_TYPE_DELETE_ALL_ROWS", + "CTC_FUNC_TYPE_GET_CBO_STATS", + "CTC_FUNC_TYPE_WRITE_LOB", + "CTC_FUNC_TYPE_READ_LOB", + "CTC_FUNC_TYPE_CREATE_TABLE", + "CTC_FUNC_TYPE_TRUNCATE_TABLE", + "CTC_FUNC_TYPE_TRUNCATE_PARTITION", + "CTC_FUNC_TYPE_RENAME_TABLE", + "CTC_FUNC_TYPE_ALTER_TABLE", + "CTC_FUNC_TYPE_GET_SERIAL_VALUE", + "CTC_FUNC_TYPE_DROP_TABLE", + "CTC_FUNC_TYPE_EXCUTE_MYSQL_DDL_SQL", + "CTC_FUNC_TYPE_BROADCAST_REWRITE_SQL", + "CTC_FUNC_TYPE_CREATE_TABLESPACE", + "CTC_FUNC_TYPE_ALTER_TABLESPACE", + "CTC_FUNC_TYPE_DROP_TABLESPACE", + "CTC_FUNC_TYPE_BULK_INSERT", + "CTC_FUNC_TYPE_ANALYZE", + "CTC_FUNC_TYPE_GET_MAX_SESSIONS", + "CTC_FUNC_LOCK_INSTANCE", + "CTC_FUNC_UNLOCK_INSTANCE", + "CTC_FUNC_CHECK_TABLE_EXIST", + "CTC_FUNC_SEARCH_METADATA_SWITCH", + "CTC_FUNC_QUERY_SHM_USAGE", + "CTC_FUNC_QUERY_CLUSTER_ROLE", + "CTC_FUNC_SET_CLUSTER_ROLE_BY_CANTIAN", + "CTC_FUNC_PRE_CREATE_DB", + "CTC_FUNC_TYPE_DROP_TABLESPACE_AND_USER", + "CTC_FUNC_DROP_DB_PRE_CHECK", + "CTC_FUNC_KILL_CONNECTION", + "CTC_FUNC_TYPE_INVALIDATE_OBJECT", + "CTC_FUNC_TYPE_RECORD_SQL", + "CTC_FUNC_TYPE_REGISTER_INSTANCE", + "CTC_FUNC_QUERY_SHM_FILE_NUM", + "CTC_FUNC_TYPE_WAIT_CONNETOR_STARTUPED", + "CTC_FUNC_TYPE_MYSQL_EXECUTE_UPDATE", + "CTC_FUNC_TYPE_CLOSE_MYSQL_CONNECTION", + "CTC_FUNC_TYPE_LOCK_TABLES", + "CTC_FUNC_TYPE_UNLOCK_TABLES", + "CTC_FUNC_TYPE_EXECUTE_REWRITE_OPEN_CONN", + "CTC_FUNC_TYPE_INVALIDATE_OBJECTS", + "CTC_FUNC_TYPE_INVALIDATE_ALL_OBJECTS", + "CTC_FUNC_TYPE_UPDATE_DDCACHE", }; #ifndef WITH_CANTIAN typedef struct tag_mem_class_cfg_s { - uint32_t size; // align to 8 bytes - uint32_t num; + uint32_t size; // align to 8 bytes + uint32_t num; } mem_class_cfg_t; mem_class_cfg_t g_mem_class_cfg[MEM_CLASS_NUM] = { - {8, 16000}, - {16, 16000}, - {32, 16000}, - {40, 16000}, - {48, 16000}, - {56, 16000}, - {64, 16000}, - {128, 16000}, - {256, 16000}, - {384, 8000}, - {512, 400}, - {1024, 400}, - {2048, 400}, - {4096, 400}, - {8192, 400}, - {12288, 1600}, - {16384, 1200}, - {40960, 4000}, - {65536, 14000}, - {66632, 20000}, - {82224, 1000}, - {102400, 800}, - {204800, 800}, - {491520, 800}, - {1048576, 40}, - {2097152, 100}, - {4194304, 200}, + {8, 16000}, {16, 16000}, {32, 16000}, {40, 16000}, {48, 16000}, {56, 16000}, {64, 16000}, + {128, 16000}, {256, 16000}, {384, 8000}, {512, 400}, {1024, 400}, {2048, 400}, {4096, 400}, + {8192, 400}, {12288, 1600}, {16384, 1200}, {40960, 4000}, {65536, 14000}, {66632, 20000}, {82224, 1000}, + {102400, 800}, {204800, 800}, {491520, 800}, {1048576, 40}, {2097152, 100}, {4194304, 200}, }; #endif -ctc_stats& ctc_stats::get_instance() noexcept { +ctc_stats &ctc_stats::get_instance() noexcept +{ static ctc_stats m_ctc_stats; return m_ctc_stats; } -bool ctc_stats::get_statistics_enabled() { - return m_statistics_enabled; -} +bool ctc_stats::get_statistics_enabled() { return m_statistics_enabled; } -void ctc_stats::set_statistics_enabled(const bool val) { +void ctc_stats::set_statistics_enabled(const bool val) +{ if (val && !m_statistics_enabled) { for (int i = 0; i < CTC_FUNC_TYPE_NUMBER; i++) { m_calls[i] = 0; m_use_time[i] = 0; } } - + m_statistics_enabled = val; } -void ctc_stats::gather_stats(const enum CTC_FUNC_TYPE& type, const uint64_t use_time) { +void ctc_stats::gather_stats(const enum CTC_FUNC_TYPE &type, const uint64_t use_time) +{ m_calls[type]++; m_use_time[type] += use_time; } -void ctc_stats::print_cost_times(std::string &ctc_srv_monitor_str) { +void ctc_stats::print_cost_times(std::string &ctc_srv_monitor_str) +{ if ((sizeof(ctc_interface_strs) / sizeof(ctc_interface_strs[0])) != CTC_FUNC_TYPE_NUMBER) { ctc_srv_monitor_str += "[CTC_STATS]: ctc_interface_strs number must be same as total ctc interfaces.\n"; return; @@ -170,9 +149,10 @@ void ctc_stats::print_cost_times(std::string &ctc_srv_monitor_str) { continue; } - double average_time = (double) use_time / calls; + double average_time = (double)use_time / calls; ctc_srv_monitor_str += ctc_interface_strs[i]; - ctc_srv_monitor_str += ": " + std::to_string(calls) + " " + std::to_string(use_time) + " "+ std::to_string(average_time)+"\n"; + ctc_srv_monitor_str += + ": " + std::to_string(calls) + " " + std::to_string(use_time) + " " + std::to_string(average_time) + "\n"; } ctc_srv_monitor_str += "\n======================================CTC_STATS=====================================\n"; @@ -180,28 +160,33 @@ void ctc_stats::print_cost_times(std::string &ctc_srv_monitor_str) { #ifndef WITH_CANTIAN extern uint32_t g_shm_file_num; -void ctc_stats::print_shm_usage(std::string &ctc_srv_monitor_str) { - uint32_t *ctc_shm_usage = (uint32_t *)my_malloc(PSI_NOT_INSTRUMENTED, (g_shm_file_num + 1) * MEM_CLASS_NUM * sizeof(uint32_t), MYF(MY_WME)); +void ctc_stats::print_shm_usage(std::string &ctc_srv_monitor_str) +{ + uint32_t *ctc_shm_usage = + (uint32_t *)my_malloc(PSI_NOT_INSTRUMENTED, (g_shm_file_num + 1) * MEM_CLASS_NUM * sizeof(uint32_t), MYF(MY_WME)); if (ctc_get_shm_usage(ctc_shm_usage) != CT_SUCCESS) { my_free(ctc_shm_usage); return; } - ctc_srv_monitor_str += "\n=====================================SHARE MEMORY USAGE STATISTICS=====================================\n"; - ctc_srv_monitor_str += "SIZE:\t" ; + ctc_srv_monitor_str += + "\n=====================================SHARE MEMORY USAGE STATISTICS=====================================\n"; + ctc_srv_monitor_str += "SIZE:\t"; for (uint32_t j = 0; j < MEM_CLASS_NUM; j++) { - ctc_srv_monitor_str += std::to_string(g_mem_class_cfg[j].size) + "\t" ; + ctc_srv_monitor_str += std::to_string(g_mem_class_cfg[j].size) + "\t"; } ctc_srv_monitor_str += "\nNUM:\t"; for (uint32_t j = 0; j < MEM_CLASS_NUM; j++) { - ctc_srv_monitor_str += std::to_string(g_mem_class_cfg[j].num) + "\t" ; + ctc_srv_monitor_str += std::to_string(g_mem_class_cfg[j].num) + "\t"; } - ctc_srv_monitor_str += "\n------------------------------------------------------------------------------------------------------\n"; + ctc_srv_monitor_str += + "\n------------------------------------------------------------------------------------------------------\n"; int idx = 0; for (uint32_t i = 0; i < g_shm_file_num + 1; i++) { - ctc_srv_monitor_str += "FILE" + std::to_string(i) + ":\t" ; + ctc_srv_monitor_str += "FILE" + std::to_string(i) + ":\t"; for (uint32_t j = 0; j < MEM_CLASS_NUM; j++) { - ctc_srv_monitor_str += std::to_string(ctc_shm_usage[idx++]) + "\t" ; // ctc_shm_usage[idx++] / g_mem_class_cfg[j].num + ctc_srv_monitor_str += + std::to_string(ctc_shm_usage[idx++]) + "\t"; // ctc_shm_usage[idx++] / g_mem_class_cfg[j].num } ctc_srv_monitor_str += "\n"; } @@ -209,7 +194,8 @@ void ctc_stats::print_shm_usage(std::string &ctc_srv_monitor_str) { } #endif -void ctc_stats::print_stats(THD *thd, stat_print_fn *stat_print) { +void ctc_stats::print_stats(THD *thd, stat_print_fn *stat_print) +{ char *ctc_srv_monitor; std::string ctc_srv_monitor_str = ""; @@ -219,8 +205,8 @@ void ctc_stats::print_stats(THD *thd, stat_print_fn *stat_print) { #ifndef WITH_CANTIAN print_shm_usage(ctc_srv_monitor_str); #endif - + ctc_srv_monitor = &ctc_srv_monitor_str[0]; - stat_print(thd, "ctc", static_cast(strlen("ctc")), STRING_WITH_LEN(""), - ctc_srv_monitor, (uint)ctc_srv_monitor_str.length()); + stat_print(thd, "ctc", static_cast(strlen("ctc")), STRING_WITH_LEN(""), ctc_srv_monitor, + (uint)ctc_srv_monitor_str.length()); } \ No newline at end of file diff --git a/storage/ctc/ctc_util.cc b/storage/ctc/ctc_util.cc index f082185..cbff136 100644 --- a/storage/ctc/ctc_util.cc +++ b/storage/ctc/ctc_util.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -15,28 +15,29 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "ctc_srv.h" #include "ctc_util.h" #include "ctc_log.h" #include "ctc_proxy_util.h" +#include "ctc_srv.h" -#include "sql/sql_class.h" -#include "sql/sql_lex.h" -#include "sql/tztime.h" +#include "ctc_error.h" +#include "decimal_convert.h" +#include "ha_ctc.h" +#include "ha_ctc_ddl.h" #include "m_ctype.h" #include "my_sys.h" #include "sql/mysqld.h" +#include "sql/sql_class.h" +#include "sql/sql_lex.h" #include "sql/strfunc.h" -#include "ha_ctc.h" -#include "ctc_error.h" -#include "decimal_convert.h" +#include "sql/tztime.h" #include "sql_string.h" -#include "ha_ctc_ddl.h" using namespace std; extern bool ctc_enable_x_lock_instance; -string cnvrt_name_for_sql(string name) { +string cnvrt_name_for_sql(string name) +{ string res = ""; for (size_t i = 0; i < name.length(); i++) { switch (name[i]) { @@ -45,7 +46,7 @@ string cnvrt_name_for_sql(string name) { default: res += name[i]; } -} + } return res; } @@ -53,28 +54,29 @@ void ctc_print_cantian_err_msg(const ddl_ctrl_t *ddl_ctrl, ct_errno_t ret) { switch (ret) { case ERR_DUPLICATE_ENTRY: - my_printf_error(ER_DUP_ENTRY, "%s", MYF(0), ddl_ctrl->error_msg); - break; + my_printf_error(ER_DUP_ENTRY, "%s", MYF(0), ddl_ctrl->error_msg); + break; case ERR_COL_TYPE_MISMATCH: - my_printf_error(ER_FK_INCOMPATIBLE_COLUMNS, "%s", MYF(0), ddl_ctrl->error_msg); - break; + my_printf_error(ER_FK_INCOMPATIBLE_COLUMNS, "%s", MYF(0), ddl_ctrl->error_msg); + break; default: - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), ddl_ctrl->error_msg); - break; + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), ddl_ctrl->error_msg); + break; } } -static uint32_t ctc_convert_identifier_to_sysname(char *to, const char *from, size_t to_len) { +static uint32_t ctc_convert_identifier_to_sysname(char *to, const char *from, size_t to_len) +{ uint32_t errors_ignored; CHARSET_INFO *cs_from = &my_charset_filename; CHARSET_INFO *cs_to = system_charset_info; - return (static_cast( - strconvert(cs_from, from, cs_to, to, to_len, &errors_ignored))); + return (static_cast(strconvert(cs_from, from, cs_to, to, to_len, &errors_ignored))); } -void ctc_split_normalized_name(const char *file_name, char db[], size_t db_buf_len, - char name[], size_t name_buf_len, bool *is_tmp_table) { +void ctc_split_normalized_name(const char *file_name, char db[], size_t db_buf_len, char name[], size_t name_buf_len, + bool *is_tmp_table) +{ size_t dir_length, prefix_length; string path(file_name); const char *buf = path.c_str(); @@ -100,49 +102,52 @@ void ctc_split_normalized_name(const char *file_name, char db[], size_t db_buf_l db[db_buf_len - 1] = '\0'; } else if (dir_length > 1) { /* Get database */ - path.replace(path.begin() + dir_length - 1, path.begin() + dir_length, 1, 0); // Remove end '/' + path.replace(path.begin() + dir_length - 1, path.begin() + dir_length, 1, 0); // Remove end '/' prefix_length = dirname_length(buf); (void)ctc_convert_identifier_to_sysname(db, buf + prefix_length, db_buf_len - 1); db[db_buf_len - 1] = '\0'; } } - -void ctc_copy_name(char to_name[], const char from_name[], size_t to_buf_len) { +void ctc_copy_name(char to_name[], const char from_name[], size_t to_buf_len) +{ if (to_name != from_name) { (void)strncpy(to_name, from_name, to_buf_len - 1); to_name[to_buf_len - 1] = '\0'; } } -bool ctc_check_ddl_sql_length(const string &query_str) { +bool ctc_check_ddl_sql_length(const string &query_str) +{ if (query_str.length() > MAX_DDL_SQL_LEN_CONTEXT) { - string err_msg = - "`" + query_str.substr(0, 100) + "...` Is Large Than " + to_string(MAX_DDL_SQL_LEN_CONTEXT); + string err_msg = "`" + query_str.substr(0, 100) + "...` Is Large Than " + to_string(MAX_DDL_SQL_LEN_CONTEXT); my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), err_msg.c_str()); return true; } return false; } -string sql_without_plaintext_password(ctc_ddl_broadcast_request* broadcast_req) { +string sql_without_plaintext_password(ctc_ddl_broadcast_request *broadcast_req) +{ if (broadcast_req->options & CTC_CURRENT_SQL_CONTAIN_PLAINTEXT_PASSWORD) { return "(contains plaintext password), sql_command = " + to_string(broadcast_req->sql_command); } return (string)broadcast_req->sql_str; } -int16_t ctc_get_column_by_field(Field **field, const char *col_name) { +int16_t ctc_get_column_by_field(Field **field, const char *col_name) +{ int16_t col_id; for (col_id = 0; *field != nullptr; field++, col_id++) { if (my_strcasecmp(system_charset_info, (*field)->field_name, col_name) == 0) { - return col_id; + return col_id; } } return INVALID_MAX_COLUMN; } -int ctc_set_cond_field_size(const field_cnvrt_aux_t *mysql_info, ctc_conds *cond) { +int ctc_set_cond_field_size(const field_cnvrt_aux_t *mysql_info, ctc_conds *cond) +{ switch (mysql_info->cantian_map_type) { case CANTIAN_COL_BITS_4: cond->field_info.field_size = 4; @@ -150,7 +155,7 @@ int ctc_set_cond_field_size(const field_cnvrt_aux_t *mysql_info, ctc_conds *cond case CANTIAN_COL_BITS_8: cond->field_info.field_size = 8; break; - case CANTIAN_COL_BITS_VAR:{ + case CANTIAN_COL_BITS_VAR: { if (mysql_info->sql_data_type == STRING_DATA || mysql_info->sql_data_type == NUMERIC_DATA) { return CT_SUCCESS; } @@ -164,7 +169,8 @@ int ctc_set_cond_field_size(const field_cnvrt_aux_t *mysql_info, ctc_conds *cond } int ctc_fill_cond_field_data_num(ctc_handler_t m_tch, Item *items, Field *mysql_field, - const field_cnvrt_aux_t *mysql_info, ctc_conds *cond) { + const field_cnvrt_aux_t *mysql_info, ctc_conds *cond) +{ int ret = CT_SUCCESS; void *data = nullptr; bool is_alloc_data = CT_FALSE; @@ -245,7 +251,8 @@ int ctc_fill_cond_field_data_num(ctc_handler_t m_tch, Item *items, Field *mysql_ return ret; } -void refill_cond_type_date(MYSQL_TIME ltime, ctc_conds *cond) { +void refill_cond_type_date(MYSQL_TIME ltime, ctc_conds *cond) +{ if (!ltime.hour || !ltime.minute || !ltime.second || !ltime.second_part) { switch (cond->func_type) { case CTC_LT_FUNC: @@ -260,8 +267,9 @@ void refill_cond_type_date(MYSQL_TIME ltime, ctc_conds *cond) { } } -int ctc_fill_cond_field_data_date(ctc_handler_t m_tch, const field_cnvrt_aux_t *mysql_info, - MYSQL_TIME ltime, date_detail_t *date_detail, ctc_conds *cond) { +int ctc_fill_cond_field_data_date(ctc_handler_t m_tch, const field_cnvrt_aux_t *mysql_info, MYSQL_TIME ltime, + date_detail_t *date_detail, ctc_conds *cond) +{ int ret = CT_SUCCESS; cond->field_info.field_value = ctc_alloc_buf(&m_tch, cond->field_info.field_size); @@ -316,10 +324,10 @@ int ctc_fill_cond_field_data_date(ctc_handler_t m_tch, const field_cnvrt_aux_t * cm_encode_date(date_detail, (date_t *)cond->field_info.field_value); return ret; } - } -void update_value_by_charset(char *data, uint16 *size, uint16 bytes) { +void update_value_by_charset(char *data, uint16 *size, uint16 bytes) +{ if (bytes == 0) { return; } @@ -333,7 +341,8 @@ void update_value_by_charset(char *data, uint16 *size, uint16 bytes) { *size = cur; } -int ctc_get_column_cs(const CHARSET_INFO *cs) { +int ctc_get_column_cs(const CHARSET_INFO *cs) +{ auto it = mysql_collate_num_to_ctc_type.find(cs->number); if (it != mysql_collate_num_to_ctc_type.end()) { return (int32_t)it->second; @@ -341,8 +350,8 @@ int ctc_get_column_cs(const CHARSET_INFO *cs) { return cs->number; } -int ctc_fill_cond_field_data_string(ctc_handler_t m_tch, Item_func *item_func, - ctc_conds *cond, bool no_backslash) { +int ctc_fill_cond_field_data_string(ctc_handler_t m_tch, Item_func *item_func, ctc_conds *cond, bool no_backslash) +{ if ((item_func->arguments()[1])->type() == Item::NULL_ITEM) { cond->field_info.null_value = true; return CT_SUCCESS; @@ -364,16 +373,17 @@ int ctc_fill_cond_field_data_string(ctc_handler_t m_tch, Item_func *item_func, ctc_log_error("ctc_fill_cond_field: alloc field_data error, size(%u).", cond->field_info.field_size); return CT_ERROR; } - memset(cond->field_info.field_value, 0, cond->field_info.field_size); + memset(cond->field_info.field_value, 0, cond->field_info.field_size); memcpy(cond->field_info.field_value, data, cond->field_info.field_size); - if(cond->func_type == CTC_LIKE_FUNC) { + if (cond->func_type == CTC_LIKE_FUNC) { update_value_by_charset((char *)cond->field_info.field_value, &cond->field_info.field_size, cslen - 1); } return CT_SUCCESS; } -int ctc_fill_cond_field_data(ctc_handler_t m_tch, Item *items, Field *mysql_field, - const field_cnvrt_aux_t *mysql_info, ctc_conds *cond) { +int ctc_fill_cond_field_data(ctc_handler_t m_tch, Item *items, Field *mysql_field, const field_cnvrt_aux_t *mysql_info, + ctc_conds *cond) +{ int ret = CT_SUCCESS; Item_func *item_func = dynamic_cast(items); CTC_RET_ERR_IF_NULL(item_func); @@ -394,7 +404,7 @@ int ctc_fill_cond_field_data(ctc_handler_t m_tch, Item *items, Field *mysql_fiel case NUMERIC_DATA: ret = ctc_fill_cond_field_data_num(m_tch, items, mysql_field, mysql_info, cond); break; - case DATETIME_DATA:{ + case DATETIME_DATA: { MYSQL_TIME ltime; date_detail_t date_detail; memset(&date_detail, 0, sizeof(date_detail_t)); @@ -423,7 +433,7 @@ int ctc_fill_cond_field_data(ctc_handler_t m_tch, Item *items, Field *mysql_fiel ret = ctc_fill_cond_field_data_date(m_tch, mysql_info, ltime, &date_detail, cond); break; } - case STRING_DATA:{ + case STRING_DATA: { ret = ctc_fill_cond_field_data_string(m_tch, item_func, cond, false); break; } @@ -436,7 +446,8 @@ int ctc_fill_cond_field_data(ctc_handler_t m_tch, Item *items, Field *mysql_fiel return ret; } -int ctc_fill_cond_field(ctc_handler_t m_tch, Item *items, Field **field, ctc_conds *cond, bool no_backslash) { +int ctc_fill_cond_field(ctc_handler_t m_tch, Item *items, Field **field, ctc_conds *cond, bool no_backslash) +{ Item_func *item_func = dynamic_cast(items); CTC_RET_ERR_IF_NULL(item_func); const char *field_name = item_func->arguments()[0]->item_name.ptr(); @@ -460,7 +471,7 @@ int ctc_fill_cond_field(ctc_handler_t m_tch, Item *items, Field **field, ctc_con cond->field_info.field_no -= gcol_cnt; if (cond->func_type == CTC_ISNULL_FUNC || cond->func_type == CTC_ISNOTNULL_FUNC) { return CT_SUCCESS; - } else if(cond->func_type == CTC_LIKE_FUNC) { + } else if (cond->func_type == CTC_LIKE_FUNC) { return ctc_fill_cond_field_data_string(m_tch, item_func, cond, no_backslash); } @@ -471,8 +482,8 @@ int ctc_fill_cond_field(ctc_handler_t m_tch, Item *items, Field **field, ctc_con return ctc_fill_cond_field_data(m_tch, items, mysql_field, mysql_info, cond); } -int ctc_push_cond_list(ctc_handler_t m_tch, Item *items, Field **field, - ctc_cond_list *list, bool no_backslash) { +int ctc_push_cond_list(ctc_handler_t m_tch, Item *items, Field **field, ctc_cond_list *list, bool no_backslash) +{ Item_cond *item_cond = dynamic_cast(items); CTC_RET_ERR_IF_NULL(item_cond); List *argument_list = item_cond->argument_list(); @@ -502,8 +513,8 @@ int ctc_push_cond_list(ctc_handler_t m_tch, Item *items, Field **field, return CT_SUCCESS; } -int ctc_push_cond_args(ctc_handler_t m_tch, Item *items, Field **field, - ctc_cond_list *list, bool no_backslash) { +int ctc_push_cond_args(ctc_handler_t m_tch, Item *items, Field **field, ctc_cond_list *list, bool no_backslash) +{ Item_func *item_func = dynamic_cast(items); CTC_RET_ERR_IF_NULL(item_func); Item **args = item_func->arguments(); @@ -529,7 +540,8 @@ int ctc_push_cond_args(ctc_handler_t m_tch, Item *items, Field **field, return CT_SUCCESS; } -ctc_func_type_t item_func_to_ctc_func(Item_func::Functype fc) { +ctc_func_type_t item_func_to_ctc_func(Item_func::Functype fc) +{ switch (fc) { case (Item_func::Functype::EQUAL_FUNC): return CTC_EQUAL_FUNC; @@ -564,7 +576,8 @@ ctc_func_type_t item_func_to_ctc_func(Item_func::Functype fc) { } } -int dfs_fill_conds(ctc_handler_t m_tch, Item *items, Field **field, ctc_conds *conds, bool no_backslash) { +int dfs_fill_conds(ctc_handler_t m_tch, Item *items, Field **field, ctc_conds *conds, bool no_backslash) +{ Item_func *item_func = dynamic_cast(items); CTC_RET_ERR_IF_NULL(item_func); Item_func::Functype fc = item_func->functype(); @@ -616,9 +629,9 @@ int dfs_fill_conds(ctc_handler_t m_tch, Item *items, Field **field, ctc_conds *c void cm_assert(bool condition) { - if (!condition) { - *((uint32 *)NULL) = 1; - } + if (!condition) { + *((uint32 *)NULL) = 1; + } } /* @@ -632,7 +645,8 @@ void cm_assert(bool condition) 3.普通字符 追加即可 */ -string ctc_deserilize_get_text(string &name) { +string ctc_deserilize_get_text(string &name) +{ THD *thd = current_thd; string res(""); int len = name.size(); @@ -686,7 +700,8 @@ string ctc_deserilize_get_text(string &name) { return res; } -string ctc_escape_single_quotation_str(string &src) { +string ctc_escape_single_quotation_str(string &src) +{ string res = ""; for (size_t i = 0; i < src.length(); i++) { switch (src[i]) { @@ -699,7 +714,8 @@ string ctc_escape_single_quotation_str(string &src) { return res; } -string ctc_deserilize_username_with_single_quotation(string &src) { +string ctc_deserilize_username_with_single_quotation(string &src) +{ string deserilize = ctc_deserilize_get_text(src); return ctc_escape_single_quotation_str(deserilize); } @@ -710,7 +726,8 @@ string ctc_deserilize_username_with_single_quotation(string &src) { - true: there is ddl in progress - false: no ddl is in progress */ -static bool ctc_is_ddl_processing() { +static bool ctc_is_ddl_processing() +{ uint32_t name_locks = get_g_name_locks(); if (name_locks > 0) { ctc_log_system("[CTC_LOCK_INSTANCE]: contains %u global name locks, there is DDL in progress.", name_locks); @@ -719,23 +736,26 @@ static bool ctc_is_ddl_processing() { return false; } -int ctc_check_lock_instance(MYSQL_THD thd, bool &need_forward) { +int ctc_check_lock_instance(MYSQL_THD thd, bool &need_forward) +{ if (thd->mdl_context.has_locks(MDL_key::BACKUP_LOCK)) { need_forward = false; return 0; } if (ctc_is_ddl_processing()) { - my_printf_error(ER_DISALLOWED_OPERATION, "Please try lock instance for backup later, DDL is in processing.", MYF(0)); + my_printf_error(ER_DISALLOWED_OPERATION, "Please try lock instance for backup later, DDL is in processing.", + MYF(0)); return -1; } if (acquire_exclusive_backup_lock(thd, 0, false)) { - my_printf_error(ER_DISALLOWED_OPERATION, "Please try lock instance for backup later, DDL is in processing.", MYF(0)); + my_printf_error(ER_DISALLOWED_OPERATION, "Please try lock instance for backup later, DDL is in processing.", + MYF(0)); ctc_log_error("[CTC_LOCK_INSTANCE]: Not allowed to lock instance, DDL is in processing"); return -1; } - + ctc_lock_table_mode_t lock_mode; bool is_mysqld_starting = is_starting(); if (ctc_enable_x_lock_instance || is_mysqld_starting) { @@ -743,7 +763,7 @@ int ctc_check_lock_instance(MYSQL_THD thd, bool &need_forward) { } else { lock_mode = CTC_LOCK_MODE_SHARE; } - + ctc_handler_t tch; handlerton *ctc_hton = get_ctc_hton(); if (get_tch_in_handler_data(ctc_hton, thd, tch)) { @@ -756,12 +776,13 @@ int ctc_check_lock_instance(MYSQL_THD thd, bool &need_forward) { update_sess_ctx_by_tch(tch, ctc_hton, thd); assert(ret == 0); - ctc_log_system("[CTC_LOCK_INSTANCE]: SUCCESS. ctc_inst:%u, conn_id:%u, lock_mode:%s", - tch.inst_id, tch.thd_id, lock_mode == CTC_LOCK_MODE_EXCLUSIVE ? "X_LATCH" : "S_LATCH"); + ctc_log_system("[CTC_LOCK_INSTANCE]: SUCCESS. ctc_inst:%u, conn_id:%u, lock_mode:%s", tch.inst_id, tch.thd_id, + lock_mode == CTC_LOCK_MODE_EXCLUSIVE ? "X_LATCH" : "S_LATCH"); return ret; } -int ctc_check_unlock_instance(MYSQL_THD thd) { +int ctc_check_unlock_instance(MYSQL_THD thd) +{ if (!thd->mdl_context.has_locks(MDL_key::BACKUP_LOCK)) { return 0; } @@ -782,11 +803,11 @@ static inline bool is_temporary_table_being_opened(const TABLE_LIST *table) #endif { return table->open_type == OT_TEMPORARY_ONLY || - (table->open_type == OT_TEMPORARY_OR_BASE && - is_temporary_table(table)); + (table->open_type == OT_TEMPORARY_OR_BASE && is_temporary_table(table)); } -int ctc_lock_table_pre(MYSQL_THD thd, vector& ticket_list, enum_mdl_type mdl_type) { +int ctc_lock_table_pre(MYSQL_THD thd, vector &ticket_list, enum_mdl_type mdl_type) +{ #ifdef FEATURE_X_FOR_MYSQL_32 Table_ref *tables_start = thd->lex->query_tables; Table_ref *tables_end = thd->lex->first_not_own_table(); @@ -796,14 +817,12 @@ int ctc_lock_table_pre(MYSQL_THD thd, vector& ticket_list, enum_mdl TABLE_LIST *tables_end = thd->lex->first_not_own_table(); TABLE_LIST *table; #endif - for (table = tables_start; table && table != tables_end; - table = table->next_global) { + for (table = tables_start; table && table != tables_end; table = table->next_global) { if (is_temporary_table_being_opened(table)) { continue; } MDL_request req; - MDL_REQUEST_INIT(&req, MDL_key::TABLE, table->db, table->table_name, - mdl_type, MDL_EXPLICIT); + MDL_REQUEST_INIT(&req, MDL_key::TABLE, table->db, table->table_name, mdl_type, MDL_EXPLICIT); if (thd->mdl_context.acquire_lock(&req, 1)) { return 1; } @@ -812,7 +831,8 @@ int ctc_lock_table_pre(MYSQL_THD thd, vector& ticket_list, enum_mdl return 0; } -void ctc_lock_table_post(MYSQL_THD thd, vector& ticket_list) { +void ctc_lock_table_post(MYSQL_THD thd, vector &ticket_list) +{ for (auto it = ticket_list.begin(); it != ticket_list.end(); ++it) { thd->mdl_context.release_lock(*it); } diff --git a/storage/ctc/datatype_cnvrt_4_index_search.cc b/storage/ctc/datatype_cnvrt_4_index_search.cc index 9fc1492..8a61f41 100644 --- a/storage/ctc/datatype_cnvrt_4_index_search.cc +++ b/storage/ctc/datatype_cnvrt_4_index_search.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -14,16 +14,18 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "datatype_cnvrt_4_index_search.h" +#include "ctc_error.h" +#include "ctc_log.h" #include "sql/field.h" #include "typelib.h" -#include "ctc_log.h" -#include "ctc_error.h" -#include "datatype_cnvrt_4_index_search.h" constexpr uint8 OFFSET_VARCHAR_TYPE = 2; -static void ctc_convert_mysql_key_to_cantian(KEY_PART_INFO &key_part, const uint8_t *key, uint16_t key_len, uint32_t *data_field_len, - uint8_t **use_key, uint32_t *use_key_len, bool *is_key_null) { +static void ctc_convert_mysql_key_to_cantian(KEY_PART_INFO &key_part, const uint8_t *key, uint16_t key_len, + uint32_t *data_field_len, uint8_t **use_key, uint32_t *use_key_len, + bool *is_key_null) +{ if (key_len == 0) { return; } @@ -38,8 +40,7 @@ static void ctc_convert_mysql_key_to_cantian(KEY_PART_INFO &key_part, const uint uint32_t data_len = field->key_length(); if (field->type() == MYSQL_TYPE_VARCHAR) { *data_field_len = offset + data_len + OFFSET_VARCHAR_TYPE; - } else if (field->is_flag_set(BLOB_FLAG) && - field->part_of_prefixkey.to_ulonglong() && + } else if (field->is_flag_set(BLOB_FLAG) && field->part_of_prefixkey.to_ulonglong() && !field->part_of_key_not_extended.to_ulonglong()) { *data_field_len = key_part.store_length; check_blob = true; @@ -58,12 +59,12 @@ static void ctc_convert_mysql_key_to_cantian(KEY_PART_INFO &key_part, const uint *use_key = const_cast(key + offset + OFFSET_VARCHAR_TYPE); *use_key_len = *(uint16_t *)const_cast(key + offset); } else if (field->real_type() == MYSQL_TYPE_STRING) { - // strip the pad_char - *use_key = const_cast(key + offset); - while (data_len > 0 && key[data_len + offset - 1] == field->charset()->pad_char) { - data_len--; - } - *use_key_len = data_len; + // strip the pad_char + *use_key = const_cast(key + offset); + while (data_len > 0 && key[data_len + offset - 1] == field->charset()->pad_char) { + data_len--; + } + *use_key_len = data_len; } else { *use_key = const_cast(key + offset); *use_key_len = data_len; @@ -72,16 +73,18 @@ static void ctc_convert_mysql_key_to_cantian(KEY_PART_INFO &key_part, const uint return; } -static void ctc_index_make_up_key_length(int *key, uint8_t **origin_key, uint32_t *origin_key_len, uint32_t length) { +static void ctc_index_make_up_key_length(int *key, uint8_t **origin_key, uint32_t *origin_key_len, uint32_t length) +{ int tmp_key = 0; uint8_t *tmp_key_ptr = (uint8_t *)&tmp_key; memcpy(tmp_key_ptr, *origin_key, *origin_key_len); // 通过符号位补齐高位字段 - if ((*origin_key_len == 1 && (tmp_key & 0x80)) || // 1表示MYSQL_TYPE_TINY类型,0x80用于获取origin_key的符号位 - (*origin_key_len == 2 && (tmp_key & 0x8000)) || // 2表示MYSQL_TYPE_SHORT类型,0x8000用于获取origin_key的符号位 - (*origin_key_len == 3 && (tmp_key & 0x800000))) { // 3表示MMYSQL_TYPE_INT24类型,0x800000用于获取origin_key的符号位 - *key = 0xFFFFFFFF; // 将key的bit位全赋值为1 + if ((*origin_key_len == 1 && (tmp_key & 0x80)) || // 1表示MYSQL_TYPE_TINY类型,0x80用于获取origin_key的符号位 + (*origin_key_len == 2 && (tmp_key & 0x8000)) || // 2表示MYSQL_TYPE_SHORT类型,0x8000用于获取origin_key的符号位 + (*origin_key_len == 3 && + (tmp_key & 0x800000))) { // 3表示MMYSQL_TYPE_INT24类型,0x800000用于获取origin_key的符号位 + *key = 0xFFFFFFFF; // 将key的bit位全赋值为1 } else { *key = 0; } @@ -94,7 +97,8 @@ static void ctc_index_make_up_key_length(int *key, uint8_t **origin_key, uint32_ } int ctc_fill_index_key_info(TABLE *table, const uchar *key, uint key_len, const key_range *end_range, - index_key_info_t *index_key_info, bool index_skip_scan) { + index_key_info_t *index_key_info, bool index_skip_scan) +{ const uchar *my_key = nullptr; const uchar *end_key = key + key_len; if (end_range != nullptr) { @@ -192,23 +196,28 @@ int ctc_convert_key_from_mysql_to_cantian(Field *field, uint8_t **mysql_ptr, dec return ret; } -int ctc_convert_index_datatype(TABLE *table, index_key_info_t *index_key_info, bool has_right_key, dec4_t *data) { +int ctc_convert_index_datatype(TABLE *table, index_key_info_t *index_key_info, bool has_right_key, dec4_t *data) +{ int ret; for (int i = 0; i < index_key_info->key_num; ++i) { Field *field = table->key_info[index_key_info->active_index].key_part[i].field; if (index_key_info->key_info[i].left_key_len != 0) { - ret = ctc_convert_key_from_mysql_to_cantian(field, &index_key_info->key_info[i].left_key, data++, &index_key_info->key_info[i].left_key_len); + ret = ctc_convert_key_from_mysql_to_cantian(field, &index_key_info->key_info[i].left_key, data++, + &index_key_info->key_info[i].left_key_len); if (ret != CT_SUCCESS) { - ctc_log_error("ctc_convert_key_from_mysql_to_cantian: convert mysql index search left key failed, ret(%d).", ret); + ctc_log_error("ctc_convert_key_from_mysql_to_cantian: convert mysql index search left key failed, ret(%d).", + ret); return ret; } } if (has_right_key && index_key_info->key_info[i].right_key_len != 0) { - ret = ctc_convert_key_from_mysql_to_cantian(field, &index_key_info->key_info[i].right_key, data++, &index_key_info->key_info[i].right_key_len); + ret = ctc_convert_key_from_mysql_to_cantian(field, &index_key_info->key_info[i].right_key, data++, + &index_key_info->key_info[i].right_key_len); if (ret != CT_SUCCESS) { - ctc_log_error("ctc_convert_key_from_mysql_to_cantian: convert mysql index search right key failed, ret(%d).", ret); + ctc_log_error("ctc_convert_key_from_mysql_to_cantian: convert mysql index search right key failed, ret(%d).", + ret); return ret; } } diff --git a/storage/ctc/datatype_cnvrtr.cc b/storage/ctc/datatype_cnvrtr.cc index da79e3a..c1bcd10 100644 --- a/storage/ctc/datatype_cnvrtr.cc +++ b/storage/ctc/datatype_cnvrtr.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -14,50 +14,48 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "datatype_cnvrtr.h" #include +#include "ctc_error.h" +#include "ctc_log.h" +#include "ctc_srv.h" +#include "decimal_convert.h" #include "field_types.h" +#include "m_string.h" +#include "my_bitmap.h" +#include "myisampack.h" // mi_int2store #include "sql/field.h" #include "sql/sql_class.h" -#include "my_bitmap.h" -#include "datatype_cnvrtr.h" #include "sql/tztime.h" // my_tz_find, my_tz_OFFSET0 -#include "m_string.h" -#include "myisampack.h" // mi_int2store -#include "ctc_error.h" -#include "ctc_log.h" -#include "decimal_convert.h" -#include "ctc_srv.h" #ifdef FEATURE_X_FOR_MYSQL_26 #include "sql/json_dom.h" #elif defined(FEATURE_X_FOR_MYSQL_32) #include "sql-common/json_dom.h" #endif -#define LOWER_LENGTH_BYTES (uint8)0x01 // Bytes that are used to represent the length of variable length data +#define LOWER_LENGTH_BYTES (uint8)0x01 // Bytes that are used to represent the length of variable length data #define UNITS_PER_DAY 86400000000LL -#define SECONDS_PER_HOUR 3600U -#define SECONDS_PER_MIN 60U +#define SECONDS_PER_HOUR 3600U +#define SECONDS_PER_MIN 60U #define CM_BASELINE_DAY ((int32)730120) /* == days_before_year(CM_BASELINE_YEAY) + 1 */ -#define DAYS_1 365 -#define DAYS_4 (DAYS_1 * 4 + 1) +#define DAYS_1 365 +#define DAYS_4 (DAYS_1 * 4 + 1) #define DAYS_100 (DAYS_4 * 25 - 1) #define DAYS_400 (DAYS_100 * 4 + 1) #define IS_LEAP_YEAR(year) (((year) % 4 == 0) && (((year) % 100 != 0) || ((year) % 400 == 0)) ? 1 : 0) -#define SECONDS_PER_DAY 86400U -#define CM_MIN_YEAR 1 -#define CM_MAX_YEAR 9999 +#define SECONDS_PER_DAY 86400U +#define CM_MIN_YEAR 1 +#define CM_MAX_YEAR 9999 /** Check whether the year is valid */ #define CM_IS_VALID_YEAR(year) ((year) >= CM_MIN_YEAR && (year) <= CM_MAX_YEAR) -#define CT_SPRS_COLUMNS (uint32)1024 -#define CM_ALIGN16(size) ((((size)&0x0F) == 0) ? (size) : ((size) + 0x10 - ((size)&0x0F))) +#define CT_SPRS_COLUMNS (uint32)1024 +#define CM_ALIGN16(size) ((((size) & 0x0F) == 0) ? (size) : ((size) + 0x10 - ((size) & 0x0F))) #define OFFSET_OF offsetof #define IS_SPRS_ROW(row) ((row)->column_count == 0) -uint16 g_cantian_month_days[2][12] = { - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; +uint16 g_cantian_month_days[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; #define CM_MONTH_DAYS(year, mon) (g_cantian_month_days[IS_LEAP_YEAR(year)][(mon) - 1]) @@ -69,38 +67,37 @@ uint16 g_cantian_month_days[2][12] = { Tips:if add new val in enum_field_types, should update this array! */ static field_cnvrt_aux_t g_field_cnvrt_aux_array[] = { - {MYSQL_TYPE_DECIMAL, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_DECIMAL }, - {MYSQL_TYPE_TINY, CANTIAN_COL_BITS_4, NUMERIC_DATA, CTC_DDL_TYPE_LONG }, - {MYSQL_TYPE_SHORT, CANTIAN_COL_BITS_4, NUMERIC_DATA, CTC_DDL_TYPE_LONG }, - {MYSQL_TYPE_LONG, CANTIAN_COL_BITS_4, NUMERIC_DATA, CTC_DDL_TYPE_LONG }, - {MYSQL_TYPE_FLOAT, CANTIAN_COL_BITS_8, NUMERIC_DATA, CTC_DDL_TYPE_DOUBLE }, - {MYSQL_TYPE_DOUBLE, CANTIAN_COL_BITS_8, NUMERIC_DATA, CTC_DDL_TYPE_DOUBLE }, - {MYSQL_TYPE_NULL, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_NULL }, - {MYSQL_TYPE_TIMESTAMP, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_TIMESTAMP }, - {MYSQL_TYPE_LONGLONG, CANTIAN_COL_BITS_8, NUMERIC_DATA, CTC_DDL_TYPE_LONGLONG }, - {MYSQL_TYPE_INT24, CANTIAN_COL_BITS_4, NUMERIC_DATA, CTC_DDL_TYPE_LONG }, - {MYSQL_TYPE_DATE, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_DATE }, - {MYSQL_TYPE_TIME, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_TIME }, - {MYSQL_TYPE_DATETIME, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_DATETIME }, - {MYSQL_TYPE_YEAR, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_YEAR }, - {MYSQL_TYPE_NEWDATE, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_NEWDATE }, - {MYSQL_TYPE_VARCHAR, CANTIAN_COL_BITS_VAR, STRING_DATA, CTC_DDL_TYPE_VARCHAR }, - {MYSQL_TYPE_BIT, CANTIAN_COL_BITS_8, NUMERIC_DATA, CTC_DDL_TYPE_LONGLONG }, - {MYSQL_TYPE_TIMESTAMP2, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_TIMESTAMP2 }, - {MYSQL_TYPE_DATETIME2, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_DATETIME2 }, - {MYSQL_TYPE_TIME2, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_TIME2 }, - {MYSQL_TYPE_TYPED_ARRAY, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_TYPED_ARRAY}, - // > MYSQL_TYPE_INVALID - {MYSQL_TYPE_JSON, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_JSON }, - {MYSQL_TYPE_NEWDECIMAL, CANTIAN_COL_BITS_VAR, NUMERIC_DATA, CTC_DDL_TYPE_NEWDECIMAL }, - {MYSQL_TYPE_TINY_BLOB, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_TINY_BLOB }, - {MYSQL_TYPE_MEDIUM_BLOB, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_MEDIUM_BLOB}, - {MYSQL_TYPE_LONG_BLOB, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_LONG_BLOB }, - {MYSQL_TYPE_BLOB, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_BLOB }, - // The following two types not used for datatype convert, Unconfirmed scenarios in which this feature will be used. - {MYSQL_TYPE_VAR_STRING, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_VAR_STRING }, - {MYSQL_TYPE_STRING, CANTIAN_COL_BITS_VAR, STRING_DATA, CTC_DDL_TYPE_STRING } -}; + {MYSQL_TYPE_DECIMAL, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_DECIMAL}, + {MYSQL_TYPE_TINY, CANTIAN_COL_BITS_4, NUMERIC_DATA, CTC_DDL_TYPE_LONG}, + {MYSQL_TYPE_SHORT, CANTIAN_COL_BITS_4, NUMERIC_DATA, CTC_DDL_TYPE_LONG}, + {MYSQL_TYPE_LONG, CANTIAN_COL_BITS_4, NUMERIC_DATA, CTC_DDL_TYPE_LONG}, + {MYSQL_TYPE_FLOAT, CANTIAN_COL_BITS_8, NUMERIC_DATA, CTC_DDL_TYPE_DOUBLE}, + {MYSQL_TYPE_DOUBLE, CANTIAN_COL_BITS_8, NUMERIC_DATA, CTC_DDL_TYPE_DOUBLE}, + {MYSQL_TYPE_NULL, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_NULL}, + {MYSQL_TYPE_TIMESTAMP, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_TIMESTAMP}, + {MYSQL_TYPE_LONGLONG, CANTIAN_COL_BITS_8, NUMERIC_DATA, CTC_DDL_TYPE_LONGLONG}, + {MYSQL_TYPE_INT24, CANTIAN_COL_BITS_4, NUMERIC_DATA, CTC_DDL_TYPE_LONG}, + {MYSQL_TYPE_DATE, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_DATE}, + {MYSQL_TYPE_TIME, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_TIME}, + {MYSQL_TYPE_DATETIME, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_DATETIME}, + {MYSQL_TYPE_YEAR, CANTIAN_COL_BITS_8, DATETIME_DATA, CTC_DDL_TYPE_YEAR}, + {MYSQL_TYPE_NEWDATE, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_NEWDATE}, + {MYSQL_TYPE_VARCHAR, CANTIAN_COL_BITS_VAR, STRING_DATA, CTC_DDL_TYPE_VARCHAR}, + {MYSQL_TYPE_BIT, CANTIAN_COL_BITS_8, NUMERIC_DATA, CTC_DDL_TYPE_LONGLONG}, + {MYSQL_TYPE_TIMESTAMP2, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_TIMESTAMP2}, + {MYSQL_TYPE_DATETIME2, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_DATETIME2}, + {MYSQL_TYPE_TIME2, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_TIME2}, + {MYSQL_TYPE_TYPED_ARRAY, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_TYPED_ARRAY}, + // > MYSQL_TYPE_INVALID + {MYSQL_TYPE_JSON, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_JSON}, + {MYSQL_TYPE_NEWDECIMAL, CANTIAN_COL_BITS_VAR, NUMERIC_DATA, CTC_DDL_TYPE_NEWDECIMAL}, + {MYSQL_TYPE_TINY_BLOB, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_TINY_BLOB}, + {MYSQL_TYPE_MEDIUM_BLOB, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_MEDIUM_BLOB}, + {MYSQL_TYPE_LONG_BLOB, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_LONG_BLOB}, + {MYSQL_TYPE_BLOB, CANTIAN_COL_BITS_VAR, LOB_DATA, CTC_DDL_TYPE_BLOB}, + // The following two types not used for datatype convert, Unconfirmed scenarios in which this feature will be used. + {MYSQL_TYPE_VAR_STRING, CANTIAN_COL_BITS_NULL, UNKNOW_DATA, CTC_DDL_TYPE_VAR_STRING}, + {MYSQL_TYPE_STRING, CANTIAN_COL_BITS_VAR, STRING_DATA, CTC_DDL_TYPE_STRING}}; /** get idx in g_field_cnvrt_aux_array. Tips: when add new val in g_field_cnvrt_aux_array, should also update this func! @@ -115,12 +112,12 @@ int32_t get_idx_for_field_convert(enum_field_types mysql_field_type) } if (mysql_field_type >= MYSQL_TYPE_TINY_BLOB && mysql_field_type <= MYSQL_TYPE_STRING) { return mysql_field_type - MYSQL_TYPE_TINY_BLOB + (MYSQL_TYPE_TYPED_ARRAY - MYSQL_TYPE_DECIMAL + 1) + - (MYSQL_TYPE_NEWDECIMAL - MYSQL_TYPE_JSON + 1) ; + (MYSQL_TYPE_NEWDECIMAL - MYSQL_TYPE_JSON + 1); } return -1; } -const field_cnvrt_aux_t* get_auxiliary_for_field_convert(Field *field, enum_field_types mysql_field_type) +const field_cnvrt_aux_t *get_auxiliary_for_field_convert(Field *field, enum_field_types mysql_field_type) { if (mysql_field_type < MYSQL_TYPE_INVALID) { return &g_field_cnvrt_aux_array[mysql_field_type]; @@ -152,11 +149,10 @@ const field_cnvrt_aux_t* get_auxiliary_for_field_convert(Field *field, enum_fiel if (idx == -1) { return nullptr; } - field_cnvrt_aux_t* ret = &g_field_cnvrt_aux_array[idx]; + field_cnvrt_aux_t *ret = &g_field_cnvrt_aux_array[idx]; if (field->is_flag_set(BLOB_FLAG)) { - if (field->charset() == &my_charset_bin && - field->is_flag_set(BINARY_FLAG)) { + if (field->charset() == &my_charset_bin && field->is_flag_set(BINARY_FLAG)) { ret->ddl_field_type = CTC_DDL_TYPE_BLOB; } else { ret->ddl_field_type = CTC_DDL_TYPE_CLOB; @@ -273,7 +269,7 @@ void cm_decode_date(date_t date, date_detail_t *detail) i = 0; while (days > (int32)day_tab[i]) { days -= (int32)day_tab[i]; - i++; + i++; } detail->mon = (uint8)(detail->mon + i); @@ -414,7 +410,7 @@ void convert_mydec_to_digital(my_decimal *myd, uint8 *digits, int &start, int &p } } point = my_point_loc * DIG_PER_MYDEC; // the first fraction index - end = point + myd->frac - 1; // the last fraction index + end = point + myd->frac - 1; // the last fraction index remove_leading_zero(digits, start, point, end); } @@ -434,7 +430,7 @@ void convert_digital_to_dec4(dec4_t *d4, uint8 *digits, bool sign, int start, in } d4->expn = expn / DIG_PER_DEC4; // record digital to cell of dec4 - int cell_idx = 0, digidx = start; + int cell_idx = 0, digidx = start; // cells[0] if (cell0_num != 0) { d4->cells[cell_idx] = 0; @@ -452,8 +448,8 @@ void convert_digital_to_dec4(dec4_t *d4, uint8 *digits, bool sign, int start, in } else { d4->cells[cell_idx] = restore_digital(digits, digidx, end, DIG_PER_DEC4); } - digidx += DIG_PER_DEC4; - cell_idx++; + digidx += DIG_PER_DEC4; + cell_idx++; } d4->ncells = cell_idx; } @@ -467,7 +463,7 @@ void convert_dec4_to_digital(dec4_t *dec4, uint8 *digits, int &start, int &point // only fraction int i = 0, j = 0; if (dec4->expn >= 0) { - point = (dec4->expn + 1) * DIG_PER_DEC4; // the first fraction index + point = (dec4->expn + 1) * DIG_PER_DEC4; // the first fraction index } else if (dec4->expn < 0) { point = 0; i = -(dec4->expn + 1); @@ -478,7 +474,7 @@ void convert_dec4_to_digital(dec4_t *dec4, uint8 *digits, int &start, int &point i++; j++; } - end = i * DIG_PER_DEC4 - 1; // the last fraction index + end = i * DIG_PER_DEC4 - 1; // the last fraction index remove_leading_zero(digits, start, point, end); } @@ -591,7 +587,7 @@ int decimal_mysql_to_double(const uint8_t *mysql_ptr, uchar *double_ptr, Field * return ret; } -static inline uint32 get_lob_locator_size(void* locator) +static inline uint32 get_lob_locator_size(void *locator) { lob_locator_t *lob = (lob_locator_t *)locator; if (lob->head.is_outline) { @@ -626,9 +622,9 @@ static inline uint32_t get_blob_buffer_size(uint32_t remain_size) because the ctc storage engine is store blob data inline when blob data length less than 4000, otherwise the blob data store outline. */ -int convert_blob_to_cantian(uchar *cantian_ptr, uint32 &cantian_offset, - uchar *blob_str, uint32 remain_size, - ctc_handler_t &tch, uint column_id, uint32_t &field_len) { +int convert_blob_to_cantian(uchar *cantian_ptr, uint32 &cantian_offset, uchar *blob_str, uint32 remain_size, + ctc_handler_t &tch, uint column_id, uint32_t &field_len) +{ uint32_t buffer_size = get_blob_buffer_size(remain_size); assert(buffer_size >= CTC_LOB_LOCATOR_BUF_SIZE); @@ -657,10 +653,10 @@ int convert_blob_to_cantian(uchar *cantian_ptr, uint32 &cantian_offset, // for outline bool force_outline = false; while (remain_size > 0) { - piece_lob.str = (char *) blob_str + offset; + piece_lob.str = (char *)blob_str + offset; piece_lob.len = remain_size > buffer_size ? buffer_size : remain_size; - int ret = ctc_knl_write_lob(&tch, (char *)lob_locator, locator_size, column_id, - (void *)piece_lob.str, (uint32_t)piece_lob.len, force_outline); + int ret = ctc_knl_write_lob(&tch, (char *)lob_locator, locator_size, column_id, (void *)piece_lob.str, + (uint32_t)piece_lob.len, force_outline); if (ret != CT_SUCCESS) { ctc_log_error("[mysql2cantian]ctc_knl_write_lob Failed:%d", ret); my_free(lob_locator); @@ -681,7 +677,7 @@ int convert_blob_to_cantian(uchar *cantian_ptr, uint32 &cantian_offset, cantian_offset += sizeof(uint16_t); // copy data memcpy(&cantian_ptr[cantian_offset], lob_locator, field_len); - + my_free(lob_locator); lob_locator = nullptr; return CT_SUCCESS; @@ -710,7 +706,7 @@ void convert_json_to_mysql(Field *mysql_field) void convert_blob_to_mysql(uchar *cantian_ptr, Field *mysql_field, ctc_handler_t &tch, uint8_t *mysql_ptr) { bitmap_set_bit(mysql_field->table->read_set, mysql_field->field_index()); - lob_locator_t *locator = (lob_locator_t *)(uint8*)cantian_ptr; + lob_locator_t *locator = (lob_locator_t *)(uint8 *)cantian_ptr; uint32_t blob_len = locator->head.size; char *blob_buf = (char *)my_malloc(PSI_NOT_INSTRUMENTED, blob_len * sizeof(char), MYF(MY_WME)); if (blob_len == 0) { @@ -758,7 +754,7 @@ void convert_blob_to_mysql(uchar *cantian_ptr, Field *mysql_field, ctc_handler_t remain_size -= read_size; offset += read_size; } - + if (!read_flag) { my_free(blob_buf); blob_buf = nullptr; @@ -769,8 +765,7 @@ void convert_blob_to_mysql(uchar *cantian_ptr, Field *mysql_field, ctc_handler_t return; } -static inline void row_set_column_bits2(row_head_t *row, uint8_t bits, - uint32_t col_id) +static inline void row_set_column_bits2(row_head_t *row, uint8_t bits, uint32_t col_id) { uint32_t map_id; uint8_t *bitmap = nullptr; @@ -900,7 +895,7 @@ void bit_cnvt_cantian_mysql(const uchar *cantian_ptr, uchar *mysql_ptr, Field *m convert numeric data from mysql to cantian */ int convert_numeric_to_cantian(const field_cnvrt_aux_t *mysql_info, const uchar *mysql_ptr, uchar *cantian_ptr, - Field *mysql_field, uint32_t *length) + Field *mysql_field, uint32_t *length) { int res = 0; switch (mysql_info->mysql_field_type) { @@ -949,7 +944,7 @@ int convert_numeric_to_cantian(const field_cnvrt_aux_t *mysql_info, const uchar @param[out] ltime The variable to convert to. @param mysql_field mysql field class */ -static void decode_mysql_year_type(MYSQL_TIME& ltime, const uchar *mysql_ptr) +static void decode_mysql_year_type(MYSQL_TIME <ime, const uchar *mysql_ptr) { // 1900 is officially defined by MySQL ltime.year = (unsigned int)*mysql_ptr == 0 ? 0 : (unsigned int)*mysql_ptr + 1900; @@ -972,13 +967,13 @@ static void decode_mysql_year_type(MYSQL_TIME& ltime, const uchar *mysql_ptr) @param mysql_ptr The value to convert from, mysql time data ptr. @param mysql_field mysql field class */ -static void decode_mysql_time_type(MYSQL_TIME& ltime, const uchar *mysql_ptr, Field *mysql_field) +static void decode_mysql_time_type(MYSQL_TIME <ime, const uchar *mysql_ptr, Field *mysql_field) { // decode mysql data uint dec = mysql_field->decimals(); longlong tmp = my_time_packed_from_binary(mysql_ptr, dec); TIME_from_longlong_time_packed(<ime, tmp); - + // fill in other fields ltime.year = 1900; ltime.month = 1; @@ -992,7 +987,7 @@ static void decode_mysql_time_type(MYSQL_TIME& ltime, const uchar *mysql_ptr, Fi @param[out] ltime The variable to convert to. @param mysql_ptr The value to convert from, mysql date data ptr. */ -static void decode_mysql_date_type(MYSQL_TIME& ltime, const uchar *mysql_ptr) +static void decode_mysql_date_type(MYSQL_TIME <ime, const uchar *mysql_ptr) { int tmp = *mysql_ptr + (((int)*(mysql_ptr + 1)) << 8) + (((int)*(mysql_ptr + 2)) << 16); ltime.year = tmp / 16 / 32; @@ -1007,7 +1002,7 @@ static void decode_mysql_date_type(MYSQL_TIME& ltime, const uchar *mysql_ptr) @param mysql_ptr The value to convert from, mysql datetime data ptr. @param mysql_field mysql field class */ -static void decode_mysql_datetime_type(MYSQL_TIME& ltime, const uchar *mysql_ptr, Field *mysql_field) +static void decode_mysql_datetime_type(MYSQL_TIME <ime, const uchar *mysql_ptr, Field *mysql_field) { uint dec = mysql_field->decimals(); longlong packed = my_datetime_packed_from_binary(mysql_ptr, dec); @@ -1021,7 +1016,7 @@ static void decode_mysql_datetime_type(MYSQL_TIME& ltime, const uchar *mysql_ptr @param mysql_ptr The value to convert from, mysql timestamp data ptr. @param mysql_field mysql field class */ -static void decode_mysql_timestamp_type(MYSQL_TIME& ltime, const uchar *mysql_ptr, Field *mysql_field) +static void decode_mysql_timestamp_type(MYSQL_TIME <ime, const uchar *mysql_ptr, Field *mysql_field) { uint dec = mysql_field->decimals(); #ifdef FEATURE_X_FOR_MYSQL_32 @@ -1051,8 +1046,8 @@ static void decode_mysql_timestamp_type(MYSQL_TIME& ltime, const uchar *mysql_pt @param mysql_ptr The value to convert from, mysql data ptr. @param mysql_field mysql field class. */ -void decode_mysql_datetime(MYSQL_TIME& ltime, const field_cnvrt_aux_t* mysql_info, - const uchar *mysql_ptr, Field *mysql_field) +void decode_mysql_datetime(MYSQL_TIME <ime, const field_cnvrt_aux_t *mysql_info, const uchar *mysql_ptr, + Field *mysql_field) { switch (mysql_info->mysql_field_type) { case MYSQL_TYPE_YEAR: @@ -1076,7 +1071,7 @@ void decode_mysql_datetime(MYSQL_TIME& ltime, const field_cnvrt_aux_t* mysql_inf } } -bool check_zero_date(const date_detail_t& date_detail) +bool check_zero_date(const date_detail_t &date_detail) { if (!(date_detail.year || date_detail.mon || date_detail.day || date_detail.hour || date_detail.min || date_detail.sec || date_detail.millisec || date_detail.microsec || date_detail.nanosec)) { @@ -1097,7 +1092,7 @@ bool check_zero_time_ltime(const MYSQL_TIME ltime) @brief Before use cm_encode_date interface, check whether the date_detail_t value is correct. */ -bool check_datetime_vaild(const date_detail_t& date_detail) +bool check_datetime_vaild(const date_detail_t &date_detail) { if (check_zero_date(date_detail)) { return true; @@ -1148,40 +1143,40 @@ int assign_mysql_date_detail(enum_field_types mysql_field_type, MYSQL_TIME ltime void cnvrt_time_decimal(const uchar *src_ptr, int src_dec, uchar *des_ptr, int des_dec, uint32 length) { - // convert decimal for MYSQL_TYPE_TIME - MYSQL_TIME ltime; - uchar tmp_ptr[CTC_BYTE_8] = {0}; - longlong packed = my_time_packed_from_binary(src_ptr, src_dec); - TIME_from_longlong_time_packed(<ime, packed); - // fill in other fields - ltime.year = 1900; - ltime.month = 1; - ltime.day = 1; - longlong ll = TIME_to_longlong_time_packed(ltime); - my_time_packed_to_binary(ll, tmp_ptr, des_dec); - memcpy(des_ptr, tmp_ptr, length); - return; + // convert decimal for MYSQL_TYPE_TIME + MYSQL_TIME ltime; + uchar tmp_ptr[CTC_BYTE_8] = {0}; + longlong packed = my_time_packed_from_binary(src_ptr, src_dec); + TIME_from_longlong_time_packed(<ime, packed); + // fill in other fields + ltime.year = 1900; + ltime.month = 1; + ltime.day = 1; + longlong ll = TIME_to_longlong_time_packed(ltime); + my_time_packed_to_binary(ll, tmp_ptr, des_dec); + memcpy(des_ptr, tmp_ptr, length); + return; } void cnvrt_datetime_decimal(const uchar *src_ptr, int src_dec, uchar *des_ptr, int des_dec, uint32 length) { - // convert decimal for MYSQL_TYPE_DATETIME - MYSQL_TIME ltime; - uchar tmp_ptr[CTC_BYTE_8] = {0}; - longlong packed = my_datetime_packed_from_binary(src_ptr, src_dec); - TIME_from_longlong_datetime_packed(<ime, packed); - longlong ll = TIME_to_longlong_datetime_packed(ltime); - my_datetime_packed_to_binary(ll, tmp_ptr, des_dec); - memcpy(des_ptr, tmp_ptr, length); - return; + // convert decimal for MYSQL_TYPE_DATETIME + MYSQL_TIME ltime; + uchar tmp_ptr[CTC_BYTE_8] = {0}; + longlong packed = my_datetime_packed_from_binary(src_ptr, src_dec); + TIME_from_longlong_datetime_packed(<ime, packed); + longlong ll = TIME_to_longlong_datetime_packed(ltime); + my_datetime_packed_to_binary(ll, tmp_ptr, des_dec); + memcpy(des_ptr, tmp_ptr, length); + return; } /** @brief convert datetime data from mysql to cantian */ -int convert_datetime_to_cantian(const field_cnvrt_aux_t* mysql_info, uchar *cantian_ptr, - const uchar *mysql_ptr, Field *mysql_field) +int convert_datetime_to_cantian(const field_cnvrt_aux_t *mysql_info, uchar *cantian_ptr, const uchar *mysql_ptr, + Field *mysql_field) { switch (mysql_info->mysql_field_type) { case MYSQL_TYPE_TIME: @@ -1219,8 +1214,8 @@ int convert_datetime_to_cantian(const field_cnvrt_aux_t* mysql_info, uchar *cant @brief convert numeric data from cantian to mysql */ -static void convert_numeric_to_mysql(const field_cnvrt_aux_t *mysql_info, uchar *mysql_ptr, - uchar *cantian_ptr, Field *mysql_field) +static void convert_numeric_to_mysql(const field_cnvrt_aux_t *mysql_info, uchar *mysql_ptr, uchar *cantian_ptr, + Field *mysql_field) { switch (mysql_info->mysql_field_type) { case MYSQL_TYPE_TINY: @@ -1258,9 +1253,9 @@ static void convert_numeric_to_mysql(const field_cnvrt_aux_t *mysql_info, uchar } } /** - 逻辑拷贝自datetime_with_no_zero_in_date_to_timeval,在mysql 8.0.28及后续版本中改函数第三个参数类型由timeval改为 my_timeval,为了兼容不同版本,这个地方函数由自己实现 - Converts a datetime in MYSQL_TIME representation to corresponding `struct - timeval` value. + 逻辑拷贝自datetime_with_no_zero_in_date_to_timeval,在mysql 8.0.28及后续版本中改函数第三个参数类型由timeval改为 + my_timeval,为了兼容不同版本,这个地方函数由自己实现 Converts a datetime in MYSQL_TIME representation to corresponding + `struct timeval` value. `ltime` must be previously checked for `TIME_NO_ZERO_IN_DATE`. Things like '0000-01-01', '2000-00-01', '2000-01-00' are not allowed @@ -1284,10 +1279,8 @@ static void convert_numeric_to_mysql(const field_cnvrt_aux_t *mysql_info, uchar @return False on success, true on error. */ -bool ctc_datetime_with_no_zero_in_date_to_timeval(const MYSQL_TIME *ltime, - const Time_zone &tz, - struct timeval *tm, - int *warnings) +bool ctc_datetime_with_no_zero_in_date_to_timeval(const MYSQL_TIME *ltime, const Time_zone &tz, struct timeval *tm, + int *warnings) { if (!ltime->month) { /* Zero date */ @@ -1325,8 +1318,9 @@ bool ctc_datetime_with_no_zero_in_date_to_timeval(const MYSQL_TIME *ltime, return false; } /** - 逻辑拷贝自my_timestamp_to_binary,在mysql 8.0.28及后续版本中改函数第一个参数类型由timeval改为 my_timeval,为了兼容不同版本,这个地方函数由自己实现 - Convert in-memory timestamp representation to on-disk representation. + 逻辑拷贝自my_timestamp_to_binary,在mysql 8.0.28及后续版本中改函数第一个参数类型由timeval改为 + my_timeval,为了兼容不同版本,这个地方函数由自己实现 Convert in-memory timestamp representation to on-disk + representation. @param tm The value to convert. @param [out] ptr The pointer to store the value to. @@ -1336,8 +1330,7 @@ static void ctc_my_timestamp_to_binary(const struct timeval *tm, uchar *ptr, uin { assert(dec <= DATETIME_MAX_DECIMALS); /* Stored value must have been previously properly rounded or truncated */ - assert((tm->tv_usec % - static_cast(log_10_int[DATETIME_MAX_DECIMALS - dec])) == 0); + assert((tm->tv_usec % static_cast(log_10_int[DATETIME_MAX_DECIMALS - dec])) == 0); mi_int4store(ptr, tm->tv_sec); switch (dec) { case 0: @@ -1345,8 +1338,7 @@ static void ctc_my_timestamp_to_binary(const struct timeval *tm, uchar *ptr, uin break; case 1: case 2: - ptr[4] = - static_cast(static_cast(tm->tv_usec / 10000)); + ptr[4] = static_cast(static_cast(tm->tv_usec / 10000)); break; case 3: case 4: @@ -1363,19 +1355,21 @@ static void ctc_my_timestamp_to_binary(const struct timeval *tm, uchar *ptr, uin @brief convert datetime data from cantian to mysql */ -static void convert_datetime_to_mysql(ctc_handler_t &tch, const field_cnvrt_aux_t* mysql_info, - uint8_t *mysql_ptr, uchar *cantian_ptr, Field *mysql_field) +static void convert_datetime_to_mysql(ctc_handler_t &tch, const field_cnvrt_aux_t *mysql_info, uint8_t *mysql_ptr, + uchar *cantian_ptr, Field *mysql_field) { if (mysql_info->mysql_field_type == MYSQL_TYPE_DATE) { memcpy(mysql_ptr, cantian_ptr, mysql_field->pack_length()); return; } if (mysql_info->mysql_field_type == MYSQL_TYPE_TIME) { - cnvrt_time_decimal(cantian_ptr, DATETIME_MAX_DECIMALS, mysql_ptr, mysql_field->decimals(), mysql_field->pack_length()); + cnvrt_time_decimal(cantian_ptr, DATETIME_MAX_DECIMALS, mysql_ptr, mysql_field->decimals(), + mysql_field->pack_length()); return; } if (mysql_info->mysql_field_type == MYSQL_TYPE_DATETIME && !tch.read_only_in_ct) { - cnvrt_datetime_decimal(cantian_ptr, DATETIME_MAX_DECIMALS, mysql_ptr, mysql_field->decimals(), mysql_field->pack_length()); + cnvrt_datetime_decimal(cantian_ptr, DATETIME_MAX_DECIMALS, mysql_ptr, mysql_field->decimals(), + mysql_field->pack_length()); return; } date_detail_t date_detail; @@ -1450,8 +1444,8 @@ static void convert_datetime_to_mysql(ctc_handler_t &tch, const field_cnvrt_aux_ @param[out] data_offset space occupied by variable-length data types @return the data length of variable-length data type */ -static uint32_t calculate_variable_len(const field_cnvrt_aux_t* mysql_info, Field *mysql_field, - const uint8_t *mysql_ptr, uint8_t& data_offset) +static uint32_t calculate_variable_len(const field_cnvrt_aux_t *mysql_info, Field *mysql_field, + const uint8_t *mysql_ptr, uint8_t &data_offset) { uint32_t field_len = 0; // check if it's mysql variable len field @@ -1470,7 +1464,7 @@ static uint32_t calculate_variable_len(const field_cnvrt_aux_t* mysql_info, Fiel case MYSQL_TYPE_BLOB: { Field_blob *dst_blob = down_cast(mysql_field); data_offset = dst_blob->row_pack_length(); - field_len = dst_blob->get_length((const uchar*)mysql_ptr); + field_len = dst_blob->get_length((const uchar *)mysql_ptr); break; } case MYSQL_TYPE_STRING: { @@ -1504,15 +1498,15 @@ static uint32_t calculate_variable_len(const field_cnvrt_aux_t* mysql_info, Fiel ctc_log_error("[mysql2cantian calculate length]unknow data type: %d", mysql_info->mysql_field_type); data_offset = 0; break; - } - return field_len; + } + return field_len; } /** @brief Padding Byte Length According the data length, and return mysql ptr offset */ -static uint8_t padding_variable_byte(const field_cnvrt_aux_t* mysql_info, - uint8_t *mysql_ptr, uint32 field_len, Field *field) +static uint8_t padding_variable_byte(const field_cnvrt_aux_t *mysql_info, uint8_t *mysql_ptr, uint32 field_len, + Field *field) { uint8_t mysql_offset = 0; switch (mysql_info->mysql_field_type) { @@ -1541,9 +1535,9 @@ static uint8_t padding_variable_byte(const field_cnvrt_aux_t* mysql_info, return mysql_offset; } -static void get_map_and_field_len(uint32_t &field_len, const field_cnvrt_aux_t* mysql_info, - field_offset_and_len_t *field_offset_info, - Field *field, record_buf_info_t *record_buf) +static void get_map_and_field_len(uint32_t &field_len, const field_cnvrt_aux_t *mysql_info, + field_offset_and_len_t *field_offset_info, Field *field, + record_buf_info_t *record_buf) { switch (mysql_info->cantian_map_type) { case CANTIAN_COL_BITS_4: @@ -1565,11 +1559,8 @@ static void get_map_and_field_len(uint32_t &field_len, const field_cnvrt_aux_t* &record_buf->mysql_record_buf[*field_offset_info->mysql_field_offset], mysql_data_length_bytes); *field_offset_info->mysql_field_offset += mysql_data_length_bytes; - if (!((mysql_info->sql_data_type == STRING_DATA) && - VARCHAR_AS_BLOB(field->row_pack_length()))) { - *(uint16_t *)&record_buf - ->cantian_record_buf[*field_offset_info->cantian_field_offset] = - field_len; + if (!((mysql_info->sql_data_type == STRING_DATA) && VARCHAR_AS_BLOB(field->row_pack_length()))) { + *(uint16_t *)&record_buf->cantian_record_buf[*field_offset_info->cantian_field_offset] = field_len; *field_offset_info->cantian_field_offset += sizeof(uint16_t); } } @@ -1581,17 +1572,17 @@ static void get_map_and_field_len(uint32_t &field_len, const field_cnvrt_aux_t* } } -static int convert_data_from_mysql_to_cantian(const field_cnvrt_aux_t* mysql_info, Field *field, +static int convert_data_from_mysql_to_cantian(const field_cnvrt_aux_t *mysql_info, Field *field, record_buf_info_t *record_buf, uint16_t *serial_column_offset, - field_offset_and_len_t *field_offset_info, - uint32_t &field_len, ctc_handler_t &tch, uint column_id) + field_offset_and_len_t *field_offset_info, uint32_t &field_len, + ctc_handler_t &tch, uint column_id) { int res = 0; switch (mysql_info->sql_data_type) { case NUMERIC_DATA: - res = convert_numeric_to_cantian(mysql_info, &record_buf->mysql_record_buf[*field_offset_info->mysql_field_offset], - &record_buf->cantian_record_buf[*field_offset_info->cantian_field_offset], - field, &field_len); + res = convert_numeric_to_cantian( + mysql_info, &record_buf->mysql_record_buf[*field_offset_info->mysql_field_offset], + &record_buf->cantian_record_buf[*field_offset_info->cantian_field_offset], field, &field_len); // 如果是自增列,记录自增列在cantian_record_buf中的offset if (field->is_flag_set(AUTO_INCREMENT_FLAG)) { *serial_column_offset = *field_offset_info->cantian_field_offset; @@ -1599,7 +1590,7 @@ static int convert_data_from_mysql_to_cantian(const field_cnvrt_aux_t* mysql_inf if (field->type() == MYSQL_TYPE_NEWDECIMAL) { *(uint16_t *)&record_buf->cantian_record_buf[*field_offset_info->cantian_field_offset - sizeof(uint16_t)] = - field_len; + field_len; } break; @@ -1610,27 +1601,20 @@ static int convert_data_from_mysql_to_cantian(const field_cnvrt_aux_t* mysql_inf break; case STRING_DATA: if (!VARCHAR_AS_BLOB(field->row_pack_length())) { - memcpy(&record_buf - ->cantian_record_buf[*field_offset_info->cantian_field_offset], - &record_buf - ->mysql_record_buf[*field_offset_info->mysql_field_offset], - field_len); + memcpy(&record_buf->cantian_record_buf[*field_offset_info->cantian_field_offset], + &record_buf->mysql_record_buf[*field_offset_info->mysql_field_offset], field_len); } else { - res = convert_blob_to_cantian( - record_buf->cantian_record_buf, - *field_offset_info->cantian_field_offset, - &record_buf - ->mysql_record_buf[*field_offset_info->mysql_field_offset], - field_len, tch, column_id, field_len); + res = convert_blob_to_cantian(record_buf->cantian_record_buf, *field_offset_info->cantian_field_offset, + &record_buf->mysql_record_buf[*field_offset_info->mysql_field_offset], field_len, + tch, column_id, field_len); } break; case LOB_DATA: { Field_blob *dst_blob = down_cast(field); uchar *blob_str = dst_blob->get_blob_data(); uint32_t remain_size = dst_blob->get_length(); - res = convert_blob_to_cantian(record_buf->cantian_record_buf, - *field_offset_info->cantian_field_offset, - blob_str, remain_size, tch, column_id, field_len); + res = convert_blob_to_cantian(record_buf->cantian_record_buf, *field_offset_info->cantian_field_offset, blob_str, + remain_size, tch, column_id, field_len); } break; case UNKNOW_DATA: default: @@ -1657,7 +1641,7 @@ int mysql_record_to_cantian_record(const TABLE &table, record_buf_info_t *record virtual_gcol_cnt = 0; uint32 cantian_field_offset = sizeof(row_head_t) + ex_maps; row_head_t *row_head = (row_head_t *)record_buf->cantian_record_buf; - + for (uint column_cnt = 0; column_cnt < n_fields; column_cnt++) { uint column_id = is_update ? fields->at(column_cnt) : column_cnt; Field *field = table.field[column_id]; @@ -1676,27 +1660,27 @@ int mysql_record_to_cantian_record(const TABLE &table, record_buf_info_t *record // mark as not intialized uint8_t map = 0xFF; if (field->is_nullable()) { - uint mysql_null_byte_offset = field->null_offset(); - uint mysql_null_bit_mask = field->null_bit; - /* If the field is null */ - if (record_buf->mysql_record_buf[mysql_null_byte_offset] & mysql_null_bit_mask) { - map = 0; - if (is_update && has_gcol) { - cal_gcol_cnts_for_update(table.field, column_id, &virtual_gcol_cnt); - row_set_column_bits2(row_head, map, column_cnt); - fields->at(column_cnt) -= virtual_gcol_cnt; - } else { - row_set_column_bits2(row_head, map, column_cnt - virtual_gcol_cnt); - } - continue; + uint mysql_null_byte_offset = field->null_offset(); + uint mysql_null_bit_mask = field->null_bit; + /* If the field is null */ + if (record_buf->mysql_record_buf[mysql_null_byte_offset] & mysql_null_bit_mask) { + map = 0; + if (is_update && has_gcol) { + cal_gcol_cnts_for_update(table.field, column_id, &virtual_gcol_cnt); + row_set_column_bits2(row_head, map, column_cnt); + fields->at(column_cnt) -= virtual_gcol_cnt; + } else { + row_set_column_bits2(row_head, map, column_cnt - virtual_gcol_cnt); } + continue; + } } uint32_t field_len = 0; uint mysql_field_offset = field->offset(table.record[0]); // Get map and field_len , according to mysql_field type - const field_cnvrt_aux_t* mysql_info = get_auxiliary_for_field_convert(field, field->type()); + const field_cnvrt_aux_t *mysql_info = get_auxiliary_for_field_convert(field, field->type()); assert(mysql_info != NULL); map = mysql_info->cantian_map_type; field_offset_and_len_t field_offset_info = {nullptr, nullptr, &cantian_field_offset, &mysql_field_offset}; @@ -1717,7 +1701,7 @@ int mysql_record_to_cantian_record(const TABLE &table, record_buf_info_t *record } else { row_set_column_bits2(row_head, map, column_cnt - virtual_gcol_cnt); } - + // Cantian align variable field (including prefix) to 4 bytes if (map == 3) { field_len += sizeof(uint16_t); @@ -1735,8 +1719,8 @@ int mysql_record_to_cantian_record(const TABLE &table, record_buf_info_t *record return 0; } -void copy_column_data_to_mysql(field_info_t *field_info, const field_cnvrt_aux_t* mysql_info, - ctc_handler_t &tch, bool is_index_only) +void copy_column_data_to_mysql(field_info_t *field_info, const field_cnvrt_aux_t *mysql_info, ctc_handler_t &tch, + bool is_index_only) { if (!bitmap_is_set(field_info->field->table->read_set, field_info->field->field_index()) && tch.sql_command == SQLCOM_SELECT) { @@ -1746,12 +1730,12 @@ void copy_column_data_to_mysql(field_info_t *field_info, const field_cnvrt_aux_t uint16_t src_len = 0; switch (mysql_info->sql_data_type) { case NUMERIC_DATA: - convert_numeric_to_mysql( - mysql_info, field_info->mysql_cur_field, field_info->cantian_cur_field, field_info->field); + convert_numeric_to_mysql(mysql_info, field_info->mysql_cur_field, field_info->cantian_cur_field, + field_info->field); break; case DATETIME_DATA: - convert_datetime_to_mysql( - tch, mysql_info, field_info->mysql_cur_field, field_info->cantian_cur_field, field_info->field); + convert_datetime_to_mysql(tch, mysql_info, field_info->mysql_cur_field, field_info->cantian_cur_field, + field_info->field); break; case STRING_DATA: { lob_locator_t *locator = NULL; @@ -1759,8 +1743,7 @@ void copy_column_data_to_mysql(field_info_t *field_info, const field_cnvrt_aux_t src = field_info->cantian_cur_field; src_len = field_info->field_len; } else { - convert_blob_to_mysql(field_info->cantian_cur_field, field_info->field, - tch, field_info->mysql_cur_field); + convert_blob_to_mysql(field_info->cantian_cur_field, field_info->field, tch, field_info->mysql_cur_field); locator = (lob_locator_t *)(uint8 *)field_info->cantian_cur_field; src_len = (uint32)locator->head.size; assert(src_len); @@ -1768,8 +1751,7 @@ void copy_column_data_to_mysql(field_info_t *field_info, const field_cnvrt_aux_t } memcpy(field_info->mysql_cur_field, src, src_len); // Char类型内存优化,mysql行数据尾部填充 - if (mysql_info->mysql_field_type == MYSQL_TYPE_STRING && - field_info->field->real_type() == MYSQL_TYPE_STRING && + if (mysql_info->mysql_field_type == MYSQL_TYPE_STRING && field_info->field->real_type() == MYSQL_TYPE_STRING && field_info->field->row_pack_length() > field_info->field_len) { memset(field_info->mysql_cur_field + field_info->field_len, field_info->field->charset()->pad_char, field_info->field->row_pack_length() - field_info->field_len); @@ -1793,8 +1775,7 @@ void copy_column_data_to_mysql(field_info_t *field_info, const field_cnvrt_aux_t } else { convert_blob_to_mysql(field_info->cantian_cur_field, field_info->field, tch, field_info->mysql_cur_field); } - } - break; + } break; case UNKNOW_DATA: /* fall through */ default: @@ -1804,16 +1785,19 @@ void copy_column_data_to_mysql(field_info_t *field_info, const field_cnvrt_aux_t } } -static inline bool ctc_field_type_is_lob(bool is_index_only, const field_cnvrt_aux_t* cnvrt_aux, Field *field, ctc_handler_t &tch) +static inline bool ctc_field_type_is_lob(bool is_index_only, const field_cnvrt_aux_t *cnvrt_aux, Field *field, + ctc_handler_t &tch) { return !is_index_only && - (cnvrt_aux->mysql_field_type == MYSQL_TYPE_BLOB || cnvrt_aux->mysql_field_type == MYSQL_TYPE_JSON || + (cnvrt_aux->mysql_field_type == MYSQL_TYPE_BLOB || cnvrt_aux->mysql_field_type == MYSQL_TYPE_JSON || ((cnvrt_aux->mysql_field_type == MYSQL_TYPE_VARCHAR) && VARCHAR_AS_BLOB(field->row_pack_length()) && !tch.read_only_in_ct)); } -static bool ctc_update_offset_single(uint col_id, Field *field, uint8 cantian_col_type, const field_cnvrt_aux_t* cnvrt_aux, record_info_t *record_info, - record_buf_info_t *record_buf, field_offset_and_len_t *size, bool is_index_only, ctc_handler_t &tch) +static bool ctc_update_offset_single(uint col_id, Field *field, uint8 cantian_col_type, + const field_cnvrt_aux_t *cnvrt_aux, record_info_t *record_info, + record_buf_info_t *record_buf, field_offset_and_len_t *size, bool is_index_only, + ctc_handler_t &tch) { switch (cantian_col_type) { case CANTIAN_COL_BITS_NULL: @@ -1837,7 +1821,8 @@ static bool ctc_update_offset_single(uint col_id, Field *field, uint8 cantian_co } else { len = (uint32)(*size->field_len); } - *size->mysql_field_offset += padding_variable_byte(cnvrt_aux, &record_buf->mysql_record_buf[*size->mysql_field_offset], len, field); + *size->mysql_field_offset += + padding_variable_byte(cnvrt_aux, &record_buf->mysql_record_buf[*size->mysql_field_offset], len, field); break; } default: @@ -1848,8 +1833,10 @@ static bool ctc_update_offset_single(uint col_id, Field *field, uint8 cantian_co return false; } -static bool ctc_parse_cantian_column_and_update_offset(Field *field, uint8 cantian_col_type, const field_cnvrt_aux_t* cnvrt_aux, - record_buf_info_t *record_buf, field_offset_and_len_t *size, bool is_index_only, ctc_handler_t &tch) +static bool ctc_parse_cantian_column_and_update_offset(Field *field, uint8 cantian_col_type, + const field_cnvrt_aux_t *cnvrt_aux, + record_buf_info_t *record_buf, field_offset_and_len_t *size, + bool is_index_only, ctc_handler_t &tch) { switch (cantian_col_type) { case CANTIAN_COL_BITS_NULL: @@ -1872,7 +1859,7 @@ static bool ctc_parse_cantian_column_and_update_offset(Field *field, uint8 canti // is_index_only && other variable-length types: Two bytes with field_len after row_head and bitmap. if (!field->table->s->tmp_table && is_index_only && cnvrt_aux->mysql_field_type == MYSQL_TYPE_NEWDECIMAL) { uint off = *size->cantian_field_offset; - *size->field_len = cm_dec4_stor_sz((dec4_t *)((char*)record_buf->cantian_record_buf + off)); + *size->field_len = cm_dec4_stor_sz((dec4_t *)((char *)record_buf->cantian_record_buf + off)); *size->aligned_field_len = ROUND_UP(*size->field_len, 4); } else { *size->field_len = *((uint16_t *)&record_buf->cantian_record_buf[*size->cantian_field_offset]); @@ -1882,7 +1869,8 @@ static bool ctc_parse_cantian_column_and_update_offset(Field *field, uint8 canti // if read_only_in_ct is true,it means it is a cantian system table // if cantian system table takes the varchar_as_blob branch,bob_len is an invalid value - // which makes the varchar column gets a huge invalid string exceeding its origin len like 4000 and field->row_pack_length 12000 + // which makes the varchar column gets a huge invalid string exceeding its origin len like 4000 and + // field->row_pack_length 12000 uint32 len = 0; if (ctc_field_type_is_lob(is_index_only, cnvrt_aux, field, tch)) { // when the type is blob,the lob data length is not field_len @@ -1892,7 +1880,8 @@ static bool ctc_parse_cantian_column_and_update_offset(Field *field, uint8 canti } else { len = (uint32)(*size->field_len); } - *size->mysql_field_offset += padding_variable_byte(cnvrt_aux, &record_buf->mysql_record_buf[*size->mysql_field_offset], len, field); + *size->mysql_field_offset += + padding_variable_byte(cnvrt_aux, &record_buf->mysql_record_buf[*size->mysql_field_offset], len, field); break; } default: @@ -1903,36 +1892,37 @@ static bool ctc_parse_cantian_column_and_update_offset(Field *field, uint8 canti return false; } -void convert_cantian_field_to_mysql_field(uint col_id, Field *field, field_offset_and_col_type *filed_offset, record_info_t *record_info, - record_buf_info_t *record_buf, ctc_handler_t &tch, bool is_index_only) -{ - // Get auxiliary info for field convertion - const field_cnvrt_aux_t* cnvrt_aux_info = get_auxiliary_for_field_convert(field, field->type()); - assert(cnvrt_aux_info != NULL); - - uint16_t field_len = 0; - uint16_t aligned_field_len = 0; - field_offset_and_len_t size = {&field_len, &aligned_field_len, filed_offset->cantian_field_offset, - filed_offset->mysql_field_offset}; - bool ret = false; - if (record_info && record_info->lens && is_single_run_mode()) { - ret = ctc_update_offset_single(col_id, field, filed_offset->cantian_col_type, cnvrt_aux_info, record_info, record_buf, - &size, is_index_only, tch); - } else { - ret = ctc_parse_cantian_column_and_update_offset(field, filed_offset->cantian_col_type, cnvrt_aux_info, record_buf, - &size, is_index_only, tch); - } - if (ret) { - // continue to next column if current field is null - return; - } +void convert_cantian_field_to_mysql_field(uint col_id, Field *field, field_offset_and_col_type *filed_offset, + record_info_t *record_info, record_buf_info_t *record_buf, ctc_handler_t &tch, + bool is_index_only) +{ + // Get auxiliary info for field convertion + const field_cnvrt_aux_t *cnvrt_aux_info = get_auxiliary_for_field_convert(field, field->type()); + assert(cnvrt_aux_info != NULL); + + uint16_t field_len = 0; + uint16_t aligned_field_len = 0; + field_offset_and_len_t size = {&field_len, &aligned_field_len, filed_offset->cantian_field_offset, + filed_offset->mysql_field_offset}; + bool ret = false; + if (record_info && record_info->lens && is_single_run_mode()) { + ret = ctc_update_offset_single(col_id, field, filed_offset->cantian_col_type, cnvrt_aux_info, record_info, + record_buf, &size, is_index_only, tch); + } else { + ret = ctc_parse_cantian_column_and_update_offset(field, filed_offset->cantian_col_type, cnvrt_aux_info, record_buf, + &size, is_index_only, tch); + } + if (ret) { + // continue to next column if current field is null + return; + } - field_info_t field_info = {field, &record_buf->cantian_record_buf[*filed_offset->cantian_field_offset], - &record_buf->mysql_record_buf[*filed_offset->mysql_field_offset], field_len}; - copy_column_data_to_mysql(&field_info, cnvrt_aux_info, tch, is_index_only); + field_info_t field_info = {field, &record_buf->cantian_record_buf[*filed_offset->cantian_field_offset], + &record_buf->mysql_record_buf[*filed_offset->mysql_field_offset], field_len}; + copy_column_data_to_mysql(&field_info, cnvrt_aux_info, tch, is_index_only); - // move cantian offset to next column - *filed_offset->cantian_field_offset += aligned_field_len; + // move cantian offset to next column + *filed_offset->cantian_field_offset += aligned_field_len; } void cantian_record_to_mysql_record(const TABLE &table, index_info_t *index, record_buf_info_t *record_buf, @@ -1940,11 +1930,11 @@ void cantian_record_to_mysql_record(const TABLE &table, index_info_t *index, rec { row_head_t *row_head = (row_head_t *)record_buf->cantian_record_buf; bool is_index_only = false; - ctc_log_debug("size %u, column cnt %u, is_changed:%hu, is_deleted:%hu, " - "is_link:%hu, is_migr:%hu, self_chg:%hu, is_csf:%hu", - row_head->size, row_head->column_count, row_head->is_changed, - row_head->is_deleted, row_head->is_link, row_head->is_migr, - row_head->self_chg, row_head->is_csf); + ctc_log_debug( + "size %u, column cnt %u, is_changed:%hu, is_deleted:%hu, " + "is_link:%hu, is_migr:%hu, self_chg:%hu, is_csf:%hu", + row_head->size, row_head->column_count, row_head->is_changed, row_head->is_deleted, row_head->is_link, + row_head->is_migr, row_head->self_chg, row_head->is_csf); if (row_head->is_csf) { ctc_log_error("csf format is not supported yet"); @@ -1960,7 +1950,7 @@ void cantian_record_to_mysql_record(const TABLE &table, index_info_t *index, rec // for a table with more than 12 columns uint n_fields = table.s->fields; - uint cantian_field_offset = 0; // prefetch in single mode no need parse column + uint cantian_field_offset = 0; // prefetch in single mode no need parse column if (!record_info || !record_info->lens || !is_single_run_mode()) { uint ex_maps = col_bitmap_ex_size(row_head->column_count); cantian_field_offset = sizeof(row_head_t) + ex_maps; @@ -1979,21 +1969,20 @@ void cantian_record_to_mysql_record(const TABLE &table, index_info_t *index, rec Field *field = table.field[column_id]; if (field->is_virtual_gcol()) { - virtual_gcol_cnt++; - continue; + virtual_gcol_cnt++; + continue; } uint mysql_field_offset = field->offset(table.record[0]); - int col_id = column_id - virtual_gcol_cnt; // column id in cantian - uint8 cantian_col_type = (col_id >= row_head->column_count) ? - CANTIAN_COL_BITS_NULL : row_get_column_bits2((row_head_t *)record_buf->cantian_record_buf, col_id); - + int col_id = column_id - virtual_gcol_cnt; // column id in cantian + uint8 cantian_col_type = (col_id >= row_head->column_count) + ? CANTIAN_COL_BITS_NULL + : row_get_column_bits2((row_head_t *)record_buf->cantian_record_buf, col_id); + field_offset_and_col_type filed_offset = {&cantian_field_offset, &mysql_field_offset, cantian_col_type}; convert_cantian_field_to_mysql_field(col_id, field, &filed_offset, record_info, record_buf, tch, is_index_only); } } - - // @note that this cnvrt func can only be used for record fetched directly // from index structures(i.e. circumstances like index-only) void cantian_index_record_to_mysql_record(const TABLE &table, index_info_t *index, record_buf_info_t *record_buf, @@ -2003,7 +1992,7 @@ void cantian_index_record_to_mysql_record(const TABLE &table, index_info_t *inde uint n_fields = index_info.actual_key_parts; bool is_index_only = true; - uint cantian_field_offset = 0; // prefetch in single mode no need parse column + uint cantian_field_offset = 0; // prefetch in single mode no need parse column if (!record_info || !record_info->lens || !is_single_run_mode()) { row_head_t *row_head = (row_head_t *)record_buf->cantian_record_buf; uint ex_maps = col_bitmap_ex_size(row_head->column_count); @@ -2049,7 +2038,7 @@ int get_cantian_record_length(const TABLE *table) Field *mysql_field = NULL; uint total_record_length = sizeof(row_head_t) + col_bitmap_ex_size(table->s->fields); uint16_t field_len; - + for (Field **field = table->field; *field; field++) { mysql_field = *field; field_len = 0; @@ -2082,8 +2071,7 @@ int get_cantian_record_length(const TABLE *table) int prec = f->precision; int ncells = ALIGN_UP(prec - scale, 4) + ALIGN_UP(scale, 4); field_len = ROUND_UP((1 + ncells) * sizeof(uint16_t) + sizeof(uint16_t), 4); - } - break; + } break; case MYSQL_TYPE_BLOB: case MYSQL_TYPE_JSON: case MYSQL_TYPE_TINY_BLOB: diff --git a/storage/ctc/decimal_convert.cc b/storage/ctc/decimal_convert.cc index 6ba11ef..216922b 100644 --- a/storage/ctc/decimal_convert.cc +++ b/storage/ctc/decimal_convert.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -16,8 +16,8 @@ */ #include "decimal_convert.h" #include -#include "stdlib.h" #include "ctc_log.h" +#include "stdlib.h" // half of g_1ten_powers, used for rounding a decimal const uint32 ct_5ten_powers[10] = { 0u, // 0 @@ -44,11 +44,13 @@ const uint32 ct_1ten_powers[10] = { 1000000000u // 10^9 }; static int32 cm_dec8_calc_prec(const dec8_t *dec); -static inline void ct_cm_str2text(char *str, text_t *text) { +static inline void ct_cm_str2text(char *str, text_t *text) +{ text->str = str; text->len = (str == NULL) ? 0 : (uint32)strlen(str); } -status_t ct_cm_str_to_dec8(const char *str, dec8_t *dec) { +status_t ct_cm_str_to_dec8(const char *str, dec8_t *dec) +{ text_t text; ct_cm_str2text(const_cast(str), &text); return ct_cm_text_to_dec8(&text, dec); @@ -56,7 +58,8 @@ status_t ct_cm_str_to_dec8(const char *str, dec8_t *dec) { /** * Translates a text_t representation of a decimal into a decimal */ -status_t ct_cm_text_to_dec8(const text_t *dec_text, dec8_t *dec) { +status_t ct_cm_text_to_dec8(const text_t *dec_text, dec8_t *dec) +{ num_errno_t err_no; num_part_t np; np.excl_flag = NF_NONE; @@ -80,7 +83,8 @@ status_t ct_cm_text_to_dec8(const text_t *dec_text, dec8_t *dec) { * zeros e.g. | u0 = 1000 | u1 = 0 | u2 = 0 |..., the precision 1 will be * returned. */ -static int32 cm_dec8_calc_prec(const dec8_t *dec) { +static int32 cm_dec8_calc_prec(const dec8_t *dec) +{ int32 i, j; uint32 u; int32 prec = 0; @@ -115,8 +119,8 @@ static int32 cm_dec8_calc_prec(const dec8_t *dec) { return prec; } /** recording the significand digits into num_part */ -static inline void ct_cm_record_digit(num_part_t *np, int32 *precision, - int32 *prec_offset, int32 pos, char c) { +static inline void ct_cm_record_digit(num_part_t *np, int32 *precision, int32 *prec_offset, int32 pos, char c) +{ if (*precision >= 0) { ++(*precision); if (*precision > (DEC_MAX_NUM_SAVING_PREC + 1)) { @@ -136,7 +140,8 @@ static inline void ct_cm_record_digit(num_part_t *np, int32 *precision, } CM_TEXT_APPEND(&np->digit_text, c); } -static inline void cm_dec8_rebuild(dec8_t *rs, uint32 cell0) { +static inline void cm_dec8_rebuild(dec8_t *rs, uint32 cell0) +{ /* decide the number of cells */ if (rs->ncells < DEC8_CELL_SIZE) { rs->ncells++; @@ -159,7 +164,8 @@ static inline void cm_dec8_rebuild(dec8_t *rs, uint32 cell0) { * of exponent. When unexpected character occur or the exponent overflow, * an error will be returned. */ -static inline num_errno_t ct_cm_parse_num_expn(text_t *expn_text, int32 *expn) { +static inline num_errno_t ct_cm_parse_num_expn(text_t *expn_text, int32 *expn) +{ char c; int32 tmp_exp; bool32 is_negexp = CT_FALSE; @@ -201,9 +207,8 @@ static inline num_errno_t ct_cm_parse_num_expn(text_t *expn_text, int32 *expn) { return NERR_SUCCESS; } /** calculate expn of the significand digits */ -static inline int32 ct_cm_calc_significand_expn(int32 dot_offset, - int32 prec_offset, - int32 precision) { +static inline int32 ct_cm_calc_significand_expn(int32 dot_offset, int32 prec_offset, int32 precision) +{ // Step 3.1. compute the sci_exp if (dot_offset >= 0) { /* if a dot exists */ /* Now, prec_offset records the distance from the first significant digit to @@ -216,13 +221,13 @@ static inline int32 ct_cm_calc_significand_expn(int32 dot_offset, return precision - 1; } } -num_errno_t ct_cm_split_num_text(const text_t *num_text, num_part_t *np) { +num_errno_t ct_cm_split_num_text(const text_t *num_text, num_part_t *np) +{ int32 i; char c; - text_t text; /** the temporary text */ - int32 dot_offset = -1; /** '.' offset, -1 if none */ - int32 prec_offset = - -1; /** the offset of the first significant digit, -1 if none */ + text_t text; /** the temporary text */ + int32 dot_offset = -1; /** '.' offset, -1 if none */ + int32 prec_offset = -1; /** the offset of the first significant digit, -1 if none */ int32 precision = -1; /* see comments of the function */ bool32 leading_flag = CT_TRUE; /** used to ignore leading zeros */ /* When the number of significant digits exceeds the dight_buf @@ -296,10 +301,8 @@ num_errno_t ct_cm_split_num_text(const text_t *num_text, num_part_t *np) { return NERR_SUCCESS; } // Step 3: Calculate the scale of the total number text - np->sci_expn += - ct_cm_calc_significand_expn(dot_offset, prec_offset, precision); - if (np->digit_text.len > num_text->len || - np->digit_text.len >= CT_MAX_NUM_PART_BUFF) { + np->sci_expn += ct_cm_calc_significand_expn(dot_offset, prec_offset, precision); + if (np->digit_text.len > num_text->len || np->digit_text.len >= CT_MAX_NUM_PART_BUFF) { return NERR_ERROR; } return NERR_SUCCESS; @@ -310,8 +313,8 @@ num_errno_t ct_cm_split_num_text(const text_t *num_text, num_part_t *np) { * Performance sensitivity.CM_ASSERT should be guaranteed by caller, i.g. * cells[0] > 0 */ -static inline int32 cm_digitext_to_cell8s(digitext_t *dtext, cell8_t cells, - int32 len_u0) { +static inline int32 cm_digitext_to_cell8s(digitext_t *dtext, cell8_t cells, int32 len_u0) +{ uint32 i, k; text_t cell_text; // make u0 @@ -342,8 +345,8 @@ static inline int32 cm_digitext_to_cell8s(digitext_t *dtext, cell8_t cells, * Performance sensitivity.CM_ASSERT should be guaranteed by caller, * i.g. dtext->len > 0 && dtext->len <= (uint32)DEC_MAX_ALLOWED_PREC */ -static inline int32 cm_digitext_to_dec8(dec8_t *dec, digitext_t *dtext, - int32 sci_exp) { +static inline int32 cm_digitext_to_dec8(dec8_t *dec, digitext_t *dtext, int32 sci_exp) +{ int32 delta; int32 len_u0; // the length of u0 len_u0 = (int32)dtext->len % DEC8_CELL_DIGIT; @@ -365,8 +368,8 @@ static inline int32 cm_digitext_to_dec8(dec8_t *dec, digitext_t *dtext, dec->expn = SEXP_2_D8EXP(sci_exp - len_u0); return len_u0; } -static inline void cm_do_numpart_round8( - const num_part_t *np MY_ATTRIBUTE((unused)), dec8_t *dec, uint32 prec0) { +static inline void cm_do_numpart_round8(const num_part_t *np MY_ATTRIBUTE((unused)), dec8_t *dec, uint32 prec0) +{ c8typ_t carry = ct_1ten_powers[prec0 % DEC8_CELL_DIGIT]; uint32 i = dec->ncells; @@ -382,7 +385,8 @@ static inline void cm_do_numpart_round8( cm_dec8_rebuild(dec, 1); } } -num_errno_t ct_cm_numpart_to_dec8(num_part_t *np, dec8_t *dec) { +num_errno_t ct_cm_numpart_to_dec8(num_part_t *np, dec8_t *dec) +{ if (NUMPART_IS_ZERO(np)) { cm_zero_dec8(dec); return NERR_SUCCESS; @@ -406,7 +410,8 @@ num_errno_t ct_cm_numpart_to_dec8(num_part_t *np, dec8_t *dec) { /** * Convert a decimal into C-string, and return the ac */ -status_t ct_cm_dec8_to_str(const dec8_t *dec, int max_len, char *str) { +status_t ct_cm_dec8_to_str(const dec8_t *dec, int max_len, char *str) +{ text_t text; text.str = str; text.len = 0; @@ -418,8 +423,8 @@ status_t ct_cm_dec8_to_str(const dec8_t *dec, int max_len, char *str) { * Convert the significant digits of cells into text with a maximal len * @note The tailing zeros are removed when outputting */ -static void cm_cell8s_to_text(const cell8_t cells, uint32 ncell, text_t *text, - int32 max_len) { +static void cm_cell8s_to_text(const cell8_t cells, uint32 ncell, text_t *text, int32 max_len) +{ uint32 i; int iret_snprintf; iret_snprintf = snprintf(text->str, DEC8_CELL_DIGIT + 1, "%u", cells[0]); @@ -428,8 +433,7 @@ static void cm_cell8s_to_text(const cell8_t cells, uint32 ncell, text_t *text, } text->len = (uint32)iret_snprintf; for (i = 1; (text->len < (uint32)max_len) && (i < ncell); ++i) { - iret_snprintf = snprintf(CM_GET_TAIL(text), DEC8_CELL_DIGIT + 1, - DEC8_CELL_FMT, (uint32)cells[i]); + iret_snprintf = snprintf(CM_GET_TAIL(text), DEC8_CELL_DIGIT + 1, DEC8_CELL_FMT, (uint32)cells[i]); if (iret_snprintf == -1) { assert(0); } @@ -449,7 +453,8 @@ static void cm_cell8s_to_text(const cell8_t cells, uint32 ncell, text_t *text, CM_NULL_TERM(text); } /* Copy the data a decimal */ -static inline void cm_dec8_copy(dec8_t *dst, const dec8_t *src) { +static inline void cm_dec8_copy(dec8_t *dst, const dec8_t *src) +{ if (SECUREC_UNLIKELY(dst == src)) { return; } @@ -498,8 +503,8 @@ static inline void cm_dec8_copy(dec8_t *dst, const dec8_t *src) { /** * Product a cell array with the digit at pos (starting from left) is k */ -static inline bool32 cm_dec8_make_round(const dec8_t *dec, uint32 pos, - dec8_t *dx) { +static inline bool32 cm_dec8_make_round(const dec8_t *dec, uint32 pos, dec8_t *dx) +{ int32 i; uint32 carry, j; cm_dec8_copy(dx, dec); @@ -534,8 +539,8 @@ static inline bool32 cm_dec8_make_round(const dec8_t *dec, uint32 pos, * Performance sensitivity.CM_ASSERT should be guaranteed by caller, * i.g. 1.max_len > 0 2.dec->cells[0] > 0 */ -static int32 cm_dec8_round_to_text(const dec8_t *dec, int32 max_len, - text_t *text_out) { +static int32 cm_dec8_round_to_text(const dec8_t *dec, int32 max_len, text_t *text_out) +{ dec8_t txtdec; uint32 prec_u0; int32 prec; @@ -564,8 +569,8 @@ static int32 cm_dec8_round_to_text(const dec8_t *dec, int32 max_len, /** * Output a decimal type in scientific format, e.g., 2.34566E-20 */ -static inline status_t cm_dec8_to_sci_text(text_t *text, const dec8_t *dec, - int32 max_len) { +static inline status_t cm_dec8_to_sci_text(text_t *text, const dec8_t *dec, int32 max_len) +{ int32 i; char obuff[CT_NUMBER_BUFFER_SIZE]; /** output buff */ text_t cell_text = {.str = obuff, .len = 0}; @@ -604,15 +609,15 @@ static inline status_t cm_dec8_to_sci_text(text_t *text, const dec8_t *dec, CM_TEXT_APPEND(text, '0'); } } - iret_snprintf = - snprintf(&text->str[text->len], DEC_EXPN_BUFF_SZ - 1, "%s", sci_buff); + iret_snprintf = snprintf(&text->str[text->len], DEC_EXPN_BUFF_SZ - 1, "%s", sci_buff); if (iret_snprintf != EOK) { return CT_ERROR; } text->len += (uint32)iret_snprintf; return CT_SUCCESS_STATUS; } -static inline void cm_concat_text(text_t *text, const text_t *part) { +static inline void cm_concat_text(text_t *text, const text_t *part) +{ for (uint32 i = 0; i < part->len; ++i) { CM_TEXT_APPEND(text, part->str[i]); } @@ -621,13 +626,14 @@ static inline void cm_concat_text(text_t *text, const text_t *part) { * Append num characters c to the text; if num<=0, do nothing; * @note the user must ensure sufficient space to store them */ -static inline void cm_text_appendc(text_t *text, int32 num, char c) { +static inline void cm_text_appendc(text_t *text, int32 num, char c) +{ while (num-- > 0) { CM_TEXT_APPEND(text, c); } } -static inline status_t cm_concat_ntext(text_t *dst, const text_t *src, - int32 num) { +static inline status_t cm_concat_ntext(text_t *dst, const text_t *src, int32 num) +{ if (num <= 0) { return CT_SUCCESS_STATUS; } @@ -645,9 +651,8 @@ static inline status_t cm_concat_ntext(text_t *dst, const text_t *src, * Performance sensitivity.CM_ASSERT should be guaranteed by caller, i.g. * dot_pos <= max_len - dec->sign */ -static inline status_t cm_dec8_to_plain_text(text_t *text, const dec8_t *dec, - int32 max_len, int32 sci_exp, - int32 prec) { +static inline status_t cm_dec8_to_plain_text(text_t *text, const dec8_t *dec, int32 max_len, int32 sci_exp, int32 prec) +{ int32 dot_pos; char obuff[CT_NUMBER_BUFFER_SIZE]; /** output buff */ text_t cell_text; @@ -712,8 +717,7 @@ static inline status_t cm_dec8_to_plain_text(text_t *text, const dec8_t *dec, } else { // dot_pos < 0 /* dot is in the most left & add |dot_pos| zeros between dot and cell_text * Thus, the maxi_len should consider sign, dot, and the adding zeros */ - dot_pos += cm_dec8_round_to_text(dec, max_len - dec->sign - 1 + dot_pos, - &cell_text); + dot_pos += cm_dec8_round_to_text(dec, max_len - dec->sign - 1 + dot_pos, &cell_text); CM_TEXT_APPEND(text, '.'); cm_text_appendc(text, -dot_pos, '0'); cm_concat_ntext(text, &cell_text, max_len - (int32)text->len); @@ -727,7 +731,8 @@ static inline status_t cm_dec8_to_plain_text(text_t *text, const dec8_t *dec, * Performance sensitivity.CM_ASSERT should be guaranteed by caller, * i.g. 1.dec->sign == DEC_SIGN_PLUS 2.dec->expn == 0 3.dec->cells[0] > 0 */ -status_t ct_cm_dec8_to_text(const dec8_t *dec, int32 max_len, text_t *text) { +status_t ct_cm_dec8_to_text(const dec8_t *dec, int32 max_len, text_t *text) +{ int32 sci_exp; /** The scientific scale of the dec */ int32 prec; if (dec == NULL || text == NULL) { diff --git a/storage/ctc/ha_ctc.cc b/storage/ctc/ha_ctc.cc index 78c6c98..a71ebe6 100644 --- a/storage/ctc/ha_ctc.cc +++ b/storage/ctc/ha_ctc.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -79,62 +79,60 @@ #include #include -#include #include +#include #include +#include #include #include #include -#include #include "field_types.h" #include "my_base.h" #include "my_macros.h" #include "my_pointer_arithmetic.h" #include "my_psi_config.h" #include "mysql/plugin.h" +#include "sql/create_field.h" #include "sql/current_thd.h" #include "sql/dd/types/table.h" -#include "sql/discrete_interval.h" // Discrete_interval +#include "sql/dd/upgrade/server.h" // UPGRADE_FORCE +#include "sql/discrete_interval.h" // Discrete_interval #include "sql/field.h" -#include "sql/create_field.h" #include "sql/sql_base.h" // enum_tdc_remove_table_type #include "sql/sql_class.h" -#include "sql/sql_lex.h" +#include "sql/sql_initialize.h" // opt_initialize_insecure #include "sql/sql_insert.h" +#include "sql/sql_lex.h" #include "sql/sql_plugin.h" -#include "sql/sql_initialize.h" // opt_initialize_insecure -#include "sql/dd/upgrade/server.h" // UPGRADE_FORCE -#include "sql/dd/properties.h" -#include "sql/dd/types/partition.h" -#include "ctc_stats.h" #include "ctc_error.h" #include "ctc_log.h" +#include "ctc_meta_data.h" #include "ctc_srv_mq_module.h" +#include "ctc_stats.h" #include "ctc_util.h" -#include "protobuf/tc_db.pb-c.h" -#include "typelib.h" #include "datatype_cnvrt_4_index_search.h" -#include "sql/mysqld.h" -#include "sql/plugin_table.h" -#include "sql/dd/object_id.h" -#include "sql/dd/string_type.h" +#include "protobuf/tc_db.pb-c.h" #include "sql/dd/cache/dictionary_client.h" #include "sql/dd/dd_schema.h" -#include "sql/sql_table.h" +#include "sql/dd/object_id.h" +#include "sql/dd/properties.h" +#include "sql/dd/string_type.h" +#include "sql/dd/types/partition.h" +#include "sql/mysqld.h" #include "sql/mysqld_thd_manager.h" +#include "sql/plugin_table.h" #include "sql/sql_backup_lock.h" -#include "ctc_meta_data.h" -#include "sql/mysqld.h" -#include "sql/sql_executor.h" // class QEP_TAB +#include "sql/sql_executor.h" // class QEP_TAB +#include "sql/sql_table.h" +#include "typelib.h" #ifdef FEATURE_X_FOR_MYSQL_32 #include "sql/join_optimizer/access_path.h" #elif defined(FEATURE_X_FOR_MYSQL_26) #include "sql/abstract_query_plan.h" -#include "sql/opt_range.h" // QUICK_SELECT_I +#include "sql/opt_range.h" // QUICK_SELECT_I #endif - //------------------------------------------------------------------------------// // SYSTEM VARIABLES // //------------------------------------------------------------------------------// @@ -143,7 +141,8 @@ * mysql> SHOW GLOBAL VARIABLES like'%ctc%' */ -static void ctc_statistics_enabled_update(THD *, SYS_VAR *, void *var_ptr, const void *save) { +static void ctc_statistics_enabled_update(THD *, SYS_VAR *, void *var_ptr, const void *save) +{ bool val = *static_cast(var_ptr) = *static_cast(save); ctc_stats::get_instance().set_statistics_enabled(val); } @@ -151,15 +150,18 @@ static void ctc_statistics_enabled_update(THD *, SYS_VAR *, void *var_ptr, const /* 创库的表空间datafile自动扩展, 默认开 */ bool ctc_db_datafile_autoextend = true; static MYSQL_SYSVAR_BOOL(db_datafile_autoextend, ctc_db_datafile_autoextend, PLUGIN_VAR_NOCMDARG, - "Indicates whether to automatically extend the tablespace data files of the CTC database.", nullptr, nullptr, true); + "Indicates whether to automatically extend the tablespace data files of the CTC database.", + nullptr, nullptr, true); /* 创库的表空间datafile大小, 单位M, 默认32M, 最小1M, 最大8T */ uint32_t ctc_db_datafile_size = 32; static MYSQL_SYSVAR_UINT(db_datafile_size, ctc_db_datafile_size, PLUGIN_VAR_RQCMDARG, - "Size of the tablespace data file of the CTC database, in MB.", nullptr, nullptr, 32, 1, 8192 * 1024, 0); + "Size of the tablespace data file of the CTC database, in MB.", nullptr, nullptr, 32, 1, + 8192 * 1024, 0); /* 创库的表空间datafile自动扩展大小, 单位M, 默认128M, 最小1M, 最大8T */ uint32_t ctc_db_datafile_extend_size = 128; static MYSQL_SYSVAR_UINT(db_datafile_extend_size, ctc_db_datafile_extend_size, PLUGIN_VAR_RQCMDARG, - "Size of the CTC database tablespace data file automatically extended, in MB.", nullptr, nullptr, 128, 1, 8192 * 1024, 0); + "Size of the CTC database tablespace data file automatically extended, in MB.", nullptr, + nullptr, 128, 1, 8192 * 1024, 0); bool ctc_concurrent_ddl = true; static MYSQL_SYSVAR_BOOL(concurrent_ddl, ctc_concurrent_ddl, PLUGIN_VAR_RQCMDARG, @@ -172,8 +174,8 @@ static MYSQL_SYSVAR_INT(metadata_normalization, ctc_metadata_normalization, PLUG static mutex m_ctc_cluster_role_mutex; int32_t ctc_cluster_role = (int32_t)dis_cluster_role::DEFAULT; -static MYSQL_SYSVAR_INT(cluster_role, ctc_cluster_role, PLUGIN_VAR_READONLY, - "flag for Disaster Recovery Cluster Role.", nullptr, nullptr, -1, -1, 2, 0); +static MYSQL_SYSVAR_INT(cluster_role, ctc_cluster_role, PLUGIN_VAR_READONLY, "flag for Disaster Recovery Cluster Role.", + nullptr, nullptr, -1, -1, 2, 0); static mutex m_ctc_shm_file_num_mutex; @@ -187,18 +189,17 @@ static MYSQL_THDVAR_UINT(lock_wait_timeout, PLUGIN_VAR_RQCMDARG, "millisecond and values 0 means disable the timeout.", nullptr, nullptr, 50000, 0, 1024 * 1024 * 1024, 0); -static MYSQL_THDVAR_DOUBLE(sampling_ratio, PLUGIN_VAR_RQCMDARG, - "sampling ratio used for analyzing tables", nullptr, +static MYSQL_THDVAR_DOUBLE(sampling_ratio, PLUGIN_VAR_RQCMDARG, "sampling ratio used for analyzing tables", nullptr, nullptr, 100, 0.000001, 100, 0); __attribute__((visibility("default"))) uint32_t ctc_instance_id = 0; static MYSQL_SYSVAR_UINT(instance_id, ctc_instance_id, PLUGIN_VAR_READONLY, - "mysql instance id which is used for cantian", nullptr, - nullptr, 0, 0, UINT32_MAX, 0); + "mysql instance id which is used for cantian", nullptr, nullptr, 0, 0, UINT32_MAX, 0); -static void ctc_gather_change_stats_update(THD *, SYS_VAR *, void *var_ptr, const void *save) { +static void ctc_gather_change_stats_update(THD *, SYS_VAR *, void *var_ptr, const void *save) +{ int ret; - update_job_info info = { "GATHER_CHANGE_STATS", 19, "SYS", 3, 0 }; + update_job_info info = {"GATHER_CHANGE_STATS", 19, "SYS", 3, 0}; bool val = *static_cast(var_ptr) = *static_cast(save); info.switch_on = val; ret = (ct_errno_t)ctc_update_job(info); @@ -216,9 +217,7 @@ static MYSQL_SYSVAR_BOOL(enable_x_lock_instance, ctc_enable_x_lock_instance, PLU "LCOK INSTANCE FOR BACKUP add X latch on the cantian side", nullptr, nullptr, false); char *ctc_version_str = const_cast(CTC_VERSION_STR); -static MYSQL_SYSVAR_STR(version, ctc_version_str, - PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY | - PLUGIN_VAR_NOPERSIST, +static MYSQL_SYSVAR_STR(version, ctc_version_str, PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOPERSIST, "ctc plugin version", nullptr, nullptr, CTC_VERSION_STR); bool ctc_statistics_enabled = false; @@ -232,8 +231,8 @@ static MYSQL_SYSVAR_UINT(autoinc_lock_mode, ctc_autoinc_lock_mode, PLUGIN_VAR_RQ uint32_t ctc_update_analyze_time = CTC_ANALYZE_TIME_SEC; static MYSQL_SYSVAR_UINT(update_analyze_time, ctc_update_analyze_time, PLUGIN_VAR_RQCMDARG, - "CBO updating time by CTC. Unit is second.", nullptr, nullptr, CTC_ANALYZE_TIME_SEC, - 0, 900, 0); + "CBO updating time by CTC. Unit is second.", nullptr, nullptr, CTC_ANALYZE_TIME_SEC, 0, 900, + 0); bool ctc_select_prefetch = true; static MYSQL_SYSVAR_BOOL(select_prefetch, ctc_select_prefetch, PLUGIN_VAR_RQCMDARG, @@ -242,75 +241,56 @@ static MYSQL_SYSVAR_BOOL(select_prefetch, ctc_select_prefetch, PLUGIN_VAR_RQCMDA // All global and session system variables must be published to mysqld before // use. This is done by constructing a NULL-terminated array of the variables // and linking to it in the plugin public interface. -static SYS_VAR *ctc_system_variables[] = { - MYSQL_SYSVAR(lock_wait_timeout), - MYSQL_SYSVAR(instance_id), - MYSQL_SYSVAR(sampling_ratio), - MYSQL_SYSVAR(enable_x_lock_instance), - MYSQL_SYSVAR(db_datafile_autoextend), - MYSQL_SYSVAR(db_datafile_size), - MYSQL_SYSVAR(db_datafile_extend_size), - MYSQL_SYSVAR(concurrent_ddl), - MYSQL_SYSVAR(metadata_normalization), - MYSQL_SYSVAR(max_cursors_no_autocommit), - MYSQL_SYSVAR(version), - MYSQL_SYSVAR(statistics_enabled), - MYSQL_SYSVAR(autoinc_lock_mode), - MYSQL_SYSVAR(cluster_role), - MYSQL_SYSVAR(update_analyze_time), - MYSQL_SYSVAR(gather_change_stats), - MYSQL_SYSVAR(select_prefetch), - nullptr -}; +static SYS_VAR *ctc_system_variables[] = {MYSQL_SYSVAR(lock_wait_timeout), + MYSQL_SYSVAR(instance_id), + MYSQL_SYSVAR(sampling_ratio), + MYSQL_SYSVAR(enable_x_lock_instance), + MYSQL_SYSVAR(db_datafile_autoextend), + MYSQL_SYSVAR(db_datafile_size), + MYSQL_SYSVAR(db_datafile_extend_size), + MYSQL_SYSVAR(concurrent_ddl), + MYSQL_SYSVAR(metadata_normalization), + MYSQL_SYSVAR(max_cursors_no_autocommit), + MYSQL_SYSVAR(version), + MYSQL_SYSVAR(statistics_enabled), + MYSQL_SYSVAR(autoinc_lock_mode), + MYSQL_SYSVAR(cluster_role), + MYSQL_SYSVAR(update_analyze_time), + MYSQL_SYSVAR(gather_change_stats), + MYSQL_SYSVAR(select_prefetch), + nullptr}; /** Operations for altering a table that CTC does not care about */ static const Alter_inplace_info::HA_ALTER_FLAGS CTC_INPLACE_IGNORE = - Alter_inplace_info::ALTER_COLUMN_DEFAULT | - Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT | - Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE | - Alter_inplace_info::ALTER_RENAME | - Alter_inplace_info::CHANGE_INDEX_OPTION | - Alter_inplace_info::ADD_CHECK_CONSTRAINT | - Alter_inplace_info::DROP_CHECK_CONSTRAINT | - Alter_inplace_info::SUSPEND_CHECK_CONSTRAINT | + Alter_inplace_info::ALTER_COLUMN_DEFAULT | Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT | + Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE | Alter_inplace_info::ALTER_RENAME | + Alter_inplace_info::CHANGE_INDEX_OPTION | Alter_inplace_info::ADD_CHECK_CONSTRAINT | + Alter_inplace_info::DROP_CHECK_CONSTRAINT | Alter_inplace_info::SUSPEND_CHECK_CONSTRAINT | Alter_inplace_info::ALTER_COLUMN_VISIBILITY; /** Operations that CTC cares about and can perform without rebuild */ static const Alter_inplace_info::HA_ALTER_FLAGS CTC_ALTER_NOREBUILD = - Alter_inplace_info::ADD_INDEX | - Alter_inplace_info::ADD_UNIQUE_INDEX | - Alter_inplace_info::ADD_SPATIAL_INDEX | - Alter_inplace_info::DROP_FOREIGN_KEY | - Alter_inplace_info::ADD_FOREIGN_KEY | - Alter_inplace_info::DROP_INDEX | - Alter_inplace_info::DROP_UNIQUE_INDEX | - Alter_inplace_info::RENAME_INDEX | - Alter_inplace_info::ALTER_COLUMN_NAME | - Alter_inplace_info::ALTER_INDEX_COMMENT | - Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH; + Alter_inplace_info::ADD_INDEX | Alter_inplace_info::ADD_UNIQUE_INDEX | Alter_inplace_info::ADD_SPATIAL_INDEX | + Alter_inplace_info::DROP_FOREIGN_KEY | Alter_inplace_info::ADD_FOREIGN_KEY | Alter_inplace_info::DROP_INDEX | + Alter_inplace_info::DROP_UNIQUE_INDEX | Alter_inplace_info::RENAME_INDEX | Alter_inplace_info::ALTER_COLUMN_NAME | + Alter_inplace_info::ALTER_INDEX_COMMENT | Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH; /** Operations for rebuilding a table in place */ static const Alter_inplace_info::HA_ALTER_FLAGS CTC_ALTER_REBUILD = - Alter_inplace_info::ADD_PK_INDEX | - Alter_inplace_info::DROP_PK_INDEX | - Alter_inplace_info::CHANGE_CREATE_OPTION | - Alter_inplace_info::ALTER_COLUMN_NULLABLE | - Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE | - Alter_inplace_info::ALTER_STORED_COLUMN_ORDER | - Alter_inplace_info::DROP_STORED_COLUMN | - Alter_inplace_info::ADD_STORED_BASE_COLUMN | - Alter_inplace_info::RECREATE_TABLE; - -static const Alter_inplace_info::HA_ALTER_FLAGS CTC_ALTER_COL_ORDER = - Alter_inplace_info::DROP_COLUMN | - Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER | - Alter_inplace_info::ALTER_STORED_COLUMN_ORDER; + Alter_inplace_info::ADD_PK_INDEX | Alter_inplace_info::DROP_PK_INDEX | Alter_inplace_info::CHANGE_CREATE_OPTION | + Alter_inplace_info::ALTER_COLUMN_NULLABLE | Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE | + Alter_inplace_info::ALTER_STORED_COLUMN_ORDER | Alter_inplace_info::DROP_STORED_COLUMN | + Alter_inplace_info::ADD_STORED_BASE_COLUMN | Alter_inplace_info::RECREATE_TABLE; + +static const Alter_inplace_info::HA_ALTER_FLAGS CTC_ALTER_COL_ORDER = Alter_inplace_info::DROP_COLUMN | + Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER | + Alter_inplace_info::ALTER_STORED_COLUMN_ORDER; static const Alter_inplace_info::HA_ALTER_FLAGS PARTITION_OPERATIONS = - Alter_inplace_info::ADD_PARTITION | Alter_inplace_info::COALESCE_PARTITION; + Alter_inplace_info::ADD_PARTITION | Alter_inplace_info::COALESCE_PARTITION; static const Alter_inplace_info::HA_ALTER_FLAGS COLUMN_TYPE_OPERATIONS = - Alter_inplace_info::ALTER_STORED_COLUMN_TYPE | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH; + Alter_inplace_info::ALTER_STORED_COLUMN_TYPE | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH; //------------------------------------------------------------------------------ constexpr int max_prefetch_num = MAX_PREFETCH_REC_NUM; @@ -333,15 +313,16 @@ void ha_ctc_set_inst_id(uint32_t inst_id) { ctc_instance_id = inst_id; } handlerton *get_ctc_hton() { return ctc_hton; } /* -* Check whether it is CREATE TABLE ... SELECT -* reference: populate_table + * Check whether it is CREATE TABLE ... SELECT + * reference: populate_table */ -static inline bool is_create_table_check(MYSQL_THD thd) { +static inline bool is_create_table_check(MYSQL_THD thd) +{ return (thd->lex->sql_command == SQLCOM_CREATE_TABLE && thd->lex->is_exec_started()); } -dml_flag_t ctc_get_dml_flag(THD *thd, bool is_replace, bool auto_inc_used, - bool has_explicit_autoinc, bool dup_update) { +dml_flag_t ctc_get_dml_flag(THD *thd, bool is_replace, bool auto_inc_used, bool has_explicit_autoinc, bool dup_update) +{ dml_flag_t flag; flag.ignore = thd->lex->is_ignore(); flag.no_foreign_key_check = (thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS) ? 1 : 0; @@ -352,7 +333,7 @@ dml_flag_t ctc_get_dml_flag(THD *thd, bool is_replace, bool auto_inc_used, flag.auto_inc_used = auto_inc_used; flag.has_explicit_autoinc = has_explicit_autoinc; flag.autoinc_lock_mode = ctc_autoinc_lock_mode; - flag.dup_update= dup_update; + flag.dup_update = dup_update; flag.auto_inc_step = thd->variables.auto_increment_increment; flag.auto_inc_offset = thd->variables.auto_increment_offset; flag.auto_increase = false; @@ -360,19 +341,14 @@ dml_flag_t ctc_get_dml_flag(THD *thd, bool is_replace, bool auto_inc_used, return flag; } -bool is_initialize() { - return opt_initialize || opt_initialize_insecure; -} +bool is_initialize() { return opt_initialize || opt_initialize_insecure; } -bool is_starting() { - return !mysqld_server_started && !is_initialize(); -} +bool is_starting() { return !mysqld_server_started && !is_initialize(); } -bool is_work_flow() { - return mysqld_server_started && !is_initialize(); -} +bool is_work_flow() { return mysqld_server_started && !is_initialize(); } -bool is_ctc_mdl_thd(THD* thd) { +bool is_ctc_mdl_thd(THD *thd) +{ if (thd->query().str && string(thd->query().str) == "ctc_mdl_thd_notify") { return true; } @@ -380,7 +356,8 @@ bool is_ctc_mdl_thd(THD* thd) { } // 是否为元数据归一的初始化流程 -bool is_meta_version_initialize() { +bool is_meta_version_initialize() +{ #ifdef METADATA_NORMALIZED return is_initialize(); #else @@ -389,7 +366,8 @@ bool is_meta_version_initialize() { } // 是否为--upgrade=FORCE -bool is_meta_version_upgrading_force() { +bool is_meta_version_upgrading_force() +{ #ifdef METADATA_NORMALIZED return (opt_upgrade_mode == UPGRADE_FORCE); #else @@ -397,12 +375,11 @@ bool is_meta_version_upgrading_force() { #endif } -bool is_alter_table_scan(bool m_error_if_not_empty) { - return m_error_if_not_empty; -} +bool is_alter_table_scan(bool m_error_if_not_empty) { return m_error_if_not_empty; } -bool ddl_enabled_normal(MYSQL_THD thd) { - handlerton* hton = get_ctc_hton(); +bool ddl_enabled_normal(MYSQL_THD thd) +{ + handlerton *hton = get_ctc_hton(); thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(hton, thd); assert(sess_ctx != nullptr); // 1.CTC_DDL_LOCAL_ENABLED被设置:不能从rewrite插件下发任何SQL语句 @@ -412,35 +389,38 @@ bool ddl_enabled_normal(MYSQL_THD thd) { (ctc_concurrent_ddl == true || (sess_ctx->set_flag & CTC_DDL_ENABLED)); } -bool engine_skip_ddl(MYSQL_THD thd) { - handlerton* hton = get_ctc_hton(); +bool engine_skip_ddl(MYSQL_THD thd) +{ + handlerton *hton = get_ctc_hton(); thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(hton, thd); assert(sess_ctx != nullptr); // 接口流程不需要走到参天: 用于参天SYS库操作 return (sess_ctx->set_flag & CTC_DDL_LOCAL_ENABLED) && ctc_concurrent_ddl == true; } -bool engine_ddl_passthru(MYSQL_THD thd) { +bool engine_ddl_passthru(MYSQL_THD thd) +{ // 元数据归一初始化场景,接口流程需要走到参天 if (is_initialize() || is_meta_version_upgrading_force()) { return false; } - handlerton* hton = get_ctc_hton(); + handlerton *hton = get_ctc_hton(); thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(hton, thd); assert(sess_ctx != nullptr); bool is_mysql_local = (sess_ctx->set_flag & CTC_DDL_LOCAL_ENABLED); return is_initialize() || !mysqld_server_started || is_mysql_local; } -bool ha_ctc::is_replay_ddl(MYSQL_THD thd) { - char db_name[SMALL_RECORD_SIZE] = { 0 }; +bool ha_ctc::is_replay_ddl(MYSQL_THD thd) +{ + char db_name[SMALL_RECORD_SIZE] = {0}; ctc_split_normalized_name(table->s->normalized_path.str, db_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); ctc_copy_name(db_name, db_name, SMALL_RECORD_SIZE); if (mysql_system_db.find(db_name) != mysql_system_db.end()) { return false; } - - handlerton* hton = get_ctc_hton(); + + handlerton *hton = get_ctc_hton(); thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(hton, thd); assert(sess_ctx != nullptr); @@ -448,7 +428,8 @@ bool ha_ctc::is_replay_ddl(MYSQL_THD thd) { return (sess_ctx->set_flag & ctc_var_flag) == ctc_var_flag; } -static int ctc_reg_instance() { +static int ctc_reg_instance() +{ uint32_t inst_id = MYSQL_PROC_START; uint32_t count = 0; ct_errno_t ret = CT_SUCCESS; @@ -457,18 +438,17 @@ static int ctc_reg_instance() { ret = (ct_errno_t)ctc_alloc_inst_id(&inst_id); if (ret == CT_SUCCESS) { ha_ctc_set_inst_id(inst_id); - ctc_log_system("[CTC_INIT]:ctc reg instance success, inst_id:%u", - ha_ctc_get_inst_id()); + ctc_log_system("[CTC_INIT]:ctc reg instance success, inst_id:%u", ha_ctc_get_inst_id()); break; } - ctc_log_system("[CTC_INIT]:ctc reg instance failed and sleep %u/%u", count, - CTC_START_TIMEOUT); + ctc_log_system("[CTC_INIT]:ctc reg instance failed and sleep %u/%u", count, CTC_START_TIMEOUT); sleep(1); } return convert_ctc_error_code_to_mysql(ret); } -static void ctc_unreg_instance() { +static void ctc_unreg_instance() +{ // 元数据归一流程初始化阶段下发参天, 主干不下发 if (opt_initialize_insecure && !CHECK_HAS_MEMBER(handlerton, get_inst_id)) { return; @@ -478,19 +458,19 @@ static void ctc_unreg_instance() { inst_id = ha_ctc_get_inst_id(); ct_errno_t ret = (ct_errno_t)ctc_release_inst_id(inst_id); if (ret != CT_SUCCESS) { - ctc_log_error("ctc release instance id:%u failed, ret:%d", - ha_ctc_get_inst_id(), ret); + ctc_log_error("ctc release instance id:%u failed, ret:%d", ha_ctc_get_inst_id(), ret); } else { ctc_log_system("ctc release instance id:%u success", ha_ctc_get_inst_id()); } } /* -* Check if the ALTER TABLE operations need table copy -* reference: is_inplace_alter_impossible() -* Alter_info::ALTER_TABLE_ALGORITHM_COPY tag set at ha_ctc::create or spcified by ALGORITHMY = COPY -*/ -bool is_alter_table_copy(MYSQL_THD thd, const char *name) { + * Check if the ALTER TABLE operations need table copy + * reference: is_inplace_alter_impossible() + * Alter_info::ALTER_TABLE_ALGORITHM_COPY tag set at ha_ctc::create or spcified by ALGORITHMY = COPY + */ +bool is_alter_table_copy(MYSQL_THD thd, const char *name) +{ if (!thd->lex->alter_info) { return false; } @@ -509,14 +489,16 @@ bool is_alter_table_copy(MYSQL_THD thd, const char *name) { return false; } -static bool is_lock_table(MYSQL_THD thd) { +static bool is_lock_table(MYSQL_THD thd) +{ if (thd->lex->sql_command == SQLCOM_LOCK_TABLES) { return true; } return false; } -static bool check_cmp_result(Item *term) { +static bool check_cmp_result(Item *term) +{ Item_func *item_func = dynamic_cast(term); if (item_func == nullptr) { return false; @@ -547,7 +529,7 @@ static bool check_cmp_result(Item *term) { if (item_func_comparison == nullptr) { return false; } - + Item_func *item_date_func = dynamic_cast(item_func->arguments()[1]); if (item_date_func == nullptr) { return false; @@ -581,7 +563,8 @@ static bool check_cmp_result(Item *term) { return false; } -static bool is_supported_datatype_cond(enum_field_types datatype) { +static bool is_supported_datatype_cond(enum_field_types datatype) +{ switch (datatype) { case MYSQL_TYPE_JSON: case MYSQL_TYPE_ENUM: @@ -600,24 +583,19 @@ static bool is_supported_datatype_cond(enum_field_types datatype) { } } -static bool is_supported_func_item(Item *term) { +static bool is_supported_func_item(Item *term) +{ Item_func *item_func = dynamic_cast(term); if (item_func == nullptr) { return false; } Item_func::Functype functype = item_func->functype(); // filter unspported func - if (functype != Item_func::EQ_FUNC && - functype != Item_func::EQUAL_FUNC && - functype != Item_func::NE_FUNC && - functype != Item_func::LT_FUNC && - functype != Item_func::LE_FUNC && - functype != Item_func::GE_FUNC && - functype != Item_func::GT_FUNC && - functype != Item_func::LIKE_FUNC && - functype != Item_func::ISNULL_FUNC && + if (functype != Item_func::EQ_FUNC && functype != Item_func::EQUAL_FUNC && functype != Item_func::NE_FUNC && + functype != Item_func::LT_FUNC && functype != Item_func::LE_FUNC && functype != Item_func::GE_FUNC && + functype != Item_func::GT_FUNC && functype != Item_func::LIKE_FUNC && functype != Item_func::ISNULL_FUNC && functype != Item_func::ISNOTNULL_FUNC) { - return false; + return false; } Item::Type type = (item_func->arguments()[0])->type(); @@ -666,9 +644,9 @@ static bool is_supported_func_item(Item *term) { return check_cmp_result(term); } -int create_and_conditions(Item_cond *cond, List pushed_list, - List remainder_list, Item *&pushed_cond, - Item *&remainder_cond) { +int create_and_conditions(Item_cond *cond, List pushed_list, List remainder_list, Item *&pushed_cond, + Item *&remainder_cond) +{ if (remainder_list.is_empty()) { // Entire cond pushed, no remainder pushed_cond = cond; @@ -707,9 +685,9 @@ int create_and_conditions(Item_cond *cond, List pushed_list, return 0; } -int create_or_conditions(Item_cond *cond, List pushed_list, - List remainder_list, Item *&pushed_cond, - Item *&remainder_cond) { +int create_or_conditions(Item_cond *cond, List pushed_list, List remainder_list, Item *&pushed_cond, + Item *&remainder_cond) +{ assert(pushed_list.elements == cond->argument_list()->elements); if (remainder_list.is_empty()) { @@ -723,14 +701,15 @@ int create_or_conditions(Item_cond *cond, List pushed_list, // Construct an OR condition of pushed terms pushed_cond = new Item_cond_or(pushed_list); - if (pushed_cond == nullptr){ + if (pushed_cond == nullptr) { return 1; } } return 0; } -void cond_push_boolean_term(Item *term, Item *&pushed_cond, Item *&remainder_cond) { +void cond_push_boolean_term(Item *term, Item *&pushed_cond, Item *&remainder_cond) +{ if (term->type() == Item::COND_ITEM) { List pushed_list; List remainder_list; @@ -771,8 +750,7 @@ void cond_push_boolean_term(Item *term, Item *&pushed_cond, Item *&remainder_con if (remainder != nullptr) remainder_list.push_back(remainder); } - if (create_or_conditions(cond, pushed_list, remainder_list, pushed_cond, - remainder_cond)) { + if (create_or_conditions(cond, pushed_list, remainder_list, pushed_cond, remainder_cond)) { // Failed, discard pushed conditions. pushed_cond = nullptr; remainder_cond = cond; @@ -795,7 +773,8 @@ void cond_push_boolean_term(Item *term, Item *&pushed_cond, Item *&remainder_con } } -void ha_ctc::prep_cond_push(const Item *cond) { +void ha_ctc::prep_cond_push(const Item *cond) +{ Item *item = const_cast(cond); Item *pushed_cond = nullptr; Item *remainder = nullptr; @@ -805,28 +784,29 @@ void ha_ctc::prep_cond_push(const Item *cond) { } // 返回值检测设置 -void ha_ctc::check_error_code_to_mysql(THD *thd, ct_errno_t *ret) { +void ha_ctc::check_error_code_to_mysql(THD *thd, ct_errno_t *ret) +{ bool no_foreign_key_check = thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS; - //判断ret是否返回死锁,死锁则回滚 + // 判断ret是否返回死锁,死锁则回滚 if (*ret == ERR_DEAD_LOCK) { thd_mark_transaction_to_rollback(thd, 1); return; - } else if(no_foreign_key_check == false) { + } else if (no_foreign_key_check == false) { return; } - static set g_ctc_ignore_foreign_key_check_ret_value = { - ERR_CONSTRAINT_VIOLATED_NO_FOUND, ERR_ROW_IS_REFERENCED}; + static set g_ctc_ignore_foreign_key_check_ret_value = {ERR_CONSTRAINT_VIOLATED_NO_FOUND, + ERR_ROW_IS_REFERENCED}; if (g_ctc_ignore_foreign_key_check_ret_value.count(*ret) > 0) { ctc_log_system("ctc_ignore_foreign_key_check catching."); *ret = CT_SUCCESS; } } -bool ha_ctc::check_unsupported_operation(THD *thd, HA_CREATE_INFO *create_info) { +bool ha_ctc::check_unsupported_operation(THD *thd, HA_CREATE_INFO *create_info) +{ // 不支持的操作 - if (thd->lex->alter_info && (thd->lex->alter_info->flags & - Alter_info::ALTER_EXCHANGE_PARTITION)) { + if (thd->lex->alter_info && (thd->lex->alter_info->flags & Alter_info::ALTER_EXCHANGE_PARTITION)) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "The current operation is not supported."); return true; } @@ -857,7 +837,7 @@ enum dd_index_keys { /** Sentinel */ DD_INDEX__LAST }; - + /** CTC private keys for dd::Table */ enum dd_table_keys { /** Auto-increment counter */ @@ -877,91 +857,90 @@ enum dd_table_keys { /** Sentinel */ DD_TABLE__LAST }; - -const char *const dd_index_key_strings[DD_INDEX__LAST] = { - "id", "space_id", "table_id", "root", "trx_id"}; - + +const char *const dd_index_key_strings[DD_INDEX__LAST] = {"id", "space_id", "table_id", "root", "trx_id"}; + static constexpr dd::Object_id g_dd_dict_space_id = 1; - + /** CTC private key strings for dd::Table. @see dd_table_keys */ -const char *const dd_table_key_strings[DD_TABLE__LAST] = { - "autoinc", "data_directory", "version", "discard", "instant_col"}; - -static void dd_set_autoinc(dd::Properties &se_private_data, uint64 autoinc) { +const char *const dd_table_key_strings[DD_TABLE__LAST] = {"autoinc", "data_directory", "version", "discard", + "instant_col"}; + +static void dd_set_autoinc(dd::Properties &se_private_data, uint64 autoinc) +{ /* The value of "autoinc" here is the AUTO_INCREMENT attribute specified at table creation. AUTO_INCREMENT=0 will silently be treated as AUTO_INCREMENT=1. Likewise, if no AUTO_INCREMENT attribute was specified, the value would be 0. */ - + if (autoinc > 0) { /* CTC persists the "previous" AUTO_INCREMENT value. */ autoinc--; } - + uint64 version = 0; - + if (se_private_data.exists(dd_table_key_strings[DD_TABLE_AUTOINC])) { /* Increment the dynamic metadata version, so that any previously buffered persistent dynamic metadata will be ignored after this transaction commits. */ - - if (!se_private_data.get(dd_table_key_strings[DD_TABLE_VERSION], - &version)) { + + if (!se_private_data.get(dd_table_key_strings[DD_TABLE_VERSION], &version)) { version++; } else { /* incomplete se_private_data */ assert(0); } } - + se_private_data.set(dd_table_key_strings[DD_TABLE_VERSION], version); se_private_data.set(dd_table_key_strings[DD_TABLE_AUTOINC], autoinc); } - -bool ha_ctc::get_se_private_data(dd::Table *dd_table, bool reset) { + +bool ha_ctc::get_se_private_data(dd::Table *dd_table, bool reset) +{ static uint n_tables = 1024; static uint n_indexes = 0; static uint n_pages = 4; - + DBUG_TRACE; assert(dd_table != nullptr); - + if (reset) { n_tables = 0; n_indexes = 0; n_pages = 4; } - - if ((*(const_cast(dd_table))->columns().begin()) - ->is_auto_increment()) { + + if ((*(const_cast(dd_table))->columns().begin())->is_auto_increment()) { dd_set_autoinc(dd_table->se_private_data(), 0); } - + dd_table->set_se_private_id(++n_tables); dd_table->set_tablespace_id(g_dd_dict_space_id); - + /* Set the table id for each column to be conform with the implementation in dd_write_table(). */ for (auto dd_column : *dd_table->table().columns()) { - dd_column->se_private_data().set(dd_index_key_strings[DD_TABLE_ID], - n_tables); + dd_column->se_private_data().set(dd_index_key_strings[DD_TABLE_ID], n_tables); } - + for (dd::Index *i : *dd_table->indexes()) { i->set_tablespace_id(g_dd_dict_space_id); - + dd::Properties &p = i->se_private_data(); - + p.set(dd_index_key_strings[DD_INDEX_ROOT], n_pages++); p.set(dd_index_key_strings[DD_INDEX_ID], ++n_indexes); p.set(dd_index_key_strings[DD_INDEX_TRX_ID], 0); p.set(dd_index_key_strings[DD_INDEX_SPACE_ID], 0); p.set(dd_index_key_strings[DD_TABLE_ID], n_tables); } - + return false; } -static handler *ctc_create_handler(handlerton *hton, TABLE_SHARE *table, bool partitioned, MEM_ROOT *mem_root) { +static handler *ctc_create_handler(handlerton *hton, TABLE_SHARE *table, bool partitioned, MEM_ROOT *mem_root) +{ if (partitioned) { ha_ctcpart *file = new (mem_root) ha_ctcpart(hton, table); if (file && (file->initialize() || file->init_partitioning(mem_root))) { @@ -981,14 +960,18 @@ static handler *ctc_create_handler(handlerton *hton, TABLE_SHARE *table, bool pa return file; } -static bool ctc_check_if_log_table(const char* db_name, const char* table_name) { +static bool ctc_check_if_log_table(const char *db_name, const char *table_name) +{ LEX_CSTRING cstr_db_name = {db_name, strlen(db_name)}; LEX_CSTRING cstr_table_name = {table_name, strlen(table_name)}; - if (cstr_db_name.length == MYSQL_SCHEMA_NAME.length && !my_strcasecmp(system_charset_info, cstr_db_name.str, MYSQL_SCHEMA_NAME.str)) { - if (cstr_table_name.length == GENERAL_LOG_NAME.length && !my_strcasecmp(system_charset_info, cstr_table_name.str, GENERAL_LOG_NAME.str)) { + if (cstr_db_name.length == MYSQL_SCHEMA_NAME.length && + !my_strcasecmp(system_charset_info, cstr_db_name.str, MYSQL_SCHEMA_NAME.str)) { + if (cstr_table_name.length == GENERAL_LOG_NAME.length && + !my_strcasecmp(system_charset_info, cstr_table_name.str, GENERAL_LOG_NAME.str)) { return true; } - if (cstr_table_name.length == SLOW_LOG_NAME.length && !my_strcasecmp(system_charset_info, cstr_table_name.str, SLOW_LOG_NAME.str)) { + if (cstr_table_name.length == SLOW_LOG_NAME.length && + !my_strcasecmp(system_charset_info, cstr_table_name.str, SLOW_LOG_NAME.str)) { return true; } } @@ -1008,8 +991,8 @@ static bool ctc_check_if_log_table(const char* db_name, const char* table_name) */ static bool ctc_is_supported_system_table(const char *db MY_ATTRIBUTE((unused)), const char *table_name MY_ATTRIBUTE((unused)), - bool is_sql_layer_system_table MY_ATTRIBUTE((unused))) { - + bool is_sql_layer_system_table MY_ATTRIBUTE((unused))) +{ if (IS_METADATA_NORMALIZATION()) { return true; } @@ -1024,14 +1007,11 @@ static bool ctc_is_supported_system_table(const char *db MY_ATTRIBUTE((unused)), @return precise type, including the charset-collation code. */ -uint ctc_dtype_form_prtype(uint old_prtype, uint charset_coll) { - return (old_prtype + (charset_coll << 16)); -} +uint ctc_dtype_form_prtype(uint old_prtype, uint charset_coll) { return (old_prtype + (charset_coll << 16)); } uint get_ctc_type_from_mysql_dd_type(uint *unsigned_flag, uint *binary_type, uint *charset_no, - dd::enum_column_types dd_type, - const CHARSET_INFO *field_charset, - bool is_unsigned) { + dd::enum_column_types dd_type, const CHARSET_INFO *field_charset, bool is_unsigned) +{ *unsigned_flag = 0; *binary_type = DATA_BINARY_TYPE; *charset_no = 0; @@ -1144,7 +1124,8 @@ uint get_ctc_type_from_mysql_dd_type(uint *unsigned_flag, uint *binary_type, uin return (0); } -void ctc_dict_mem_fill_column_struct(dict_col *column, uint mtype, uint prtype, uint col_len) { +void ctc_dict_mem_fill_column_struct(dict_col *column, uint mtype, uint prtype, uint col_len) +{ column->mtype = (unsigned int)mtype; column->prtype = (unsigned int)prtype; column->len = (unsigned int)col_len; @@ -1157,21 +1138,21 @@ compatibility check from column description in Ha_fk_column_type form. @param[out] col dict_col filled by this function @param[in] fk_col_type foreign key type information */ -static void ctc_fill_fake_column_struct( - dict_col *col, const Ha_fk_column_type *fk_col_type) { +static void ctc_fill_fake_column_struct(dict_col *col, const Ha_fk_column_type *fk_col_type) +{ uint unsigned_type; uint binary_type; uint charset_no; uint mtype = get_ctc_type_from_mysql_dd_type(&unsigned_type, &binary_type, &charset_no, fk_col_type->type, - fk_col_type->field_charset, fk_col_type->is_unsigned); + fk_col_type->field_charset, fk_col_type->is_unsigned); uint fake_prtype = ctc_dtype_form_prtype(unsigned_type | binary_type, charset_no); /* Fake prtype only contains info which is relevant for foreign key type compatibility check, especially the info used in ctc_cmp_cols_are_equal. */ - uint col_len = calc_pack_length(fk_col_type->type, fk_col_type->char_length, fk_col_type->elements_count, - true, fk_col_type->numeric_scale, fk_col_type->is_unsigned); + uint col_len = calc_pack_length(fk_col_type->type, fk_col_type->char_length, fk_col_type->elements_count, true, + fk_col_type->numeric_scale, fk_col_type->is_unsigned); memset(col, 0, sizeof(dict_col)); ctc_dict_mem_fill_column_struct(col, mtype, fake_prtype, col_len); @@ -1180,7 +1161,8 @@ static void ctc_fill_fake_column_struct( /** Checks if a data main type is a string type. Also a BLOB is considered a string type. @return true if string type */ -bool ctc_dtype_is_string_type(uint mtype) { +bool ctc_dtype_is_string_type(uint mtype) +{ if (mtype <= DATA_BLOB || mtype == DATA_MYSQL || mtype == DATA_VARMYSQL) { return (true); } @@ -1195,9 +1177,9 @@ bool ctc_dtype_is_string_type(uint mtype) { @param prtype precise type @return true if binary string type */ -bool ctc_dtype_is_binary_string_type(uint mtype, uint prtype) { - if ((mtype == DATA_FIXBINARY) || (mtype == DATA_BINARY) || - (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE))) { +bool ctc_dtype_is_binary_string_type(uint mtype, uint prtype) +{ + if ((mtype == DATA_FIXBINARY) || (mtype == DATA_BINARY) || (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE))) { return (true); } @@ -1212,9 +1194,9 @@ bool ctc_dtype_is_binary_string_type(uint mtype, uint prtype) { @param prtype precise type @return true if non-binary string type */ -bool ctc_dtype_is_non_binary_string_type(uint mtype, uint prtype) { - if (ctc_dtype_is_string_type(mtype) == true && - ctc_dtype_is_binary_string_type(mtype, prtype) == false) { +bool ctc_dtype_is_non_binary_string_type(uint mtype, uint prtype) +{ + if (ctc_dtype_is_string_type(mtype) == true && ctc_dtype_is_binary_string_type(mtype, prtype) == false) { return (true); } @@ -1223,20 +1205,17 @@ bool ctc_dtype_is_non_binary_string_type(uint mtype, uint prtype) { /** Gets the MySQL charset-collation code for MySQL string types. @return MySQL charset-collation code */ -static inline uint ctc_dtype_get_charset_coll(uint prtype) { - return ((prtype >> 16) & CHAR_COLL_MASK); -} +static inline uint ctc_dtype_get_charset_coll(uint prtype) { return ((prtype >> 16) & CHAR_COLL_MASK); } -bool ctc_cmp_cols_are_equal(const dict_col *col1, const dict_col *col2, - bool check_charsets) { +bool ctc_cmp_cols_are_equal(const dict_col *col1, const dict_col *col2, bool check_charsets) +{ if (ctc_dtype_is_non_binary_string_type(col1->mtype, col1->prtype) && ctc_dtype_is_non_binary_string_type(col2->mtype, col2->prtype)) { /* Both are non-binary string types: they can be compared if and only if the charset-collation is the same */ if (check_charsets) { - return (ctc_dtype_get_charset_coll(col1->prtype) == - ctc_dtype_get_charset_coll(col2->prtype)); + return (ctc_dtype_get_charset_coll(col1->prtype) == ctc_dtype_get_charset_coll(col2->prtype)); } else { return (true); } @@ -1252,8 +1231,7 @@ bool ctc_cmp_cols_are_equal(const dict_col *col1, const dict_col *col2, return (false); } - if (col1->mtype == DATA_INT && - (col1->prtype & DATA_UNSIGNED) != (col2->prtype & DATA_UNSIGNED)) { + if (col1->mtype == DATA_INT && (col1->prtype & DATA_UNSIGNED) != (col2->prtype & DATA_UNSIGNED)) { /* The storage format of an unsigned integer is different from a signed integer: in a signed integer we OR 0x8000... to the value of positive integers. */ @@ -1262,14 +1240,14 @@ bool ctc_cmp_cols_are_equal(const dict_col *col1, const dict_col *col2, return (col1->mtype != DATA_INT || col1->len == col2->len); } - /** Check if types of child and parent columns in foreign key are compatible. @param[in] check_charsets Indicates whether we need to check that charsets of string columns match. Which is true in most cases. @return True if types are compatible, False if not. */ static bool ctc_check_fk_column_compat(const Ha_fk_column_type *child_column_type, - const Ha_fk_column_type *parent_column_type, bool check_charsets) { + const Ha_fk_column_type *parent_column_type, bool check_charsets) +{ dict_col dict_child_col, dict_parent_col; ctc_fill_fake_column_struct(&dict_child_col, child_column_type); @@ -1283,16 +1261,16 @@ static bool ctc_check_fk_column_compat(const Ha_fk_column_type *child_column_typ Initialize one if session context is not exists. A session context is one-to-one mapping of thread. */ -thd_sess_ctx_s *get_or_init_sess_ctx(handlerton *hton, THD *thd) { +thd_sess_ctx_s *get_or_init_sess_ctx(handlerton *hton, THD *thd) +{ thd_sess_ctx_s *sess_ctx = (thd_sess_ctx_s *)thd_get_ha_data(thd, hton); if (sess_ctx == nullptr) { - sess_ctx = (thd_sess_ctx_s *)my_malloc(PSI_NOT_INSTRUMENTED, - sizeof(thd_sess_ctx_s), MYF(MY_WME)); + sess_ctx = (thd_sess_ctx_s *)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(thd_sess_ctx_s), MYF(MY_WME)); if (sess_ctx == nullptr) { ctc_log_error("my_malloc error for sess_ctx"); return nullptr; } - + memset(sess_ctx, 0xFF, sizeof(thd_sess_ctx_s)); sess_ctx->is_ctc_trx_begin = 0; sess_ctx->sql_stat_start = 0; @@ -1311,13 +1289,14 @@ thd_sess_ctx_s *get_or_init_sess_ctx(handlerton *hton, THD *thd) { This ctc handler will be only use for one time and initialized with session context. Handlerton functions need it since they don't have m_tch member. */ -int get_tch_in_handler_data(handlerton *hton, THD *thd, ctc_handler_t &tch, bool alloc_msg_buf MY_ATTRIBUTE((unused))) { +int get_tch_in_handler_data(handlerton *hton, THD *thd, ctc_handler_t &tch, bool alloc_msg_buf MY_ATTRIBUTE((unused))) +{ memset(&tch, 0, sizeof(tch)); thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(hton, thd); if (sess_ctx == nullptr) { return HA_ERR_OUT_OF_MEM; } - + if (sess_ctx->thd_id != thd->thread_id()) { sess_ctx->sess_addr = INVALID_VALUE64; sess_ctx->thd_id = thd->thread_id(); @@ -1325,7 +1304,7 @@ int get_tch_in_handler_data(handlerton *hton, THD *thd, ctc_handler_t &tch, bool sess_ctx->is_ctc_trx_begin = 0; sess_ctx->sql_stat_start = 0; } - + tch.inst_id = ctc_instance_id; tch.ctx_addr = INVALID_VALUE64; tch.sess_addr = sess_ctx->sess_addr; @@ -1340,15 +1319,16 @@ int get_tch_in_handler_data(handlerton *hton, THD *thd, ctc_handler_t &tch, bool if (sess_ctx->msg_buf == nullptr && alloc_msg_buf) { void *shm_inst = get_one_shm_inst(&tch); - sess_ctx->msg_buf = (void*)shm_alloc((shm_seg_s *)shm_inst, sizeof(dsw_message_block_t)); - sem_init(&(((dsw_message_block_t*)(sess_ctx->msg_buf))->head.sem), 1, 0); + sess_ctx->msg_buf = (void *)shm_alloc((shm_seg_s *)shm_inst, sizeof(dsw_message_block_t)); + sem_init(&(((dsw_message_block_t *)(sess_ctx->msg_buf))->head.sem), 1, 0); tch.msg_buf = sess_ctx->msg_buf; } #endif return 0; } -static void ctc_copy_cursors_to_free(thd_sess_ctx_s *sess_ctx, uint64_t *cursors, uint32_t left) { +static void ctc_copy_cursors_to_free(thd_sess_ctx_s *sess_ctx, uint64_t *cursors, uint32_t left) +{ uint32_t idx = 0; if (sess_ctx->invalid_cursors && sess_ctx->invalid_cursors->size() > 0) { uint32_t invalid_csize = sess_ctx->invalid_cursors->size(); @@ -1365,7 +1345,8 @@ static void ctc_copy_cursors_to_free(thd_sess_ctx_s *sess_ctx, uint64_t *cursors } } -void update_sess_ctx_cursor_by_tch(ctc_handler_t &tch, handlerton *hton, THD *thd) { +void update_sess_ctx_cursor_by_tch(ctc_handler_t &tch, handlerton *hton, THD *thd) +{ if (tch.cursor_addr == INVALID_VALUE64) { return; } @@ -1409,13 +1390,14 @@ void update_sess_ctx_cursor_by_tch(ctc_handler_t &tch, handlerton *hton, THD *th Since session address and sql_stat_start may be changed in tch after processing in cantian, call this method if session address or sql_stat_start may be updated in tch. */ -void update_sess_ctx_by_tch(ctc_handler_t &tch, handlerton *hton, THD *thd) { +void update_sess_ctx_by_tch(ctc_handler_t &tch, handlerton *hton, THD *thd) +{ thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(hton, thd); if (sess_ctx == nullptr) { ctc_log_error("update_sess_ctx_by_tch failed, thd_sess_ctx_s my_malloc error!"); return; } - + sess_ctx->thd_id = tch.thd_id; sess_ctx->sess_addr = tch.sess_addr; sess_ctx->bind_core = tch.bind_core; @@ -1427,7 +1409,8 @@ void update_sess_ctx_by_tch(ctc_handler_t &tch, handlerton *hton, THD *thd) { 2. Call this method if the following ctc interface may be the first call of a dml sql (may use sql_stat_start). */ -void update_member_tch(ctc_handler_t &tch, handlerton *hton, THD *thd, bool alloc_msg_buf MY_ATTRIBUTE((unused))) { +void update_member_tch(ctc_handler_t &tch, handlerton *hton, THD *thd, bool alloc_msg_buf MY_ATTRIBUTE((unused))) +{ thd_sess_ctx_s *sess_ctx = (thd_sess_ctx_s *)thd_get_ha_data(thd, hton); if (sess_ctx == nullptr || sess_ctx->thd_id != thd->thread_id()) { tch.thd_id = thd->thread_id(); @@ -1457,8 +1440,8 @@ void update_member_tch(ctc_handler_t &tch, handlerton *hton, THD *thd, bool allo if (sess_ctx->msg_buf == nullptr && alloc_msg_buf) { void *shm_inst = get_one_shm_inst(&tch); - sess_ctx->msg_buf = (void*)shm_alloc((shm_seg_s *)shm_inst, sizeof(dsw_message_block_t)); - sem_init(&(((dsw_message_block_t*)(sess_ctx->msg_buf))->head.sem), 1, 0); + sess_ctx->msg_buf = (void *)shm_alloc((shm_seg_s *)shm_inst, sizeof(dsw_message_block_t)); + sem_init(&(((dsw_message_block_t *)(sess_ctx->msg_buf))->head.sem), 1, 0); tch.msg_buf = sess_ctx->msg_buf; } #endif @@ -1470,7 +1453,8 @@ void update_member_tch(ctc_handler_t &tch, handlerton *hton, THD *thd, bool allo } // called in disconnect when current thd is no longer used -void release_sess_ctx(thd_sess_ctx_s *sess_ctx, handlerton *hton, THD *thd) { +void release_sess_ctx(thd_sess_ctx_s *sess_ctx, handlerton *hton, THD *thd) +{ assert(sess_ctx); delete sess_ctx->cursors_map; sess_ctx->cursors_map = nullptr; @@ -1480,7 +1464,7 @@ void release_sess_ctx(thd_sess_ctx_s *sess_ctx, handlerton *hton, THD *thd) { } #ifndef WITH_CANTIAN if (sess_ctx->msg_buf != nullptr) { - sem_destroy(&(((dsw_message_block_t*)(sess_ctx->msg_buf))->head.sem)); + sem_destroy(&(((dsw_message_block_t *)(sess_ctx->msg_buf))->head.sem)); shm_free(nullptr, sess_ctx->msg_buf); sess_ctx->msg_buf = nullptr; } @@ -1494,10 +1478,9 @@ void release_sess_ctx(thd_sess_ctx_s *sess_ctx, handlerton *hton, THD *thd) { assigns a new snapshot for a consistent read if the transaction does not yet have one. @return 0 */ -static int ctc_start_trx_and_assign_scn( - handlerton *hton, /*!< in: CTC handlerton */ - THD *thd) /*!< in: MySQL thread handle of the user for - whom the transaction should be committed */ +static int ctc_start_trx_and_assign_scn(handlerton *hton, /*!< in: CTC handlerton */ + THD *thd) /*!< in: MySQL thread handle of the user for + whom the transaction should be committed */ { DBUG_TRACE; @@ -1544,7 +1527,8 @@ static int ctc_start_trx_and_assign_scn( return 0; } -void broadcast_and_reload_buffer(ctc_handler_t *tch, ctc_invalidate_broadcast_request *req) { +void broadcast_and_reload_buffer(ctc_handler_t *tch, ctc_invalidate_broadcast_request *req) +{ if (req->buff_len + sizeof(invalidate_obj_entry_t) > DD_BROADCAST_RECORD_LENGTH) { (void)ctc_broadcast_mysql_dd_invalidate(tch, req); memset(req->buff, 0, DD_BROADCAST_RECORD_LENGTH); @@ -1553,15 +1537,15 @@ void broadcast_and_reload_buffer(ctc_handler_t *tch, ctc_invalidate_broadcast_re } template -static typename std::enable_if::type - invalidate_remote_dd(T *thd, ctc_handler_t *tch) +static typename std::enable_if::type invalidate_remote_dd( + T *thd, ctc_handler_t *tch) { ctc_invalidate_broadcast_request req; req.mysql_inst_id = ctc_instance_id; req.buff_len = 1; req.is_dcl = false; invalidate_obj_entry_t *obj = NULL; - + for (auto invalidate_it : thd->invalidates()) { switch (invalidate_it.second) { case T::OBJ_ABSTRACT_TABLE: @@ -1569,32 +1553,38 @@ static typename std::enable_if::typ case T::OBJ_COLUMN_STATISTICS: case T::OBJ_RT_PROCEDURE: case T::OBJ_RT_FUNCTION: - broadcast_and_reload_buffer(tch, &req); - obj = (invalidate_obj_entry_t *)((char *)req.buff + req.buff_len); - obj->type = invalidate_it.second; - strncpy(obj->first, invalidate_it.first.first.c_str(), SMALL_RECORD_SIZE - 1); - strncpy(obj->second, invalidate_it.first.second.c_str(), SMALL_RECORD_SIZE - 1); - req.buff_len += sizeof(invalidate_obj_entry_t); - printf("\n[invalidate_remote_dd] add to invalidate %d, %s, %s.\n", invalidate_it.second, invalidate_it.first.first.c_str(), invalidate_it.first.second.c_str()); fflush(stdout); - break; + broadcast_and_reload_buffer(tch, &req); + obj = (invalidate_obj_entry_t *)((char *)req.buff + req.buff_len); + obj->type = invalidate_it.second; + strncpy(obj->first, invalidate_it.first.first.c_str(), SMALL_RECORD_SIZE - 1); + strncpy(obj->second, invalidate_it.first.second.c_str(), SMALL_RECORD_SIZE - 1); + req.buff_len += sizeof(invalidate_obj_entry_t); + printf("\n[invalidate_remote_dd] add to invalidate %d, %s, %s.\n", invalidate_it.second, + invalidate_it.first.first.c_str(), invalidate_it.first.second.c_str()); + fflush(stdout); + break; case T::OBJ_SCHEMA: case T::OBJ_TABLESPACE: case T::OBJ_RESOURCE_GROUP: case T::OBJ_SPATIAL_REFERENCE_SYSTEM: - broadcast_and_reload_buffer(tch, &req); - obj = (invalidate_obj_entry_t *)((char *)req.buff + req.buff_len); - obj->type = invalidate_it.second; - strncpy(obj->first, invalidate_it.first.first.c_str(), SMALL_RECORD_SIZE - 1); - strncpy(obj->second, "", SMALL_RECORD_SIZE - 1); - req.buff_len += sizeof(invalidate_obj_entry_t); - printf("\n[invalidate_remote_dd] add to invalidate %d, %s, %s.\n", invalidate_it.second, invalidate_it.first.first.c_str(), invalidate_it.first.second.c_str()); fflush(stdout); - break; + broadcast_and_reload_buffer(tch, &req); + obj = (invalidate_obj_entry_t *)((char *)req.buff + req.buff_len); + obj->type = invalidate_it.second; + strncpy(obj->first, invalidate_it.first.first.c_str(), SMALL_RECORD_SIZE - 1); + strncpy(obj->second, "", SMALL_RECORD_SIZE - 1); + req.buff_len += sizeof(invalidate_obj_entry_t); + printf("\n[invalidate_remote_dd] add to invalidate %d, %s, %s.\n", invalidate_it.second, + invalidate_it.first.first.c_str(), invalidate_it.first.second.c_str()); + fflush(stdout); + break; case T::OBJ_CHARSET: case T::OBJ_COLLATION: - printf("\n[invalidate_remote_dd] add to invalidate %d, %s, %s.\n", invalidate_it.second, invalidate_it.first.first.c_str(), invalidate_it.first.second.c_str()); fflush(stdout); - break; + printf("\n[invalidate_remote_dd] add to invalidate %d, %s, %s.\n", invalidate_it.second, + invalidate_it.first.first.c_str(), invalidate_it.first.second.c_str()); + fflush(stdout); + break; default: - break; + break; } } req.buff[0] = '1'; @@ -1602,8 +1592,9 @@ static typename std::enable_if::typ } template -static typename std::enable_if::type - invalidate_remote_dd(T *thd MY_ATTRIBUTE((unused)), ctc_handler_t *tch MY_ATTRIBUTE((unused))) { +static typename std::enable_if::type invalidate_remote_dd( + T *thd MY_ATTRIBUTE((unused)), ctc_handler_t *tch MY_ATTRIBUTE((unused))) +{ // do nothing } @@ -1617,7 +1608,8 @@ bool invalidate_remote_dcl_cache(ctc_handler_t *tch) return result; } -static void ctc_register_trx(handlerton *hton, THD *thd) { +static void ctc_register_trx(handlerton *hton, THD *thd) +{ trans_register_ha(thd, false, hton, nullptr); if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { trans_register_ha(thd, true, hton, nullptr); @@ -1626,8 +1618,9 @@ static void ctc_register_trx(handlerton *hton, THD *thd) { // 利用SFINAE特性,控制是否调用thd->is_empty() template -static typename std::enable_if::type - commit_preprocess(T* thd, ctc_handler_t *tch) { +static typename std::enable_if::type commit_preprocess(T *thd, + ctc_handler_t *tch) +{ if (is_work_flow() && !thd->is_empty() && !thd->is_attachable_transaction_active()) { (void)invalidate_remote_dd(thd, tch); thd->clear(); @@ -1635,27 +1628,31 @@ static typename std::enable_if::type } template -static typename std::enable_if::type - commit_preprocess(T* thd MY_ATTRIBUTE((unused)), ctc_handler_t *tch MY_ATTRIBUTE((unused))) { +static typename std::enable_if::type commit_preprocess( + T *thd MY_ATTRIBUTE((unused)), ctc_handler_t *tch MY_ATTRIBUTE((unused))) +{ // no action here } template -static typename std::enable_if::type -attachable_trx_update_pre_addr(T *ctc_hton, THD *thd, ctc_handler_t *tch, bool set_to_pre_addr) { - if (thd->is_attachable_transaction_active() && (thd->tx_isolation == ISO_READ_UNCOMMITTED) - && (ctc_hton->pre_sess_addr != 0) && thd->query_plan.get_command() == SQLCOM_RENAME_TABLE) { +static typename std::enable_if::type attachable_trx_update_pre_addr( + T *ctc_hton, THD *thd, ctc_handler_t *tch, bool set_to_pre_addr) +{ + if (thd->is_attachable_transaction_active() && (thd->tx_isolation == ISO_READ_UNCOMMITTED) && + (ctc_hton->pre_sess_addr != 0) && thd->query_plan.get_command() == SQLCOM_RENAME_TABLE) { tch->pre_sess_addr = set_to_pre_addr ? ctc_hton->pre_sess_addr : 0; } } template -static typename std::enable_if::type -attachable_trx_update_pre_addr(T *ctc_hton MY_ATTRIBUTE((unused)), THD *thd MY_ATTRIBUTE((unused)), - ctc_handler_t *tch MY_ATTRIBUTE((unused)), bool set_to_pre_addr MY_ATTRIBUTE((unused))) { +static typename std::enable_if::type attachable_trx_update_pre_addr( + T *ctc_hton MY_ATTRIBUTE((unused)), THD *thd MY_ATTRIBUTE((unused)), ctc_handler_t *tch MY_ATTRIBUTE((unused)), + bool set_to_pre_addr MY_ATTRIBUTE((unused))) +{ } -static void ctc_free_cursors_no_autocommit(THD *thd, ctc_handler_t *tch, thd_sess_ctx_s *sess_ctx) { +static void ctc_free_cursors_no_autocommit(THD *thd, ctc_handler_t *tch, thd_sess_ctx_s *sess_ctx) +{ if (!thd->in_multi_stmt_transaction_mode()) { return; } @@ -1689,7 +1686,8 @@ static void ctc_free_cursors_no_autocommit(THD *thd, ctc_handler_t *tch, thd_ses @return 0 or deadlock error if the transaction was aborted by another higher priority transaction. */ -static int ctc_commit(handlerton *hton, THD *thd, bool commit_trx) { +static int ctc_commit(handlerton *hton, THD *thd, bool commit_trx) +{ DBUG_TRACE; if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd) || is_create_table_check(thd) || is_lock_table(thd))) { @@ -1725,20 +1723,22 @@ static int ctc_commit(handlerton *hton, THD *thd, bool commit_trx) { return convert_ctc_error_code_to_mysql(ret); } if (is_ddl_commit && !engine_skip_ddl(thd)) { - ctc_ddl_broadcast_request broadcast_req {{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; + ctc_ddl_broadcast_request broadcast_req{{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; string sql = string(thd->query().str).substr(0, thd->query().length); FILL_BROADCAST_BASE_REQ(broadcast_req, sql.c_str(), thd->m_main_security_ctx.priv_user().str, - thd->m_main_security_ctx.priv_host().str, ctc_instance_id, thd->lex->sql_command); + thd->m_main_security_ctx.priv_host().str, ctc_instance_id, thd->lex->sql_command); if (thd->db().str != NULL && thd->db().length > 0) { strncpy(broadcast_req.db_name, thd->db().str, SMALL_RECORD_SIZE - 1); } broadcast_req.options &= (~CTC_NOT_NEED_CANTIAN_EXECUTE); ret = (ct_errno_t)ctc_execute_mysql_ddl_sql(&tch, &broadcast_req, false); DBUG_EXECUTE_IF("core_after_ddl_cantian_commit_broadcast", { assert(0); }); - ctc_log_system("[CTC_BROARDCAST_ATOMIC_DDL]:ret:%d, query:%s, user_name:%s, err_code:%d, broadcast_inst_id:%u, " - "conn_id:%u, ctc_inst_id:%u", ret, broadcast_req.sql_str, broadcast_req.user_name, - broadcast_req.err_code, broadcast_req.mysql_inst_id, tch.thd_id, tch.inst_id); - assert (ret == CT_SUCCESS); + ctc_log_system( + "[CTC_BROARDCAST_ATOMIC_DDL]:ret:%d, query:%s, user_name:%s, err_code:%d, broadcast_inst_id:%u, " + "conn_id:%u, ctc_inst_id:%u", + ret, broadcast_req.sql_str, broadcast_req.user_name, broadcast_req.err_code, broadcast_req.mysql_inst_id, + tch.thd_id, tch.inst_id); + assert(ret == CT_SUCCESS); } sess_ctx->is_ctc_trx_begin = 0; } else { @@ -1763,7 +1763,8 @@ static int ctc_commit(handlerton *hton, THD *thd, bool commit_trx) { higher priority transaction. @note: */ -static int ctc_rollback(handlerton *hton, THD *thd, bool rollback_trx) { +static int ctc_rollback(handlerton *hton, THD *thd, bool rollback_trx) +{ DBUG_TRACE; if (thd->lex->sql_command == SQLCOM_DROP_TABLE) { @@ -1822,7 +1823,8 @@ static int ctc_rollback(handlerton *hton, THD *thd, bool rollback_trx) { return 0; } -static int ctc_close_connect(handlerton *hton, THD *thd) { +static int ctc_close_connect(handlerton *hton, THD *thd) +{ ctc_handler_t tch; CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); thd_sess_ctx_s *sess_ctx = (thd_sess_ctx_s *)thd_get_ha_data(thd, hton); @@ -1845,7 +1847,8 @@ static int ctc_close_connect(handlerton *hton, THD *thd) { return convert_ctc_error_code_to_mysql((ct_errno_t)ret); } -static void ctc_kill_connection(handlerton *hton, THD *thd) { +static void ctc_kill_connection(handlerton *hton, THD *thd) +{ ctc_handler_t tch; int ret = get_tch_in_handler_data(hton, thd, tch); if (ret != CT_SUCCESS) { @@ -1853,7 +1856,7 @@ static void ctc_kill_connection(handlerton *hton, THD *thd) { } if (tch.sess_addr == INVALID_VALUE64) { ctc_log_system("[CTC_KILL_SESSION]:trying to kill a thd without session assigned, conn_id=%u, instid=%u", - tch.thd_id, tch.inst_id); + tch.thd_id, tch.inst_id); return; } @@ -1871,11 +1874,12 @@ static void ctc_kill_connection(handlerton *hton, THD *thd) { ctc_log_system("[CTC_KILL_SESSION]:conn_id:%u, ctc_instance_id:%u", tch.thd_id, tch.inst_id); } -static int ctc_pre_create_db4cantian(THD *thd, ctc_handler_t *tch) { +static int ctc_pre_create_db4cantian(THD *thd, ctc_handler_t *tch) +{ if (engine_skip_ddl(thd)) { return CT_SUCCESS; } - char user_name[SMALL_RECORD_SIZE] = { 0 }; + char user_name[SMALL_RECORD_SIZE] = {0}; ctc_copy_name(user_name, thd->lex->name.str, SMALL_RECORD_SIZE); int error_code = 0; char error_message[ERROR_MESSAGE_LEN] = {0}; @@ -1893,28 +1897,30 @@ static int ctc_pre_create_db4cantian(THD *thd, ctc_handler_t *tch) { DBUG_EXECUTE_IF("core_after_create_tablespace_and_db", { assert(0); }); // 元数据不一致的问题 - ctc_log_system("[CTC_PRE_CREATE_DB]:ret:%d, database:%s, error_code:%d, error_message:%s, conn_id:%u, ctc_instance_id:%u", - ret, thd->lex->name.str, error_code, error_message, tch->thd_id, tch->inst_id); + ctc_log_system( + "[CTC_PRE_CREATE_DB]:ret:%d, database:%s, error_code:%d, error_message:%s, conn_id:%u, ctc_instance_id:%u", ret, + thd->lex->name.str, error_code, error_message, tch->thd_id, tch->inst_id); if (ret != CT_SUCCESS) { /* 如果参天上报tablespace或user已存在,且创库命令包含if not exists关键字,则忽略此错误 */ if (error_code == ERR_USER_NOT_EMPTY_4MYSQL) { - if (thd->lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { - return CT_SUCCESS; - } - my_printf_error(ER_DB_CREATE_EXISTS, "Can't create database '%s'; database exists", MYF(0), thd->lex->name.str); - return ER_DB_CREATE_EXISTS; + if (thd->lex->create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { + return CT_SUCCESS; + } + my_printf_error(ER_DB_CREATE_EXISTS, "Can't create database '%s'; database exists", MYF(0), thd->lex->name.str); + return ER_DB_CREATE_EXISTS; } if (error_code != 0) { - my_error(ER_CANT_CREATE_DB, MYF(0), thd->lex->name.str, error_code, error_message); + my_error(ER_CANT_CREATE_DB, MYF(0), thd->lex->name.str, error_code, error_message); } } ctc_log_system("[CTC_INIT]:ctc_pre_create_db4cantian end, ret=%d", ret); return ret; } -static void ctc_lock_table_handle_error(int err_code, ctc_lock_table_info *lock_info, ctc_handler_t &tch, THD *thd) { +static void ctc_lock_table_handle_error(int err_code, ctc_lock_table_info *lock_info, ctc_handler_t &tch, THD *thd) +{ DBUG_EXECUTE_IF("ctc_lock_table_fail_DDL_LOCKED", { err_code = ERR_USER_DDL_LOCKED; }); DBUG_EXECUTE_IF("ctc_lock_table_fail_VERSION_NOT_MATCH", { err_code = CTC_DDL_VERSION_NOT_MATCH; }); DBUG_EXECUTE_IF("ctc_lock_table_fail_DISALLOW_OPERATION", { err_code = ER_DISALLOWED_OPERATION; }); @@ -1922,14 +1928,17 @@ static void ctc_lock_table_handle_error(int err_code, ctc_lock_table_info *lock_ switch (err_code) { case ERR_USER_DDL_LOCKED: my_printf_error(ER_DISALLOWED_OPERATION, "Instance has been locked, disallow this operation", MYF(0)); - ctc_log_system("[CTC_MDL_LOCK]: Instance has been locked, disallow this operation," - "lock_info=(%s, %s), sql=%s, conn_id=%u, ctc_instance_id=%u", - lock_info->db_name, lock_info->table_name, thd->query().str, tch.thd_id, tch.inst_id); + ctc_log_system( + "[CTC_MDL_LOCK]: Instance has been locked, disallow this operation," + "lock_info=(%s, %s), sql=%s, conn_id=%u, ctc_instance_id=%u", + lock_info->db_name, lock_info->table_name, thd->query().str, tch.thd_id, tch.inst_id); break; case CTC_DDL_VERSION_NOT_MATCH: - my_printf_error(ER_DISALLOWED_OPERATION, "Version not match. Please make sure cluster on the same version.", MYF(0)); - ctc_log_system("[CTC_MDL_LOCK]: Version not match,lock_info=(%s, %s), sql=%s", lock_info->db_name, lock_info->table_name, thd->query().str); + my_printf_error(ER_DISALLOWED_OPERATION, "Version not match. Please make sure cluster on the same version.", + MYF(0)); + ctc_log_system("[CTC_MDL_LOCK]: Version not match,lock_info=(%s, %s), sql=%s", lock_info->db_name, + lock_info->table_name, thd->query().str); break; default: @@ -1942,7 +1951,8 @@ static void ctc_lock_table_handle_error(int err_code, ctc_lock_table_info *lock_ return; } -static int ctc_notify_pre_event(THD *thd, handlerton *ctc_hton, ctc_handler_t &tch, ctc_lock_table_info *lock_info) { +static int ctc_notify_pre_event(THD *thd, handlerton *ctc_hton, ctc_handler_t &tch, ctc_lock_table_info *lock_info) +{ thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(ctc_hton, thd); assert(sess_ctx != nullptr); if (sess_ctx == nullptr) { @@ -1959,7 +1969,7 @@ static int ctc_notify_pre_event(THD *thd, handlerton *ctc_hton, ctc_handler_t &t if (is_work_flow()) { ret = ctc_lock_table(&tch, cur_db_name, lock_info, &err_code); - + DBUG_EXECUTE_IF("ctc_lock_table_fail", { ret = -1; }); if (ret != 0) { ctc_lock_table_handle_error(err_code, lock_info, tch, thd); @@ -1968,26 +1978,27 @@ static int ctc_notify_pre_event(THD *thd, handlerton *ctc_hton, ctc_handler_t &t } switch (sql_command) { - case SQLCOM_CREATE_DB:{ - ret = ctc_pre_create_db4cantian(thd, &tch); - break; - } - case SQLCOM_DROP_DB:{ - char err_msg[ERROR_MESSAGE_LEN] = {0}; - ret = ctc_drop_db_pre_check(&tch, lock_info->db_name, &err_code, err_msg); - if (ret != 0) { - my_printf_error(ER_DISALLOWED_OPERATION, "Can't drop database '%s' (errno: %d - %s)", MYF(0), - lock_info->db_name, err_code, err_msg); - } - break; + case SQLCOM_CREATE_DB: { + ret = ctc_pre_create_db4cantian(thd, &tch); + break; + } + case SQLCOM_DROP_DB: { + char err_msg[ERROR_MESSAGE_LEN] = {0}; + ret = ctc_drop_db_pre_check(&tch, lock_info->db_name, &err_code, err_msg); + if (ret != 0) { + my_printf_error(ER_DISALLOWED_OPERATION, "Can't drop database '%s' (errno: %d - %s)", MYF(0), + lock_info->db_name, err_code, err_msg); } - default: - break; + break; + } + default: + break; } return ret; } -static int ctc_notify_post_event(THD *thd, handlerton *ctc_hton, ctc_handler_t &tch, ctc_lock_table_info *lock_info) { +static int ctc_notify_post_event(THD *thd, handlerton *ctc_hton, ctc_handler_t &tch, ctc_lock_table_info *lock_info) +{ thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(ctc_hton, thd); assert(sess_ctx != nullptr); if (sess_ctx == nullptr) { @@ -2012,13 +2023,14 @@ static int ctc_notify_post_event(THD *thd, handlerton *ctc_hton, ctc_handler_t & return ret; } - - ctc_log_system("[UNLOCK_TABLE]: ctc_unlock_table lock_info=(%s, %s), sql=%s", lock_info->db_name, lock_info->table_name, thd->query().str); + + ctc_log_system("[UNLOCK_TABLE]: ctc_unlock_table lock_info=(%s, %s), sql=%s", lock_info->db_name, + lock_info->table_name, thd->query().str); ret = ctc_unlock_table(&tch, ctc_instance_id, lock_info); if (ret != 0) { - ctc_log_error("[CTC_MDL_LOCK]: unlock failed, ret: %d, sql: %s, conn_id: %u, ctc_instance_id: %u", - ret, thd->query().str, tch.thd_id, tch.inst_id); + ctc_log_error("[CTC_MDL_LOCK]: unlock failed, ret: %d, sql: %s, conn_id: %u, ctc_instance_id: %u", ret, + thd->query().str, tch.thd_id, tch.inst_id); } } return ret; @@ -2035,11 +2047,11 @@ static int ctc_notify_post_event(THD *thd, handlerton *ctc_hton, ctc_handler_t & @return False if notification was successful and it is OK to acquire lock, True if one of SEs asks to abort lock acquisition. */ -static bool ctc_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key, - ha_notification_type notification_type, - bool *victimized MY_ATTRIBUTE((unused))) { - if (is_ctc_mdl_thd(thd) || (notification_type == HA_NOTIFY_PRE_EVENT && - mdl_key->mdl_namespace() == MDL_key::ACL_CACHE)) { +static bool ctc_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key, ha_notification_type notification_type, + bool *victimized MY_ATTRIBUTE((unused))) +{ + if (is_ctc_mdl_thd(thd) || + (notification_type == HA_NOTIFY_PRE_EVENT && mdl_key->mdl_namespace() == MDL_key::ACL_CACHE)) { return false; } /* @@ -2048,7 +2060,8 @@ static bool ctc_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key, */ size_t query_len = thd->query().length; if (!IS_METADATA_NORMALIZATION() && query_len > MAX_DDL_SQL_LEN_CONTEXT) { - string err_msg = "`" + string(thd->query().str).substr(0, 100) + "...` Is Large Than " + to_string(MAX_DDL_SQL_LEN_CONTEXT); + string err_msg = + "`" + string(thd->query().str).substr(0, 100) + "...` Is Large Than " + to_string(MAX_DDL_SQL_LEN_CONTEXT); my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), err_msg.c_str()); return true; } @@ -2056,7 +2069,7 @@ static bool ctc_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key, if (engine_ddl_passthru(thd)) { return false; } - + if (!IS_METADATA_NORMALIZATION()) { if (engine_skip_ddl(thd)) { ctc_log_warning("[CTC_NOMETA_SQL]:record sql str only generate metadata. sql:%s", thd->query().str); @@ -2064,14 +2077,15 @@ static bool ctc_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key, } if (!ddl_enabled_normal(thd)) { - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "DDL not allowed in this mode, Please check the value of @@ctc_concurrent_ddl."); + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), + "DDL not allowed in this mode, Please check the value of @@ctc_concurrent_ddl."); return true; } if (thd->lex->query_tables == nullptr && mdl_key->mdl_namespace() != MDL_key::SCHEMA) { return false; } - + if (mysql_system_db.find(mdl_key->db_name()) != mysql_system_db.end()) { return false; } @@ -2092,18 +2106,18 @@ static bool ctc_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key, ret = ctc_notify_post_event(thd, ctc_hton, tch, &lock_info); } update_sess_ctx_by_tch(tch, ctc_hton, thd); - + if (ret != 0) { ctc_unlock_table(&tch, ctc_instance_id, &lock_info); return true; } - + return false; } -static bool ctc_notify_alter_table(THD *thd, const MDL_key *mdl_key, - ha_notification_type notification_type) { - vector ticket_list; +static bool ctc_notify_alter_table(THD *thd, const MDL_key *mdl_key, ha_notification_type notification_type) +{ + vector ticket_list; if (IS_METADATA_NORMALIZATION() && notification_type == HA_NOTIFY_PRE_EVENT) { int pre_lock_ret = ctc_lock_table_pre(thd, ticket_list, MDL_SHARED_UPGRADABLE); if (pre_lock_ret != 0) { @@ -2131,7 +2145,8 @@ static const int BASE36 = 36; // 0~9 and a~z, total 36 encoded character @param: savepoint in, savepoint data @return: 0 if succeeds */ -static int ctc_set_savepoint(handlerton *hton, THD *thd, void *savepoint) { +static int ctc_set_savepoint(handlerton *hton, THD *thd, void *savepoint) +{ DBUG_TRACE; char name[MAX_SAVEPOINT_NAME_LEN]; @@ -2139,8 +2154,8 @@ static int ctc_set_savepoint(handlerton *hton, THD *thd, void *savepoint) { ctc_handler_t tch; CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); if (!strcmp(name, CTC_SQL_START_INTERNAL_SAVEPOINT)) { - my_error(ER_DISALLOWED_OPERATION, MYF(0), "this savepoint has been used by sys db!"); - return ER_DISALLOWED_OPERATION; + my_error(ER_DISALLOWED_OPERATION, MYF(0), "this savepoint has been used by sys db!"); + return ER_DISALLOWED_OPERATION; } ct_errno_t ret = (ct_errno_t)ctc_srv_set_savepoint(&tch, name); if (ret != CT_SUCCESS) { @@ -2156,7 +2171,8 @@ static int ctc_set_savepoint(handlerton *hton, THD *thd, void *savepoint) { @param: savepoint in, savepoint data @return: 0 if succeeds */ -static int ctc_rollback_savepoint(handlerton *hton, THD *thd, void *savepoint) { +static int ctc_rollback_savepoint(handlerton *hton, THD *thd, void *savepoint) +{ DBUG_TRACE; char name[MAX_SAVEPOINT_NAME_LEN]; @@ -2190,7 +2206,8 @@ static int ctc_rollback_savepoint(handlerton *hton, THD *thd, void *savepoint) { @param: savepoint in, savepoint data @return: 0 if succeeds */ -static int ctc_release_savepoint(handlerton *hton, THD *thd, void *savepoint) { +static int ctc_release_savepoint(handlerton *hton, THD *thd, void *savepoint) +{ DBUG_TRACE; /** @@ -2221,7 +2238,8 @@ static int ctc_release_savepoint(handlerton *hton, THD *thd, void *savepoint) { times @return: 0 if succeeds */ -int ha_ctc::prefetch_and_fill_record_buffer(uchar *buf, ctc_prefetch_fn prefetch) { +int ha_ctc::prefetch_and_fill_record_buffer(uchar *buf, ctc_prefetch_fn prefetch) +{ // update max col id needed by executor set_max_col_index_4_reading(); uint32_t fetched_num; @@ -2236,8 +2254,8 @@ int ha_ctc::prefetch_and_fill_record_buffer(uchar *buf, ctc_prefetch_fn prefetch return HA_ERR_OUT_OF_MEM; } - ct_errno_t ret = (ct_errno_t)prefetch(&m_tch, m_prefetch_buf, m_record_lens, - &fetched_num, m_rowids, m_cantian_rec_len); + ct_errno_t ret = + (ct_errno_t)prefetch(&m_tch, m_prefetch_buf, m_record_lens, &fetched_num, m_rowids, m_cantian_rec_len); check_error_code_to_mysql(ha_thd(), &ret); if (ret != CT_SUCCESS) { return convert_ctc_error_code_to_mysql(ret); @@ -2263,13 +2281,14 @@ int ha_ctc::prefetch_and_fill_record_buffer(uchar *buf, ctc_prefetch_fn prefetch } bool is_out_of_range = (cur_off_in_prefetch_buf <= (uint64_t)(MAX_RECORD_SIZE - m_cantian_rec_len)) && - actual_fetched_nums < MAX_PREFETCH_REC_NUM; + actual_fetched_nums < MAX_PREFETCH_REC_NUM; m_rec_buf->set_out_of_range(is_out_of_range); - + return 0; } -void ha_ctc::fill_record_to_rec_buffer() { +void ha_ctc::fill_record_to_rec_buffer() +{ m_rec_buf->clear(); for (uint32_t i = 0; i < m_rec_buf->max_records() && cur_fill_buf_index < actual_fetched_nums; i++) { uint8_t *tmpRecBuf = m_rec_buf->add_record(); @@ -2282,11 +2301,12 @@ void ha_ctc::fill_record_to_rec_buffer() { } bool is_out_of_range = (cur_off_in_prefetch_buf <= (uint64_t)(MAX_RECORD_SIZE - m_cantian_rec_len)) && - actual_fetched_nums < MAX_PREFETCH_REC_NUM; + actual_fetched_nums < MAX_PREFETCH_REC_NUM; m_rec_buf->set_out_of_range(is_out_of_range); } -void ha_ctc::reset_rec_buf(bool is_prefetch) { +void ha_ctc::reset_rec_buf(bool is_prefetch) +{ cur_pos_in_buf = INVALID_MAX_UINT32; if (is_prefetch) { cur_pos_in_buf = 0; @@ -2297,7 +2317,8 @@ void ha_ctc::reset_rec_buf(bool is_prefetch) { m_rec_buf->reset(); } -void ha_ctc::set_max_col_index_4_reading() { +void ha_ctc::set_max_col_index_4_reading() +{ max_col_index = table->read_set->n_bits - 1; // max_col_index equals to num_of_cols - 1 in table if it's not a read-only // scan @@ -2311,10 +2332,10 @@ void ha_ctc::set_max_col_index_4_reading() { // find max col index needed by optimizer according to read_set // max_col_index is needed by cantian2mysql func to get a early return for // fullfilling record_buffer - if (m_is_covering_index && active_index != MAX_KEY) { // index_only + if (m_is_covering_index && active_index != MAX_KEY) { // index_only auto index_info = (*table).key_info[active_index]; uint key_fields = index_info.actual_key_parts; - for (int key_id = key_fields -1; key_id >= 0; key_id--) { + for (int key_id = key_fields - 1; key_id >= 0; key_id--) { uint col_id = index_info.key_part[key_id].field->field_index(); if (bitmap_is_set(table->read_set, col_id)) { max_col_index = col_id; @@ -2326,21 +2347,19 @@ void ha_ctc::set_max_col_index_4_reading() { max_col_index--; } } - } -bool ha_ctc::pre_check_for_cascade(bool is_update) { +bool ha_ctc::pre_check_for_cascade(bool is_update) +{ TABLE_SHARE_FOREIGN_KEY_PARENT_INFO *fk = table->s->foreign_key_parent; - + for (uint i = 0; i < table->s->foreign_key_parents; i++) { if (is_update) { - if (dd::Foreign_key::RULE_CASCADE != fk[i].update_rule && - dd::Foreign_key::RULE_SET_NULL != fk[i].update_rule) { + if (dd::Foreign_key::RULE_CASCADE != fk[i].update_rule && dd::Foreign_key::RULE_SET_NULL != fk[i].update_rule) { return false; } } else { - if (dd::Foreign_key::RULE_CASCADE != fk[i].delete_rule && - dd::Foreign_key::RULE_SET_NULL != fk[i].delete_rule) { + if (dd::Foreign_key::RULE_CASCADE != fk[i].delete_rule && dd::Foreign_key::RULE_SET_NULL != fk[i].delete_rule) { return false; } } @@ -2349,11 +2368,13 @@ bool ha_ctc::pre_check_for_cascade(bool is_update) { } ha_ctc::ha_ctc(handlerton *hton, TABLE_SHARE *table_arg) - : handler(hton, table_arg), m_rec_buf(nullptr), m_share(nullptr) { + : handler(hton, table_arg), m_rec_buf(nullptr), m_share(nullptr) +{ ref_length = ROW_ID_LENGTH; } -ha_ctc::~ha_ctc() { +ha_ctc::~ha_ctc() +{ if (m_ctc_buf != nullptr) { ctc_free_buf(&m_tch, m_ctc_buf); m_ctc_buf = nullptr; @@ -2385,7 +2406,8 @@ ha_ctc::~ha_ctc() { free_blob_addrs(); } -int ha_ctc::initialize() { +int ha_ctc::initialize() +{ THD *thd = ha_thd(); int ret = get_tch_in_handler_data(ht, thd, m_tch); if (ret != 0) { @@ -2400,9 +2422,7 @@ int ha_ctc::initialize() { return CT_SUCCESS; } -bool ctc_is_temporary(const dd::Table *table_def) { - return table_def ? table_def->is_temporary() : true; -} +bool ctc_is_temporary(const dd::Table *table_def) { return table_def ? table_def->is_temporary() : true; } /** @brief @@ -2431,7 +2451,8 @@ bool ctc_is_temporary(const dd::Table *table_def) { @retval 0 Success. */ -EXTER_ATTACK int ha_ctc::open(const char *name, int, uint test_if_locked, const dd::Table *table_def) { +EXTER_ATTACK int ha_ctc::open(const char *name, int, uint test_if_locked, const dd::Table *table_def) +{ DBUG_TRACE; assert(table_share == table->s); THD *thd = ha_thd(); @@ -2482,8 +2503,8 @@ EXTER_ATTACK int ha_ctc::open(const char *name, int, uint test_if_locked, const update_sess_ctx_by_tch(m_tch, ctc_hton, thd); check_error_code_to_mysql(ha_thd(), &ret); - if (ret != CT_SUCCESS && !(test_if_locked & (HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)) - && table_share->m_part_info == nullptr) { + if (ret != CT_SUCCESS && !(test_if_locked & (HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)) && + table_share->m_part_info == nullptr) { free_share(); } @@ -2505,7 +2526,8 @@ EXTER_ATTACK int ha_ctc::open(const char *name, int, uint test_if_locked, const sql_base.cc, sql_select.cc and table.cc */ -int ha_ctc::close(void) { +int ha_ctc::close(void) +{ DBUG_TRACE; THD *thd = ha_thd(); @@ -2520,7 +2542,7 @@ int ha_ctc::close(void) { if (is_replay_ddl(thd)) { return 0; } - + // rename table的故障场景下,参天的表不存在,需要忽略open close table的错误 if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd, table->s->table_name.str))) { return 0; @@ -2538,7 +2560,8 @@ int ha_ctc::close(void) { return convert_ctc_error_code_to_mysql(ret); } -int ha_ctc::handle_auto_increment(bool &has_explicit_autoinc) { +int ha_ctc::handle_auto_increment(bool &has_explicit_autoinc) +{ THD *thd = ha_thd(); const Discrete_interval *insert_id_info; insert_id_for_cur_row = 0; @@ -2548,11 +2571,9 @@ int ha_ctc::handle_auto_increment(bool &has_explicit_autoinc) { 2. specify zero but in NO_AUTO_VALUE_ON_ZERO sql mode */ if (table->next_number_field->val_int() != 0 || - (table->autoinc_field_has_explicit_non_null_value && - thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)) { - if (thd->is_error() && - thd->get_stmt_da()->mysql_errno() == ER_TRUNCATED_WRONG_VALUE) { - return HA_ERR_AUTOINC_ERANGE; + (table->autoinc_field_has_explicit_non_null_value && thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)) { + if (thd->is_error() && thd->get_stmt_da()->mysql_errno() == ER_TRUNCATED_WRONG_VALUE) { + return HA_ERR_AUTOINC_ERANGE; } has_explicit_autoinc = true; return CT_SUCCESS; @@ -2571,7 +2592,7 @@ int ha_ctc::handle_auto_increment(bool &has_explicit_autoinc) { insert_id_for_cur_row = forced_val; return CT_SUCCESS; } - + has_explicit_autoinc = false; return CT_SUCCESS; } @@ -2606,2444 +2627,2501 @@ int ha_ctc::handle_auto_increment(bool &has_explicit_autoinc) { sql_insert.cc, sql_select.cc, sql_table.cc, sql_udf.cc and sql_update.cc */ #ifdef METADATA_NORMALIZED -EXTER_ATTACK int ha_ctc::write_row(uchar *buf, bool write_through) { +EXTER_ATTACK int ha_ctc::write_row(uchar *buf, bool write_through) +{ #endif #ifndef METADATA_NORMALIZED -EXTER_ATTACK int ha_ctc::write_row(uchar *buf) { + EXTER_ATTACK int ha_ctc::write_row(uchar * buf) + { #endif - DBUG_TRACE; - THD *thd = ha_thd(); - - if (engine_ddl_passthru(thd) && is_create_table_check(thd)) { - return CT_SUCCESS; - } + DBUG_TRACE; + THD *thd = ha_thd(); - int cantian_record_buf_size = CTC_BUF_LEN; - uint16_t serial_column_offset = 0; - int error_result = CT_SUCCESS; - bool auto_inc_used = false; - bool has_explicit_autoinc = false; - ha_statistic_increment(&System_status_var::ha_write_count); + if (engine_ddl_passthru(thd) && is_create_table_check(thd)) { + return CT_SUCCESS; + } - // if has auto_inc column - if (table->next_number_field && buf == table->record[0]) { - error_result = handle_auto_increment(has_explicit_autoinc); - if (error_result != CT_SUCCESS) { - return error_result; + int cantian_record_buf_size = CTC_BUF_LEN; + uint16_t serial_column_offset = 0; + int error_result = CT_SUCCESS; + bool auto_inc_used = false; + bool has_explicit_autoinc = false; + ha_statistic_increment(&System_status_var::ha_write_count); + + // if has auto_inc column + if (table->next_number_field && buf == table->record[0]) { + error_result = handle_auto_increment(has_explicit_autoinc); + if (error_result != CT_SUCCESS) { + return error_result; + } + auto_inc_used = true; } - auto_inc_used = true; - } - if (!m_rec_buf_4_writing) { - dml_flag_t flag = ctc_get_dml_flag(thd, false, auto_inc_used, has_explicit_autoinc, false); + if (!m_rec_buf_4_writing) { + dml_flag_t flag = ctc_get_dml_flag(thd, false, auto_inc_used, has_explicit_autoinc, false); #ifdef METADATA_NORMALIZED - flag.write_through = write_through; + flag.write_through = write_through; #endif #ifndef METADATA_NORMALIZED - flag.write_through = false; + flag.write_through = false; #endif - error_result = convert_mysql_record_and_write_to_cantian(buf, &cantian_record_buf_size, &serial_column_offset, flag); - return error_result; - } - - // flush records to engine if buffer is full - if (m_rec_buf_4_writing->records() == m_rec_buf_4_writing->max_records()) { - error_result = bulk_insert(); - if (error_result != CT_SUCCESS) { - delete m_rec_buf_4_writing; - m_rec_buf_4_writing = nullptr; + error_result = + convert_mysql_record_and_write_to_cantian(buf, &cantian_record_buf_size, &serial_column_offset, flag); return error_result; } - m_rec_buf_4_writing->reset(); - } - - uchar *cur_write_pos = m_rec_buf_4_writing->add_record(); - memset(cur_write_pos, 0, sizeof(row_head_t)); - record_buf_info_t record_buf = {cur_write_pos, buf, &cantian_record_buf_size}; - - update_member_tch(m_tch, ctc_hton, thd, false); - error_result = mysql_record_to_cantian_record(*table, &record_buf, m_tch, &serial_column_offset); - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); // update for ctc_knl_write_lob in mysql_record_to_cantian_record + // flush records to engine if buffer is full + if (m_rec_buf_4_writing->records() == m_rec_buf_4_writing->max_records()) { + error_result = bulk_insert(); + if (error_result != CT_SUCCESS) { + delete m_rec_buf_4_writing; + m_rec_buf_4_writing = nullptr; + return error_result; + } - if (error_result != 0) { - m_rec_buf_4_writing->reset(); - return error_result; - } - assert(cantian_record_buf_size <= m_cantian_rec_len); + m_rec_buf_4_writing->reset(); + } - return CT_SUCCESS; -} + uchar *cur_write_pos = m_rec_buf_4_writing->add_record(); + memset(cur_write_pos, 0, sizeof(row_head_t)); + record_buf_info_t record_buf = {cur_write_pos, buf, &cantian_record_buf_size}; + update_member_tch(m_tch, ctc_hton, thd, false); + error_result = mysql_record_to_cantian_record(*table, &record_buf, m_tch, &serial_column_offset); + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); // update for ctc_knl_write_lob in mysql_record_to_cantian_record -int ha_ctc::convert_mysql_record_and_write_to_cantian(uchar *buf, int *cantian_record_buf_size, - uint16_t *serial_column_offset, dml_flag_t flag) { - int error_result; - ct_errno_t ret; - uint64_t cur_last_insert_id = 0; - if (m_ctc_buf == nullptr) { - m_ctc_buf = ctc_alloc_buf(&m_tch, BIG_RECORD_SIZE); - if (m_ctc_buf == nullptr) { - return convert_ctc_error_code_to_mysql(ERR_ALLOC_MEMORY); + if (error_result != 0) { + m_rec_buf_4_writing->reset(); + return error_result; } - } - memset(m_ctc_buf, 0, sizeof(row_head_t)); - record_buf_info_t record_buf = {m_ctc_buf, buf, cantian_record_buf_size}; - - update_member_tch(m_tch, ctc_hton, ha_thd()); - error_result = mysql_record_to_cantian_record(*table, &record_buf, m_tch, serial_column_offset); - update_sess_ctx_by_tch(m_tch, ctc_hton, ha_thd()); // update for ctc_knl_write_lob in mysql_record_to_cantian_record - - if (error_result != 0) { - return error_result; - } - update_member_tch(m_tch, ctc_hton, ha_thd()); - record_info_t record_info = {m_ctc_buf, (uint16_t)*cantian_record_buf_size, nullptr, nullptr}; - ret = (ct_errno_t)ctc_write_row(&m_tch, &record_info, *serial_column_offset, &cur_last_insert_id, flag); - update_sess_ctx_by_tch(m_tch, ctc_hton, ha_thd()); - check_error_code_to_mysql(ha_thd(), &ret); + assert(cantian_record_buf_size <= m_cantian_rec_len); - if (table->next_number_field && buf == table->record[0] && !flag.has_explicit_autoinc) { - table->next_number_field->store(cur_last_insert_id, true); - insert_id_for_cur_row = cur_last_insert_id; + return CT_SUCCESS; } - return convert_ctc_error_code_to_mysql(ret); -} + int ha_ctc::convert_mysql_record_and_write_to_cantian(uchar * buf, int *cantian_record_buf_size, + uint16_t *serial_column_offset, dml_flag_t flag) + { + int error_result; + ct_errno_t ret; + uint64_t cur_last_insert_id = 0; + if (m_ctc_buf == nullptr) { + m_ctc_buf = ctc_alloc_buf(&m_tch, BIG_RECORD_SIZE); + if (m_ctc_buf == nullptr) { + return convert_ctc_error_code_to_mysql(ERR_ALLOC_MEMORY); + } + } + memset(m_ctc_buf, 0, sizeof(row_head_t)); + record_buf_info_t record_buf = {m_ctc_buf, buf, cantian_record_buf_size}; -int ha_ctc::bulk_insert_low(dml_flag_t flag, uint *dup_offset) { - record_info_t record_info = {m_rec_buf_data, (uint16_t)m_cantian_rec_len, nullptr, nullptr}; - return ctc_bulk_write(&m_tch, &record_info, m_rec_buf_4_writing->records(), dup_offset, flag, nullptr); -} + update_member_tch(m_tch, ctc_hton, ha_thd()); + error_result = mysql_record_to_cantian_record(*table, &record_buf, m_tch, serial_column_offset); + update_sess_ctx_by_tch(m_tch, ctc_hton, + ha_thd()); // update for ctc_knl_write_lob in mysql_record_to_cantian_record -int ha_ctc::bulk_insert() { - ct_errno_t ret; - uint dup_offset = 0; - THD *thd = ha_thd(); - dml_flag_t flag = ctc_get_dml_flag(thd, false, false, false, false); - update_member_tch(m_tch, ctc_hton, thd); - ret = (ct_errno_t)bulk_insert_low(flag, &dup_offset); - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - check_error_code_to_mysql(thd, &ret); - - if (ret != CT_SUCCESS) { - // refresh table->record[0] to make sure that duplicated contents are correctly set in output - if (ret == ERR_DUPLICATE_KEY) { - record_buf_info_t record_buf = {m_rec_buf_4_writing->record(dup_offset), table->record[0], nullptr}; - index_info_t index = {UINT_MAX, UINT_MAX}; - cantian_record_to_mysql_record(*table, &index, &record_buf, m_tch, nullptr); + if (error_result != 0) { + return error_result; } + update_member_tch(m_tch, ctc_hton, ha_thd()); + record_info_t record_info = {m_ctc_buf, (uint16_t)*cantian_record_buf_size, nullptr, nullptr}; + ret = (ct_errno_t)ctc_write_row(&m_tch, &record_info, *serial_column_offset, &cur_last_insert_id, flag); + update_sess_ctx_by_tch(m_tch, ctc_hton, ha_thd()); + check_error_code_to_mysql(ha_thd(), &ret); + + if (table->next_number_field && buf == table->record[0] && !flag.has_explicit_autoinc) { + table->next_number_field->store(cur_last_insert_id, true); + insert_id_for_cur_row = cur_last_insert_id; + } + return convert_ctc_error_code_to_mysql(ret); } - return CT_SUCCESS; -} -void ha_ctc::start_bulk_insert(ha_rows rows) { - assert(m_rec_buf_4_writing == nullptr); - - THD *thd = ha_thd(); - if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd) || is_create_table_check(thd))) { - return; + int ha_ctc::bulk_insert_low(dml_flag_t flag, uint * dup_offset) + { + record_info_t record_info = {m_rec_buf_data, (uint16_t)m_cantian_rec_len, nullptr, nullptr}; + return ctc_bulk_write(&m_tch, &record_info, m_rec_buf_4_writing->records(), dup_offset, flag, nullptr); } - if (m_rec_buf_data == nullptr) { - m_rec_buf_data = (uchar *)my_malloc(PSI_NOT_INSTRUMENTED, MAX_RECORD_BUFFER_SIZE_CTC, MYF(MY_WME)); - } + int ha_ctc::bulk_insert() + { + ct_errno_t ret; + uint dup_offset = 0; + THD *thd = ha_thd(); + dml_flag_t flag = ctc_get_dml_flag(thd, false, false, false, false); + update_member_tch(m_tch, ctc_hton, thd); + ret = (ct_errno_t)bulk_insert_low(flag, &dup_offset); + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + check_error_code_to_mysql(thd, &ret); - if (rows == 1 || m_is_insert_dup || m_is_replace || m_ignore_dup || table->s->blob_fields > 0 || - table->next_number_field || m_rec_buf_data == nullptr) { - m_rec_buf_4_writing = nullptr; - return; + if (ret != CT_SUCCESS) { + // refresh table->record[0] to make sure that duplicated contents are correctly set in output + if (ret == ERR_DUPLICATE_KEY) { + record_buf_info_t record_buf = {m_rec_buf_4_writing->record(dup_offset), table->record[0], nullptr}; + index_info_t index = {UINT_MAX, UINT_MAX}; + cantian_record_to_mysql_record(*table, &index, &record_buf, m_tch, nullptr); + } + return convert_ctc_error_code_to_mysql(ret); + } + return CT_SUCCESS; } - m_rec_buf_4_writing = new Record_buffer{m_max_batch_num, (size_t)m_cantian_rec_len, m_rec_buf_data}; -} -int ha_ctc::end_bulk_insert() { - if (engine_ddl_passthru(ha_thd()) && is_create_table_check(ha_thd())) { - return 0; - } + void ha_ctc::start_bulk_insert(ha_rows rows) + { + assert(m_rec_buf_4_writing == nullptr); - if (m_rec_buf_4_writing == nullptr) { - return 0; - } + THD *thd = ha_thd(); + if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd) || is_create_table_check(thd))) { + return; + } - int ret = 0; - if (m_rec_buf_4_writing->records() != 0) { - ret = bulk_insert(); - if (ret != 0) { - set_my_errno(ret); + if (m_rec_buf_data == nullptr) { + m_rec_buf_data = (uchar *)my_malloc(PSI_NOT_INSTRUMENTED, MAX_RECORD_BUFFER_SIZE_CTC, MYF(MY_WME)); + } + + if (rows == 1 || m_is_insert_dup || m_is_replace || m_ignore_dup || table->s->blob_fields > 0 || + table->next_number_field || m_rec_buf_data == nullptr) { + m_rec_buf_4_writing = nullptr; + return; } + m_rec_buf_4_writing = new Record_buffer{m_max_batch_num, (size_t)m_cantian_rec_len, m_rec_buf_data}; } - delete m_rec_buf_4_writing; - m_rec_buf_4_writing = nullptr; - return ret; -} + int ha_ctc::end_bulk_insert() + { + if (engine_ddl_passthru(ha_thd()) && is_create_table_check(ha_thd())) { + return 0; + } + + if (m_rec_buf_4_writing == nullptr) { + return 0; + } -static bool check_if_update_primary_key(TABLE *table) { - if (table->s->primary_key < MAX_KEY) { - KEY *keyinfo; - keyinfo = table->s->key_info + table->s->primary_key; - for (uint i = 0; i < keyinfo->user_defined_key_parts; i++) { - uint fieldnr = keyinfo->key_part[i].fieldnr - 1; - if (bitmap_is_set(table->write_set, fieldnr)) { - return true; + int ret = 0; + if (m_rec_buf_4_writing->records() != 0) { + ret = bulk_insert(); + if (ret != 0) { + set_my_errno(ret); } } + + delete m_rec_buf_4_writing; + m_rec_buf_4_writing = nullptr; + return ret; } - - return false; -} -int ctc_cmp_key_values(TABLE *table, const uchar *old_data, const uchar *new_data, uint key_nr) { - if (key_nr == MAX_KEY) { - return 0; + static bool check_if_update_primary_key(TABLE * table) + { + if (table->s->primary_key < MAX_KEY) { + KEY *keyinfo; + keyinfo = table->s->key_info + table->s->primary_key; + for (uint i = 0; i < keyinfo->user_defined_key_parts; i++) { + uint fieldnr = keyinfo->key_part[i].fieldnr - 1; + if (bitmap_is_set(table->write_set, fieldnr)) { + return true; + } + } + } + + return false; } - KEY *key_info = table->key_info + key_nr; - KEY_PART_INFO *key_part = key_info->key_part; - KEY_PART_INFO *key_part_end = key_part + key_info->user_defined_key_parts; + int ctc_cmp_key_values(TABLE * table, const uchar *old_data, const uchar *new_data, uint key_nr) + { + if (key_nr == MAX_KEY) { + return 0; + } + + KEY *key_info = table->key_info + key_nr; + KEY_PART_INFO *key_part = key_info->key_part; + KEY_PART_INFO *key_part_end = key_part + key_info->user_defined_key_parts; - for (; key_part != key_part_end; key_part++) { - Field *field = key_part->field; - if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) { - if (field->cmp_binary((old_data + key_part->offset), (new_data + key_part->offset), (ulong)key_part->length)) { + for (; key_part != key_part_end; key_part++) { + Field *field = key_part->field; + if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) { + if (field->cmp_binary((old_data + key_part->offset), (new_data + key_part->offset), (ulong)key_part->length)) { + return 1; + } + } else if (memcmp(old_data + key_part->offset, new_data + key_part->offset, key_part->length)) { return 1; } - } else if (memcmp(old_data + key_part->offset, new_data + key_part->offset, key_part->length)) { - return 1; } - } - return 0; -} + return 0; + } -/** - @brief - Yes, update_row() does what you expect, it updates a row. old_data will have - the previous row record in it, while new_data will have the newest data in it. - Keep in mind that the server can do updates based on ordering if an ORDER BY - clause was used. Consecutive ordering is not guaranteed. + /** + @brief + Yes, update_row() does what you expect, it updates a row. old_data will have + the previous row record in it, while new_data will have the newest data in it. + Keep in mind that the server can do updates based on ordering if an ORDER BY + clause was used. Consecutive ordering is not guaranteed. - @details - Currently new_data will not have an updated auto_increament record. You can - do this for ctc by doing: + @details + Currently new_data will not have an updated auto_increament record. You can + do this for ctc by doing: - @code + @code - if (table->next_number_field && record == table->record[0]) - update_auto_increment(); + if (table->next_number_field && record == table->record[0]) + update_auto_increment(); - @endcode + @endcode - Called from sql_select.cc, sql_acl.cc, sql_update.cc, and sql_insert.cc. + Called from sql_select.cc, sql_acl.cc, sql_update.cc, and sql_insert.cc. - @see - sql_select.cc, sql_acl.cc, sql_update.cc and sql_insert.cc -*/ -EXTER_ATTACK int ha_ctc::update_row(const uchar *old_data, uchar *new_data) { - DBUG_TRACE; + @see + sql_select.cc, sql_acl.cc, sql_update.cc and sql_insert.cc + */ + EXTER_ATTACK int ha_ctc::update_row(const uchar *old_data, uchar *new_data) + { + DBUG_TRACE; - THD *thd = ha_thd(); - m_is_replace = (thd->lex->sql_command == SQLCOM_REPLACE || - thd->lex->sql_command == SQLCOM_REPLACE_SELECT) ? true : m_is_replace; - if (thd->lex->sql_command == SQLCOM_REPLACE || thd->lex->sql_command == SQLCOM_REPLACE_SELECT) { - uint key_nr = table->file->errkey; - if (key_nr < MAX_KEY && ctc_cmp_key_values(table, old_data, new_data, key_nr) != 0) { - return HA_ERR_KEY_NOT_FOUND; + THD *thd = ha_thd(); + m_is_replace = (thd->lex->sql_command == SQLCOM_REPLACE || thd->lex->sql_command == SQLCOM_REPLACE_SELECT) + ? true + : m_is_replace; + if (thd->lex->sql_command == SQLCOM_REPLACE || thd->lex->sql_command == SQLCOM_REPLACE_SELECT) { + uint key_nr = table->file->errkey; + if (key_nr < MAX_KEY && ctc_cmp_key_values(table, old_data, new_data, key_nr) != 0) { + return HA_ERR_KEY_NOT_FOUND; + } } - } - int cantian_new_record_buf_size = CTC_BUF_LEN; - uint16_t serial_column_offset = 0; - ha_statistic_increment(&System_status_var::ha_update_count); - + int cantian_new_record_buf_size = CTC_BUF_LEN; + uint16_t serial_column_offset = 0; + ha_statistic_increment(&System_status_var::ha_update_count); - vector upd_fields; - bool update_primary_key = m_tch.change_data_capture && check_if_update_primary_key(table); - for (uint16_t i = 0; i < table->write_set->n_bits; i++) { - if (update_primary_key || bitmap_is_set(table->write_set, i)) { - upd_fields.push_back(i); + vector upd_fields; + bool update_primary_key = m_tch.change_data_capture && check_if_update_primary_key(table); + for (uint16_t i = 0; i < table->write_set->n_bits; i++) { + if (update_primary_key || bitmap_is_set(table->write_set, i)) { + upd_fields.push_back(i); + } } - } - if (upd_fields.size() == 0) { - return HA_ERR_RECORD_IS_THE_SAME; - } + if (upd_fields.size() == 0) { + return HA_ERR_RECORD_IS_THE_SAME; + } - if (m_ctc_buf == nullptr) { - m_ctc_buf = ctc_alloc_buf(&m_tch, BIG_RECORD_SIZE); if (m_ctc_buf == nullptr) { - return convert_ctc_error_code_to_mysql(ERR_ALLOC_MEMORY); + m_ctc_buf = ctc_alloc_buf(&m_tch, BIG_RECORD_SIZE); + if (m_ctc_buf == nullptr) { + return convert_ctc_error_code_to_mysql(ERR_ALLOC_MEMORY); + } } - } - memset(m_ctc_buf, 0, sizeof(row_head_t)); + memset(m_ctc_buf, 0, sizeof(row_head_t)); - record_buf_info_t record_buf = {m_ctc_buf, new_data, &cantian_new_record_buf_size}; - ct_errno_t ret = (ct_errno_t)mysql_record_to_cantian_record(*table, &record_buf, - m_tch, &serial_column_offset, &upd_fields); - if (ret != CT_SUCCESS) { - return ret; - } - // return if only update gcol - if (upd_fields.size() == 0) { - return 0; - } - // (m_ignore_dup && m_is_replace) -> special case for load data ... replace into - bool dup_update = m_is_insert_dup || (m_ignore_dup && m_is_replace); - dml_flag_t flag = ctc_get_dml_flag(thd, m_is_replace, false, false, dup_update); - if (!flag.no_foreign_key_check) { - flag.no_cascade_check = flag.dd_update ? true : pre_check_for_cascade(true); + record_buf_info_t record_buf = {m_ctc_buf, new_data, &cantian_new_record_buf_size}; + ct_errno_t ret = + (ct_errno_t)mysql_record_to_cantian_record(*table, &record_buf, m_tch, &serial_column_offset, &upd_fields); + if (ret != CT_SUCCESS) { + return ret; + } + // return if only update gcol + if (upd_fields.size() == 0) { + return 0; + } + // (m_ignore_dup && m_is_replace) -> special case for load data ... replace into + bool dup_update = m_is_insert_dup || (m_ignore_dup && m_is_replace); + dml_flag_t flag = ctc_get_dml_flag(thd, m_is_replace, false, false, dup_update); + if (!flag.no_foreign_key_check) { + flag.no_cascade_check = flag.dd_update ? true : pre_check_for_cascade(true); + } + ret = (ct_errno_t)ctc_update_row(&m_tch, cantian_new_record_buf_size, m_ctc_buf, &upd_fields[0], upd_fields.size(), + flag); + check_error_code_to_mysql(thd, &ret); + return convert_ctc_error_code_to_mysql(ret); } - ret = (ct_errno_t)ctc_update_row(&m_tch, cantian_new_record_buf_size, m_ctc_buf, - &upd_fields[0], upd_fields.size(), flag); - check_error_code_to_mysql(thd, &ret); - return convert_ctc_error_code_to_mysql(ret); -} -/** - @brief - This will delete a row. buf will contain a copy of the row to be deleted. - The server will call this right after the current row has been called (from - either a previous rnd_nexT() or index call). - - @details - If you keep a pointer to the last row or can access a primary key it will - make doing the deletion quite a bit easier. Keep in mind that the server does - not guarantee consecutive deletions. ORDER BY clauses can be used. - - Called in sql_acl.cc and sql_udf.cc to manage internal table - information. Called in sql_delete.cc, sql_insert.cc, and - sql_select.cc. In sql_select it is used for removing duplicates - while in insert it is used for REPLACE calls. + /** + @brief + This will delete a row. buf will contain a copy of the row to be deleted. + The server will call this right after the current row has been called (from + either a previous rnd_nexT() or index call). - @see - sql_acl.cc, sql_udf.cc, sql_delete.cc, sql_insert.cc and sql_select.cc -*/ + @details + If you keep a pointer to the last row or can access a primary key it will + make doing the deletion quite a bit easier. Keep in mind that the server does + not guarantee consecutive deletions. ORDER BY clauses can be used. -int ha_ctc::delete_row(const uchar *buf) { - DBUG_TRACE; - UNUSED_PARAM(buf); - ha_statistic_increment(&System_status_var::ha_delete_count); - THD *thd = ha_thd(); - m_is_replace = (thd->lex->sql_command == SQLCOM_REPLACE || - thd->lex->sql_command == SQLCOM_REPLACE_SELECT) ? true : m_is_replace; - // m_is_insert_dup for on duplicate key update in partiton table when new row is in different partition - dml_flag_t flag = ctc_get_dml_flag(thd, m_is_replace || m_is_insert_dup, false, false, false); - if (!flag.no_foreign_key_check) { - flag.no_cascade_check = flag.dd_update ? true : pre_check_for_cascade(false); - } - ct_errno_t ret = (ct_errno_t)ctc_delete_row(&m_tch, table->s->reclength, flag); - check_error_code_to_mysql(thd, &ret); - return convert_ctc_error_code_to_mysql(ret); -} + Called in sql_acl.cc and sql_udf.cc to manage internal table + information. Called in sql_delete.cc, sql_insert.cc, and + sql_select.cc. In sql_select it is used for removing duplicates + while in insert it is used for REPLACE calls. -bool ha_ctc::is_record_buffer_wanted(ha_rows *const max_rows) const { - *max_rows = 0; - return false; -} + @see + sql_acl.cc, sql_udf.cc, sql_delete.cc, sql_insert.cc and sql_select.cc + */ -// @ref set_record_buffer -int ha_ctc::set_prefetch_buffer() { - if (m_rec_buf) { - delete m_rec_buf; - m_rec_buf = nullptr; + int ha_ctc::delete_row(const uchar *buf) + { + DBUG_TRACE; + UNUSED_PARAM(buf); + ha_statistic_increment(&System_status_var::ha_delete_count); + THD *thd = ha_thd(); + m_is_replace = (thd->lex->sql_command == SQLCOM_REPLACE || thd->lex->sql_command == SQLCOM_REPLACE_SELECT) + ? true + : m_is_replace; + // m_is_insert_dup for on duplicate key update in partiton table when new row is in different partition + dml_flag_t flag = ctc_get_dml_flag(thd, m_is_replace || m_is_insert_dup, false, false, false); + if (!flag.no_foreign_key_check) { + flag.no_cascade_check = flag.dd_update ? true : pre_check_for_cascade(false); + } + ct_errno_t ret = (ct_errno_t)ctc_delete_row(&m_tch, table->s->reclength, flag); + check_error_code_to_mysql(thd, &ret); + return convert_ctc_error_code_to_mysql(ret); } - if (!can_prefetch_records()) { - return CT_SUCCESS; + + bool ha_ctc::is_record_buffer_wanted(ha_rows *const max_rows) const + { + *max_rows = 0; + return false; } - // calculate how many rows to fetch - uint32_t mysql_rec_length = table->s->rec_buff_length; - // max rows that internal buf can support - ha_rows max_rows = max_prefetch_num; - // max rows that record buffer can support - max_rows = (max_rows > MAX_RECORD_BUFFER_SIZE_CTC / mysql_rec_length) ? - MAX_RECORD_BUFFER_SIZE_CTC / mysql_rec_length : max_rows; - // max rows that limited by array in shared mem intf - max_rows = (max_rows > max_prefetch_num - 1) ? max_prefetch_num - 1 : max_rows; + // @ref set_record_buffer + int ha_ctc::set_prefetch_buffer() + { + if (m_rec_buf) { + delete m_rec_buf; + m_rec_buf = nullptr; + } + if (!can_prefetch_records()) { + return CT_SUCCESS; + } + + // calculate how many rows to fetch + uint32_t mysql_rec_length = table->s->rec_buff_length; + // max rows that internal buf can support + ha_rows max_rows = max_prefetch_num; + // max rows that record buffer can support + max_rows = (max_rows > MAX_RECORD_BUFFER_SIZE_CTC / mysql_rec_length) + ? MAX_RECORD_BUFFER_SIZE_CTC / mysql_rec_length + : max_rows; + // max rows that limited by array in shared mem intf + max_rows = (max_rows > max_prefetch_num - 1) ? max_prefetch_num - 1 : max_rows; + + // alloc m_rec_buf_data + if (m_rec_buf_data == nullptr) { + m_rec_buf_data = (uchar *)my_malloc(PSI_NOT_INSTRUMENTED, MAX_RECORD_BUFFER_SIZE_CTC, MYF(MY_WME)); + } + if (m_rec_buf_data == nullptr) { + ctc_log_error("alloc mem failed, m_rec_buf_data size(%u)", MAX_RECORD_BUFFER_SIZE_CTC); + return ERR_ALLOC_MEMORY; + } - // alloc m_rec_buf_data - if (m_rec_buf_data == nullptr) { - m_rec_buf_data = (uchar *)my_malloc(PSI_NOT_INSTRUMENTED, MAX_RECORD_BUFFER_SIZE_CTC, MYF(MY_WME)); - } - if (m_rec_buf_data == nullptr) { - ctc_log_error("alloc mem failed, m_rec_buf_data size(%u)", MAX_RECORD_BUFFER_SIZE_CTC); - return ERR_ALLOC_MEMORY; + m_rec_buf = new Record_buffer{max_rows, mysql_rec_length, m_rec_buf_data}; + ctc_log_note("prefetch record %llu", max_rows); + return CT_SUCCESS; } - m_rec_buf = new Record_buffer{max_rows, mysql_rec_length, m_rec_buf_data}; - ctc_log_note("prefetch record %llu", max_rows); - return CT_SUCCESS; -} + /* + All table scans call this first. + The order of a table scan is: + + ha_tina::store_lock + ha_tina::external_lock + ha_tina::info + ha_tina::rnd_init + ha_tina::extra + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::extra + ha_tina::external_lock + ha_tina::extra + ENUM HA_EXTRA_RESET Reset database to after open + + Each call to ::rnd_next() represents a row returned in the can. When no more + rows can be returned, rnd_next() returns a value of HA_ERR_END_OF_FILE. + The ::info() call is just for the optimizer. -/* - All table scans call this first. - The order of a table scan is: - - ha_tina::store_lock - ha_tina::external_lock - ha_tina::info - ha_tina::rnd_init - ha_tina::extra - ha_tina::rnd_next - ha_tina::rnd_next - ha_tina::rnd_next - ha_tina::rnd_next - ha_tina::rnd_next - ha_tina::rnd_next - ha_tina::rnd_next - ha_tina::rnd_next - ha_tina::rnd_next - ha_tina::extra - ha_tina::external_lock - ha_tina::extra - ENUM HA_EXTRA_RESET Reset database to after open - - Each call to ::rnd_next() represents a row returned in the can. When no more - rows can be returned, rnd_next() returns a value of HA_ERR_END_OF_FILE. - The ::info() call is just for the optimizer. + */ -*/ + // @ref row_prebuilt_t::can_prefetch_records() + bool ha_ctc::can_prefetch_records() const + { + // do not prefetch if set ctc_select_prefetch = false + if (!ctc_select_prefetch) { + return false; + } -// @ref row_prebuilt_t::can_prefetch_records() -bool ha_ctc::can_prefetch_records() const { - // do not prefetch if set ctc_select_prefetch = false - if (!ctc_select_prefetch) { - return false; - } + // do not prefetch if it's not a read-only scan + THD *thd = ha_thd(); + if (thd->lex->sql_command != SQLCOM_SELECT) { + return false; + } - // do not prefetch if it's not a read-only scan - THD *thd = ha_thd(); - if (thd->lex->sql_command != SQLCOM_SELECT) { - return false; - } + // do not prefetch if we have column that may be extremely huge + if (table->s->blob_fields) { + return false; + } - // do not prefetch if we have column that may be extremely huge - if (table->s->blob_fields) { - return false; - } + // do not prefetch, for with recursive & big_tables + if (thd->lex->all_query_blocks_list && thd->lex->all_query_blocks_list->is_recursive()) { + return false; + } - // do not prefetch, for with recursive & big_tables - if (thd->lex->all_query_blocks_list && thd->lex->all_query_blocks_list->is_recursive()) { - return false; + return true; } - return true; -} + /** + @brief + After malloc outline memory for blob field (in convert_blob_to_mysql), + we need to push them into m_blob_addrs and free them after usage. -/** - @brief - After malloc outline memory for blob field (in convert_blob_to_mysql), - we need to push them into m_blob_addrs and free them after usage. + @details + Our purpose is to free the memory we malloc for the current buf that mysql pass to ctc, + so we need to move the field to the current buf we get (either record[0] or record[1], depends on mysql). + Like with DUP_REPLACE (replace into) / DUP_UPDATE (on duplicate key update) sql, + write_record (sql_insert.cc) will use table->record[1] for read instead of table->record[0]. - @details - Our purpose is to free the memory we malloc for the current buf that mysql pass to ctc, - so we need to move the field to the current buf we get (either record[0] or record[1], depends on mysql). - Like with DUP_REPLACE (replace into) / DUP_UPDATE (on duplicate key update) sql, - write_record (sql_insert.cc) will use table->record[1] for read instead of table->record[0]. + @see + sql_insert.cc, reference ha_federated::convert_row_to_internal_format in ha_federated.cc. + */ + void ha_ctc::update_blob_addrs(uchar * record) + { + ptrdiff_t old_ptr = (ptrdiff_t)(record - table->record[0]); + for (uint i = 0; i < table->s->blob_fields; i++) { + uint field_no = table->s->blob_field[i]; + if (!bitmap_is_set(table->read_set, field_no)) { + continue; + } - @see - sql_insert.cc, reference ha_federated::convert_row_to_internal_format in ha_federated.cc. -*/ -void ha_ctc::update_blob_addrs(uchar *record) { - ptrdiff_t old_ptr = (ptrdiff_t)(record - table->record[0]); - for (uint i = 0; i < table->s->blob_fields; i++) { - uint field_no = table->s->blob_field[i]; - if (!bitmap_is_set(table->read_set, field_no)) { - continue; - } + if (table->field[field_no]->is_virtual_gcol()) { + continue; + } - if (table->field[field_no]->is_virtual_gcol()) { - continue; - } - - Field_blob *blob_field = down_cast(table->field[field_no]); - blob_field->move_field_offset(old_ptr); + Field_blob *blob_field = down_cast(table->field[field_no]); + blob_field->move_field_offset(old_ptr); + + if (blob_field->is_null()) { + blob_field->move_field_offset(-old_ptr); + continue; + } - if (blob_field->is_null()) { + m_blob_addrs.push_back(blob_field->get_blob_data()); blob_field->move_field_offset(-old_ptr); - continue; } - - m_blob_addrs.push_back(blob_field->get_blob_data()); - blob_field->move_field_offset(-old_ptr); } -} -void ha_ctc::free_blob_addrs() { - for (auto addr : m_blob_addrs) { - my_free(addr); + void ha_ctc::free_blob_addrs() + { + for (auto addr : m_blob_addrs) { + my_free(addr); + } + m_blob_addrs.clear(); } - m_blob_addrs.clear(); -} -void free_m_cond(ctc_handler_t m_tch, ctc_conds **conds) { - ctc_conds *cond = *conds; - if (cond == nullptr) { - return; - } - if (cond->cond_list == nullptr) { - if (cond->field_info.field_value != nullptr) { - ctc_free_buf(&m_tch, (uint8_t *)(cond->field_info.field_value)); - cond->field_info.field_value = nullptr; + void free_m_cond(ctc_handler_t m_tch, ctc_conds * *conds) + { + ctc_conds *cond = *conds; + if (cond == nullptr) { + return; } - ctc_free_buf(&m_tch, (uint8_t *)cond); - *conds = nullptr; - return; - } - ctc_conds *node = cond->cond_list->first; - int size = cond->cond_list->elements; - for (int i = 0; i < size; i++) { - ctc_conds *tmp = node->next; - free_m_cond(m_tch, &node); - if (tmp == nullptr) { - cond->cond_list->last = nullptr; - ctc_free_buf(&m_tch, (uint8_t *)(cond->cond_list)); - cond->cond_list = nullptr; + if (cond->cond_list == nullptr) { + if (cond->field_info.field_value != nullptr) { + ctc_free_buf(&m_tch, (uint8_t *)(cond->field_info.field_value)); + cond->field_info.field_value = nullptr; + } ctc_free_buf(&m_tch, (uint8_t *)cond); *conds = nullptr; + return; + } + ctc_conds *node = cond->cond_list->first; + int size = cond->cond_list->elements; + for (int i = 0; i < size; i++) { + ctc_conds *tmp = node->next; + free_m_cond(m_tch, &node); + if (tmp == nullptr) { + cond->cond_list->last = nullptr; + ctc_free_buf(&m_tch, (uint8_t *)(cond->cond_list)); + cond->cond_list = nullptr; + ctc_free_buf(&m_tch, (uint8_t *)cond); + *conds = nullptr; + } + node = tmp; } - node = tmp; } -} -int ctc_fill_conds(ctc_handler_t m_tch, const Item *pushed_cond, Field **field, - ctc_conds *m_cond, bool no_backslash) { - memset(m_cond, 0, sizeof(ctc_conds)); - Item *items = const_cast(pushed_cond); - return dfs_fill_conds(m_tch, items, field, m_cond, no_backslash); -} + int ctc_fill_conds(ctc_handler_t m_tch, const Item *pushed_cond, Field **field, ctc_conds *m_cond, bool no_backslash) + { + memset(m_cond, 0, sizeof(ctc_conds)); + Item *items = const_cast(pushed_cond); + return dfs_fill_conds(m_tch, items, field, m_cond, no_backslash); + } -/** - @brief - rnd_init() is called when the system wants the storage engine to do a table - scan. See the ctc in the introduction at the top of this file to see when - rnd_init() is called. + /** + @brief + rnd_init() is called when the system wants the storage engine to do a table + scan. See the ctc in the introduction at the top of this file to see when + rnd_init() is called. - @details - Called from filesort.cc, records.cc, sql_handler.cc, sql_select.cc, - sql_table.cc, and sql_update.cc. + @details + Called from filesort.cc, records.cc, sql_handler.cc, sql_select.cc, + sql_table.cc, and sql_update.cc. - @see - filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc and - sql_update.cc -*/ + @see + filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc and + sql_update.cc + */ -int ha_ctc::rnd_init(bool) { - DBUG_TRACE; - m_index_sorted = false; - THD *thd = ha_thd(); - if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd) || is_create_table_check(thd) || - is_alter_table_scan(m_error_if_not_empty))) { - return 0; - } + int ha_ctc::rnd_init(bool) + { + DBUG_TRACE; + m_index_sorted = false; + THD *thd = ha_thd(); + if (engine_ddl_passthru(thd) && + (is_alter_table_copy(thd) || is_create_table_check(thd) || is_alter_table_scan(m_error_if_not_empty))) { + return 0; + } - ct_errno_t ret = (ct_errno_t)set_prefetch_buffer(); - if (ret != CT_SUCCESS) { - return ret; - } - expected_cursor_action_t action = EXP_CURSOR_ACTION_SELECT; - if (m_select_lock == lock_mode::EXCLUSIVE_LOCK) { - enum_sql_command sql_command = (enum_sql_command)thd_sql_command(ha_thd()); - if (sql_command == SQLCOM_DELETE) { - action = EXP_CURSOR_ACTION_DELETE; - } else if (sql_command != SQLCOM_ALTER_TABLE){ // action can't be set to update when alter operation using copy algorithm - action = EXP_CURSOR_ACTION_UPDATE; + ct_errno_t ret = (ct_errno_t)set_prefetch_buffer(); + if (ret != CT_SUCCESS) { + return ret; + } + expected_cursor_action_t action = EXP_CURSOR_ACTION_SELECT; + if (m_select_lock == lock_mode::EXCLUSIVE_LOCK) { + enum_sql_command sql_command = (enum_sql_command)thd_sql_command(ha_thd()); + if (sql_command == SQLCOM_DELETE) { + action = EXP_CURSOR_ACTION_DELETE; + } else if (sql_command != + SQLCOM_ALTER_TABLE) { // action can't be set to update when alter operation using copy algorithm + action = EXP_CURSOR_ACTION_UPDATE; + } + } + update_member_tch(m_tch, ctc_hton, ha_thd()); + m_tch.cursor_valid = false; + ret = (ct_errno_t)ctc_rnd_init(&m_tch, action, get_select_mode(), m_cond); + update_sess_ctx_by_tch(m_tch, ctc_hton, ha_thd()); + + if (!(table_share->tmp_table != NO_TMP_TABLE && table_share->tmp_table != TRANSACTIONAL_TMP_TABLE) || + !is_log_table) { + update_sess_ctx_cursor_by_tch(m_tch, ctc_hton, thd); } - } - update_member_tch(m_tch, ctc_hton, ha_thd()); - m_tch.cursor_valid = false; - ret = (ct_errno_t)ctc_rnd_init(&m_tch, action, get_select_mode(), m_cond); - update_sess_ctx_by_tch(m_tch, ctc_hton, ha_thd()); - if (!(table_share->tmp_table != NO_TMP_TABLE && table_share->tmp_table != TRANSACTIONAL_TMP_TABLE) - || !is_log_table) { - update_sess_ctx_cursor_by_tch(m_tch, ctc_hton, thd); + check_error_code_to_mysql(ha_thd(), &ret); + cnvrt_to_mysql_record = cantian_record_to_mysql_record; + reset_rec_buf(); + return convert_ctc_error_code_to_mysql(ret); } - check_error_code_to_mysql(ha_thd(), &ret); - cnvrt_to_mysql_record = cantian_record_to_mysql_record; - reset_rec_buf(); - return convert_ctc_error_code_to_mysql(ret); -} + /** + @brief + alloc m_read_buf for select. + */ + int ha_ctc::ctc_alloc_ctc_buf_4_read() + { + // no need alloc/copy/free record in single run mode + if (is_single_run_mode()) { + m_read_buf = nullptr; + return CT_SUCCESS; + } -/** - @brief - alloc m_read_buf for select. -*/ -int ha_ctc::ctc_alloc_ctc_buf_4_read() { - // no need alloc/copy/free record in single run mode - if (is_single_run_mode()) { - m_read_buf = nullptr; - return CT_SUCCESS; - } - - if (m_read_buf != nullptr) { - return CT_SUCCESS; - } + if (m_read_buf != nullptr) { + return CT_SUCCESS; + } - m_read_buf = ctc_alloc_buf(&m_tch, BIG_RECORD_SIZE); - if (m_read_buf == nullptr) { - return convert_ctc_error_code_to_mysql(ERR_ALLOC_MEMORY); + m_read_buf = ctc_alloc_buf(&m_tch, BIG_RECORD_SIZE); + if (m_read_buf == nullptr) { + return convert_ctc_error_code_to_mysql(ERR_ALLOC_MEMORY); + } + return CT_SUCCESS; } - return CT_SUCCESS; -} -/** - @brief - This is called for each row of the table scan. When you run out of records - you should return HA_ERR_END_OF_FILE. Fill buff up with the row information. - The Field structure for the table is the key to getting data into buf - in a manner that will allow the server to understand it. + /** + @brief + This is called for each row of the table scan. When you run out of records + you should return HA_ERR_END_OF_FILE. Fill buff up with the row information. + The Field structure for the table is the key to getting data into buf + in a manner that will allow the server to understand it. - @details - Called from filesort.cc, records.cc, sql_handler.cc, sql_select.cc, - sql_table.cc, and sql_update.cc. + @details + Called from filesort.cc, records.cc, sql_handler.cc, sql_select.cc, + sql_table.cc, and sql_update.cc. - @see - filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc and - sql_update.cc -*/ -int ha_ctc::rnd_next(uchar *buf) { - DBUG_TRACE; + @see + filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc and + sql_update.cc + */ + int ha_ctc::rnd_next(uchar * buf) + { + DBUG_TRACE; - if (unlikely(!m_rec_buf || m_rec_buf->records() == 0)) { - THD *thd = ha_thd(); - if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd) || is_create_table_check(thd) || - is_alter_table_scan(m_error_if_not_empty))) { - return HA_ERR_END_OF_FILE; + if (unlikely(!m_rec_buf || m_rec_buf->records() == 0)) { + THD *thd = ha_thd(); + if (engine_ddl_passthru(thd) && + (is_alter_table_copy(thd) || is_create_table_check(thd) || is_alter_table_scan(m_error_if_not_empty))) { + return HA_ERR_END_OF_FILE; + } } - } - ha_statistic_increment(&System_status_var::ha_read_rnd_next_count); + ha_statistic_increment(&System_status_var::ha_read_rnd_next_count); - if (!m_rec_buf || m_rec_buf->max_records() == 0) { - int ret = CT_SUCCESS; - ct_errno_t ct_ret = CT_SUCCESS; - CTC_RETURN_IF_NOT_ZERO(ctc_alloc_ctc_buf_4_read()); - record_info_t record_info = {m_read_buf, 0, nullptr, nullptr}; - ct_ret = (ct_errno_t)ctc_rnd_next(&m_tch, &record_info); - ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_END_OF_FILE); - return ret; - } + if (!m_rec_buf || m_rec_buf->max_records() == 0) { + int ret = CT_SUCCESS; + ct_errno_t ct_ret = CT_SUCCESS; + CTC_RETURN_IF_NOT_ZERO(ctc_alloc_ctc_buf_4_read()); + record_info_t record_info = {m_read_buf, 0, nullptr, nullptr}; + ct_ret = (ct_errno_t)ctc_rnd_next(&m_tch, &record_info); + ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_END_OF_FILE); + return ret; + } - // initial fetch - if (m_rec_buf->records() != 0) { - if (cur_pos_in_buf >= actual_fetched_nums - 1) { - // records in rec buf are not enough - // reset cur_pos_in_buf - cur_pos_in_buf = INVALID_MAX_UINT32; - if (m_rec_buf->is_out_of_range()) { - set_my_errno(HA_ERR_END_OF_FILE); - return HA_ERR_END_OF_FILE; - } - } else { - // directly fetch record from rec buf - uint8_t *curRecordStart = m_rec_buf->record(cur_pos_in_buf % m_rec_buf->max_records()); - memcpy(buf, curRecordStart, m_rec_buf->record_size()); - cur_pos_in_buf += 1; - if (cur_pos_in_buf % m_rec_buf->max_records() == 0) { - fill_record_to_rec_buffer(); + // initial fetch + if (m_rec_buf->records() != 0) { + if (cur_pos_in_buf >= actual_fetched_nums - 1) { + // records in rec buf are not enough + // reset cur_pos_in_buf + cur_pos_in_buf = INVALID_MAX_UINT32; + if (m_rec_buf->is_out_of_range()) { + set_my_errno(HA_ERR_END_OF_FILE); + return HA_ERR_END_OF_FILE; + } + } else { + // directly fetch record from rec buf + uint8_t *curRecordStart = m_rec_buf->record(cur_pos_in_buf % m_rec_buf->max_records()); + memcpy(buf, curRecordStart, m_rec_buf->record_size()); + cur_pos_in_buf += 1; + if (cur_pos_in_buf % m_rec_buf->max_records() == 0) { + fill_record_to_rec_buffer(); + } + return 0; } - return 0; } - } - int mysql_ret = prefetch_and_fill_record_buffer(buf, ctc_rnd_prefetch); - if (mysql_ret != 0) { - set_my_errno(mysql_ret); - return mysql_ret; + int mysql_ret = prefetch_and_fill_record_buffer(buf, ctc_rnd_prefetch); + if (mysql_ret != 0) { + set_my_errno(mysql_ret); + return mysql_ret; + } + return 0; } - return 0; -} -/** - @brief - position() is called after each call to rnd_next() if the data needs - to be ordered. You can do something like the following to store - the position: - @code - my_store_ptr(ref, ref_length, current_position); - @endcode + /** + @brief + position() is called after each call to rnd_next() if the data needs + to be ordered. You can do something like the following to store + the position: + @code + my_store_ptr(ref, ref_length, current_position); + @endcode - @details - The server uses ref to store data. ref_length in the above case is - the size needed to store current_position. ref is just a byte array - that the server will maintain. If you are using offsets to mark rows, then - current_position should be the offset. If it is a primary key like in - BDB, then it needs to be a primary key. + @details + The server uses ref to store data. ref_length in the above case is + the size needed to store current_position. ref is just a byte array + that the server will maintain. If you are using offsets to mark rows, then + current_position should be the offset. If it is a primary key like in + BDB, then it needs to be a primary key. - Called from filesort.cc, sql_select.cc, sql_delete.cc, and sql_update.cc. + Called from filesort.cc, sql_select.cc, sql_delete.cc, and sql_update.cc. - @see - filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc -*/ -void ha_ctc::position(const uchar *) { - if (cur_pos_in_buf == INVALID_MAX_UINT32) { - ctc_position(&m_tch, ref, ref_length); - return; + @see + filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc + */ + void ha_ctc::position(const uchar *) + { + if (cur_pos_in_buf == INVALID_MAX_UINT32) { + ctc_position(&m_tch, ref, ref_length); + return; + } + assert(cur_pos_in_buf < max_prefetch_num); + memcpy(ref, &m_rowids[cur_pos_in_buf], ref_length); } - assert(cur_pos_in_buf < max_prefetch_num); - memcpy(ref, &m_rowids[cur_pos_in_buf], ref_length); -} - -/** - @brief - This is like rnd_next, but you are given a position to use - to determine the row. The position will be of the type that you stored in - ref. You can use ha_get_ptr(pos,ref_length) to retrieve whatever key - or position you saved when position() was called. - @details - Called from filesort.cc, records.cc, sql_insert.cc, sql_select.cc, and - sql_update.cc. - - @see - filesort.cc, records.cc, sql_insert.cc, sql_select.cc and sql_update.cc -*/ -EXTER_ATTACK int ha_ctc::rnd_pos(uchar *buf, uchar *pos) { - DBUG_TRACE; - ha_statistic_increment(&System_status_var::ha_read_rnd_count); - int ret = CT_SUCCESS; - ct_errno_t ct_ret = CT_SUCCESS; - CTC_RETURN_IF_NOT_ZERO(ctc_alloc_ctc_buf_4_read()); - record_info_t record_info = {m_read_buf, 0, nullptr, nullptr}; - uint key_len = ref_length; - if (IS_CTC_PART(m_tch.part_id)) { - key_len -= PARTITION_BYTES_IN_POS; - } - ct_ret = (ct_errno_t)ctc_rnd_pos(&m_tch, key_len, pos, &record_info); - ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_KEY_NOT_FOUND); - return ret; -} + /** + @brief + This is like rnd_next, but you are given a position to use + to determine the row. The position will be of the type that you stored in + ref. You can use ha_get_ptr(pos,ref_length) to retrieve whatever key + or position you saved when position() was called. -/** - @brief - ::info() is used to return information to the optimizer. See my_base.h for - the complete description. + @details + Called from filesort.cc, records.cc, sql_insert.cc, sql_select.cc, and + sql_update.cc. - @details - Currently this table handler doesn't implement most of the fields really - needed. SHOW also makes use of this data. + @see + filesort.cc, records.cc, sql_insert.cc, sql_select.cc and sql_update.cc + */ + EXTER_ATTACK int ha_ctc::rnd_pos(uchar * buf, uchar * pos) + { + DBUG_TRACE; + ha_statistic_increment(&System_status_var::ha_read_rnd_count); + int ret = CT_SUCCESS; + ct_errno_t ct_ret = CT_SUCCESS; + CTC_RETURN_IF_NOT_ZERO(ctc_alloc_ctc_buf_4_read()); + record_info_t record_info = {m_read_buf, 0, nullptr, nullptr}; + uint key_len = ref_length; + if (IS_CTC_PART(m_tch.part_id)) { + key_len -= PARTITION_BYTES_IN_POS; + } + ct_ret = (ct_errno_t)ctc_rnd_pos(&m_tch, key_len, pos, &record_info); + ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_KEY_NOT_FOUND); + return ret; + } - You will probably want to have the following in your code: - @code - if (records < 2) - records = 2; - @endcode - The reason is that the server will optimize for cases of only a single - record. If, in a table scan, you don't know the number of records, it - will probably be better to set records to two so you can return as many - records as you need. Along with records, a few more variables you may wish - to set are: - records - deleted - data_file_length - index_file_length - delete_length - check_time - Take a look at the public variables in handler.h for more information. - - Called in filesort.cc, ha_heap.cc, item_sum.cc, opt_sum.cc, sql_delete.cc, - sql_delete.cc, sql_derived.cc, sql_select.cc, sql_select.cc, sql_select.cc, - sql_select.cc, sql_select.cc, sql_show.cc, sql_show.cc, sql_show.cc, - sql_show.cc, sql_table.cc, sql_union.cc, and sql_update.cc. + /** + @brief + ::info() is used to return information to the optimizer. See my_base.h for + the complete description. - @see - filesort.cc, ha_heap.cc, item_sum.cc, opt_sum.cc, sql_delete.cc, - sql_delete.cc, sql_derived.cc, sql_select.cc, sql_select.cc, sql_select.cc, - sql_select.cc, sql_select.cc, sql_show.cc, sql_show.cc, sql_show.cc, - sql_show.cc, sql_table.cc, sql_union.cc and sql_update.cc -*/ + @details + Currently this table handler doesn't implement most of the fields really + needed. SHOW also makes use of this data. + + You will probably want to have the following in your code: + @code + if (records < 2) + records = 2; + @endcode + The reason is that the server will optimize for cases of only a single + record. If, in a table scan, you don't know the number of records, it + will probably be better to set records to two so you can return as many + records as you need. Along with records, a few more variables you may wish + to set are: + records + deleted + data_file_length + index_file_length + delete_length + check_time + Take a look at the public variables in handler.h for more information. + + Called in filesort.cc, ha_heap.cc, item_sum.cc, opt_sum.cc, sql_delete.cc, + sql_delete.cc, sql_derived.cc, sql_select.cc, sql_select.cc, sql_select.cc, + sql_select.cc, sql_select.cc, sql_show.cc, sql_show.cc, sql_show.cc, + sql_show.cc, sql_table.cc, sql_union.cc, and sql_update.cc. -void ha_ctc::info_low() { - if (m_share && m_share->cbo_stats != nullptr) { - stats.records = m_share->cbo_stats->ctc_cbo_stats_table->estimate_rows; - } -} + @see + filesort.cc, ha_heap.cc, item_sum.cc, opt_sum.cc, sql_delete.cc, + sql_delete.cc, sql_derived.cc, sql_select.cc, sql_select.cc, sql_select.cc, + sql_select.cc, sql_select.cc, sql_show.cc, sql_show.cc, sql_show.cc, + sql_show.cc, sql_table.cc, sql_union.cc and sql_update.cc + */ -int ha_ctc::info(uint flag) { - DBUG_TRACE; - THD *thd = ha_thd(); - if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd) || is_create_table_check(thd))) { - return 0; + void ha_ctc::info_low() + { + if (m_share && m_share->cbo_stats != nullptr) { + stats.records = m_share->cbo_stats->ctc_cbo_stats_table->estimate_rows; + } } - ct_errno_t ret = CT_SUCCESS; - if (flag & HA_STATUS_VARIABLE) { - if (thd->lex->sql_command == SQLCOM_DELETE && - thd->lex->query_block->where_cond() == nullptr) { - records(&stats.records); + int ha_ctc::info(uint flag) + { + DBUG_TRACE; + THD *thd = ha_thd(); + if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd) || is_create_table_check(thd))) { return 0; } - // analyze..update histogram on colname flag - if ((flag & HA_STATUS_VARIABLE) && (flag & HA_STATUS_NO_LOCK) && - thd->lex->sql_command == SQLCOM_ANALYZE) { - ret = (ct_errno_t)analyze(thd, nullptr); + + ct_errno_t ret = CT_SUCCESS; + if (flag & HA_STATUS_VARIABLE) { + if (thd->lex->sql_command == SQLCOM_DELETE && thd->lex->query_block->where_cond() == nullptr) { + records(&stats.records); + return 0; + } + // analyze..update histogram on colname flag + if ((flag & HA_STATUS_VARIABLE) && (flag & HA_STATUS_NO_LOCK) && thd->lex->sql_command == SQLCOM_ANALYZE) { + ret = (ct_errno_t)analyze(thd, nullptr); + if (ret != CT_SUCCESS) { + return convert_ctc_error_code_to_mysql(ret); + } + } + + ret = (ct_errno_t)get_cbo_stats_4share(); if (ret != CT_SUCCESS) { return convert_ctc_error_code_to_mysql(ret); } } - - ret = (ct_errno_t)get_cbo_stats_4share(); - if (ret != CT_SUCCESS) { - return convert_ctc_error_code_to_mysql(ret); - } - } - info_low(); - if (stats.records < 2) { - /* This is a lie, but you don't want the optimizer to see zero or 1 */ - stats.records = 3; - } + info_low(); + if (stats.records < 2) { + /* This is a lie, but you don't want the optimizer to see zero or 1 */ + stats.records = 3; + } - if (flag & HA_STATUS_ERRKEY) { - char index_name[CTC_MAX_KEY_NAME_LENGTH + 1] = { 0 }; - ret = (ct_errno_t)ctc_get_index_name(&m_tch, index_name); + if (flag & HA_STATUS_ERRKEY) { + char index_name[CTC_MAX_KEY_NAME_LENGTH + 1] = {0}; + ret = (ct_errno_t)ctc_get_index_name(&m_tch, index_name); - if (ret == CT_SUCCESS) { - for (uint i = 0; i < table->s->keys; i++) { - if (strncmp(table->key_info[i].name, index_name, strlen(index_name)) == 0) { - table->file->errkey = i; - break; + if (ret == CT_SUCCESS) { + for (uint i = 0; i < table->s->keys; i++) { + if (strncmp(table->key_info[i].name, index_name, strlen(index_name)) == 0) { + table->file->errkey = i; + break; + } + } + if (table->file->errkey == UINT_MAX) { + return HA_ERR_KEY_NOT_FOUND; } - } - if (table->file->errkey == UINT_MAX) { - return HA_ERR_KEY_NOT_FOUND; } } - } - - return convert_ctc_error_code_to_mysql(ret); -} -int ha_ctc::analyze(THD *thd, HA_CHECK_OPT *) { - - if (engine_ddl_passthru(thd)) { - if (m_share) { - m_share->need_fetch_cbo = true; - } - return 0; + return convert_ctc_error_code_to_mysql(ret); } - if (table->s->tmp_table) { - return HA_ADMIN_OK; - } + int ha_ctc::analyze(THD * thd, HA_CHECK_OPT *) + { + if (engine_ddl_passthru(thd)) { + if (m_share) { + m_share->need_fetch_cbo = true; + } + return 0; + } - char user_name_str[SMALL_RECORD_SIZE] = { 0 }; - ctc_copy_name(user_name_str, thd->lex->query_tables->get_db_name(), SMALL_RECORD_SIZE); + if (table->s->tmp_table) { + return HA_ADMIN_OK; + } - ct_errno_t ret = (ct_errno_t)ctc_analyze_table( - &m_tch, user_name_str, thd->lex->query_tables->table_name, THDVAR(thd, sampling_ratio)); - check_error_code_to_mysql(thd, &ret); - if (ret == CT_SUCCESS && m_share && table_share->m_part_info == nullptr) { - m_share->need_fetch_cbo = true; - } - return convert_ctc_error_code_to_mysql(ret); -} + char user_name_str[SMALL_RECORD_SIZE] = {0}; + ctc_copy_name(user_name_str, thd->lex->query_tables->get_db_name(), SMALL_RECORD_SIZE); -int ha_ctc::optimize(THD *thd, HA_CHECK_OPT *) -{ - if (engine_ddl_passthru(thd)) { - return 0; - } - ctc_ddl_stack_mem stack_mem(0); - update_member_tch(m_tch, ctc_hton, thd); - ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; - FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); - ct_errno_t ret = (ct_errno_t)fill_rebuild_index_req(table, thd, &ddl_ctrl, &stack_mem); - if (ret != 0) { + ct_errno_t ret = (ct_errno_t)ctc_analyze_table(&m_tch, user_name_str, thd->lex->query_tables->table_name, + THDVAR(thd, sampling_ratio)); + check_error_code_to_mysql(thd, &ret); + if (ret == CT_SUCCESS && m_share && table_share->m_part_info == nullptr) { + m_share->need_fetch_cbo = true; + } return convert_ctc_error_code_to_mysql(ret); } - void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); - if (ctc_ddl_req_msg_mem == nullptr) { - return HA_ERR_OUT_OF_MEM; - } - ctc_register_trx(ctc_hton, thd); - ret = (ct_errno_t)ctc_alter_table(ctc_ddl_req_msg_mem, &ddl_ctrl); - ctc_ddl_hook_cantian_error("ctc_optimize_table_cantian_error", thd, &ddl_ctrl, &ret); - m_tch = ddl_ctrl.tch; - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + int ha_ctc::optimize(THD * thd, HA_CHECK_OPT *) + { + if (engine_ddl_passthru(thd)) { + return 0; + } + ctc_ddl_stack_mem stack_mem(0); + update_member_tch(m_tch, ctc_hton, thd); + ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; + FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); + ct_errno_t ret = (ct_errno_t)fill_rebuild_index_req(table, thd, &ddl_ctrl, &stack_mem); + if (ret != 0) { + return convert_ctc_error_code_to_mysql(ret); + } - return ctc_ddl_handle_fault("ctc_optimize table", thd, &ddl_ctrl, ret); -} + void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); + if (ctc_ddl_req_msg_mem == nullptr) { + return HA_ERR_OUT_OF_MEM; + } + ctc_register_trx(ctc_hton, thd); + ret = (ct_errno_t)ctc_alter_table(ctc_ddl_req_msg_mem, &ddl_ctrl); + ctc_ddl_hook_cantian_error("ctc_optimize_table_cantian_error", thd, &ddl_ctrl, &ret); + m_tch = ddl_ctrl.tch; + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); -/** - @brief - extra() is called whenever the server wishes to send a hint to - the storage engine. The myisam engine implements the most hints. - ha_innodb.cc has the most exhaustive list of these hints. + return ctc_ddl_handle_fault("ctc_optimize table", thd, &ddl_ctrl, ret); + } - @see - ha_innodb.cc -*/ -int ha_ctc::extra(enum ha_extra_function operation) { - DBUG_TRACE; + /** + @brief + extra() is called whenever the server wishes to send a hint to + the storage engine. The myisam engine implements the most hints. + ha_innodb.cc has the most exhaustive list of these hints. - switch (operation) { - case HA_EXTRA_WRITE_CAN_REPLACE: - m_is_replace = true; - break; - case HA_EXTRA_WRITE_CANNOT_REPLACE: - m_is_replace = false; - break; - case HA_EXTRA_IGNORE_DUP_KEY: - m_ignore_dup = true; - break; - case HA_EXTRA_NO_IGNORE_DUP_KEY: - m_ignore_dup = false; - m_is_insert_dup = false; - break; - case HA_EXTRA_INSERT_WITH_UPDATE: - m_is_insert_dup = true; - break; - case HA_EXTRA_KEYREAD: - m_is_covering_index = true; - break; - case HA_EXTRA_NO_KEYREAD: - default: - m_is_covering_index = false; - break; - } - return 0; -} + @see + ha_innodb.cc + */ + int ha_ctc::extra(enum ha_extra_function operation) + { + DBUG_TRACE; -int ha_ctc::reset() { - m_is_replace = false; - m_is_insert_dup = false; - m_is_covering_index = false; - m_ignore_dup = false; - m_error_if_not_empty = false; - free_blob_addrs(); - m_pushed_conds = nullptr; - m_remainder_conds = nullptr; - if (m_cond != nullptr) { - free_m_cond(m_tch, &m_cond); + switch (operation) { + case HA_EXTRA_WRITE_CAN_REPLACE: + m_is_replace = true; + break; + case HA_EXTRA_WRITE_CANNOT_REPLACE: + m_is_replace = false; + break; + case HA_EXTRA_IGNORE_DUP_KEY: + m_ignore_dup = true; + break; + case HA_EXTRA_NO_IGNORE_DUP_KEY: + m_ignore_dup = false; + m_is_insert_dup = false; + break; + case HA_EXTRA_INSERT_WITH_UPDATE: + m_is_insert_dup = true; + break; + case HA_EXTRA_KEYREAD: + m_is_covering_index = true; + break; + case HA_EXTRA_NO_KEYREAD: + default: + m_is_covering_index = false; + break; + } + return 0; } - return 0; -} + int ha_ctc::reset() + { + m_is_replace = false; + m_is_insert_dup = false; + m_is_covering_index = false; + m_ignore_dup = false; + m_error_if_not_empty = false; + free_blob_addrs(); + m_pushed_conds = nullptr; + m_remainder_conds = nullptr; + if (m_cond != nullptr) { + free_m_cond(m_tch, &m_cond); + } -int ha_ctc::rnd_end() { - DBUG_TRACE; - THD *thd = ha_thd(); - if (engine_ddl_passthru(thd) && (is_alter_table_copy(thd) || is_create_table_check(thd) || - is_alter_table_scan(m_error_if_not_empty))) { return 0; } - int ret = CT_SUCCESS; - if ((table_share->tmp_table != NO_TMP_TABLE && table_share->tmp_table != TRANSACTIONAL_TMP_TABLE) || - is_log_table) { - ct_errno_t ctc_ret = (ct_errno_t)ctc_rnd_end(&m_tch); - check_error_code_to_mysql(ha_thd(), &ctc_ret); - ret = convert_ctc_error_code_to_mysql(ctc_ret); - } + int ha_ctc::rnd_end() + { + DBUG_TRACE; + THD *thd = ha_thd(); + if (engine_ddl_passthru(thd) && + (is_alter_table_copy(thd) || is_create_table_check(thd) || is_alter_table_scan(m_error_if_not_empty))) { + return 0; + } - m_tch.cursor_valid = false; - m_tch.cursor_addr = INVALID_VALUE64; - return ret; -} + int ret = CT_SUCCESS; + if ((table_share->tmp_table != NO_TMP_TABLE && table_share->tmp_table != TRANSACTIONAL_TMP_TABLE) || is_log_table) { + ct_errno_t ctc_ret = (ct_errno_t)ctc_rnd_end(&m_tch); + check_error_code_to_mysql(ha_thd(), &ctc_ret); + ret = convert_ctc_error_code_to_mysql(ctc_ret); + } -int ha_ctc::index_init(uint index, bool sorted) { - DBUG_TRACE; - ct_errno_t ret = (ct_errno_t)set_prefetch_buffer(); - if (ret != CT_SUCCESS) { - return ret; - } - update_member_tch(m_tch, ctc_hton, ha_thd(), false); - m_index_sorted = sorted; - active_index = index; - reset_rec_buf(); - if (m_tch.cursor_ref <= 0) { - m_tch.cursor_ref = 0; + m_tch.cursor_valid = false; m_tch.cursor_addr = INVALID_VALUE64; - } - m_tch.cursor_ref++; - m_tch.cursor_valid = false; - return CT_SUCCESS; -} - -int ha_ctc::index_end() { - DBUG_TRACE; - - active_index = MAX_KEY; - - int ret = CT_SUCCESS; - if (table_share->tmp_table != NO_TMP_TABLE && table_share->tmp_table != TRANSACTIONAL_TMP_TABLE) { - ret = (ct_errno_t)ctc_index_end(&m_tch); - assert(ret == CT_SUCCESS); + return ret; } - m_tch.cursor_ref--; - if (m_tch.cursor_ref <= 0) { + int ha_ctc::index_init(uint index, bool sorted) + { + DBUG_TRACE; + ct_errno_t ret = (ct_errno_t)set_prefetch_buffer(); + if (ret != CT_SUCCESS) { + return ret; + } + update_member_tch(m_tch, ctc_hton, ha_thd(), false); + m_index_sorted = sorted; + active_index = index; + reset_rec_buf(); + if (m_tch.cursor_ref <= 0) { + m_tch.cursor_ref = 0; + m_tch.cursor_addr = INVALID_VALUE64; + } + m_tch.cursor_ref++; m_tch.cursor_valid = false; + return CT_SUCCESS; } - return ret; -} -int ha_ctc::process_cantian_record(uchar *buf, record_info_t *record_info, ct_errno_t ct_ret, int rc_ret) { - int ret = CT_SUCCESS; - check_error_code_to_mysql(ha_thd(), &ct_ret); - if (ct_ret != CT_SUCCESS) { - ret = convert_ctc_error_code_to_mysql(ct_ret); - return ret; - } + int ha_ctc::index_end() + { + DBUG_TRACE; + + active_index = MAX_KEY; + + int ret = CT_SUCCESS; + if (table_share->tmp_table != NO_TMP_TABLE && table_share->tmp_table != TRANSACTIONAL_TMP_TABLE) { + ret = (ct_errno_t)ctc_index_end(&m_tch); + assert(ret == CT_SUCCESS); + } - if (record_info->record_len == 0) { - set_my_errno(rc_ret); - ret = rc_ret; + m_tch.cursor_ref--; + if (m_tch.cursor_ref <= 0) { + m_tch.cursor_valid = false; + } return ret; } - record_buf_info_t record_buf = {record_info->record, buf, nullptr}; - index_info_t index = {active_index, UINT_MAX}; - cnvrt_to_mysql_record(*table, &index, &record_buf, m_tch, record_info); - update_blob_addrs(buf); + int ha_ctc::process_cantian_record(uchar * buf, record_info_t * record_info, ct_errno_t ct_ret, int rc_ret) + { + int ret = CT_SUCCESS; + check_error_code_to_mysql(ha_thd(), &ct_ret); + if (ct_ret != CT_SUCCESS) { + ret = convert_ctc_error_code_to_mysql(ct_ret); + return ret; + } - return ret; -} + if (record_info->record_len == 0) { + set_my_errno(rc_ret); + ret = rc_ret; + return ret; + } -EXTER_ATTACK int ha_ctc::index_read(uchar *buf, const uchar *key, uint key_len, ha_rkey_function find_flag) { - DBUG_TRACE; - ha_statistic_increment(&System_status_var::ha_read_key_count); + record_buf_info_t record_buf = {record_info->record, buf, nullptr}; + index_info_t index = {active_index, UINT_MAX}; + cnvrt_to_mysql_record(*table, &index, &record_buf, m_tch, record_info); + update_blob_addrs(buf); - // reset prefetch buf if calling multiple index_read continuously without index_init as interval - if (m_rec_buf && m_rec_buf->records() > 0) { - reset_rec_buf(); + return ret; } - m_action = m_is_covering_index ? EXP_CURSOR_ACTION_INDEX_ONLY : EXP_CURSOR_ACTION_SELECT; - if (m_select_lock == lock_mode::EXCLUSIVE_LOCK) { - enum_sql_command sql_command = (enum_sql_command)thd_sql_command(ha_thd()); - if (sql_command == SQLCOM_DELETE) { - m_action = EXP_CURSOR_ACTION_DELETE; - m_is_covering_index = false; - } else if (sql_command != SQLCOM_ALTER_TABLE) { - m_action = EXP_CURSOR_ACTION_UPDATE; - m_is_covering_index = false; - } - } - cnvrt_to_mysql_record = m_is_covering_index ? cantian_index_record_to_mysql_record : cantian_record_to_mysql_record; - - index_key_info_t index_key_info; - memset(&index_key_info.key_info, 0, sizeof(index_key_info.key_info)); - index_key_info.find_flag = find_flag; - index_key_info.action = m_action; - index_key_info.active_index = active_index; - index_key_info.sorted = m_index_sorted; - index_key_info.need_init = !m_tch.cursor_valid; - int len = strlen(table->key_info[active_index].name); - memcpy(index_key_info.index_name, table->key_info[active_index].name, len + 1); - index_key_info.index_skip_scan = false; + EXTER_ATTACK int ha_ctc::index_read(uchar * buf, const uchar *key, uint key_len, ha_rkey_function find_flag) + { + DBUG_TRACE; + ha_statistic_increment(&System_status_var::ha_read_key_count); + + // reset prefetch buf if calling multiple index_read continuously without index_init as interval + if (m_rec_buf && m_rec_buf->records() > 0) { + reset_rec_buf(); + } + + m_action = m_is_covering_index ? EXP_CURSOR_ACTION_INDEX_ONLY : EXP_CURSOR_ACTION_SELECT; + if (m_select_lock == lock_mode::EXCLUSIVE_LOCK) { + enum_sql_command sql_command = (enum_sql_command)thd_sql_command(ha_thd()); + if (sql_command == SQLCOM_DELETE) { + m_action = EXP_CURSOR_ACTION_DELETE; + m_is_covering_index = false; + } else if (sql_command != SQLCOM_ALTER_TABLE) { + m_action = EXP_CURSOR_ACTION_UPDATE; + m_is_covering_index = false; + } + } + cnvrt_to_mysql_record = m_is_covering_index ? cantian_index_record_to_mysql_record : cantian_record_to_mysql_record; + + index_key_info_t index_key_info; + memset(&index_key_info.key_info, 0, sizeof(index_key_info.key_info)); + index_key_info.find_flag = find_flag; + index_key_info.action = m_action; + index_key_info.active_index = active_index; + index_key_info.sorted = m_index_sorted; + index_key_info.need_init = !m_tch.cursor_valid; + int len = strlen(table->key_info[active_index].name); + memcpy(index_key_info.index_name, table->key_info[active_index].name, len + 1); + index_key_info.index_skip_scan = false; #ifdef FEATURE_X_FOR_MYSQL_32 - if (table->reginfo.qep_tab && table->reginfo.qep_tab->range_scan() && - table->reginfo.qep_tab->range_scan()->type == AccessPath::INDEX_SKIP_SCAN) { - index_key_info.index_skip_scan = true; - } + if (table->reginfo.qep_tab && table->reginfo.qep_tab->range_scan() && + table->reginfo.qep_tab->range_scan()->type == AccessPath::INDEX_SKIP_SCAN) { + index_key_info.index_skip_scan = true; + } #elif defined(FEATURE_X_FOR_MYSQL_26) if (table->reginfo.qep_tab && table->reginfo.qep_tab->quick_optim() && table->reginfo.qep_tab->quick_optim()->get_type() == QUICK_SELECT_I::QS_TYPE_SKIP_SCAN) { index_key_info.index_skip_scan = true; } #endif - int ret = ctc_fill_index_key_info(table, key, key_len, end_range, &index_key_info, index_key_info.index_skip_scan); - if (ret != CT_SUCCESS) { + int ret = ctc_fill_index_key_info(table, key, key_len, end_range, &index_key_info, index_key_info.index_skip_scan); + if (ret != CT_SUCCESS) { ctc_log_error("ha_ctc::index_read: fill index key info failed, ret(%d).", ret); return ret; - } + } - bool has_right_key = !index_key_info.index_skip_scan && end_range != nullptr && end_range->length != 0; + bool has_right_key = !index_key_info.index_skip_scan && end_range != nullptr && end_range->length != 0; - dec4_t d4[MAX_KEY_COLUMNS * 2]; - ret = ctc_convert_index_datatype(table, &index_key_info, has_right_key, d4); - if (ret != CT_SUCCESS) { + dec4_t d4[MAX_KEY_COLUMNS * 2]; + ret = ctc_convert_index_datatype(table, &index_key_info, has_right_key, d4); + if (ret != CT_SUCCESS) { ctc_log_error("ha_ctc::index_read: convert data type for index search failed, ret(%d).", ret); return ret; - } - - CTC_RETURN_IF_NOT_ZERO(ctc_alloc_ctc_buf_4_read()); - update_member_tch(m_tch, ctc_hton, ha_thd()); - record_info_t record_info = {m_read_buf, 0, nullptr, nullptr}; - - attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, true); - ct_errno_t ct_ret = (ct_errno_t)ctc_index_read(&m_tch, &record_info, &index_key_info, - get_select_mode(), m_cond, m_is_replace || m_is_insert_dup); - update_sess_ctx_by_tch(m_tch, ctc_hton, ha_thd()); - attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, false); - if (index_key_info.need_init) { - if (!(table_share->tmp_table != NO_TMP_TABLE && table_share->tmp_table != TRANSACTIONAL_TMP_TABLE)) { - update_sess_ctx_cursor_by_tch(m_tch, ctc_hton, ha_thd()); } - index_key_info.need_init = false; - } - ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_KEY_NOT_FOUND); - return ret; -} - -EXTER_ATTACK int ha_ctc::index_read_last(uchar *buf, const uchar *key_ptr, uint key_len) { - return index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST); -} - -int ha_ctc::index_fetch(uchar *buf) { - DBUG_TRACE; - int mysql_ret = 0; - - if (!m_rec_buf || m_rec_buf->max_records() == 0) { - int ret = CT_SUCCESS; - ct_errno_t ct_ret = CT_SUCCESS; CTC_RETURN_IF_NOT_ZERO(ctc_alloc_ctc_buf_4_read()); + update_member_tch(m_tch, ctc_hton, ha_thd()); record_info_t record_info = {m_read_buf, 0, nullptr, nullptr}; + attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, true); - ct_ret = (ct_errno_t)ctc_general_fetch(&m_tch, &record_info); + ct_errno_t ct_ret = (ct_errno_t)ctc_index_read(&m_tch, &record_info, &index_key_info, get_select_mode(), m_cond, + m_is_replace || m_is_insert_dup); + update_sess_ctx_by_tch(m_tch, ctc_hton, ha_thd()); attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, false); - ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_END_OF_FILE); - return ret; - } - - // initial fetch - if (m_rec_buf->records() != 0) { - if (cur_pos_in_buf >= actual_fetched_nums - 1) { - // records in rec buf are not enough - // reset cur_pos_in_buf - cur_pos_in_buf = INVALID_MAX_UINT32; - if (m_rec_buf->is_out_of_range()) { - set_my_errno(HA_ERR_END_OF_FILE); - return HA_ERR_END_OF_FILE; - } - } else { - // directly fetch record from rec buf - uint8_t *curRecordStart = m_rec_buf->record(cur_pos_in_buf % m_rec_buf->max_records()); - memcpy(buf, curRecordStart, m_rec_buf->record_size()); - cur_pos_in_buf += 1; - if (cur_pos_in_buf % m_rec_buf->max_records() == 0) { - fill_record_to_rec_buffer(); + if (index_key_info.need_init) { + if (!(table_share->tmp_table != NO_TMP_TABLE && table_share->tmp_table != TRANSACTIONAL_TMP_TABLE)) { + update_sess_ctx_cursor_by_tch(m_tch, ctc_hton, ha_thd()); } - return CT_SUCCESS; + index_key_info.need_init = false; } - } - attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, true); - mysql_ret = prefetch_and_fill_record_buffer(buf, ctc_general_prefetch); - attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, false); + ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_KEY_NOT_FOUND); + return ret; + } - if (mysql_ret != 0) { - set_my_errno(mysql_ret); - return mysql_ret; + EXTER_ATTACK int ha_ctc::index_read_last(uchar * buf, const uchar *key_ptr, uint key_len) + { + return index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST); } - return CT_SUCCESS; -} -int ha_ctc::index_next_same(uchar *buf, const uchar *, uint) { - DBUG_TRACE; - ha_statistic_increment(&System_status_var::ha_read_next_count); - return index_fetch(buf); -} + int ha_ctc::index_fetch(uchar * buf) + { + DBUG_TRACE; + int mysql_ret = 0; + + if (!m_rec_buf || m_rec_buf->max_records() == 0) { + int ret = CT_SUCCESS; + ct_errno_t ct_ret = CT_SUCCESS; + CTC_RETURN_IF_NOT_ZERO(ctc_alloc_ctc_buf_4_read()); + record_info_t record_info = {m_read_buf, 0, nullptr, nullptr}; + attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, true); + ct_ret = (ct_errno_t)ctc_general_fetch(&m_tch, &record_info); + attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, false); + ret = process_cantian_record(buf, &record_info, ct_ret, HA_ERR_END_OF_FILE); + return ret; + } -/** - @brief - Used to read forward through the index. -*/ -int ha_ctc::index_next(uchar *buf) { - DBUG_TRACE; - ha_statistic_increment(&System_status_var::ha_read_next_count); - return index_fetch(buf); -} + // initial fetch + if (m_rec_buf->records() != 0) { + if (cur_pos_in_buf >= actual_fetched_nums - 1) { + // records in rec buf are not enough + // reset cur_pos_in_buf + cur_pos_in_buf = INVALID_MAX_UINT32; + if (m_rec_buf->is_out_of_range()) { + set_my_errno(HA_ERR_END_OF_FILE); + return HA_ERR_END_OF_FILE; + } + } else { + // directly fetch record from rec buf + uint8_t *curRecordStart = m_rec_buf->record(cur_pos_in_buf % m_rec_buf->max_records()); + memcpy(buf, curRecordStart, m_rec_buf->record_size()); + cur_pos_in_buf += 1; + if (cur_pos_in_buf % m_rec_buf->max_records() == 0) { + fill_record_to_rec_buffer(); + } + return CT_SUCCESS; + } + } -/** - @brief - Used to read backwards through the index. -*/ -int ha_ctc::index_prev(uchar *buf) { - DBUG_TRACE; - ha_statistic_increment(&System_status_var::ha_read_prev_count); - return index_fetch(buf); -} + attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, true); + mysql_ret = prefetch_and_fill_record_buffer(buf, ctc_general_prefetch); + attachable_trx_update_pre_addr(ctc_hton, ha_thd(), &m_tch, false); -/** - @brief - index_first() asks for the first key in the index. + if (mysql_ret != 0) { + set_my_errno(mysql_ret); + return mysql_ret; + } + return CT_SUCCESS; + } - @details - Called from opt_range.cc, opt_sum.cc, sql_handler.cc, and sql_select.cc. + int ha_ctc::index_next_same(uchar * buf, const uchar *, uint) + { + DBUG_TRACE; + ha_statistic_increment(&System_status_var::ha_read_next_count); + return index_fetch(buf); + } - @see - opt_range.cc, opt_sum.cc, sql_handler.cc and sql_select.cc -*/ -int ha_ctc::index_first(uchar *buf) { - DBUG_TRACE; - ha_statistic_increment(&System_status_var::ha_read_first_count); - int error = index_read(buf, nullptr, 0, HA_READ_AFTER_KEY); - /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */ - if (error == HA_ERR_KEY_NOT_FOUND) { - error = HA_ERR_END_OF_FILE; + /** + @brief + Used to read forward through the index. + */ + int ha_ctc::index_next(uchar * buf) + { + DBUG_TRACE; + ha_statistic_increment(&System_status_var::ha_read_next_count); + return index_fetch(buf); } - return error; -} -/** - @brief - index_last() asks for the last key in the index. + /** + @brief + Used to read backwards through the index. + */ + int ha_ctc::index_prev(uchar * buf) + { + DBUG_TRACE; + ha_statistic_increment(&System_status_var::ha_read_prev_count); + return index_fetch(buf); + } - @details - Called from opt_range.cc, opt_sum.cc, sql_handler.cc, and sql_select.cc. + /** + @brief + index_first() asks for the first key in the index. - @see - opt_range.cc, opt_sum.cc, sql_handler.cc and sql_select.cc -*/ -int ha_ctc::index_last(uchar *buf) { - DBUG_TRACE; - ha_statistic_increment(&System_status_var::ha_read_last_count); - int error = index_read(buf, nullptr, 0, HA_READ_BEFORE_KEY); - /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */ - if (error == HA_ERR_KEY_NOT_FOUND) { - error = HA_ERR_END_OF_FILE; + @details + Called from opt_range.cc, opt_sum.cc, sql_handler.cc, and sql_select.cc. + + @see + opt_range.cc, opt_sum.cc, sql_handler.cc and sql_select.cc + */ + int ha_ctc::index_first(uchar * buf) + { + DBUG_TRACE; + ha_statistic_increment(&System_status_var::ha_read_first_count); + int error = index_read(buf, nullptr, 0, HA_READ_AFTER_KEY); + /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */ + if (error == HA_ERR_KEY_NOT_FOUND) { + error = HA_ERR_END_OF_FILE; + } + return error; } - return error; -} -/** - @brief - Used to delete all rows in a table, including cases of truncate and cases - where the optimizer realizes that all rows will be removed as a result of an - SQL statement. + /** + @brief + index_last() asks for the last key in the index. - @details - Called from item_sum.cc by Item_func_group_concat::clear(), - Item_sum_count_distinct::clear(), and Item_func_group_concat::clear(). - Called from sql_delete.cc by mysql_delete(). - Called from sql_select.cc by JOIN::reinit(). - Called from sql_union.cc by st_select_lex_unit::exec(). + @details + Called from opt_range.cc, opt_sum.cc, sql_handler.cc, and sql_select.cc. - @see - Item_func_group_concat::clear(), Item_sum_count_distinct::clear() and - Item_func_group_concat::clear() in item_sum.cc; - mysql_delete() in sql_delete.cc; - JOIN::reinit() in sql_select.cc and - st_select_lex_unit::exec() in sql_union.cc. -*/ -int ha_ctc::delete_all_rows() { - DBUG_TRACE; - THD *thd = ha_thd(); - update_member_tch(m_tch, ctc_hton, thd); - dml_flag_t flag = ctc_get_dml_flag(thd, false, false, false, false); - if (!flag.no_foreign_key_check) { - flag.no_cascade_check = pre_check_for_cascade(false); - } - ct_errno_t ret = (ct_errno_t)ctc_delete_all_rows(&m_tch, flag); - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - check_error_code_to_mysql(thd, &ret); - if (thd->lex->is_ignore() && ret == ERR_ROW_IS_REFERENCED) { - return 0; + @see + opt_range.cc, opt_sum.cc, sql_handler.cc and sql_select.cc + */ + int ha_ctc::index_last(uchar * buf) + { + DBUG_TRACE; + ha_statistic_increment(&System_status_var::ha_read_last_count); + int error = index_read(buf, nullptr, 0, HA_READ_BEFORE_KEY); + /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */ + if (error == HA_ERR_KEY_NOT_FOUND) { + error = HA_ERR_END_OF_FILE; + } + return error; } - return convert_ctc_error_code_to_mysql(ret); -} -/** - @brief - max_supported_keys() is called when create indexes; + /** + @brief + Used to delete all rows in a table, including cases of truncate and cases + where the optimizer realizes that all rows will be removed as a result of an + SQL statement. - @details - To get the the maximum number of indexes per table of CANTIAN -*/ -uint ha_ctc::max_supported_keys() const { - return CTC_MAX_KEY_NUM; -} + @details + Called from item_sum.cc by Item_func_group_concat::clear(), + Item_sum_count_distinct::clear(), and Item_func_group_concat::clear(). + Called from sql_delete.cc by mysql_delete(). + Called from sql_select.cc by JOIN::reinit(). + Called from sql_union.cc by st_select_lex_unit::exec(). -/** - @brief - max_supported_key_length() is called when create indexes; + @see + Item_func_group_concat::clear(), Item_sum_count_distinct::clear() and + Item_func_group_concat::clear() in item_sum.cc; + mysql_delete() in sql_delete.cc; + JOIN::reinit() in sql_select.cc and + st_select_lex_unit::exec() in sql_union.cc. + */ + int ha_ctc::delete_all_rows() + { + DBUG_TRACE; + THD *thd = ha_thd(); + update_member_tch(m_tch, ctc_hton, thd); + dml_flag_t flag = ctc_get_dml_flag(thd, false, false, false, false); + if (!flag.no_foreign_key_check) { + flag.no_cascade_check = pre_check_for_cascade(false); + } + ct_errno_t ret = (ct_errno_t)ctc_delete_all_rows(&m_tch, flag); + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + check_error_code_to_mysql(thd, &ret); + if (thd->lex->is_ignore() && ret == ERR_ROW_IS_REFERENCED) { + return 0; + } + return convert_ctc_error_code_to_mysql(ret); + } - @details - To get the max possible key length of CANTIAN -*/ -uint ha_ctc::max_supported_key_length() const { - return CTC_MAX_KEY_LENGTH; -} + /** + @brief + max_supported_keys() is called when create indexes; -/** - @brief - max_supported_key_parts() is called when create indexes; + @details + To get the the maximum number of indexes per table of CANTIAN + */ + uint ha_ctc::max_supported_keys() const { return CTC_MAX_KEY_NUM; } - @details - To get the maximum columns of a composite index -*/ -uint ha_ctc::max_supported_key_parts() const { - return CTC_MAX_KEY_PARTS; -} + /** + @brief + max_supported_key_length() is called when create indexes; -/** - @brief - max_supported_key_part_length() is called when create indexes; + @details + To get the max possible key length of CANTIAN + */ + uint ha_ctc::max_supported_key_length() const { return CTC_MAX_KEY_LENGTH; } - @details - To get the maximum supported indexed columns length -*/ -uint ha_ctc::max_supported_key_part_length( - HA_CREATE_INFO *create_info MY_ATTRIBUTE((unused))) const { - return CTC_MAX_KEY_PART_LENGTH; -} + /** + @brief + max_supported_key_parts() is called when create indexes; -enum_alter_inplace_result ha_ctc::check_if_supported_inplace_alter( - TABLE *altered_table, Alter_inplace_info *ha_alter_info) { - DBUG_TRACE; - THD *thd = ha_thd(); + @details + To get the maximum columns of a composite index + */ + uint ha_ctc::max_supported_key_parts() const { return CTC_MAX_KEY_PARTS; } - // remote node execute ALTER statement using default way - if (engine_ddl_passthru(thd)) { - return HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - } + /** + @brief + max_supported_key_part_length() is called when create indexes; - m_error_if_not_empty = ha_alter_info->error_if_not_empty; - if (ha_alter_info->handler_flags & ~(CTC_INPLACE_IGNORE | CTC_ALTER_NOREBUILD | CTC_ALTER_REBUILD)) { - if (ha_alter_info->handler_flags & COLUMN_TYPE_OPERATIONS) { - ha_alter_info->unsupported_reason = my_get_err_msg(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE); - return HA_ALTER_INPLACE_NOT_SUPPORTED; - } + @details + To get the maximum supported indexed columns length + */ + uint ha_ctc::max_supported_key_part_length(HA_CREATE_INFO * create_info MY_ATTRIBUTE((unused))) const + { + return CTC_MAX_KEY_PART_LENGTH; } - /* Only support NULL -> NOT NULL change if strict table sql_mode is set. */ - if ((ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE) && - !thd_is_strict_mode(thd)) { - ha_alter_info->unsupported_reason = my_get_err_msg(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL); - return HA_ALTER_INPLACE_NOT_SUPPORTED; - } + enum_alter_inplace_result ha_ctc::check_if_supported_inplace_alter(TABLE * altered_table, + Alter_inplace_info * ha_alter_info) + { + DBUG_TRACE; + THD *thd = ha_thd(); - // alter table add column containing stored generated column: json_array() as default - if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_STORED_GENERATED_COLUMN) { - ha_alter_info->unsupported_reason = my_get_err_msg(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON); - return HA_ALTER_INPLACE_NOT_SUPPORTED; - } + // remote node execute ALTER statement using default way + if (engine_ddl_passthru(thd)) { + return HA_ALTER_INPLACE_EXCLUSIVE_LOCK; + } - if (ha_alter_info->handler_flags & CTC_ALTER_COL_ORDER) { - ha_alter_info->unsupported_reason = "Altering column order or drop column"; - return HA_ALTER_INPLACE_NOT_SUPPORTED; - } + m_error_if_not_empty = ha_alter_info->error_if_not_empty; + if (ha_alter_info->handler_flags & ~(CTC_INPLACE_IGNORE | CTC_ALTER_NOREBUILD | CTC_ALTER_REBUILD)) { + if (ha_alter_info->handler_flags & COLUMN_TYPE_OPERATIONS) { + ha_alter_info->unsupported_reason = my_get_err_msg(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE); + return HA_ALTER_INPLACE_NOT_SUPPORTED; + } + } - if ((ha_alter_info->handler_flags & Alter_inplace_info::ALTER_RENAME) && - (strcmp(altered_table->s->db.str, table->s->db.str) != 0)) { - ha_alter_info->unsupported_reason = "Table is renamed cross database"; - return HA_ALTER_INPLACE_NOT_SUPPORTED; - } + /* Only support NULL -> NOT NULL change if strict table sql_mode is set. */ + if ((ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE) && !thd_is_strict_mode(thd)) { + ha_alter_info->unsupported_reason = my_get_err_msg(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL); + return HA_ALTER_INPLACE_NOT_SUPPORTED; + } - // alter table add NOT NULL column - if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_STORED_BASE_COLUMN) { - uint32_t old_table_fields = table->s->fields; - uint32_t new_table_fields = altered_table->s->fields; - uint32_t drop_list_size = ha_alter_info->alter_info->drop_list.size(); - uint32_t create_list_size = ha_alter_info->alter_info->create_list.size(); - uint32_t index_drop_count = ha_alter_info->index_drop_count; + // alter table add column containing stored generated column: json_array() as default + if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_STORED_GENERATED_COLUMN) { + ha_alter_info->unsupported_reason = my_get_err_msg(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON); + return HA_ALTER_INPLACE_NOT_SUPPORTED; + } - // if this table have any added columns - uint32_t add_column_size = new_table_fields - old_table_fields + (drop_list_size - index_drop_count); + if (ha_alter_info->handler_flags & CTC_ALTER_COL_ORDER) { + ha_alter_info->unsupported_reason = "Altering column order or drop column"; + return HA_ALTER_INPLACE_NOT_SUPPORTED; + } - ctc_log_system("[SUPPORT_INPLACE]:old_table_fields:%u new_table_fields:%u drop_list_size:%u create_list_size:%u add_column_size:%u, index_drop_count:%u", - old_table_fields, new_table_fields, drop_list_size, create_list_size, add_column_size, index_drop_count); + if ((ha_alter_info->handler_flags & Alter_inplace_info::ALTER_RENAME) && + (strcmp(altered_table->s->db.str, table->s->db.str) != 0)) { + ha_alter_info->unsupported_reason = "Table is renamed cross database"; + return HA_ALTER_INPLACE_NOT_SUPPORTED; + } - for (int i = add_column_size; i > 0; i--) { - int32_t add_column_idx = create_list_size - i; - if (add_column_idx < 0) { - assert(0); - ctc_log_error("[SUPPORT_INPLACE]: add_column_idx smaller than 0."); - break; - } + // alter table add NOT NULL column + if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_STORED_BASE_COLUMN) { + uint32_t old_table_fields = table->s->fields; + uint32_t new_table_fields = altered_table->s->fields; + uint32_t drop_list_size = ha_alter_info->alter_info->drop_list.size(); + uint32_t create_list_size = ha_alter_info->alter_info->create_list.size(); + uint32_t index_drop_count = ha_alter_info->index_drop_count; + + // if this table have any added columns + uint32_t add_column_size = new_table_fields - old_table_fields + (drop_list_size - index_drop_count); + + ctc_log_system( + "[SUPPORT_INPLACE]:old_table_fields:%u new_table_fields:%u drop_list_size:%u create_list_size:%u " + "add_column_size:%u, index_drop_count:%u", + old_table_fields, new_table_fields, drop_list_size, create_list_size, add_column_size, index_drop_count); + + for (int i = add_column_size; i > 0; i--) { + int32_t add_column_idx = create_list_size - i; + if (add_column_idx < 0) { + assert(0); + ctc_log_error("[SUPPORT_INPLACE]: add_column_idx smaller than 0."); + break; + } - bool is_nullable = ha_alter_info->alter_info->create_list[add_column_idx]->is_nullable; // NOT NULL - bool is_have_default_val = ha_alter_info->alter_info->create_list[add_column_idx]->constant_default == nullptr ? false : true; - if (!is_nullable && !is_have_default_val) { - ha_alter_info->unsupported_reason = my_get_err_msg(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON); - return HA_ALTER_INPLACE_NOT_SUPPORTED; + bool is_nullable = ha_alter_info->alter_info->create_list[add_column_idx]->is_nullable; // NOT NULL + bool is_have_default_val = + ha_alter_info->alter_info->create_list[add_column_idx]->constant_default == nullptr ? false : true; + if (!is_nullable && !is_have_default_val) { + ha_alter_info->unsupported_reason = my_get_err_msg(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON); + return HA_ALTER_INPLACE_NOT_SUPPORTED; + } } } - } - if (ha_alter_info->handler_flags & Alter_inplace_info::REORGANIZE_PARTITION) { - ha_alter_info->unsupported_reason = "Reorganize Partition"; - return HA_ALTER_INPLACE_NOT_SUPPORTED; - } + if (ha_alter_info->handler_flags & Alter_inplace_info::REORGANIZE_PARTITION) { + ha_alter_info->unsupported_reason = "Reorganize Partition"; + return HA_ALTER_INPLACE_NOT_SUPPORTED; + } - if ((ha_alter_info->handler_flags & PARTITION_OPERATIONS) != 0 && - altered_table->part_info->get_full_clone(thd)->part_type == partition_type::HASH) { + if ((ha_alter_info->handler_flags & PARTITION_OPERATIONS) != 0 && + altered_table->part_info->get_full_clone(thd)->part_type == partition_type::HASH) { ha_alter_info->unsupported_reason = "INPLACE is not supported for this operation."; return HA_ALTER_INPLACE_NOT_SUPPORTED; - } - return HA_ALTER_INPLACE_EXCLUSIVE_LOCK; -} - -/** - @brief - Construct ctc range key based on mysql range key -*/ -void ha_ctc::set_ctc_range_key(ctc_key *ctc_key, key_range *mysql_range_key, bool is_min_key) { - if (!mysql_range_key) { - ctc_key->key = nullptr; - ctc_key->cmp_type = CMP_TYPE_NULL; - ctc_key->len = 0; - ctc_key->col_map = 0; - return; + } + return HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } - ctc_key->col_map = mysql_range_key->keypart_map; - ctc_key->key = mysql_range_key->key; - ctc_key->len = mysql_range_key->length; - - switch(mysql_range_key->flag) { - case HA_READ_KEY_EXACT: - ctc_key->cmp_type = CMP_TYPE_CLOSE_INTERNAL; - break; - case HA_READ_BEFORE_KEY: - ctc_key->cmp_type = CMP_TYPE_OPEN_INTERNAL; - break; - case HA_READ_AFTER_KEY: - ctc_key->cmp_type = is_min_key ? CMP_TYPE_OPEN_INTERNAL : CMP_TYPE_CLOSE_INTERNAL; - break; - default: + /** + @brief + Construct ctc range key based on mysql range key + */ + void ha_ctc::set_ctc_range_key(ctc_key * ctc_key, key_range * mysql_range_key, bool is_min_key) + { + if (!mysql_range_key) { + ctc_key->key = nullptr; ctc_key->cmp_type = CMP_TYPE_NULL; + ctc_key->len = 0; + ctc_key->col_map = 0; + return; + } + + ctc_key->col_map = mysql_range_key->keypart_map; + ctc_key->key = mysql_range_key->key; + ctc_key->len = mysql_range_key->length; + + switch (mysql_range_key->flag) { + case HA_READ_KEY_EXACT: + ctc_key->cmp_type = CMP_TYPE_CLOSE_INTERNAL; + break; + case HA_READ_BEFORE_KEY: + ctc_key->cmp_type = CMP_TYPE_OPEN_INTERNAL; + break; + case HA_READ_AFTER_KEY: + ctc_key->cmp_type = is_min_key ? CMP_TYPE_OPEN_INTERNAL : CMP_TYPE_CLOSE_INTERNAL; + break; + default: + ctc_key->cmp_type = CMP_TYPE_NULL; + } } -} -/** - @brief - Given a starting key and an ending key, estimate the number of rows that - will exist between the two keys. + /** + @brief + Given a starting key and an ending key, estimate the number of rows that + will exist between the two keys. - @details - end_key may be empty, in which case determine if start_key matches any rows. + @details + end_key may be empty, in which case determine if start_key matches any rows. - Called from opt_range.cc by check_quick_keys(). + Called from opt_range.cc by check_quick_keys(). - @see - check_quick_keys() in opt_range.cc -*/ -ha_rows ha_ctc::records_in_range(uint inx, key_range *min_key, - key_range *max_key) { - DBUG_TRACE; - ctc_key ctc_min_key; - ctc_key ctc_max_key; - set_ctc_range_key(&ctc_min_key, min_key, true); - set_ctc_range_key(&ctc_max_key, max_key, false); - if (ctc_max_key.len < ctc_min_key.len) { - ctc_max_key.cmp_type = CMP_TYPE_NULL; - } else if (ctc_max_key.len > ctc_min_key.len) { - ctc_min_key.cmp_type = CMP_TYPE_NULL; - } - ctc_range_key key = {&ctc_min_key, &ctc_max_key}; - - uint64_t n_rows = 0; - double density; - - if (m_share) { - if (!m_share->cbo_stats->is_updated) { + @see + check_quick_keys() in opt_range.cc + */ + ha_rows ha_ctc::records_in_range(uint inx, key_range * min_key, key_range * max_key) + { + DBUG_TRACE; + ctc_key ctc_min_key; + ctc_key ctc_max_key; + set_ctc_range_key(&ctc_min_key, min_key, true); + set_ctc_range_key(&ctc_max_key, max_key, false); + if (ctc_max_key.len < ctc_min_key.len) { + ctc_max_key.cmp_type = CMP_TYPE_NULL; + } else if (ctc_max_key.len > ctc_min_key.len) { + ctc_min_key.cmp_type = CMP_TYPE_NULL; + } + ctc_range_key key = {&ctc_min_key, &ctc_max_key}; + + uint64_t n_rows = 0; + double density; + + if (m_share) { + if (!m_share->cbo_stats->is_updated) { ctc_log_debug("table %s has not been analyzed", table->alias); return 1; + } + density = calc_density_one_table(inx, &key, m_share->cbo_stats->ctc_cbo_stats_table, *table); + /* + * This is a safe-guard logic since we don't handle ctc call error in this method, + * we need this to make sure that our optimizer continue to work even when we + * miscalculated the density, and it's still prefer index read + */ + n_rows += m_share->cbo_stats->ctc_cbo_stats_table->estimate_rows * density; } - density = calc_density_one_table(inx, &key, m_share->cbo_stats->ctc_cbo_stats_table, *table); - /* - * This is a safe-guard logic since we don't handle ctc call error in this method, - * we need this to make sure that our optimizer continue to work even when we - * miscalculated the density, and it's still prefer index read - */ - n_rows += m_share->cbo_stats->ctc_cbo_stats_table->estimate_rows * density; - } - /* - * The MySQL optimizer seems to believe an estimate of 0 rows is - * always accurate and may return the result 'Empty set' based on that - */ - if (n_rows == 0) { + /* + * The MySQL optimizer seems to believe an estimate of 0 rows is + * always accurate and may return the result 'Empty set' based on that + */ + if (n_rows == 0) { n_rows = 1; + } + return n_rows; } - return n_rows; -} -int ha_ctc::records(ha_rows *num_rows) /*!< out: number of rows */ -{ - DBUG_TRACE; - uint64_t n_rows = 0; - ct_errno_t ret = CT_SUCCESS; - - THD *thd = ha_thd(); - update_member_tch(m_tch, ctc_hton, thd); - char *index_name = nullptr; - if (active_index != MAX_KEY) { - index_name = const_cast (table->key_info[active_index].name); + int ha_ctc::records(ha_rows * num_rows) /*!< out: number of rows */ + { + DBUG_TRACE; + uint64_t n_rows = 0; + ct_errno_t ret = CT_SUCCESS; + + THD *thd = ha_thd(); + update_member_tch(m_tch, ctc_hton, thd); + char *index_name = nullptr; + if (active_index != MAX_KEY) { + index_name = const_cast(table->key_info[active_index].name); + } + + /* Count the records */ + ret = (ct_errno_t)ctc_scan_records(&m_tch, &n_rows, index_name); + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + + assert(ret == CT_SUCCESS); + if (ret != CT_SUCCESS) { + ctc_log_error("scan records failed with error code: %d", ret); + return convert_ctc_error_code_to_mysql(ret); + } + + *num_rows = n_rows; + return 0; } - /* Count the records */ - ret = (ct_errno_t)ctc_scan_records(&m_tch, &n_rows, index_name); - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - - assert(ret == CT_SUCCESS); - if (ret != CT_SUCCESS) { - ctc_log_error("scan records failed with error code: %d", ret); - return convert_ctc_error_code_to_mysql(ret); + int ha_ctc::records_from_index(ha_rows * num_rows, uint inx) + { + active_index = inx; + int ret = records(num_rows); + active_index = MAX_KEY; + return ret; } - - *num_rows = n_rows; - return 0; -} - -int ha_ctc::records_from_index(ha_rows *num_rows, uint inx) -{ - active_index = inx; - int ret = records(num_rows); - active_index = MAX_KEY; - return ret; -} -int32_t ctc_get_cluster_role() { - if (ctc_cluster_role != (int32_t)dis_cluster_role::DEFAULT) { + int32_t ctc_get_cluster_role() + { + if (ctc_cluster_role != (int32_t)dis_cluster_role::DEFAULT) { + return ctc_cluster_role; + } + lock_guard lock(m_ctc_cluster_role_mutex); + bool is_slave = false; + bool cantian_cluster_ready = false; + int ret = ctc_query_cluster_role(&is_slave, &cantian_cluster_ready); + if (ret != CT_SUCCESS || !cantian_cluster_ready) { + ctc_cluster_role = (int32_t)dis_cluster_role::CLUSTER_NOT_READY; + ctc_log_error( + "[Disaster Rocovery] ctc_query_cluster_role failed with error code: %d, is_slave:%d, cantian_cluster_ready: " + "%d", + ret, is_slave, cantian_cluster_ready); + return ctc_cluster_role; + } + ctc_log_system("[Disaster Recovery] is_slave:%d, cantian_cluster_ready:%d", is_slave, cantian_cluster_ready); + // ctc_cluster_role: The character the node was before change + // is_slave: The character the node is now + // Only reset 'read_only's to false when the node turns from slave to master + if (is_slave) { + ctc_set_mysql_read_only(); + } else if (ctc_cluster_role == (int32_t)dis_cluster_role::STANDBY) { + ctc_reset_mysql_read_only(); + } + ctc_cluster_role = is_slave ? (int32_t)dis_cluster_role::STANDBY : (int32_t)dis_cluster_role::PRIMARY; + return ctc_cluster_role; } - lock_guard lock(m_ctc_cluster_role_mutex); - bool is_slave = false; - bool cantian_cluster_ready = false; - int ret = ctc_query_cluster_role(&is_slave, &cantian_cluster_ready); - if (ret != CT_SUCCESS || !cantian_cluster_ready) { - ctc_cluster_role = (int32_t)dis_cluster_role::CLUSTER_NOT_READY; - ctc_log_error("[Disaster Rocovery] ctc_query_cluster_role failed with error code: %d, is_slave:%d, cantian_cluster_ready: %d", ret, is_slave, cantian_cluster_ready); - return ctc_cluster_role; + + int32_t ctc_get_shm_file_num(uint32_t * shm_file_num) + { + lock_guard lock(m_ctc_shm_file_num_mutex); + int ret = ctc_query_shm_file_num(shm_file_num); + return ret; } - ctc_log_system("[Disaster Recovery] is_slave:%d, cantian_cluster_ready:%d", is_slave, cantian_cluster_ready); - // ctc_cluster_role: The character the node was before change - // is_slave: The character the node is now - // Only reset 'read_only's to false when the node turns from slave to master - if (is_slave) { - ctc_set_mysql_read_only(); - } else if (ctc_cluster_role == (int32_t)dis_cluster_role::STANDBY) { - ctc_reset_mysql_read_only(); - } - ctc_cluster_role = is_slave ? (int32_t)dis_cluster_role::STANDBY : (int32_t)dis_cluster_role::PRIMARY; - - return ctc_cluster_role; -} -int32_t ctc_get_shm_file_num(uint32_t *shm_file_num) { - lock_guard lock(m_ctc_shm_file_num_mutex); - int ret = ctc_query_shm_file_num(shm_file_num); - return ret; -} + extern uint32_t g_shm_file_num; + int32_t ctc_get_shm_usage(uint32_t * ctc_shm_usage) + { + uint32_t size = (g_shm_file_num + 1) * MEM_CLASS_NUM * sizeof(uint32_t); + uint32_t *shm_usage = (uint32_t *)ctc_alloc_buf(NULL, size); + memset(shm_usage, 0, size); + int ret = ctc_query_shm_usage(shm_usage); + memcpy(ctc_shm_usage, shm_usage, size); + ctc_free_buf(nullptr, (uint8_t *)shm_usage); + return ret; + } -extern uint32_t g_shm_file_num; -int32_t ctc_get_shm_usage(uint32_t *ctc_shm_usage) { - uint32_t size = (g_shm_file_num + 1) * MEM_CLASS_NUM * sizeof(uint32_t); - uint32_t *shm_usage = (uint32_t *)ctc_alloc_buf(NULL, size); - memset(shm_usage, 0, size); - int ret = ctc_query_shm_usage(shm_usage); - memcpy(ctc_shm_usage, shm_usage, size); - ctc_free_buf(nullptr, (uint8_t *)shm_usage); - return ret; -} + /** + @brief + The idea with handler::store_lock() is: The statement decides which locks + should be needed for the table. For updates/deletes/inserts we get WRITE + locks, for SELECT... we get read locks. -/** - @brief - The idea with handler::store_lock() is: The statement decides which locks - should be needed for the table. For updates/deletes/inserts we get WRITE - locks, for SELECT... we get read locks. + @details + Before adding the lock into the table lock handler (see thr_lock.c), + mysqld calls store lock with the requested locks. Store lock can now + modify a write lock to a read lock (or some other lock), ignore the + lock (if we don't want to use MySQL table locks at all), or add locks + for many tables (like we do when we are using a MERGE handler). - @details - Before adding the lock into the table lock handler (see thr_lock.c), - mysqld calls store lock with the requested locks. Store lock can now - modify a write lock to a read lock (or some other lock), ignore the - lock (if we don't want to use MySQL table locks at all), or add locks - for many tables (like we do when we are using a MERGE handler). + Berkeley DB, for ctc, changes all WRITE locks to TL_WRITE_ALLOW_WRITE + (which signals that we are doing WRITES, but are still allowing other + readers and writers). + + When releasing locks, store_lock() is also called. In this case one + usually doesn't have to do anything. - Berkeley DB, for ctc, changes all WRITE locks to TL_WRITE_ALLOW_WRITE - (which signals that we are doing WRITES, but are still allowing other - readers and writers). + In some exceptional cases MySQL may send a request for a TL_IGNORE; + This means that we are requesting the same lock as last time and this + should also be ignored. (This may happen when someone does a flush + table when we have opened a part of the tables, in which case mysqld + closes and reopens the tables and tries to get the same locks at last + time). In the future we will probably try to remove this. - When releasing locks, store_lock() is also called. In this case one - usually doesn't have to do anything. + Called from lock.cc by get_lock_data(). - In some exceptional cases MySQL may send a request for a TL_IGNORE; - This means that we are requesting the same lock as last time and this - should also be ignored. (This may happen when someone does a flush - table when we have opened a part of the tables, in which case mysqld - closes and reopens the tables and tries to get the same locks at last - time). In the future we will probably try to remove this. + @note + In this method one should NEVER rely on table->in_use, it may, in fact, + refer to a different thread! (this happens if get_lock_data() is called + from mysql_lock_abort_for_thread() function) + + @see + get_lock_data() in lock.cc + */ + THR_LOCK_DATA **ha_ctc::store_lock(THD *, THR_LOCK_DATA * *to, enum thr_lock_type lock_type) + { + /* + This method should not be called for internal temporary tables + as they don't have properly initialized THR_LOCK and THR_LOCK_DATA + structures. + cantian engine dose not need mysql lock type, need long testing on this. + May need map mysql lock type to cantian lock type in the future after figure + out they lock meaning. + */ + DBUG_TRACE; + + // SELECT FOR SHARE / SELECT FOR UPDATE use exclusive lock + if ((lock_type == TL_READ_WITH_SHARED_LOCKS && ctc_get_cluster_role() == (int32_t)dis_cluster_role::PRIMARY) || + (lock_type >= TL_WRITE_ALLOW_WRITE && lock_type <= TL_WRITE_ONLY)) { + m_select_lock = lock_mode::EXCLUSIVE_LOCK; + } else { + m_select_lock = lock_mode::SHARED_LOCK; + } + + return to; + } + + /** + @brief + As MySQL will execute an external lock for every new table it uses when it + starts to process an SQL statement (an exception is when MySQL calls + start_stmt directly for the handle when thread has table lock explicitly), + we will use this function to indicate CTC that a new SQL statement has started. + + @details + Called from lock.cc by lock_external() and unlock_external(). Also called + from sql_table.cc by copy_data_between_tables(). + + @see + lock.cc by lock_external() and unlock_external() in lock.cc; + the section "locking functions for mysql" in lock.cc; + copy_data_between_tables() in sql_table.cc. + */ + int ha_ctc::external_lock(THD * thd, int lock_type) + { + /* + cantian dose not need mysql lock type, need long testing on this. + May need map mysql lock type to cantian lock type in the future after figure + out they lock meaning. + */ + DBUG_TRACE; + + if (IS_METADATA_NORMALIZATION() && ctc_check_if_log_table(table_share->db.str, table_share->table_name.str)) { + is_log_table = true; + if (!thd->in_sub_stmt) { + thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(ctc_hton, thd); + sess_ctx->sql_stat_start = 1; + m_tch.sql_stat_start = 1; + } + return 0; + } - Called from lock.cc by get_lock_data(). + is_log_table = false; - @note - In this method one should NEVER rely on table->in_use, it may, in fact, - refer to a different thread! (this happens if get_lock_data() is called - from mysql_lock_abort_for_thread() function) + if (engine_ddl_passthru(thd) && (is_create_table_check(thd) || is_alter_table_copy(thd))) { + return 0; + } - @see - get_lock_data() in lock.cc -*/ -THR_LOCK_DATA **ha_ctc::store_lock(THD *, THR_LOCK_DATA **to, - enum thr_lock_type lock_type) { - /* - This method should not be called for internal temporary tables - as they don't have properly initialized THR_LOCK and THR_LOCK_DATA - structures. - cantian engine dose not need mysql lock type, need long testing on this. - May need map mysql lock type to cantian lock type in the future after figure - out they lock meaning. - */ - DBUG_TRACE; + // F_RDLCK:0, F_WRLCK:1, F_UNLCK:2 + if (lock_type == F_UNLCK) { + m_select_lock = lock_mode::NO_LOCK; + return 0; + } - // SELECT FOR SHARE / SELECT FOR UPDATE use exclusive lock - if ((lock_type == TL_READ_WITH_SHARED_LOCKS && ctc_get_cluster_role() == (int32_t)dis_cluster_role::PRIMARY) || - (lock_type >= TL_WRITE_ALLOW_WRITE && lock_type <= TL_WRITE_ONLY)) { - m_select_lock = lock_mode::EXCLUSIVE_LOCK; - } else { - m_select_lock = lock_mode::SHARED_LOCK; + return start_stmt(thd, TL_IGNORE); } - return to; -} - -/** - @brief - As MySQL will execute an external lock for every new table it uses when it - starts to process an SQL statement (an exception is when MySQL calls - start_stmt directly for the handle when thread has table lock explicitly), - we will use this function to indicate CTC that a new SQL statement has started. + /** + @brief + When thread has table lock explicitly, MySQL will execute an external lock + for every new table it uses instead of external lock. + 1. Without explicit table lock, MySQL execute external_lock, + we make external_lock to call start_stmt for ctc_trx_begin. + 2. With explicit table lock, MySQL execute start_stmt directly. + We will use this function to indicate CTC that a new SQL statement has started. - @details - Called from lock.cc by lock_external() and unlock_external(). Also called - from sql_table.cc by copy_data_between_tables(). + @details + Called from ha_ctc::external_lock(). + Called from sql_base.cc by check_lock_and_start_stmt(). - @see - lock.cc by lock_external() and unlock_external() in lock.cc; - the section "locking functions for mysql" in lock.cc; - copy_data_between_tables() in sql_table.cc. -*/ -int ha_ctc::external_lock(THD *thd, int lock_type) { - /* - cantian dose not need mysql lock type, need long testing on this. - May need map mysql lock type to cantian lock type in the future after figure - out they lock meaning. + @see + sql_base.cc by check_lock_and_start_stmt(). */ - DBUG_TRACE; + int ha_ctc::start_stmt(THD * thd, thr_lock_type) + { + DBUG_TRACE; + + trans_register_ha(thd, false, ht, nullptr); // register trans to STMT - if (IS_METADATA_NORMALIZATION() && - ctc_check_if_log_table(table_share->db.str, table_share->table_name.str)) { - is_log_table = true; + update_member_tch(m_tch, ctc_hton, thd, false); + thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(ctc_hton, thd); + if (sess_ctx == nullptr) { + return HA_ERR_OUT_OF_MEM; + } + sess_ctx->thd_id = thd->thread_id(); if (!thd->in_sub_stmt) { - thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(ctc_hton, thd); - sess_ctx->sql_stat_start = 1; + sess_ctx->sql_stat_start = 1; // indicate cantian for a new sql border m_tch.sql_stat_start = 1; } - return 0; - } - is_log_table = false; - - if (engine_ddl_passthru(thd) && (is_create_table_check(thd) || is_alter_table_copy(thd))) { - return 0; - } - - // F_RDLCK:0, F_WRLCK:1, F_UNLCK:2 - if (lock_type == F_UNLCK) { - m_select_lock = lock_mode::NO_LOCK; - return 0; - } + // lock tables不开启事务 + if (thd->query_plan.get_command() == SQLCOM_LOCK_TABLES) { + return 0; + } - return start_stmt(thd, TL_IGNORE); -} + // if session level transaction we only start one time + if (sess_ctx->is_ctc_trx_begin) { + assert(m_tch.sess_addr != INVALID_VALUE64); + assert(m_tch.thd_id == thd->thread_id()); + return 0; + } -/** - @brief - When thread has table lock explicitly, MySQL will execute an external lock - for every new table it uses instead of external lock. - 1. Without explicit table lock, MySQL execute external_lock, - we make external_lock to call start_stmt for ctc_trx_begin. - 2. With explicit table lock, MySQL execute start_stmt directly. - We will use this function to indicate CTC that a new SQL statement has started. + uint32_t lock_wait_timeout = THDVAR(thd, lock_wait_timeout); + uint32_t autocommit = !thd->in_multi_stmt_transaction_mode(); + int isolation_level = isolation_level_to_cantian(thd_get_trx_isolation(thd)); - @details - Called from ha_ctc::external_lock(). - Called from sql_base.cc by check_lock_and_start_stmt(). + ctc_trx_context_t trx_context = {isolation_level, autocommit, lock_wait_timeout, + m_select_lock == lock_mode::EXCLUSIVE_LOCK}; - @see - sql_base.cc by check_lock_and_start_stmt(). -*/ -int ha_ctc::start_stmt(THD *thd, thr_lock_type) { - DBUG_TRACE; + bool is_mysql_local = (sess_ctx->set_flag & CTC_DDL_LOCAL_ENABLED); + ct_errno_t ret = (ct_errno_t)ctc_trx_begin(&m_tch, trx_context, is_mysql_local); - trans_register_ha(thd, false, ht, nullptr); // register trans to STMT + check_error_code_to_mysql(ha_thd(), &ret); - update_member_tch(m_tch, ctc_hton, thd, false); - thd_sess_ctx_s *sess_ctx = get_or_init_sess_ctx(ctc_hton, thd); - if (sess_ctx == nullptr) { - return HA_ERR_OUT_OF_MEM; - } - sess_ctx->thd_id = thd->thread_id(); - if (!thd->in_sub_stmt) { - sess_ctx->sql_stat_start = 1; // indicate cantian for a new sql border - m_tch.sql_stat_start = 1; - } + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - // lock tables不开启事务 - if (thd->query_plan.get_command() == SQLCOM_LOCK_TABLES) { - return 0; - } + if (ret != CT_SUCCESS) { + ctc_log_error("start trx failed with error code: %d", ret); + return convert_ctc_error_code_to_mysql(ret); + } - // if session level transaction we only start one time - if (sess_ctx->is_ctc_trx_begin) { - assert(m_tch.sess_addr != INVALID_VALUE64); - assert(m_tch.thd_id == thd->thread_id()); + sess_ctx->is_ctc_trx_begin = 1; + if (!autocommit) { + trans_register_ha(thd, true, ht, nullptr); + } return 0; } - uint32_t lock_wait_timeout = THDVAR(thd, lock_wait_timeout); - uint32_t autocommit = !thd->in_multi_stmt_transaction_mode(); - int isolation_level = isolation_level_to_cantian(thd_get_trx_isolation(thd)); - - ctc_trx_context_t trx_context = {isolation_level, autocommit, lock_wait_timeout, m_select_lock == lock_mode::EXCLUSIVE_LOCK}; - - bool is_mysql_local = (sess_ctx->set_flag & CTC_DDL_LOCAL_ENABLED); - ct_errno_t ret = (ct_errno_t)ctc_trx_begin(&m_tch, trx_context, is_mysql_local); - - check_error_code_to_mysql(ha_thd(), &ret); - - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - - if (ret != CT_SUCCESS) { - ctc_log_error("start trx failed with error code: %d", ret); - return convert_ctc_error_code_to_mysql(ret); - } - - sess_ctx->is_ctc_trx_begin = 1; - if (!autocommit) { - trans_register_ha(thd, true, ht, nullptr); - } - return 0; -} - -/** Return partitioning flags. */ -static uint ctc_partition_flags() { - return (HA_CANNOT_PARTITION_FK | HA_TRUNCATE_PARTITION_PRECLOSE); -} + /** Return partitioning flags. */ + static uint ctc_partition_flags() { return (HA_CANNOT_PARTITION_FK | HA_TRUNCATE_PARTITION_PRECLOSE); } -struct st_mysql_storage_engine ctc_storage_engine = { - MYSQL_HANDLERTON_INTERFACE_VERSION}; + struct st_mysql_storage_engine ctc_storage_engine = {MYSQL_HANDLERTON_INTERFACE_VERSION}; -static bool ctc_get_tablespace_statistics( - const char *tablespace_name, const char *file_name, - const dd::Properties &ts_se_private_data, ha_tablespace_statistics *stats) { + static bool ctc_get_tablespace_statistics(const char *tablespace_name, const char *file_name, + const dd::Properties &ts_se_private_data, ha_tablespace_statistics *stats) + { UNUSED_PARAM(tablespace_name); UNUSED_PARAM(file_name); UNUSED_PARAM(ts_se_private_data); UNUSED_PARAM(stats); return true; -} + } -EXTER_ATTACK bool ctc_drop_database_with_err(handlerton *hton, char *path) { - THD *thd = current_thd; - assert(thd != nullptr); + EXTER_ATTACK bool ctc_drop_database_with_err(handlerton * hton, char *path) + { + THD *thd = current_thd; + assert(thd != nullptr); - if (engine_ddl_passthru(thd)) { - return false; - } + if (engine_ddl_passthru(thd)) { + return false; + } - ctc_handler_t tch; - int res = get_tch_in_handler_data(hton, thd, tch); - if (res != CT_SUCCESS) { - return true; - } + ctc_handler_t tch; + int res = get_tch_in_handler_data(hton, thd, tch); + if (res != CT_SUCCESS) { + return true; + } - char db_name[SMALL_RECORD_SIZE] = { 0 }; - ctc_split_normalized_name(path, db_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); - int error_code = 0; - char error_message[ERROR_MESSAGE_LEN] = {0}; - /* ctc_drop_tablespace_and_user接口内部新建session并自己释放 */ - string sql = string(thd->query().str).substr(0, thd->query().length); - int ret = ctc_drop_tablespace_and_user( - &tch, db_name, sql.c_str(), - thd->m_main_security_ctx.priv_user().str, - thd->m_main_security_ctx.priv_host().str, &error_code, error_message); - update_sess_ctx_by_tch(tch, hton, thd); - ctc_log_system("[CTC_DROP_DB]: ret:%d, database(%s), error_code:%d, error_message:%s", - ret, db_name, error_code, error_message); - if (ret != CT_SUCCESS) { - ctc_log_error("drop database failed with error code: %d", convert_ctc_error_code_to_mysql((ct_errno_t)ret)); - cm_assert(0); + char db_name[SMALL_RECORD_SIZE] = {0}; + ctc_split_normalized_name(path, db_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); + int error_code = 0; + char error_message[ERROR_MESSAGE_LEN] = {0}; + /* ctc_drop_tablespace_and_user接口内部新建session并自己释放 */ + string sql = string(thd->query().str).substr(0, thd->query().length); + int ret = ctc_drop_tablespace_and_user(&tch, db_name, sql.c_str(), thd->m_main_security_ctx.priv_user().str, + thd->m_main_security_ctx.priv_host().str, &error_code, error_message); + update_sess_ctx_by_tch(tch, hton, thd); + ctc_log_system("[CTC_DROP_DB]: ret:%d, database(%s), error_code:%d, error_message:%s", ret, db_name, error_code, + error_message); + if (ret != CT_SUCCESS) { + ctc_log_error("drop database failed with error code: %d", convert_ctc_error_code_to_mysql((ct_errno_t)ret)); + cm_assert(0); + } + return false; } - return false; -} -EXTER_ATTACK void ctc_drop_database(handlerton *hton, char *path) { - (void)ctc_drop_database_with_err(hton, path); -} + EXTER_ATTACK void ctc_drop_database(handlerton * hton, char *path) { (void)ctc_drop_database_with_err(hton, path); } -static int ctc_check_tx_isolation() { - // 检查GLOBAL变量 - enum_tx_isolation tx_isol = (enum_tx_isolation)global_system_variables.transaction_isolation; - if (tx_isol == ISO_SERIALIZABLE || tx_isol == ISO_READ_UNCOMMITTED) { - ctc_log_error("CTC init failed. GLOBAL transaction isolation can not " - "be SERIALIZABLE and READ-UNCOMMITTED. Please check system variable or my.cnf file."); - return HA_ERR_INITIALIZATION; - } + static int ctc_check_tx_isolation() + { + // 检查GLOBAL变量 + enum_tx_isolation tx_isol = (enum_tx_isolation)global_system_variables.transaction_isolation; + if (tx_isol == ISO_SERIALIZABLE || tx_isol == ISO_READ_UNCOMMITTED) { + ctc_log_error( + "CTC init failed. GLOBAL transaction isolation can not " + "be SERIALIZABLE and READ-UNCOMMITTED. Please check system variable or my.cnf file."); + return HA_ERR_INITIALIZATION; + } - // 检查SESSION 变量 - THD *thd = current_thd; - if (thd && (thd->tx_isolation == ISO_SERIALIZABLE || thd->tx_isolation == ISO_READ_UNCOMMITTED)) { - ctc_log_error("CTC init failed. SESSION transaction isolation can not " - "be SERIALIZABLE and READ-UNCOMMITTED. Please check system variable or my.cnf file."); - return HA_ERR_INITIALIZATION; + // 检查SESSION 变量 + THD *thd = current_thd; + if (thd && (thd->tx_isolation == ISO_SERIALIZABLE || thd->tx_isolation == ISO_READ_UNCOMMITTED)) { + ctc_log_error( + "CTC init failed. SESSION transaction isolation can not " + "be SERIALIZABLE and READ-UNCOMMITTED. Please check system variable or my.cnf file."); + return HA_ERR_INITIALIZATION; + } + return 0; } - return 0; -} -static int ctc_create_db(THD *thd, handlerton *hton) { - if (engine_skip_ddl(thd)) { - return CT_SUCCESS; - } - ctc_handler_t tch; - CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); + static int ctc_create_db(THD * thd, handlerton * hton) + { + if (engine_skip_ddl(thd)) { + return CT_SUCCESS; + } + ctc_handler_t tch; + CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(hton, thd, tch)); - ctc_ddl_broadcast_request broadcast_req {{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; + ctc_ddl_broadcast_request broadcast_req{{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; - DBUG_EXECUTE_IF("core_before_create_tablespace_and_db", { assert(0); }); // 有锁的问题 - - string sql = string(thd->query().str).substr(0, thd->query().length); - FILL_BROADCAST_BASE_REQ(broadcast_req, sql.c_str(), thd->m_main_security_ctx.priv_user().str, - thd->m_main_security_ctx.priv_host().str, ctc_instance_id, tch.sql_command); - broadcast_req.options &= (~CTC_NOT_NEED_CANTIAN_EXECUTE); - int ret = ctc_execute_mysql_ddl_sql(&tch, &broadcast_req, false); + DBUG_EXECUTE_IF("core_before_create_tablespace_and_db", { assert(0); }); // 有锁的问题 - DBUG_EXECUTE_IF("core_after_create_tablespace_and_db", { assert(0); }); // 元数据不一致的问题 - ctc_log_system("[CTC_BROARDCAST_CREATE_DB]:ret:%d, query:%s, user_name:%s, err_code:%d, broadcast_inst_id:%u, " - "conn_id:%u, ctc_inst_id:%u", ret, broadcast_req.sql_str, broadcast_req.user_name, - broadcast_req.err_code, broadcast_req.mysql_inst_id, tch.thd_id, tch.inst_id); - update_sess_ctx_by_tch(tch, hton, thd); - assert(ret == CT_SUCCESS); - - return ret; -} + string sql = string(thd->query().str).substr(0, thd->query().length); + FILL_BROADCAST_BASE_REQ(broadcast_req, sql.c_str(), thd->m_main_security_ctx.priv_user().str, + thd->m_main_security_ctx.priv_host().str, ctc_instance_id, tch.sql_command); + broadcast_req.options &= (~CTC_NOT_NEED_CANTIAN_EXECUTE); + int ret = ctc_execute_mysql_ddl_sql(&tch, &broadcast_req, false); -bool ctc_binlog_log_query_with_err(handlerton *hton, THD *thd, - enum_binlog_command binlog_command, - const char *query, uint query_length, - const char *db, const char *table_name) { - UNUSED_PARAM(query); - UNUSED_PARAM(query_length); - UNUSED_PARAM(db); - UNUSED_PARAM(table_name); - if (engine_ddl_passthru(thd)) { + DBUG_EXECUTE_IF("core_after_create_tablespace_and_db", { assert(0); }); // 元数据不一致的问题 + ctc_log_system( + "[CTC_BROARDCAST_CREATE_DB]:ret:%d, query:%s, user_name:%s, err_code:%d, broadcast_inst_id:%u, " + "conn_id:%u, ctc_inst_id:%u", + ret, broadcast_req.sql_str, broadcast_req.user_name, broadcast_req.err_code, broadcast_req.mysql_inst_id, + tch.thd_id, tch.inst_id); + update_sess_ctx_by_tch(tch, hton, thd); + assert(ret == CT_SUCCESS); + + return ret; + } + + bool ctc_binlog_log_query_with_err(handlerton * hton, THD * thd, enum_binlog_command binlog_command, + const char *query, uint query_length, const char *db, const char *table_name) + { + UNUSED_PARAM(query); + UNUSED_PARAM(query_length); + UNUSED_PARAM(db); + UNUSED_PARAM(table_name); + if (engine_ddl_passthru(thd)) { + return false; + } + if (binlog_command == LOGCOM_CREATE_DB) { + return ctc_create_db(thd, hton); + } return false; } - if (binlog_command == LOGCOM_CREATE_DB) { - return ctc_create_db(thd, hton); + + void ctc_binlog_log_query(handlerton * hton, THD * thd, enum_binlog_command binlog_command, const char *query, + uint query_length, const char *db, const char *table_name) + { + (void)ctc_binlog_log_query_with_err(hton, thd, binlog_command, query, query_length, db, table_name); } - return false; -} -void ctc_binlog_log_query(handlerton *hton, THD *thd, - enum_binlog_command binlog_command, - const char *query, uint query_length, - const char *db, const char *table_name) { - (void)ctc_binlog_log_query_with_err(hton, thd, binlog_command, query, query_length, db, table_name); -} + /** Return 0 on success and non-zero on failure. + @param[in] hton the ctc handlerton + @param[in] thd the MySQL query thread of the caller + @param[in] stat_print print function + @param[in] stat_type status to show */ + static bool ctc_show_status(handlerton *, THD * thd, stat_print_fn * stat_print, enum ha_stat_type stat_type) + { + if (stat_type == HA_ENGINE_STATUS) { + ctc_stats::get_instance().print_stats(thd, stat_print); + } -/** Return 0 on success and non-zero on failure. -@param[in] hton the ctc handlerton -@param[in] thd the MySQL query thread of the caller -@param[in] stat_print print function -@param[in] stat_type status to show */ -static bool ctc_show_status(handlerton *, THD *thd, stat_print_fn *stat_print, enum ha_stat_type stat_type) { - if (stat_type == HA_ENGINE_STATUS) { - ctc_stats::get_instance().print_stats(thd, stat_print); + return false; } - return false; -} - -void ctc_set_mysql_read_only() { - ctc_log_system("[Disaster Recovecy] starting or initializing"); - super_read_only = true; - read_only = true; - opt_readonly = true; - ctc_log_system("[Disaster Recovery] set super_read_only = true."); -} + void ctc_set_mysql_read_only() + { + ctc_log_system("[Disaster Recovecy] starting or initializing"); + super_read_only = true; + read_only = true; + opt_readonly = true; + ctc_log_system("[Disaster Recovery] set super_read_only = true."); + } -void ctc_reset_mysql_read_only() { - ctc_log_system("[Disaster Recovecy] starting or initializing"); - super_read_only = false; - read_only = false; - opt_readonly = false; - ctc_log_system("[Disaster Recovery] set super_read_only = false."); -} + void ctc_reset_mysql_read_only() + { + ctc_log_system("[Disaster Recovecy] starting or initializing"); + super_read_only = false; + read_only = false; + opt_readonly = false; + ctc_log_system("[Disaster Recovery] set super_read_only = false."); + } -int ctc_set_cluster_role_by_cantian(bool is_slave) { - lock_guard lock(m_ctc_cluster_role_mutex); - if (is_slave) { - ctc_cluster_role = (int32_t)dis_cluster_role::STANDBY; - ctc_set_mysql_read_only(); - } else { - ctc_cluster_role = (int32_t)dis_cluster_role::PRIMARY; - ctc_reset_mysql_read_only(); + int ctc_set_cluster_role_by_cantian(bool is_slave) + { + lock_guard lock(m_ctc_cluster_role_mutex); + if (is_slave) { + ctc_cluster_role = (int32_t)dis_cluster_role::STANDBY; + ctc_set_mysql_read_only(); + } else { + ctc_cluster_role = (int32_t)dis_cluster_role::PRIMARY; + ctc_reset_mysql_read_only(); + } + return 0; } - return 0; -} -bool is_single_run_mode() -{ + bool is_single_run_mode() + { #ifndef WITH_CANTIAN - return false; + return false; #else return true; #endif -} - -void ctc_set_metadata_switch() { // MySQL为元数据归一版本 - lock_guard lock(m_ctc_metadata_normalization_mutex); - if (ctc_metadata_normalization != (int32_t)metadata_switchs::DEFAULT) { - return; } - bool cantian_metadata_switch = false; - bool cantian_cluster_ready = false; - int ret = ctc_search_metadata_status(&cantian_metadata_switch, &cantian_cluster_ready); - if (ret != CT_SUCCESS || !cantian_cluster_ready) { - ctc_metadata_normalization = (int32_t)metadata_switchs::CLUSTER_NOT_READY; - ctc_log_error("[ctc_set_metadata_switch] ctc_search_metadata_status failed with error code: %d, cantian_cluster_ready: %d", ret, cantian_cluster_ready); - return; - } - ctc_log_system("[ctc_set_metadata_switch] mysql_metadata_switch: 1, cantian_metadata_switch: %d, cantian_cluster_ready: %d", cantian_metadata_switch, cantian_cluster_ready); - ctc_metadata_normalization = cantian_metadata_switch ? (int32_t)metadata_switchs::MATCH_META : (int32_t)metadata_switchs::NOT_MATCH; -} - -int32_t ctc_get_metadata_switch() { - if (ctc_metadata_normalization != (int32_t)metadata_switchs::DEFAULT) { - return ctc_metadata_normalization; + + void ctc_set_metadata_switch() + { // MySQL为元数据归一版本 + lock_guard lock(m_ctc_metadata_normalization_mutex); + if (ctc_metadata_normalization != (int32_t)metadata_switchs::DEFAULT) { + return; + } + bool cantian_metadata_switch = false; + bool cantian_cluster_ready = false; + int ret = ctc_search_metadata_status(&cantian_metadata_switch, &cantian_cluster_ready); + if (ret != CT_SUCCESS || !cantian_cluster_ready) { + ctc_metadata_normalization = (int32_t)metadata_switchs::CLUSTER_NOT_READY; + ctc_log_error( + "[ctc_set_metadata_switch] ctc_search_metadata_status failed with error code: %d, cantian_cluster_ready: %d", + ret, cantian_cluster_ready); + return; + } + ctc_log_system( + "[ctc_set_metadata_switch] mysql_metadata_switch: 1, cantian_metadata_switch: %d, cantian_cluster_ready: %d", + cantian_metadata_switch, cantian_cluster_ready); + ctc_metadata_normalization = + cantian_metadata_switch ? (int32_t)metadata_switchs::MATCH_META : (int32_t)metadata_switchs::NOT_MATCH; } - lock_guard lock(m_ctc_metadata_normalization_mutex); - if (ctc_metadata_normalization != (int32_t)metadata_switchs::DEFAULT) { + int32_t ctc_get_metadata_switch() + { + if (ctc_metadata_normalization != (int32_t)metadata_switchs::DEFAULT) { + return ctc_metadata_normalization; + } + + lock_guard lock(m_ctc_metadata_normalization_mutex); + if (ctc_metadata_normalization != (int32_t)metadata_switchs::DEFAULT) { + return ctc_metadata_normalization; + } + bool mysql_metadata_switch = CHECK_HAS_MEMBER(handlerton, get_metadata_switch); + bool cantian_metadata_switch = false; + bool cantian_cluster_ready = false; + int ret = ctc_search_metadata_status(&cantian_metadata_switch, &cantian_cluster_ready); + if (ret != CT_SUCCESS || !cantian_cluster_ready) { + ctc_metadata_normalization = (int32_t)metadata_switchs::CLUSTER_NOT_READY; + ctc_log_error( + "[ctc_get_metadata_switch] ctc_search_metadata_status failed with error code: %d, cantian_metadata_switch: " + "%d, cantian_cluster_ready: %d", + ret, cantian_metadata_switch, cantian_cluster_ready); + return ctc_metadata_normalization; + } + ctc_log_system("[ctc_get_metadata_switch] cantian_metadata_switch: %d, cantian_cluster_ready: %d", + cantian_metadata_switch, cantian_cluster_ready); + ctc_metadata_normalization = + (mysql_metadata_switch == cantian_metadata_switch) + ? (mysql_metadata_switch ? (int32_t)metadata_switchs::MATCH_META : (int32_t)metadata_switchs::MATCH_NO_META) + : (int32_t)metadata_switchs::NOT_MATCH; + return ctc_metadata_normalization; } - bool mysql_metadata_switch = CHECK_HAS_MEMBER(handlerton, get_metadata_switch); - bool cantian_metadata_switch = false; - bool cantian_cluster_ready = false; - int ret = ctc_search_metadata_status(&cantian_metadata_switch, &cantian_cluster_ready); - if (ret != CT_SUCCESS || !cantian_cluster_ready) { - ctc_metadata_normalization = (int32_t)metadata_switchs::CLUSTER_NOT_READY; - ctc_log_error("[ctc_get_metadata_switch] ctc_search_metadata_status failed with error code: %d, cantian_metadata_switch: %d, cantian_cluster_ready: %d", ret, cantian_metadata_switch, cantian_cluster_ready); - return ctc_metadata_normalization; + + /** + Check metadata init status in CTC. + */ + static int ctc_get_metadata_status() + { + DBUG_TRACE; + + bool is_exists; + int ret = 0; + ct_errno_t begin = (ct_errno_t)ctc_check_db_table_exists("mysql", "", &is_exists); + if (begin != CT_SUCCESS) { + ctc_log_error("check metadata init start failed with error code: %d", begin); + return convert_ctc_error_code_to_mysql(begin); + } + ret = is_exists ? 1 : 0; + + ct_errno_t end = (ct_errno_t)ctc_check_db_table_exists("sys", "sys_config", &is_exists); + if (end != CT_SUCCESS) { + ctc_log_error("check metadata init end failed with error code: %d", end); + return convert_ctc_error_code_to_mysql(end); + } + ret = is_exists ? 2 : ret; + return ret; } - ctc_log_system("[ctc_get_metadata_switch] cantian_metadata_switch: %d, cantian_cluster_ready: %d", cantian_metadata_switch, cantian_cluster_ready); - ctc_metadata_normalization = (mysql_metadata_switch == cantian_metadata_switch) ? (mysql_metadata_switch ? (int32_t)metadata_switchs::MATCH_META : (int32_t)metadata_switchs::MATCH_NO_META) : (int32_t)metadata_switchs::NOT_MATCH; - return ctc_metadata_normalization; -} + static int ctc_init_tablespace(List * tablespaces) + { + DBUG_TRACE; + const size_t len = 30 + sizeof("id=;flags=;server_version=;space_version=;state=normal"); + const char *fmt = "id=%u;flags=%u;server_version=%u;space_version=%u;state=normal"; + static char se_private_data_dd[len]; + snprintf(se_private_data_dd, len, fmt, 8, 0, 0, 0); + + static Plugin_tablespace dd_space((const char *)"mysql", "", se_private_data_dd, "", (const char *)"CTC"); + static Plugin_tablespace::Plugin_tablespace_file dd_file((const char *)"mysql.ibd", ""); + dd_space.add_file(&dd_file); + tablespaces->push_back(&dd_space); + return 0; + } + static bool ctc_ddse_dict_init(dict_init_mode_t dict_init_mode, uint version, List * tables, + List * tablespaces) + { + DBUG_TRACE; + ctc_log_system("[CTC_INIT]: begin ctc_ddse_dict_init."); + + assert(tables && tables->is_empty()); + assert(tablespaces && tablespaces->is_empty()); + assert(dict_init_mode == DICT_INIT_CREATE_FILES || dict_init_mode == DICT_INIT_CHECK_FILES); + assert(version < 1000000000); + // valid value check + if (!(tables && tables->is_empty()) || !(tablespaces && tablespaces->is_empty()) || + !(dict_init_mode == DICT_INIT_CREATE_FILES || dict_init_mode == DICT_INIT_CHECK_FILES) || + version >= 1000000000) { + return true; + } -/** - Check metadata init status in CTC. -*/ -static int ctc_get_metadata_status() { - DBUG_TRACE; + if (ctc_init_tablespace(tablespaces)) { + return true; + } - bool is_exists; - int ret = 0; - ct_errno_t begin = (ct_errno_t)ctc_check_db_table_exists("mysql", "", &is_exists); - if (begin != CT_SUCCESS) { - ctc_log_error("check metadata init start failed with error code: %d", begin); - return convert_ctc_error_code_to_mysql(begin); - } - ret = is_exists ? 1 : 0; + /* Instantiate table defs only if we are successful so far. */ + dd::Object_table *innodb_dynamic_metadata = dd::Object_table::create_object_table(); + innodb_dynamic_metadata->set_hidden(true); + dd::Object_table_definition *def = innodb_dynamic_metadata->target_table_definition(); + def->set_table_name("innodb_dynamic_metadata"); + def->add_field(0, "table_id", "table_id BIGINT UNSIGNED NOT NULL"); + def->add_field(1, "version", "version BIGINT UNSIGNED NOT NULL"); + def->add_field(2, "metadata", "metadata BLOB NOT NULL"); + def->add_index(0, "index_pk", "PRIMARY KEY (table_id)"); + /* Options and tablespace are set at the SQL layer. */ + + /* Changing these values would change the specification of innodb statistics + tables. */ + static constexpr size_t DB_NAME_FIELD_SIZE = 64; + static constexpr size_t TABLE_NAME_FIELD_SIZE = 199; + + /* Set length for database name field. */ + std::ostringstream db_name_field; + db_name_field << "database_name VARCHAR(" << DB_NAME_FIELD_SIZE << ") NOT NULL"; + std::string db_field = db_name_field.str(); + + /* Set length for table name field. */ + std::ostringstream table_name_field; + table_name_field << "table_name VARCHAR(" << TABLE_NAME_FIELD_SIZE << ") NOT NULL"; + std::string table_field = table_name_field.str(); + + dd::Object_table *innodb_table_stats = dd::Object_table::create_object_table(); + innodb_table_stats->set_hidden(false); + def = innodb_table_stats->target_table_definition(); + def->set_table_name("innodb_table_stats"); + def->add_field(0, "database_name", db_field.c_str()); + def->add_field(1, "table_name", table_field.c_str()); + def->add_field(2, "last_update", + "last_update TIMESTAMP NOT NULL \n" + " DEFAULT CURRENT_TIMESTAMP \n" + " ON UPDATE CURRENT_TIMESTAMP"); + def->add_field(3, "n_rows", "n_rows BIGINT UNSIGNED NOT NULL"); + def->add_field(4, "clustered_index_size", "clustered_index_size BIGINT UNSIGNED NOT NULL"); + def->add_field(5, "sum_of_other_index_sizes", "sum_of_other_index_sizes BIGINT UNSIGNED NOT NULL"); + def->add_index(0, "index_pk", "PRIMARY KEY (database_name, table_name)"); + /* Options and tablespace are set at the SQL layer. */ + + dd::Object_table *innodb_index_stats = dd::Object_table::create_object_table(); + innodb_index_stats->set_hidden(false); + def = innodb_index_stats->target_table_definition(); + def->set_table_name("innodb_index_stats"); + def->add_field(0, "database_name", db_field.c_str()); + def->add_field(1, "table_name", table_field.c_str()); + def->add_field(2, "index_name", "index_name VARCHAR(64) NOT NULL"); + def->add_field(3, "last_update", + "last_update TIMESTAMP NOT NULL" + " DEFAULT CURRENT_TIMESTAMP" + " ON UPDATE CURRENT_TIMESTAMP"); + /* + There are at least: stat_name='size' + stat_name='n_leaf_pages' + stat_name='n_diff_pfx%' + */ + def->add_field(4, "stat_name", "stat_name VARCHAR(64) NOT NULL"); + def->add_field(5, "stat_value", "stat_value BIGINT UNSIGNED NOT NULL"); + def->add_field(6, "sample_size", "sample_size BIGINT UNSIGNED"); + def->add_field(7, "stat_description", "stat_description VARCHAR(1024) NOT NULL"); + def->add_index(0, "index_pk", + "PRIMARY KEY (database_name, table_name, " + "index_name, stat_name)"); + /* Options and tablespace are set at the SQL layer. */ + + dd::Object_table *innodb_ddl_log = dd::Object_table::create_object_table(); + innodb_ddl_log->set_hidden(true); + def = innodb_ddl_log->target_table_definition(); + def->set_table_name("innodb_ddl_log"); + def->add_field(0, "id", "id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT"); + def->add_field(1, "thread_id", "thread_id BIGINT UNSIGNED NOT NULL"); + def->add_field(2, "type", "type INT UNSIGNED NOT NULL"); + def->add_field(3, "space_id", "space_id INT UNSIGNED"); + def->add_field(4, "page_no", "page_no INT UNSIGNED"); + def->add_field(5, "index_id", "index_id BIGINT UNSIGNED"); + def->add_field(6, "table_id", "table_id BIGINT UNSIGNED"); + def->add_field(7, "old_file_path", "old_file_path VARCHAR(512) COLLATE UTF8_BIN"); + def->add_field(8, "new_file_path", "new_file_path VARCHAR(512) COLLATE UTF8_BIN"); + def->add_index(0, "index_pk", "PRIMARY KEY(id)"); + def->add_index(1, "index_k_thread_id", "KEY(thread_id)"); + /* Options and tablespace are set at the SQL layer. */ + + tables->push_back(innodb_dynamic_metadata); + tables->push_back(innodb_table_stats); + tables->push_back(innodb_index_stats); + tables->push_back(innodb_ddl_log); + + ctc_log_system("[CTC_INIT]:end init dict!"); - ct_errno_t end = (ct_errno_t)ctc_check_db_table_exists("sys", "sys_config", &is_exists); - if (end != CT_SUCCESS) { - ctc_log_error("check metadata init end failed with error code: %d", end); - return convert_ctc_error_code_to_mysql(end); + return false; } - ret = is_exists ? 2 : ret; - return ret; -} -static int ctc_init_tablespace(List *tablespaces) -{ - DBUG_TRACE; - const size_t len = 30 + sizeof("id=;flags=;server_version=;space_version=;state=normal"); - const char *fmt = "id=%u;flags=%u;server_version=%u;space_version=%u;state=normal"; - static char se_private_data_dd[len]; - snprintf(se_private_data_dd, len, fmt, 8, 0, 0, 0); - - static Plugin_tablespace dd_space((const char *)"mysql", "", se_private_data_dd, "", (const char *)"CTC"); - static Plugin_tablespace::Plugin_tablespace_file dd_file((const char *)"mysql.ibd", ""); - dd_space.add_file(&dd_file); - tablespaces->push_back(&dd_space); - return 0; -} + /** Set of ids of DD tables */ + static set s_dd_table_ids; -static bool ctc_ddse_dict_init( - dict_init_mode_t dict_init_mode, uint version, - List *tables, - List *tablespaces) { - DBUG_TRACE; - ctc_log_system("[CTC_INIT]: begin ctc_ddse_dict_init."); - - assert(tables && tables->is_empty()); - assert(tablespaces && tablespaces->is_empty()); - assert(dict_init_mode == DICT_INIT_CREATE_FILES || dict_init_mode == DICT_INIT_CHECK_FILES); - assert(version < 1000000000); - // valid value check - if (!(tables && tables->is_empty()) || !(tablespaces && tablespaces->is_empty()) || - !(dict_init_mode == DICT_INIT_CREATE_FILES || dict_init_mode == DICT_INIT_CHECK_FILES) || - version >= 1000000000) { - return true; + static bool is_dd_table_id(uint16_t id) + { + DBUG_TRACE; + return (s_dd_table_ids.find(id) != s_dd_table_ids.end()); } - if (ctc_init_tablespace(tablespaces)) { - return true; + static void ctc_dict_register_dd_table_id(dd::Object_id dd_table_id) + { + DBUG_TRACE; + s_dd_table_ids.insert(dd_table_id); + return; } - /* Instantiate table defs only if we are successful so far. */ - dd::Object_table *innodb_dynamic_metadata = - dd::Object_table::create_object_table(); - innodb_dynamic_metadata->set_hidden(true); - dd::Object_table_definition *def = - innodb_dynamic_metadata->target_table_definition(); - def->set_table_name("innodb_dynamic_metadata"); - def->add_field(0, "table_id", "table_id BIGINT UNSIGNED NOT NULL"); - def->add_field(1, "version", "version BIGINT UNSIGNED NOT NULL"); - def->add_field(2, "metadata", "metadata BLOB NOT NULL"); - def->add_index(0, "index_pk", "PRIMARY KEY (table_id)"); - /* Options and tablespace are set at the SQL layer. */ - - /* Changing these values would change the specification of innodb statistics - tables. */ - static constexpr size_t DB_NAME_FIELD_SIZE = 64; - static constexpr size_t TABLE_NAME_FIELD_SIZE = 199; - - /* Set length for database name field. */ - std::ostringstream db_name_field; - db_name_field << "database_name VARCHAR(" << DB_NAME_FIELD_SIZE - << ") NOT NULL"; - std::string db_field = db_name_field.str(); - - /* Set length for table name field. */ - std::ostringstream table_name_field; - table_name_field << "table_name VARCHAR(" << TABLE_NAME_FIELD_SIZE - << ") NOT NULL"; - std::string table_field = table_name_field.str(); - - dd::Object_table *innodb_table_stats = - dd::Object_table::create_object_table(); - innodb_table_stats->set_hidden(false); - def = innodb_table_stats->target_table_definition(); - def->set_table_name("innodb_table_stats"); - def->add_field(0, "database_name", db_field.c_str()); - def->add_field(1, "table_name", table_field.c_str()); - def->add_field(2, "last_update", - "last_update TIMESTAMP NOT NULL \n" - " DEFAULT CURRENT_TIMESTAMP \n" - " ON UPDATE CURRENT_TIMESTAMP"); - def->add_field(3, "n_rows", "n_rows BIGINT UNSIGNED NOT NULL"); - def->add_field(4, "clustered_index_size", - "clustered_index_size BIGINT UNSIGNED NOT NULL"); - def->add_field(5, "sum_of_other_index_sizes", - "sum_of_other_index_sizes BIGINT UNSIGNED NOT NULL"); - def->add_index(0, "index_pk", "PRIMARY KEY (database_name, table_name)"); - /* Options and tablespace are set at the SQL layer. */ - - dd::Object_table *innodb_index_stats = - dd::Object_table::create_object_table(); - innodb_index_stats->set_hidden(false); - def = innodb_index_stats->target_table_definition(); - def->set_table_name("innodb_index_stats"); - def->add_field(0, "database_name", db_field.c_str()); - def->add_field(1, "table_name", table_field.c_str()); - def->add_field(2, "index_name", "index_name VARCHAR(64) NOT NULL"); - def->add_field(3, "last_update", - "last_update TIMESTAMP NOT NULL" - " DEFAULT CURRENT_TIMESTAMP" - " ON UPDATE CURRENT_TIMESTAMP"); - /* - There are at least: stat_name='size' - stat_name='n_leaf_pages' - stat_name='n_diff_pfx%' - */ - def->add_field(4, "stat_name", "stat_name VARCHAR(64) NOT NULL"); - def->add_field(5, "stat_value", "stat_value BIGINT UNSIGNED NOT NULL"); - def->add_field(6, "sample_size", "sample_size BIGINT UNSIGNED"); - def->add_field(7, "stat_description", - "stat_description VARCHAR(1024) NOT NULL"); - def->add_index(0, "index_pk", - "PRIMARY KEY (database_name, table_name, " - "index_name, stat_name)"); - /* Options and tablespace are set at the SQL layer. */ - - dd::Object_table *innodb_ddl_log = dd::Object_table::create_object_table(); - innodb_ddl_log->set_hidden(true); - def = innodb_ddl_log->target_table_definition(); - def->set_table_name("innodb_ddl_log"); - def->add_field(0, "id", "id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT"); - def->add_field(1, "thread_id", "thread_id BIGINT UNSIGNED NOT NULL"); - def->add_field(2, "type", "type INT UNSIGNED NOT NULL"); - def->add_field(3, "space_id", "space_id INT UNSIGNED"); - def->add_field(4, "page_no", "page_no INT UNSIGNED"); - def->add_field(5, "index_id", "index_id BIGINT UNSIGNED"); - def->add_field(6, "table_id", "table_id BIGINT UNSIGNED"); - def->add_field(7, "old_file_path", - "old_file_path VARCHAR(512) COLLATE UTF8_BIN"); - def->add_field(8, "new_file_path", - "new_file_path VARCHAR(512) COLLATE UTF8_BIN"); - def->add_index(0, "index_pk", "PRIMARY KEY(id)"); - def->add_index(1, "index_k_thread_id", "KEY(thread_id)"); - /* Options and tablespace are set at the SQL layer. */ - - tables->push_back(innodb_dynamic_metadata); - tables->push_back(innodb_table_stats); - tables->push_back(innodb_index_stats); - tables->push_back(innodb_ddl_log); - - ctc_log_system("[CTC_INIT]:end init dict!"); - - return false; -} + static bool ctc_dict_recover(dict_recovery_mode_t, uint) + { + DBUG_TRACE; + return false; + } -/** Set of ids of DD tables */ -static set s_dd_table_ids; - -static bool is_dd_table_id(uint16_t id) { - DBUG_TRACE; - return (s_dd_table_ids.find(id) != s_dd_table_ids.end()); -} + static bool ctc_dict_get_server_version(uint * version) + { + DBUG_TRACE; + *version = MYSQL_VERSION_ID; + return false; + } -static void ctc_dict_register_dd_table_id(dd::Object_id dd_table_id) { - DBUG_TRACE; - s_dd_table_ids.insert(dd_table_id); - return; -} - -static bool ctc_dict_recover(dict_recovery_mode_t, uint){ - DBUG_TRACE; - return false; -} - -static bool ctc_dict_get_server_version(uint *version) { - DBUG_TRACE; - *version = MYSQL_VERSION_ID; - return false; -} - -static bool ctc_dict_set_server_version() { - DBUG_TRACE; - return false; -} - -static void ctc_dict_cache_reset(const char *, const char *) { - DBUG_TRACE; - return; -} - -static void ctc_dict_cache_reset_tables_and_tablespaces() { - DBUG_TRACE; - return; -} + static bool ctc_dict_set_server_version() + { + DBUG_TRACE; + return false; + } -static int ctc_op_before_load_meta(THD *thd) { - bool need_forward = true; - return ctc_check_lock_instance(thd, need_forward); -} - -static int ctc_op_after_load_meta(THD *thd) { - return ctc_check_unlock_instance(thd); -} - -static bool ctc_dict_readonly() { - return false; -} + static void ctc_dict_cache_reset(const char *, const char *) + { + DBUG_TRACE; + return; + } -template -static typename std::enable_if::type set_hton_members(T *ctc_hton) { - ctc_hton->get_inst_id = ha_ctc_get_inst_id; - ctc_hton->get_metadata_switch = ctc_get_metadata_switch; - ctc_hton->set_metadata_switch = ctc_set_metadata_switch; - ctc_hton->get_metadata_status = ctc_get_metadata_status; - ctc_hton->op_before_load_meta = ctc_op_before_load_meta; - ctc_hton->op_after_load_meta = ctc_op_after_load_meta; - ctc_hton->drop_database = ctc_drop_database_with_err; - ctc_hton->binlog_log_query = ctc_binlog_log_query_with_err; - ctc_hton->get_cluster_role = ctc_get_cluster_role; -} + static void ctc_dict_cache_reset_tables_and_tablespaces() + { + DBUG_TRACE; + return; + } -template -static typename std::enable_if::type set_hton_members(T *ctc_hton) { - ctc_hton->drop_database = ctc_drop_database; - ctc_hton->binlog_log_query = ctc_binlog_log_query; -} + static int ctc_op_before_load_meta(THD * thd) + { + bool need_forward = true; + return ctc_check_lock_instance(thd, need_forward); + } -extern int (*ctc_init)(); -extern int (*ctc_deinit)(); + static int ctc_op_after_load_meta(THD * thd) { return ctc_check_unlock_instance(thd); } -static int ctc_init_func(void *p) { - DBUG_TRACE; - ctc_hton = (handlerton *)p; - ctc_hton->state = SHOW_OPTION_YES; - ctc_hton->db_type = (legacy_db_type)30; - ctc_hton->create = ctc_create_handler; - ctc_hton->is_supported_system_table = ctc_is_supported_system_table; - ctc_hton->check_fk_column_compat = ctc_check_fk_column_compat; - ctc_hton->commit = ctc_commit; - ctc_hton->rollback = ctc_rollback; - ctc_hton->savepoint_set = ctc_set_savepoint; - ctc_hton->savepoint_rollback = ctc_rollback_savepoint; - ctc_hton->savepoint_release = ctc_release_savepoint; - ctc_hton->close_connection = ctc_close_connect; - ctc_hton->kill_connection = ctc_kill_connection; - ctc_hton->notify_exclusive_mdl = ctc_notify_exclusive_mdl; - ctc_hton->notify_alter_table = ctc_notify_alter_table; - ctc_hton->start_consistent_snapshot = ctc_start_trx_and_assign_scn; - ctc_hton->partition_flags = ctc_partition_flags; - ctc_hton->flags = HTON_SUPPORTS_FOREIGN_KEYS | HTON_CAN_RECREATE | HTON_SUPPORTS_ATOMIC_DDL; - // TODO: HTON_SUPPORTS_TABLE_ENCRYPTION 表空间 tablespace加密功能暂时不做支持,后面会考虑添加。 - ctc_hton->foreign_keys_flags = HTON_FKS_WITH_PREFIX_PARENT_KEYS | - HTON_FKS_NEED_DIFFERENT_PARENT_AND_SUPPORTING_KEYS | - HTON_FKS_WITH_EXTENDED_PARENT_KEYS; - ctc_hton->alter_tablespace = ctcbase_alter_tablespace; - ctc_hton->file_extensions = nullptr; - ctc_hton->get_tablespace_statistics = ctc_get_tablespace_statistics; - ctc_hton->show_status = ctc_show_status; - ctc_hton->ddse_dict_init = ctc_ddse_dict_init; - ctc_hton->dict_register_dd_table_id = ctc_dict_register_dd_table_id; - ctc_hton->dict_recover = ctc_dict_recover; - ctc_hton->dict_get_server_version = ctc_dict_get_server_version; - ctc_hton->dict_set_server_version = ctc_dict_set_server_version; - ctc_hton->dict_cache_reset = ctc_dict_cache_reset; - ctc_hton->dict_cache_reset_tables_and_tablespaces = ctc_dict_cache_reset_tables_and_tablespaces; - ctc_hton->is_dict_readonly = ctc_dict_readonly; + static bool ctc_dict_readonly() { return false; } + + template + static typename std::enable_if::type set_hton_members(T * ctc_hton) + { + ctc_hton->get_inst_id = ha_ctc_get_inst_id; + ctc_hton->get_metadata_switch = ctc_get_metadata_switch; + ctc_hton->set_metadata_switch = ctc_set_metadata_switch; + ctc_hton->get_metadata_status = ctc_get_metadata_status; + ctc_hton->op_before_load_meta = ctc_op_before_load_meta; + ctc_hton->op_after_load_meta = ctc_op_after_load_meta; + ctc_hton->drop_database = ctc_drop_database_with_err; + ctc_hton->binlog_log_query = ctc_binlog_log_query_with_err; + ctc_hton->get_cluster_role = ctc_get_cluster_role; + } + + template + static typename std::enable_if::type set_hton_members(T * ctc_hton) + { + ctc_hton->drop_database = ctc_drop_database; + ctc_hton->binlog_log_query = ctc_binlog_log_query; + } + + extern int (*ctc_init)(); + extern int (*ctc_deinit)(); + + static int ctc_init_func(void *p) + { + DBUG_TRACE; + ctc_hton = (handlerton *)p; + ctc_hton->state = SHOW_OPTION_YES; + ctc_hton->db_type = (legacy_db_type)30; + ctc_hton->create = ctc_create_handler; + ctc_hton->is_supported_system_table = ctc_is_supported_system_table; + ctc_hton->check_fk_column_compat = ctc_check_fk_column_compat; + ctc_hton->commit = ctc_commit; + ctc_hton->rollback = ctc_rollback; + ctc_hton->savepoint_set = ctc_set_savepoint; + ctc_hton->savepoint_rollback = ctc_rollback_savepoint; + ctc_hton->savepoint_release = ctc_release_savepoint; + ctc_hton->close_connection = ctc_close_connect; + ctc_hton->kill_connection = ctc_kill_connection; + ctc_hton->notify_exclusive_mdl = ctc_notify_exclusive_mdl; + ctc_hton->notify_alter_table = ctc_notify_alter_table; + ctc_hton->start_consistent_snapshot = ctc_start_trx_and_assign_scn; + ctc_hton->partition_flags = ctc_partition_flags; + ctc_hton->flags = HTON_SUPPORTS_FOREIGN_KEYS | HTON_CAN_RECREATE | HTON_SUPPORTS_ATOMIC_DDL; + // TODO: HTON_SUPPORTS_TABLE_ENCRYPTION 表空间 tablespace加密功能暂时不做支持,后面会考虑添加。 + ctc_hton->foreign_keys_flags = HTON_FKS_WITH_PREFIX_PARENT_KEYS | + HTON_FKS_NEED_DIFFERENT_PARENT_AND_SUPPORTING_KEYS | + HTON_FKS_WITH_EXTENDED_PARENT_KEYS; + ctc_hton->alter_tablespace = ctcbase_alter_tablespace; + ctc_hton->file_extensions = nullptr; + ctc_hton->get_tablespace_statistics = ctc_get_tablespace_statistics; + ctc_hton->show_status = ctc_show_status; + ctc_hton->ddse_dict_init = ctc_ddse_dict_init; + ctc_hton->dict_register_dd_table_id = ctc_dict_register_dd_table_id; + ctc_hton->dict_recover = ctc_dict_recover; + ctc_hton->dict_get_server_version = ctc_dict_get_server_version; + ctc_hton->dict_set_server_version = ctc_dict_set_server_version; + ctc_hton->dict_cache_reset = ctc_dict_cache_reset; + ctc_hton->dict_cache_reset_tables_and_tablespaces = ctc_dict_cache_reset_tables_and_tablespaces; + ctc_hton->is_dict_readonly = ctc_dict_readonly; #ifdef FEATURE_X_FOR_MYSQL_32 - ctc_hton->push_to_engine = ctc_push_to_engine; + ctc_hton->push_to_engine = ctc_push_to_engine; #endif - set_hton_members(ctc_hton); - int ret = ctc_init(); - if (ret != 0) { - ctc_log_error("[CTC_INIT]: ctc storage engine plugin init failed:%d", ret); - return HA_ERR_INITIALIZATION; - } + set_hton_members(ctc_hton); + int ret = ctc_init(); + if (ret != 0) { + ctc_log_error("[CTC_INIT]: ctc storage engine plugin init failed:%d", ret); + return HA_ERR_INITIALIZATION; + } - // 元数据归一流程初始化下发参天 - // 主干非initialize_insecure模式,需要注册共享内存接收线程并等待参天启动完成 - ret = srv_wait_instance_startuped(); - if (ret != 0) { - ctc_log_error("wait cantian instance startuped failed:%d", ret); - return HA_ERR_INITIALIZATION; - } - - ret = ctc_reg_instance(); - if (ret != 0) { - ctc_log_error("[CTC_INIT]:ctc_reg_instance failed:%d", ret); - return HA_ERR_INITIALIZATION; - } - - ret = ctc_check_tx_isolation(); - if (ret != 0) { - ctc_log_error("[CTC_INIT]:ctc_check_tx_isolation failed:%d", ret); - return HA_ERR_INITIALIZATION; + // 元数据归一流程初始化下发参天 + // 主干非initialize_insecure模式,需要注册共享内存接收线程并等待参天启动完成 + ret = srv_wait_instance_startuped(); + if (ret != 0) { + ctc_log_error("wait cantian instance startuped failed:%d", ret); + return HA_ERR_INITIALIZATION; + } + + ret = ctc_reg_instance(); + if (ret != 0) { + ctc_log_error("[CTC_INIT]:ctc_reg_instance failed:%d", ret); + return HA_ERR_INITIALIZATION; + } + + ret = ctc_check_tx_isolation(); + if (ret != 0) { + ctc_log_error("[CTC_INIT]:ctc_check_tx_isolation failed:%d", ret); + return HA_ERR_INITIALIZATION; + } + ctc_get_cluster_role(); + ctc_log_system("[CTC_INIT]:SUCCESS!"); + return 0; } - ctc_get_cluster_role(); - ctc_log_system("[CTC_INIT]:SUCCESS!"); - return 0; -} -static int ctc_deinit_func(void *p) { - // handler.cc:726 此处传的p固定为null, 不是handlerton,不能依赖这部分逻辑 - UNUSED_PARAM(p); - ctc_log_system( - "ctc_deinit_func ctc_ddl_req_msg_mem_use_heap_cnt:%u, " - "ctc_ddl_req_msg_mem_max_size:%u.", - (uint32_t)ctc_ddl_stack_mem::ctc_ddl_req_msg_mem_use_heap_cnt, - (uint32_t)ctc_ddl_stack_mem::ctc_ddl_req_msg_mem_max_size); - ctc_unreg_instance(); - return ctc_deinit(); -} + static int ctc_deinit_func(void *p) + { + // handler.cc:726 此处传的p固定为null, 不是handlerton,不能依赖这部分逻辑 + UNUSED_PARAM(p); + ctc_log_system( + "ctc_deinit_func ctc_ddl_req_msg_mem_use_heap_cnt:%u, " + "ctc_ddl_req_msg_mem_max_size:%u.", + (uint32_t)ctc_ddl_stack_mem::ctc_ddl_req_msg_mem_use_heap_cnt, + (uint32_t)ctc_ddl_stack_mem::ctc_ddl_req_msg_mem_max_size); + ctc_unreg_instance(); + return ctc_deinit(); + } -static SHOW_VAR ctc_status[] = { - {nullptr, nullptr, SHOW_UNDEF, SHOW_SCOPE_UNDEF}}; + static SHOW_VAR ctc_status[] = {{nullptr, nullptr, SHOW_UNDEF, SHOW_SCOPE_UNDEF}}; -extern struct st_mysql_plugin g_ctc_ddl_rewriter_plugin; + extern struct st_mysql_plugin g_ctc_ddl_rewriter_plugin; -const char *ctc_hton_name = "CTC"; + const char *ctc_hton_name = "CTC"; #pragma GCC visibility push(default) -mysql_declare_plugin(ctc) g_ctc_ddl_rewriter_plugin,{ - MYSQL_STORAGE_ENGINE_PLUGIN, - &ctc_storage_engine, - ctc_hton_name, - PLUGIN_AUTHOR_ORACLE, - "CTC storage engine", - PLUGIN_LICENSE_GPL, - ctc_init_func, - nullptr, - ctc_deinit_func, - CTC_CLIENT_VERSION_NUMBER, - ctc_status, - ctc_system_variables, - nullptr, - PLUGIN_OPT_ALLOW_EARLY, -} mysql_declare_plugin_end; + mysql_declare_plugin(ctc) g_ctc_ddl_rewriter_plugin, { + MYSQL_STORAGE_ENGINE_PLUGIN, + &ctc_storage_engine, + ctc_hton_name, + PLUGIN_AUTHOR_ORACLE, + "CTC storage engine", + PLUGIN_LICENSE_GPL, + ctc_init_func, + nullptr, + ctc_deinit_func, + CTC_CLIENT_VERSION_NUMBER, + ctc_status, + ctc_system_variables, + nullptr, + PLUGIN_OPT_ALLOW_EARLY, + } mysql_declare_plugin_end; #pragma GCC visibility pop -void ha_ctc::update_create_info(HA_CREATE_INFO *create_info) { - if ((create_info->used_fields & HA_CREATE_USED_AUTO) || !table->found_next_number_field) { - return; - } + void ha_ctc::update_create_info(HA_CREATE_INFO * create_info) + { + if ((create_info->used_fields & HA_CREATE_USED_AUTO) || !table->found_next_number_field) { + return; + } - THD* thd = ha_thd(); - if (engine_ddl_passthru(thd) && is_create_table_check(thd)) { - return; - } + THD *thd = ha_thd(); + if (engine_ddl_passthru(thd) && is_create_table_check(thd)) { + return; + } - int ret = 0; - if (m_tch.ctx_addr == INVALID_VALUE64) { - char user_name[SMALL_RECORD_SIZE] = { 0 }; - ctc_split_normalized_name(table->s->normalized_path.str, user_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); - ctc_copy_name(user_name, user_name, SMALL_RECORD_SIZE); + int ret = 0; + if (m_tch.ctx_addr == INVALID_VALUE64) { + char user_name[SMALL_RECORD_SIZE] = {0}; + ctc_split_normalized_name(table->s->normalized_path.str, user_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); + ctc_copy_name(user_name, user_name, SMALL_RECORD_SIZE); + update_member_tch(m_tch, ctc_hton, thd); + ret = ctc_open_table(&m_tch, table->s->table_name.str, user_name); + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + if (ret != 0) { + create_info->auto_increment_value = (ulonglong)0; + } + } + + uint64_t inc_value = 0; + uint16_t auto_inc_step = thd->variables.auto_increment_increment; + uint16_t auto_inc_offset = thd->variables.auto_increment_offset; update_member_tch(m_tch, ctc_hton, thd); - ret = ctc_open_table(&m_tch, table->s->table_name.str, user_name); + dml_flag_t flag; + flag.auto_inc_offset = auto_inc_offset; + flag.auto_inc_step = auto_inc_step; + flag.auto_increase = false; + ret = ctc_get_serial_value(&m_tch, &inc_value, flag); update_sess_ctx_by_tch(m_tch, ctc_hton, thd); if (ret != 0) { create_info->auto_increment_value = (ulonglong)0; + } else { + create_info->auto_increment_value = (ulonglong)inc_value; + stats.auto_increment_value = (ulonglong)inc_value; } } - uint64_t inc_value = 0; - uint16_t auto_inc_step = thd->variables.auto_increment_increment; - uint16_t auto_inc_offset = thd->variables.auto_increment_offset; - update_member_tch(m_tch, ctc_hton, thd); - dml_flag_t flag; - flag.auto_inc_offset = auto_inc_offset; - flag.auto_inc_step = auto_inc_step; - flag.auto_increase = false; - ret = ctc_get_serial_value(&m_tch, &inc_value, flag); - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - if (ret != 0) { - create_info->auto_increment_value = (ulonglong)0; - } else { - create_info->auto_increment_value = (ulonglong)inc_value; - stats.auto_increment_value = (ulonglong)inc_value; - } - -} - -/** - @brief - Used to delete a table. By the time delete_table() has been called all - opened references to this table will have been closed (and your globally - shared references released). The variable name will just be the name of - the table. You will need to remove any files you have created at this point. + /** + @brief + Used to delete a table. By the time delete_table() has been called all + opened references to this table will have been closed (and your globally + shared references released). The variable name will just be the name of + the table. You will need to remove any files you have created at this point. - @details - If you do not implement this, the default delete_table() is called from - handler.cc and it will delete all files with the file extensions from - handlerton::file_extensions. + @details + If you do not implement this, the default delete_table() is called from + handler.cc and it will delete all files with the file extensions from + handlerton::file_extensions. - Called from handler.cc by delete_table and ha_create_table(). Only used - during create if the table_flag HA_DROP_BEFORE_CREATE was specified for - the storage engine. + Called from handler.cc by delete_table and ha_create_table(). Only used + during create if the table_flag HA_DROP_BEFORE_CREATE was specified for + the storage engine. - @see - delete_table and ha_create_table() in handler.cc -*/ -EXTER_ATTACK int ha_ctc::delete_table(const char *full_path_name, const dd::Table *table_def) { - THD *thd = ha_thd(); - ct_errno_t ret = CT_SUCCESS; + @see + delete_table and ha_create_table() in handler.cc + */ + EXTER_ATTACK int ha_ctc::delete_table(const char *full_path_name, const dd::Table *table_def) + { + THD *thd = ha_thd(); + ct_errno_t ret = CT_SUCCESS; - if (engine_ddl_passthru(thd)) { - if (thd->locked_tables_mode) { - for (const dd::Foreign_key_parent *parent_fk : table_def->foreign_key_parents()) { - close_all_tables_for_name(thd, parent_fk->child_schema_name().c_str(), parent_fk->child_table_name().c_str(), true); + if (engine_ddl_passthru(thd)) { + if (thd->locked_tables_mode) { + for (const dd::Foreign_key_parent *parent_fk : table_def->foreign_key_parents()) { + close_all_tables_for_name(thd, parent_fk->child_schema_name().c_str(), parent_fk->child_table_name().c_str(), + true); + } } + return ret; } - return ret; - } - /* 删除db时 会直接删除参天用户 所有表也会直接被删除 无需再次下发 */ - if (thd->lex->sql_command == SQLCOM_DROP_DB) { - return ret; - } + /* 删除db时 会直接删除参天用户 所有表也会直接被删除 无需再次下发 */ + if (thd->lex->sql_command == SQLCOM_DROP_DB) { + return ret; + } - if (table_def != nullptr && table_def->is_persistent()) { - ctc_register_trx(ht, thd); - } + if (table_def != nullptr && table_def->is_persistent()) { + ctc_register_trx(ht, thd); + } - update_member_tch(m_tch, ctc_hton, thd); - ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; - FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); - ctc_ddl_stack_mem stack_mem(0); - int mysql_ret = fill_delete_table_req(full_path_name, table_def, thd, &ddl_ctrl, &stack_mem); - if (mysql_ret != CT_SUCCESS) { - return mysql_ret; - } - void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); - if (ctc_ddl_req_msg_mem == nullptr) { - return HA_ERR_OUT_OF_MEM; - } - ctc_log_note("ctc_drop_table enter"); - ret = (ct_errno_t)ctc_drop_table(ctc_ddl_req_msg_mem, &ddl_ctrl); - ctc_log_note("ctc_drop_table finish"); - ctc_ddl_hook_cantian_error("ctc_drop_table_cantian_error", thd, &ddl_ctrl, &ret); - m_tch = ddl_ctrl.tch; - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - return ctc_ddl_handle_fault("ctc_drop_table", thd, &ddl_ctrl, ret, full_path_name, HA_ERR_WRONG_TABLE_NAME); -} -static map> - g_ctc_ddl_ignore_cantian_errors = { - {"ctc_create_table_cantian_error", {ERR_DUPLICATE_TABLE}}, // 创建表,自动忽略参天表已经存在的错误 - {"ctc_drop_table_cantian_error", {ERR_TABLE_OR_VIEW_NOT_EXIST}}, // 删除表,自动忽略参天表不存在的错误 - {"ctc_rename_table_cantian_error", {ERR_TABLE_OR_VIEW_NOT_EXIST}}, // rename表,自动忽略参天表不存在的错误 - {"ctc_alter_table_cantian_error", {ERR_OBJECT_EXISTS,ERR_COLUMN_NOT_EXIST}}}; - -void ctc_ddl_hook_cantian_error(const char *tag, THD *thd, ddl_ctrl_t *ddl_ctrl, - ct_errno_t *ret) { - bool ignore_error = false; - - DBUG_EXECUTE_IF(tag, { - ignore_error = true; - *ret = (ct_errno_t)(*ret == 0 ? -1 : *ret); - }); - - if (!ignore_error) { - return; + update_member_tch(m_tch, ctc_hton, thd); + ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; + FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); + ctc_ddl_stack_mem stack_mem(0); + int mysql_ret = fill_delete_table_req(full_path_name, table_def, thd, &ddl_ctrl, &stack_mem); + if (mysql_ret != CT_SUCCESS) { + return mysql_ret; + } + void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); + if (ctc_ddl_req_msg_mem == nullptr) { + return HA_ERR_OUT_OF_MEM; + } + ctc_log_note("ctc_drop_table enter"); + ret = (ct_errno_t)ctc_drop_table(ctc_ddl_req_msg_mem, &ddl_ctrl); + ctc_log_note("ctc_drop_table finish"); + ctc_ddl_hook_cantian_error("ctc_drop_table_cantian_error", thd, &ddl_ctrl, &ret); + m_tch = ddl_ctrl.tch; + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + return ctc_ddl_handle_fault("ctc_drop_table", thd, &ddl_ctrl, ret, full_path_name, HA_ERR_WRONG_TABLE_NAME); } + static map> g_ctc_ddl_ignore_cantian_errors = { + {"ctc_create_table_cantian_error", {ERR_DUPLICATE_TABLE}}, // 创建表,自动忽略参天表已经存在的错误 + {"ctc_drop_table_cantian_error", {ERR_TABLE_OR_VIEW_NOT_EXIST}}, // 删除表,自动忽略参天表不存在的错误 + {"ctc_rename_table_cantian_error", {ERR_TABLE_OR_VIEW_NOT_EXIST}}, // rename表,自动忽略参天表不存在的错误 + {"ctc_alter_table_cantian_error", {ERR_OBJECT_EXISTS, ERR_COLUMN_NOT_EXIST}}}; - auto st = g_ctc_ddl_ignore_cantian_errors.find(tag); - if (*ret != 0 && st != g_ctc_ddl_ignore_cantian_errors.end() && st->second.count(*ret) > 0) { - ctc_log_system( - "tag:%s cantian ret:%d ignore by ignore_cantian_error_code, " - "sql:%s, table_name:%s, error_message:%s", - tag, *ret, thd->query().str, thd->lex->query_tables->table_name, - ddl_ctrl->error_msg); - *ret = (ct_errno_t)0; + void ctc_ddl_hook_cantian_error(const char *tag, THD *thd, ddl_ctrl_t *ddl_ctrl, ct_errno_t *ret) + { + bool ignore_error = false; + + DBUG_EXECUTE_IF(tag, { + ignore_error = true; + *ret = (ct_errno_t)(*ret == 0 ? -1 : *ret); + }); + + if (!ignore_error) { + return; + } + + auto st = g_ctc_ddl_ignore_cantian_errors.find(tag); + if (*ret != 0 && st != g_ctc_ddl_ignore_cantian_errors.end() && st->second.count(*ret) > 0) { + ctc_log_system( + "tag:%s cantian ret:%d ignore by ignore_cantian_error_code, " + "sql:%s, table_name:%s, error_message:%s", + tag, *ret, thd->query().str, thd->lex->query_tables->table_name, ddl_ctrl->error_msg); + *ret = (ct_errno_t)0; + } } -} -int ctc_ddl_handle_fault(const char *tag, const THD *thd, - const ddl_ctrl_t *ddl_ctrl, ct_errno_t ret, - const char *param, int fix_ret) { - if (ret != CT_SUCCESS) { - ctc_log_system("[CTC_DDL_RES]:tag ret:%d, msg_len:%u, sql:%s, param:%s, error_message:%s", - ret, (uint32_t)(ddl_ctrl->msg_len), thd->query().str, param == nullptr ? "" : - param, ddl_ctrl->error_msg); - RETURN_IF_OOM(ret); - int32_t error = convert_ctc_error_code_to_mysql(ret); - if (error != HA_ERR_GENERIC) { + int ctc_ddl_handle_fault(const char *tag, const THD *thd, const ddl_ctrl_t *ddl_ctrl, ct_errno_t ret, + const char *param, int fix_ret) + { + if (ret != CT_SUCCESS) { + ctc_log_system("[CTC_DDL_RES]:tag ret:%d, msg_len:%u, sql:%s, param:%s, error_message:%s", ret, + (uint32_t)(ddl_ctrl->msg_len), thd->query().str, param == nullptr ? "" : param, + ddl_ctrl->error_msg); + RETURN_IF_OOM(ret); + int32_t error = convert_ctc_error_code_to_mysql(ret); + if (error != HA_ERR_GENERIC) { + return error; + } else if (strlen(ddl_ctrl->error_msg) > 0) { + ctc_print_cantian_err_msg(ddl_ctrl, ret); + } else { + my_error(ER_DISALLOWED_OPERATION, MYF(0), UN_SUPPORT_DDL, thd->query().str); + } + if (fix_ret != 0) { + return fix_ret; + } return error; - } else if (strlen(ddl_ctrl->error_msg) > 0) { - ctc_print_cantian_err_msg(ddl_ctrl, ret); } else { - my_error(ER_DISALLOWED_OPERATION, MYF(0), UN_SUPPORT_DDL, thd->query().str); - } - if (fix_ret != 0) { - return fix_ret; + ctc_log_system("[CTC_DDL_RES]:%s success, ret: %d, sql:%s", tag, ret, thd->query().str); + return ret; } - return error; - } else { - ctc_log_system("[CTC_DDL_RES]:%s success, ret: %d, sql:%s", tag, ret, thd->query().str); - return ret; } -} /** @brief @@ -5082,461 +5160,453 @@ int ctc_ddl_handle_fault(const char *tag, const THD *thd, @retval 0 Success. @retval non-0 Error. */ -EXTER_ATTACK int ha_ctc::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info, - dd::Table *table_def) { - THD *thd = ha_thd(); - ct_errno_t ret = CT_SUCCESS; - if (check_unsupported_operation(thd, create_info)) { - ctc_log_system("Unsupported operation. sql = %s", thd->query().str); - return HA_ERR_WRONG_COMMAND; - } - - /* - copy algorithm is used when ha_create is called by mysql_alter_table - */ - bool is_tmp_table = create_info->options & HA_LEX_CREATE_TMP_TABLE || ctc_is_temporary(table_def); - if (thd->lex->sql_command != SQLCOM_CREATE_TABLE && thd->lex->sql_command != SQLCOM_CREATE_VIEW - && thd->lex->alter_info) { - if (is_tmp_table) { + EXTER_ATTACK int ha_ctc::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info, dd::Table *table_def) + { + THD *thd = ha_thd(); + ct_errno_t ret = CT_SUCCESS; + if (check_unsupported_operation(thd, create_info)) { ctc_log_system("Unsupported operation. sql = %s", thd->query().str); - return HA_ERR_NOT_ALLOWED_COMMAND; + return HA_ERR_WRONG_COMMAND; } - // do not move this under engine_ddl_passthru(thd) function - thd->lex->alter_info->requested_algorithm = Alter_info::ALTER_TABLE_ALGORITHM_COPY; - } - if (engine_skip_ddl(thd) || engine_ddl_passthru(thd)) { - return ret; - } + /* + copy algorithm is used when ha_create is called by mysql_alter_table + */ + bool is_tmp_table = create_info->options & HA_LEX_CREATE_TMP_TABLE || ctc_is_temporary(table_def); + if (thd->lex->sql_command != SQLCOM_CREATE_TABLE && thd->lex->sql_command != SQLCOM_CREATE_VIEW && + thd->lex->alter_info) { + if (is_tmp_table) { + ctc_log_system("Unsupported operation. sql = %s", thd->query().str); + return HA_ERR_NOT_ALLOWED_COMMAND; + } + // do not move this under engine_ddl_passthru(thd) function + thd->lex->alter_info->requested_algorithm = Alter_info::ALTER_TABLE_ALGORITHM_COPY; + } - char db_name[SMALL_RECORD_SIZE] = {0}; - char table_name[SMALL_RECORD_SIZE] = {0}; - ctc_split_normalized_name(name, db_name, SMALL_RECORD_SIZE, table_name, SMALL_RECORD_SIZE, &is_tmp_table); - if (!is_tmp_table) { - CTC_RETURN_IF_NOT_ZERO(check_ctc_identifier_name(table_def->name().c_str())); - ctc_copy_name(table_name, const_cast(table_def->name().c_str()), SMALL_RECORD_SIZE); - } + if (engine_skip_ddl(thd) || engine_ddl_passthru(thd)) { + return ret; + } - if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { - ctc_register_trx(ht, thd); - } + char db_name[SMALL_RECORD_SIZE] = {0}; + char table_name[SMALL_RECORD_SIZE] = {0}; + ctc_split_normalized_name(name, db_name, SMALL_RECORD_SIZE, table_name, SMALL_RECORD_SIZE, &is_tmp_table); + if (!is_tmp_table) { + CTC_RETURN_IF_NOT_ZERO(check_ctc_identifier_name(table_def->name().c_str())); + ctc_copy_name(table_name, const_cast(table_def->name().c_str()), SMALL_RECORD_SIZE); + } - if (thd->lex->sql_command == SQLCOM_TRUNCATE) { - return ha_ctc_truncate_table(&m_tch, thd, db_name, table_name, is_tmp_table); - } + if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { + ctc_register_trx(ht, thd); + } - if (get_cantian_record_length(form) > CT_MAX_RECORD_LENGTH) { - return HA_ERR_TOO_BIG_ROW; - } + if (thd->lex->sql_command == SQLCOM_TRUNCATE) { + return ha_ctc_truncate_table(&m_tch, thd, db_name, table_name, is_tmp_table); + } - ctc_ddl_stack_mem stack_mem(0); - update_member_tch(m_tch, ctc_hton, thd); - ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; - FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); + if (get_cantian_record_length(form) > CT_MAX_RECORD_LENGTH) { + return HA_ERR_TOO_BIG_ROW; + } - if (is_alter_table_copy(thd)) { - ddl_ctrl.is_alter_copy = true; - } + ctc_ddl_stack_mem stack_mem(0); + update_member_tch(m_tch, ctc_hton, thd); + ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; + FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); - uint32_t table_flags = 0; - if (is_tmp_table) { - table_flags |= CTC_TMP_TABLE; - if (create_info->options & HA_LEX_CREATE_INTERNAL_TMP_TABLE) { - table_flags |= CTC_INTERNAL_TMP_TABLE; + if (is_alter_table_copy(thd)) { + ddl_ctrl.is_alter_copy = true; } - ddl_ctrl.table_flags = table_flags; - } - ret = (ct_errno_t)fill_create_table_req(create_info, table_def, db_name, table_name, form, thd, &ddl_ctrl, &stack_mem); - if (ret != CT_SUCCESS) { - return ret; - } - void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); - if (ctc_ddl_req_msg_mem == nullptr) { - return HA_ERR_OUT_OF_MEM; - } + uint32_t table_flags = 0; + if (is_tmp_table) { + table_flags |= CTC_TMP_TABLE; + if (create_info->options & HA_LEX_CREATE_INTERNAL_TMP_TABLE) { + table_flags |= CTC_INTERNAL_TMP_TABLE; + } + ddl_ctrl.table_flags = table_flags; + } + ret = (ct_errno_t)fill_create_table_req(create_info, table_def, db_name, table_name, form, thd, &ddl_ctrl, + &stack_mem); + if (ret != CT_SUCCESS) { + return ret; + } - ret = (ct_errno_t)ctc_create_table(ctc_ddl_req_msg_mem, &ddl_ctrl); - if (ret == ERR_FUNCTION_NOT_EXIST) { - char *err_msg; - char *field_name = strtok_r(ddl_ctrl.error_msg, ",", &err_msg); - char *func_name = strtok_r(NULL, ",", &err_msg); - if (func_name) { - // func_name非空的情况对应default function - my_error(ER_DEFAULT_VAL_GENERATED_NAMED_FUNCTION_IS_NOT_ALLOWED, MYF(0), - field_name, func_name); - return CT_ERROR; + void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); + if (ctc_ddl_req_msg_mem == nullptr) { + return HA_ERR_OUT_OF_MEM; } - } - ctc_ddl_hook_cantian_error("ctc_create_table_cantian_error", thd, &ddl_ctrl, &ret); - m_tch = ddl_ctrl.tch; - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - return ctc_ddl_handle_fault("ctc_create_table", thd, &ddl_ctrl, ret); -} -/** Implementation of inplace_alter_table() -@tparam Table dd::Table or dd::Partition -@param[in] altered_table TABLE object for new version of table. -@param[in,out] ha_alter_info Structure describing changes to be done - by ALTER TABLE and holding data used - during in-place alter. -@param[in] old_dd_tab dd::Table object describing old version - of the table. -@param[in,out] new_dd_tab dd::Table object for the new version of the - table. Can be adjusted by this call. - Changes to the table definition will be - persisted in the data-dictionary at statement - commit time. -@retval true Failure -@retval false Success -*/ -bool ha_ctc::inplace_alter_table(TABLE *altered_table, - Alter_inplace_info *ha_alter_info, - const dd::Table *old_table_def, - dd::Table *new_table_def) -{ - if (old_table_def == nullptr || new_table_def == nullptr) { - ctc_log_error( - "inplace_alter_table old_table_def:%p, or new_table_def:%p is NULL", - old_table_def, new_table_def); - return true; - } + ret = (ct_errno_t)ctc_create_table(ctc_ddl_req_msg_mem, &ddl_ctrl); + if (ret == ERR_FUNCTION_NOT_EXIST) { + char *err_msg; + char *field_name = strtok_r(ddl_ctrl.error_msg, ",", &err_msg); + char *func_name = strtok_r(NULL, ",", &err_msg); + if (func_name) { + // func_name非空的情况对应default function + my_error(ER_DEFAULT_VAL_GENERATED_NAMED_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name, func_name); + return CT_ERROR; + } + } + ctc_ddl_hook_cantian_error("ctc_create_table_cantian_error", thd, &ddl_ctrl, &ret); + m_tch = ddl_ctrl.tch; + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + return ctc_ddl_handle_fault("ctc_create_table", thd, &ddl_ctrl, ret); + } + + /** Implementation of inplace_alter_table() + @tparam Table dd::Table or dd::Partition + @param[in] altered_table TABLE object for new version of table. + @param[in,out] ha_alter_info Structure describing changes to be done + by ALTER TABLE and holding data used + during in-place alter. + @param[in] old_dd_tab dd::Table object describing old version + of the table. + @param[in,out] new_dd_tab dd::Table object for the new version of the + table. Can be adjusted by this call. + Changes to the table definition will be + persisted in the data-dictionary at statement + commit time. + @retval true Failure + @retval false Success + */ + bool ha_ctc::inplace_alter_table(TABLE * altered_table, Alter_inplace_info * ha_alter_info, + const dd::Table *old_table_def, dd::Table *new_table_def) + { + if (old_table_def == nullptr || new_table_def == nullptr) { + ctc_log_error("inplace_alter_table old_table_def:%p, or new_table_def:%p is NULL", old_table_def, new_table_def); + return true; + } - THD *thd = ha_thd(); - Alter_info *alter_info = ha_alter_info->alter_info; - ct_errno_t ret = CT_SUCCESS; + THD *thd = ha_thd(); + Alter_info *alter_info = ha_alter_info->alter_info; + ct_errno_t ret = CT_SUCCESS; - if (check_unsupported_operation(thd, nullptr)) { - ctc_log_system("Unsupported operation. sql = %s", thd->query().str); - return true; - } + if (check_unsupported_operation(thd, nullptr)) { + ctc_log_system("Unsupported operation. sql = %s", thd->query().str); + return true; + } - if (get_cantian_record_length(altered_table) > CT_MAX_RECORD_LENGTH) { - return true; - } - /* Nothing to commit/rollback, mark all handlers committed! */ - ha_alter_info->group_commit_ctx = nullptr; + if (get_cantian_record_length(altered_table) > CT_MAX_RECORD_LENGTH) { + return true; + } + /* Nothing to commit/rollback, mark all handlers committed! */ + ha_alter_info->group_commit_ctx = nullptr; - if (engine_ddl_passthru(thd)) { + if (engine_ddl_passthru(thd)) { return false; - } + } - ctc_ddl_stack_mem stack_mem(0); - update_member_tch(m_tch, ctc_hton, thd); - ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; - FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); - if (alter_info->flags & Alter_info::ALTER_RECREATE) { + ctc_ddl_stack_mem stack_mem(0); + update_member_tch(m_tch, ctc_hton, thd); + ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; + FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); + if (alter_info->flags & Alter_info::ALTER_RECREATE) { ret = (ct_errno_t)fill_rebuild_index_req(altered_table, thd, &ddl_ctrl, &stack_mem); - } else { - ret = (ct_errno_t)fill_alter_table_req( - altered_table, ha_alter_info, old_table_def, new_table_def, thd, - &ddl_ctrl, &stack_mem); - } - if (ret != CT_SUCCESS) { - return true; - } + } else { + ret = (ct_errno_t)fill_alter_table_req(altered_table, ha_alter_info, old_table_def, new_table_def, thd, &ddl_ctrl, + &stack_mem); + } + if (ret != CT_SUCCESS) { + return true; + } - void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); - if (ctc_ddl_req_msg_mem == nullptr) { - return true; - } - ctc_register_trx(ht, thd); - ret = (ct_errno_t)ctc_alter_table(ctc_ddl_req_msg_mem, &ddl_ctrl); - ctc_ddl_hook_cantian_error("ctc_alter_table_cantian_error", thd, &ddl_ctrl, &ret); - m_tch = ddl_ctrl.tch; - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - ctc_ddl_handle_fault("ctc_alter_table", thd, &ddl_ctrl, ret); - // 这个地方alter table需要特殊处理返回值 - if (ret != CT_SUCCESS) { - ctc_alter_table_handle_fault(ret); - return true; - } + void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); + if (ctc_ddl_req_msg_mem == nullptr) { + return true; + } + ctc_register_trx(ht, thd); + ret = (ct_errno_t)ctc_alter_table(ctc_ddl_req_msg_mem, &ddl_ctrl); + ctc_ddl_hook_cantian_error("ctc_alter_table_cantian_error", thd, &ddl_ctrl, &ret); + m_tch = ddl_ctrl.tch; + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + ctc_ddl_handle_fault("ctc_alter_table", thd, &ddl_ctrl, ret); + // 这个地方alter table需要特殊处理返回值 + if (ret != CT_SUCCESS) { + ctc_alter_table_handle_fault(ret); + return true; + } - return false; -} + return false; + } -/** - @brief + /** + @brief - Renames a table from one name to another via an alter table call. + Renames a table from one name to another via an alter table call. - @details - If you do not implement this, the default rename_table() is called from - handler.cc and it will delete all files with the file extensions from - handlerton::file_extensions. + @details + If you do not implement this, the default rename_table() is called from + handler.cc and it will delete all files with the file extensions from + handlerton::file_extensions. - Called from sql_table.cc by mysql_rename_table(). + Called from sql_table.cc by mysql_rename_table(). - @see - mysql_rename_table() in sql_table.cc -*/ -EXTER_ATTACK int ha_ctc::rename_table(const char *from, const char *to, - const dd::Table *from_table_def, - dd::Table *to_table_def) { - THD *thd = ha_thd(); - ct_errno_t ret = CT_SUCCESS; + @see + mysql_rename_table() in sql_table.cc + */ + EXTER_ATTACK int ha_ctc::rename_table(const char *from, const char *to, const dd::Table *from_table_def, + dd::Table *to_table_def) + { + THD *thd = ha_thd(); + ct_errno_t ret = CT_SUCCESS; - if (engine_ddl_passthru(thd)) { - return false; - } + if (engine_ddl_passthru(thd)) { + return false; + } - if (is_dd_table_id(to_table_def->se_private_id())) { - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); - return HA_ERR_UNSUPPORTED; - } + if (is_dd_table_id(to_table_def->se_private_id())) { + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); + return HA_ERR_UNSUPPORTED; + } - ctc_ddl_stack_mem stack_mem(0); - update_member_tch(m_tch, ctc_hton, thd); - ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; - FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); - if (is_alter_table_copy(thd)) { - ddl_ctrl.is_alter_copy = true; - } + ctc_ddl_stack_mem stack_mem(0); + update_member_tch(m_tch, ctc_hton, thd); + ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; + FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); + if (is_alter_table_copy(thd)) { + ddl_ctrl.is_alter_copy = true; + } - ret = (ct_errno_t)fill_rename_table_req(from, to, from_table_def, to_table_def, thd, &ddl_ctrl, &stack_mem); - if (ret != CT_SUCCESS) { - return ret; - } + ret = (ct_errno_t)fill_rename_table_req(from, to, from_table_def, to_table_def, thd, &ddl_ctrl, &stack_mem); + if (ret != CT_SUCCESS) { + return ret; + } - void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); - if(ctc_ddl_req_msg_mem == nullptr) { - return HA_ERR_OUT_OF_MEM; + void *ctc_ddl_req_msg_mem = stack_mem.get_buf(); + if (ctc_ddl_req_msg_mem == nullptr) { + return HA_ERR_OUT_OF_MEM; + } + ctc_register_trx(ht, thd); + ret = (ct_errno_t)ctc_rename_table(ctc_ddl_req_msg_mem, &ddl_ctrl); + ctc_ddl_hook_cantian_error("ctc_rename_table_cantian_error", thd, &ddl_ctrl, &ret); + m_tch = ddl_ctrl.tch; + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + return ctc_ddl_handle_fault("ctc_rename_table", thd, &ddl_ctrl, ret, to); } - ctc_register_trx(ht, thd); - ret = (ct_errno_t)ctc_rename_table(ctc_ddl_req_msg_mem, &ddl_ctrl); - ctc_ddl_hook_cantian_error("ctc_rename_table_cantian_error", thd, &ddl_ctrl, &ret); - m_tch = ddl_ctrl.tch; - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - return ctc_ddl_handle_fault("ctc_rename_table", thd, &ddl_ctrl, ret, to); -} -int ha_ctc::check(THD *, HA_CHECK_OPT *) -{ - return HA_ADMIN_OK; -} + int ha_ctc::check(THD *, HA_CHECK_OPT *) { return HA_ADMIN_OK; } -bool ha_ctc::get_error_message(int error, String *buf) -{ - if (error == HA_ERR_ROW_IS_REFERENCED) { + bool ha_ctc::get_error_message(int error, String *buf) + { + if (error == HA_ERR_ROW_IS_REFERENCED) { buf->append(STRING_WITH_LEN("Record is referenced by child tables(")); for (uint i = 0; i < table->s->foreign_key_parents; i++) { - buf->append(table->s->foreign_key_parent[i].referencing_table_db); - buf->append(STRING_WITH_LEN(".")); - buf->append(table->s->foreign_key_parent[i].referencing_table_name); - if (i != table->s->foreign_key_parents - 1) - buf->append(STRING_WITH_LEN(", ")); + buf->append(table->s->foreign_key_parent[i].referencing_table_db); + buf->append(STRING_WITH_LEN(".")); + buf->append(table->s->foreign_key_parent[i].referencing_table_name); + if (i != table->s->foreign_key_parents - 1) buf->append(STRING_WITH_LEN(", ")); + } + buf->append(STRING_WITH_LEN(")")); + return false; } - buf->append(STRING_WITH_LEN(")")); - return false; - } - if (error == HA_ERR_NO_REFERENCED_ROW){ - buf->append(STRING_WITH_LEN("Referenced key value not found in parent tables(")); - for (uint i = 0; i < table->s->foreign_keys; i++) { - buf->append(table->s->foreign_key[i].referenced_table_db); - buf->append(STRING_WITH_LEN(".")); - buf->append(table->s->foreign_key[i].referenced_table_name); - if (i != table->s->foreign_keys - 1) - buf->append(STRING_WITH_LEN(", ")); + if (error == HA_ERR_NO_REFERENCED_ROW) { + buf->append(STRING_WITH_LEN("Referenced key value not found in parent tables(")); + for (uint i = 0; i < table->s->foreign_keys; i++) { + buf->append(table->s->foreign_key[i].referenced_table_db); + buf->append(STRING_WITH_LEN(".")); + buf->append(table->s->foreign_key[i].referenced_table_name); + if (i != table->s->foreign_keys - 1) buf->append(STRING_WITH_LEN(", ")); + } + buf->append(STRING_WITH_LEN(")")); } - buf->append(STRING_WITH_LEN(")")); + return false; } - return false; -} -ctc_select_mode_t ha_ctc::get_select_mode() -{ - /* Set select mode for SKIP LOCKED / NOWAIT */ - if (table->pos_in_table_list == nullptr) { - return SELECT_ORDINARY; - } - ctc_select_mode_t mode; - switch (table->pos_in_table_list->lock_descriptor().action) { - case THR_SKIP: - mode = SELECT_SKIP_LOCKED; - break; - case THR_NOWAIT: - mode = SELECT_NOWAIT; - break; - default: - mode = SELECT_ORDINARY; - break; + ctc_select_mode_t ha_ctc::get_select_mode() + { + /* Set select mode for SKIP LOCKED / NOWAIT */ + if (table->pos_in_table_list == nullptr) { + return SELECT_ORDINARY; + } + ctc_select_mode_t mode; + switch (table->pos_in_table_list->lock_descriptor().action) { + case THR_SKIP: + mode = SELECT_SKIP_LOCKED; + break; + case THR_NOWAIT: + mode = SELECT_NOWAIT; + break; + default: + mode = SELECT_ORDINARY; + break; + } + return mode; } - return mode; -} -int alloc_str_mysql_mem(ctc_cbo_stats_t *cbo_stats, uint32_t part_num, TABLE *table) -{ - uint32_t acc_gcol_num[CTC_MAX_COLUMNS] = {0}; - calc_accumulate_gcol_num(table->s->fields, table->s->field, acc_gcol_num); - cbo_stats->col_type =(bool *)my_malloc(PSI_NOT_INSTRUMENTED, table->s->fields * sizeof(bool), MYF(MY_WME)); - if (cbo_stats->col_type == nullptr) { - ctc_log_error("alloc shm mem failed, cbo_stats->col_type(%lu)", table->s->fields * sizeof(bool)); - return ERR_ALLOC_MEMORY; - } - memset(cbo_stats->col_type, 0, table->s->fields * sizeof(bool)); - cbo_stats->num_str_cols = 0; - for (uint i = 0; i < table->s->fields; i++) { - Field *field = table->field[i]; - if (field->is_virtual_gcol()) { - continue; - } - uint32_t ct_col_id = i - acc_gcol_num[i]; - if (field->real_type() == MYSQL_TYPE_VARCHAR || field->real_type() == MYSQL_TYPE_VAR_STRING || - field->real_type() == MYSQL_TYPE_STRING) { - cbo_stats->col_type[ct_col_id] = true; - cbo_stats->num_str_cols++; - } - } - uint32_t str_stats_mem_size = part_num * cbo_stats->num_str_cols * (STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN; - char *str_stats_mem = (char *)my_malloc(PSI_NOT_INSTRUMENTED, str_stats_mem_size, MYF(MY_WME)); - if (str_stats_mem == nullptr) { - ctc_log_error("alloc shm mem failed, str_stats_mem size(%u)", str_stats_mem_size); - return ERR_ALLOC_MEMORY; - } - memset(str_stats_mem, 0, str_stats_mem_size); - for (uint i = 0; i < part_num; i++) { - for (uint j = 0; j < table->s->fields; j++) { - Field *field = table->field[j]; + int alloc_str_mysql_mem(ctc_cbo_stats_t * cbo_stats, uint32_t part_num, TABLE * table) + { + uint32_t acc_gcol_num[CTC_MAX_COLUMNS] = {0}; + calc_accumulate_gcol_num(table->s->fields, table->s->field, acc_gcol_num); + cbo_stats->col_type = (bool *)my_malloc(PSI_NOT_INSTRUMENTED, table->s->fields * sizeof(bool), MYF(MY_WME)); + if (cbo_stats->col_type == nullptr) { + ctc_log_error("alloc shm mem failed, cbo_stats->col_type(%lu)", table->s->fields * sizeof(bool)); + return ERR_ALLOC_MEMORY; + } + memset(cbo_stats->col_type, 0, table->s->fields * sizeof(bool)); + cbo_stats->num_str_cols = 0; + for (uint i = 0; i < table->s->fields; i++) { + Field *field = table->field[i]; if (field->is_virtual_gcol()) { continue; } - uint32_t ct_col_id = j - acc_gcol_num[j]; + uint32_t ct_col_id = i - acc_gcol_num[i]; if (field->real_type() == MYSQL_TYPE_VARCHAR || field->real_type() == MYSQL_TYPE_VAR_STRING || field->real_type() == MYSQL_TYPE_STRING) { - cbo_stats->ctc_cbo_stats_table[i].columns[ct_col_id].high_value.v_str = str_stats_mem; - cbo_stats->ctc_cbo_stats_table[i].columns[ct_col_id].low_value.v_str = str_stats_mem + CBO_STRING_MAX_LEN; - str_stats_mem = str_stats_mem + CBO_STRING_MAX_LEN * 2; - for (uint k = 0; k < STATS_HISTGRAM_MAX_SIZE; k++) { - cbo_stats->ctc_cbo_stats_table[i].columns[ct_col_id].column_hist[k].ep_value.v_str = str_stats_mem; - str_stats_mem = str_stats_mem + CBO_STRING_MAX_LEN; + cbo_stats->col_type[ct_col_id] = true; + cbo_stats->num_str_cols++; + } + } + uint32_t str_stats_mem_size = + part_num * cbo_stats->num_str_cols * (STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN; + char *str_stats_mem = (char *)my_malloc(PSI_NOT_INSTRUMENTED, str_stats_mem_size, MYF(MY_WME)); + if (str_stats_mem == nullptr) { + ctc_log_error("alloc shm mem failed, str_stats_mem size(%u)", str_stats_mem_size); + return ERR_ALLOC_MEMORY; + } + memset(str_stats_mem, 0, str_stats_mem_size); + for (uint i = 0; i < part_num; i++) { + for (uint j = 0; j < table->s->fields; j++) { + Field *field = table->field[j]; + if (field->is_virtual_gcol()) { + continue; + } + uint32_t ct_col_id = j - acc_gcol_num[j]; + if (field->real_type() == MYSQL_TYPE_VARCHAR || field->real_type() == MYSQL_TYPE_VAR_STRING || + field->real_type() == MYSQL_TYPE_STRING) { + cbo_stats->ctc_cbo_stats_table[i].columns[ct_col_id].high_value.v_str = str_stats_mem; + cbo_stats->ctc_cbo_stats_table[i].columns[ct_col_id].low_value.v_str = str_stats_mem + CBO_STRING_MAX_LEN; + str_stats_mem = str_stats_mem + CBO_STRING_MAX_LEN * 2; + for (uint k = 0; k < STATS_HISTGRAM_MAX_SIZE; k++) { + cbo_stats->ctc_cbo_stats_table[i].columns[ct_col_id].column_hist[k].ep_value.v_str = str_stats_mem; + str_stats_mem = str_stats_mem + CBO_STRING_MAX_LEN; + } } } } - } - return CT_SUCCESS; -} - -int ha_ctc::initialize_cbo_stats() -{ - if (!m_share || m_share->cbo_stats != nullptr) { return CT_SUCCESS; } - m_share->cbo_stats = (ctc_cbo_stats_t*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(ctc_cbo_stats_t), MYF(MY_WME)); - if (m_share->cbo_stats == nullptr) { - ctc_log_error("alloc mem failed, m_share->cbo_stats size(%lu)", sizeof(ctc_cbo_stats_t)); - return ERR_ALLOC_MEMORY; - } - *m_share->cbo_stats = {0, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr}; - m_share->cbo_stats->ctc_cbo_stats_table = - (ctc_cbo_stats_table_t*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(ctc_cbo_stats_table_t), MYF(MY_WME)); - if (m_share->cbo_stats->ctc_cbo_stats_table == nullptr) { - ctc_log_error("alloc mem failed, m_share->cbo_stats->ctc_cbo_stats_table(%lu)", sizeof(ctc_cbo_stats_table_t)); - return ERR_ALLOC_MEMORY; - } - m_share->cbo_stats->ctc_cbo_stats_table->columns = - (ctc_cbo_stats_column_t*)my_malloc(PSI_NOT_INSTRUMENTED, table->s->fields * sizeof(ctc_cbo_stats_column_t), MYF(MY_WME)); - if (m_share->cbo_stats->ctc_cbo_stats_table->columns == nullptr) { - ctc_log_error("alloc mem failed, m_share->cbo_stats->ctc_cbo_stats_table->columns size(%lu)", table->s->fields * sizeof(ctc_cbo_stats_column_t)); - return ERR_ALLOC_MEMORY; - } - for (uint col_id = 0; col_id < table->s->fields; col_id++) { - m_share->cbo_stats->ctc_cbo_stats_table->columns[col_id].hist_count = 0; - } - - ct_errno_t ret = (ct_errno_t)alloc_str_mysql_mem(m_share->cbo_stats, 1, table); - if (ret != CT_SUCCESS) { - ctc_log_error("m_share:ctc alloc str mysql mem failed, ret:%d", ret); - } - m_share->cbo_stats->ndv_keys = - (uint32_t*)my_malloc(PSI_NOT_INSTRUMENTED, table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS, MYF(MY_WME)); - if (m_share->cbo_stats->ndv_keys == nullptr) { - ctc_log_error("alloc mem failed, m_share->cbo_stats->ndv_keys size(%lu)", table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS); - return ERR_ALLOC_MEMORY; + int ha_ctc::initialize_cbo_stats() + { + if (!m_share || m_share->cbo_stats != nullptr) { + return CT_SUCCESS; + } + m_share->cbo_stats = (ctc_cbo_stats_t *)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(ctc_cbo_stats_t), MYF(MY_WME)); + if (m_share->cbo_stats == nullptr) { + ctc_log_error("alloc mem failed, m_share->cbo_stats size(%lu)", sizeof(ctc_cbo_stats_t)); + return ERR_ALLOC_MEMORY; + } + *m_share->cbo_stats = {0, 0, 0, 0, 0, nullptr, 0, nullptr, nullptr}; + m_share->cbo_stats->ctc_cbo_stats_table = + (ctc_cbo_stats_table_t *)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(ctc_cbo_stats_table_t), MYF(MY_WME)); + if (m_share->cbo_stats->ctc_cbo_stats_table == nullptr) { + ctc_log_error("alloc mem failed, m_share->cbo_stats->ctc_cbo_stats_table(%lu)", sizeof(ctc_cbo_stats_table_t)); + return ERR_ALLOC_MEMORY; + } + m_share->cbo_stats->ctc_cbo_stats_table->columns = (ctc_cbo_stats_column_t *)my_malloc( + PSI_NOT_INSTRUMENTED, table->s->fields * sizeof(ctc_cbo_stats_column_t), MYF(MY_WME)); + if (m_share->cbo_stats->ctc_cbo_stats_table->columns == nullptr) { + ctc_log_error("alloc mem failed, m_share->cbo_stats->ctc_cbo_stats_table->columns size(%lu)", + table->s->fields * sizeof(ctc_cbo_stats_column_t)); + return ERR_ALLOC_MEMORY; + } + for (uint col_id = 0; col_id < table->s->fields; col_id++) { + m_share->cbo_stats->ctc_cbo_stats_table->columns[col_id].hist_count = 0; + } + + ct_errno_t ret = (ct_errno_t)alloc_str_mysql_mem(m_share->cbo_stats, 1, table); + if (ret != CT_SUCCESS) { + ctc_log_error("m_share:ctc alloc str mysql mem failed, ret:%d", ret); + } + + m_share->cbo_stats->ndv_keys = + (uint32_t *)my_malloc(PSI_NOT_INSTRUMENTED, table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS, MYF(MY_WME)); + if (m_share->cbo_stats->ndv_keys == nullptr) { + ctc_log_error("alloc mem failed, m_share->cbo_stats->ndv_keys size(%lu)", + table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS); + return ERR_ALLOC_MEMORY; + } + + m_share->cbo_stats->msg_len = table->s->fields * sizeof(ctc_cbo_stats_column_t); + m_share->cbo_stats->key_len = table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS; + return CT_SUCCESS; } - - m_share->cbo_stats->msg_len = table->s->fields * sizeof(ctc_cbo_stats_column_t); - m_share->cbo_stats->key_len = table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS; - return CT_SUCCESS; -} -int ha_ctc::get_cbo_stats_4share() -{ - THD *thd = ha_thd(); - int ret = CT_SUCCESS; - time_t now = time(nullptr); - if (m_share && (m_share->need_fetch_cbo || now - m_share->get_cbo_time > ctc_update_analyze_time)) { - if (m_tch.ctx_addr == INVALID_VALUE64) { - char user_name[SMALL_RECORD_SIZE] = { 0 }; - ctc_split_normalized_name(table->s->normalized_path.str, user_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); - ctc_copy_name(user_name, user_name, SMALL_RECORD_SIZE); + int ha_ctc::get_cbo_stats_4share() + { + THD *thd = ha_thd(); + int ret = CT_SUCCESS; + time_t now = time(nullptr); + if (m_share && (m_share->need_fetch_cbo || now - m_share->get_cbo_time > ctc_update_analyze_time)) { + if (m_tch.ctx_addr == INVALID_VALUE64) { + char user_name[SMALL_RECORD_SIZE] = {0}; + ctc_split_normalized_name(table->s->normalized_path.str, user_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); + ctc_copy_name(user_name, user_name, SMALL_RECORD_SIZE); + update_member_tch(m_tch, ctc_hton, thd); + ret = ctc_open_table(&m_tch, table->s->table_name.str, user_name); + update_sess_ctx_by_tch(m_tch, ctc_hton, thd); + if (ret != CT_SUCCESS) { + return ret; + } + } update_member_tch(m_tch, ctc_hton, thd); - ret = ctc_open_table(&m_tch, table->s->table_name.str, user_name); + ret = ctc_get_cbo_stats(&m_tch, m_share->cbo_stats, m_share->cbo_stats->ctc_cbo_stats_table, 0, 0); update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - if (ret != CT_SUCCESS) { - return ret; + if (ret == CT_SUCCESS && m_share->cbo_stats->is_updated) { + m_share->need_fetch_cbo = false; + ctc_index_stats_update(table, m_share->cbo_stats); } + m_share->get_cbo_time = now; } - update_member_tch(m_tch, ctc_hton, thd); - ret = ctc_get_cbo_stats(&m_tch, m_share->cbo_stats, m_share->cbo_stats->ctc_cbo_stats_table, 0, 0); - update_sess_ctx_by_tch(m_tch, ctc_hton, thd); - if (ret == CT_SUCCESS && m_share->cbo_stats->is_updated) { - m_share->need_fetch_cbo = false; - ctc_index_stats_update(table, m_share->cbo_stats); - } - m_share->get_cbo_time = now; - } - return ret; -} + return ret; + } -void free_columns_cbo_stats(ctc_cbo_stats_column_t *ctc_cbo_stats_columns, bool *is_str_first_addr, TABLE *table) -{ - uint32_t acc_gcol_num[CTC_MAX_COLUMNS] = {0}; - calc_accumulate_gcol_num(table->s->fields, table->s->field, acc_gcol_num); - for (uint j = 0; j < table->s->fields; j++) { - Field *field = table->field[j]; - uint32_t ct_col_id = j - acc_gcol_num[j]; - if (field->is_virtual_gcol()) { - continue; - } - if (field->real_type() == MYSQL_TYPE_VARCHAR || field->real_type() == MYSQL_TYPE_VAR_STRING || - field->real_type() == MYSQL_TYPE_STRING) { - if (*is_str_first_addr) { - my_free(ctc_cbo_stats_columns[ct_col_id].high_value.v_str); - *is_str_first_addr = false; + void free_columns_cbo_stats(ctc_cbo_stats_column_t * ctc_cbo_stats_columns, bool *is_str_first_addr, TABLE *table) + { + uint32_t acc_gcol_num[CTC_MAX_COLUMNS] = {0}; + calc_accumulate_gcol_num(table->s->fields, table->s->field, acc_gcol_num); + for (uint j = 0; j < table->s->fields; j++) { + Field *field = table->field[j]; + uint32_t ct_col_id = j - acc_gcol_num[j]; + if (field->is_virtual_gcol()) { + continue; } - ctc_cbo_stats_columns[ct_col_id].high_value.v_str = nullptr; - ctc_cbo_stats_columns[ct_col_id].low_value.v_str = nullptr; - for (uint k = 0; k < STATS_HISTGRAM_MAX_SIZE; k++) { - ctc_cbo_stats_columns[ct_col_id].column_hist[k].ep_value.v_str = nullptr; + if (field->real_type() == MYSQL_TYPE_VARCHAR || field->real_type() == MYSQL_TYPE_VAR_STRING || + field->real_type() == MYSQL_TYPE_STRING) { + if (*is_str_first_addr) { + my_free(ctc_cbo_stats_columns[ct_col_id].high_value.v_str); + *is_str_first_addr = false; + } + ctc_cbo_stats_columns[ct_col_id].high_value.v_str = nullptr; + ctc_cbo_stats_columns[ct_col_id].low_value.v_str = nullptr; + for (uint k = 0; k < STATS_HISTGRAM_MAX_SIZE; k++) { + ctc_cbo_stats_columns[ct_col_id].column_hist[k].ep_value.v_str = nullptr; + } } } - } - my_free(ctc_cbo_stats_columns); - ctc_cbo_stats_columns = nullptr; -} - -void ha_ctc::free_cbo_stats() -{ - if (!m_share || m_share->cbo_stats == nullptr) { - return; + my_free(ctc_cbo_stats_columns); + ctc_cbo_stats_columns = nullptr; } - my_free((m_share->cbo_stats->ndv_keys)); - m_share->cbo_stats->ndv_keys = nullptr; - my_free((m_share->cbo_stats->col_type)); - m_share->cbo_stats->col_type = nullptr; + void ha_ctc::free_cbo_stats() + { + if (!m_share || m_share->cbo_stats == nullptr) { + return; + } - bool is_str_first_addr = true; - free_columns_cbo_stats(m_share->cbo_stats->ctc_cbo_stats_table->columns, &is_str_first_addr, table); + my_free((m_share->cbo_stats->ndv_keys)); + m_share->cbo_stats->ndv_keys = nullptr; + my_free((m_share->cbo_stats->col_type)); + m_share->cbo_stats->col_type = nullptr; - my_free(m_share->cbo_stats->ctc_cbo_stats_table); - m_share->cbo_stats->ctc_cbo_stats_table = nullptr; - my_free((uchar *)(m_share->cbo_stats)); - m_share->cbo_stats = nullptr; + bool is_str_first_addr = true; + free_columns_cbo_stats(m_share->cbo_stats->ctc_cbo_stats_table->columns, &is_str_first_addr, table); -} + my_free(m_share->cbo_stats->ctc_cbo_stats_table); + m_share->cbo_stats->ctc_cbo_stats_table = nullptr; + my_free((uchar *)(m_share->cbo_stats)); + m_share->cbo_stats = nullptr; + } /** Condition pushdown for update/delete @@ -5549,52 +5619,54 @@ void ha_ctc::free_cbo_stats() is returned if entire condition was supported. */ #ifdef FEATURE_X_FOR_MYSQL_32 -const Item *ha_ctc::cond_push(const Item *cond) { + const Item *ha_ctc::cond_push(const Item *cond) + { #elif defined(FEATURE_X_FOR_MYSQL_26) -const Item *ha_ctc::cond_push(const Item *cond, bool other_tbls_ok MY_ATTRIBUTE((unused))) { +const Item *ha_ctc::cond_push(const Item *cond, bool other_tbls_ok MY_ATTRIBUTE((unused))) +{ #endif - assert(m_cond == nullptr); - assert(pushed_cond == nullptr); - assert(cond != nullptr); - const Item *remainder = cond; + assert(m_cond == nullptr); + assert(pushed_cond == nullptr); + assert(cond != nullptr); + const Item *remainder = cond; + + THD *const thd = table->in_use; + if (!thd->optimizer_switch_flag(OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN)) { + return remainder; + } + if (thd->lex->all_query_blocks_list && thd->lex->all_query_blocks_list->is_recursive()) { + return remainder; + } - THD *const thd = table->in_use; - if (!thd->optimizer_switch_flag(OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN)) { - return remainder; - } - if (thd->lex->all_query_blocks_list && thd->lex->all_query_blocks_list->is_recursive()) { - return remainder; - } + prep_cond_push(cond); + if (m_pushed_conds == nullptr) { + return remainder; + } - prep_cond_push(cond); - if (m_pushed_conds == nullptr) { - return remainder; - } + m_cond = (ctc_conds *)ctc_alloc_buf(&m_tch, sizeof(ctc_conds)); + if (m_cond == nullptr) { + ctc_log_error("alloc mem failed, m_cond size(%lu), pushdown cond is null.", sizeof(ctc_conds)); + return remainder; + } - m_cond = (ctc_conds *)ctc_alloc_buf(&m_tch, sizeof(ctc_conds)); - if (m_cond == nullptr) { - ctc_log_error("alloc mem failed, m_cond size(%lu), pushdown cond is null.", sizeof(ctc_conds)); - return remainder; - } + bool no_backslash = false; + if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) { + no_backslash = true; + } + Field **field = table->field; + if (ctc_fill_conds(m_tch, m_pushed_conds, field, m_cond, no_backslash) != CT_SUCCESS) { + free_m_cond(m_tch, &m_cond); + m_pushed_conds = nullptr; + m_remainder_conds = nullptr; + return remainder; + } + + pushed_cond = m_pushed_conds; + m_remainder_conds = const_cast(cond); - bool no_backslash = false; - if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) { - no_backslash = true; - } - Field **field = table->field; - if (ctc_fill_conds(m_tch, m_pushed_conds, field, m_cond, no_backslash) != CT_SUCCESS) { - free_m_cond(m_tch, &m_cond); - m_pushed_conds = nullptr; - m_remainder_conds = nullptr; return remainder; } - pushed_cond = m_pushed_conds; - m_remainder_conds = const_cast(cond); - - return remainder; -} - /** Condition pushdown Push a condition to ctc storage engine for evaluation @@ -5621,231 +5693,231 @@ const Item *ha_ctc::cond_push(const Item *cond, bool other_tbls_ok MY_ATTRIBUTE( * @return Possible error code, '0' if no errors. */ #ifdef FEATURE_X_FOR_MYSQL_26 -int ha_ctc::engine_push(AQP::Table_access *table_aqp) -{ - DBUG_TRACE; - const Item *cond = table_aqp->get_condition(); - assert(m_cond == nullptr); + int ha_ctc::engine_push(AQP::Table_access * table_aqp) + { + DBUG_TRACE; + const Item *cond = table_aqp->get_condition(); + assert(m_cond == nullptr); - THD *const thd = table->in_use; - if (!thd->optimizer_switch_flag(OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN)) { - return 0; - } - - if (thd->lex->all_query_blocks_list && thd->lex->all_query_blocks_list->is_recursive()) { - return 0; - } + THD *const thd = table->in_use; + if (!thd->optimizer_switch_flag(OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN)) { + return 0; + } - if (cond == nullptr) { - return 0; - } - // Filter Multi-Table Queries - const AQP::Join_plan *const plan = table_aqp->get_join_plan(); - if (plan->get_access_count() > 1) { - return 0; - } + if (thd->lex->all_query_blocks_list && thd->lex->all_query_blocks_list->is_recursive()) { + return 0; + } - prep_cond_push(cond); - if (m_pushed_conds == nullptr) { - return 0; - } + if (cond == nullptr) { + return 0; + } + // Filter Multi-Table Queries + const AQP::Join_plan *const plan = table_aqp->get_join_plan(); + if (plan->get_access_count() > 1) { + return 0; + } - m_cond = (ctc_conds *)ctc_alloc_buf(&m_tch, sizeof(ctc_conds)); - if (m_cond == nullptr) { - ctc_log_error("alloc mem failed, m_cond size(%lu), pushdown cond is null.", sizeof(ctc_conds)); - return 0; - } + prep_cond_push(cond); + if (m_pushed_conds == nullptr) { + return 0; + } - bool no_backslash = false; - if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) { - no_backslash = true; - } - Field **field = table_aqp->get_table()->field; - if (ctc_fill_conds(m_tch, m_pushed_conds, field, m_cond, no_backslash) != CT_SUCCESS) { - free_m_cond(m_tch, &m_cond); - m_pushed_conds = nullptr; - m_remainder_conds = nullptr; + m_cond = (ctc_conds *)ctc_alloc_buf(&m_tch, sizeof(ctc_conds)); + if (m_cond == nullptr) { + ctc_log_error("alloc mem failed, m_cond size(%lu), pushdown cond is null.", sizeof(ctc_conds)); + return 0; + } + + bool no_backslash = false; + if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) { + no_backslash = true; + } + Field **field = table_aqp->get_table()->field; + if (ctc_fill_conds(m_tch, m_pushed_conds, field, m_cond, no_backslash) != CT_SUCCESS) { + free_m_cond(m_tch, &m_cond); + m_pushed_conds = nullptr; + m_remainder_conds = nullptr; + return 0; + } + + pushed_cond = m_pushed_conds; + m_remainder_conds = const_cast(cond); + table_aqp->set_condition(const_cast(m_remainder_conds)); return 0; } - - pushed_cond = m_pushed_conds; - m_remainder_conds = const_cast(cond); - table_aqp->set_condition(const_cast(m_remainder_conds)); - return 0; -} #endif - #ifdef FEATURE_X_FOR_MYSQL_32 -TABLE *get_base_table(const AccessPath *path) { - switch (path->type) { - // Basic access paths (those with no children, at least nominally). - case AccessPath::TABLE_SCAN: - return path->table_scan().table; - case AccessPath::INDEX_SCAN: - return path->index_scan().table; - case AccessPath::REF: - return path->ref().table; - case AccessPath::REF_OR_NULL: - return path->ref_or_null().table; - case AccessPath::EQ_REF: - return path->eq_ref().table; - case AccessPath::PUSHED_JOIN_REF: - return path->pushed_join_ref().table; - case AccessPath::FULL_TEXT_SEARCH: - return path->full_text_search().table; - case AccessPath::CONST_TABLE: - return path->const_table().table; - case AccessPath::MRR: - return path->mrr().table; - case AccessPath::FOLLOW_TAIL: - return path->follow_tail().table; - case AccessPath::INDEX_RANGE_SCAN: - return path->index_range_scan().used_key_part[0].field->table; - case AccessPath::INDEX_MERGE: - return path->index_merge().table; - case AccessPath::ROWID_INTERSECTION: - return path->rowid_intersection().table; - case AccessPath::ROWID_UNION: - return path->rowid_union().table; - case AccessPath::INDEX_SKIP_SCAN: - return path->index_skip_scan().table; - case AccessPath::GROUP_INDEX_SKIP_SCAN: - return path->group_index_skip_scan().table; - case AccessPath::DYNAMIC_INDEX_RANGE_SCAN: - return path->dynamic_index_range_scan().table; - default: - return nullptr; + TABLE *get_base_table(const AccessPath *path) + { + switch (path->type) { + // Basic access paths (those with no children, at least nominally). + case AccessPath::TABLE_SCAN: + return path->table_scan().table; + case AccessPath::INDEX_SCAN: + return path->index_scan().table; + case AccessPath::REF: + return path->ref().table; + case AccessPath::REF_OR_NULL: + return path->ref_or_null().table; + case AccessPath::EQ_REF: + return path->eq_ref().table; + case AccessPath::PUSHED_JOIN_REF: + return path->pushed_join_ref().table; + case AccessPath::FULL_TEXT_SEARCH: + return path->full_text_search().table; + case AccessPath::CONST_TABLE: + return path->const_table().table; + case AccessPath::MRR: + return path->mrr().table; + case AccessPath::FOLLOW_TAIL: + return path->follow_tail().table; + case AccessPath::INDEX_RANGE_SCAN: + return path->index_range_scan().used_key_part[0].field->table; + case AccessPath::INDEX_MERGE: + return path->index_merge().table; + case AccessPath::ROWID_INTERSECTION: + return path->rowid_intersection().table; + case AccessPath::ROWID_UNION: + return path->rowid_union().table; + case AccessPath::INDEX_SKIP_SCAN: + return path->index_skip_scan().table; + case AccessPath::GROUP_INDEX_SKIP_SCAN: + return path->group_index_skip_scan().table; + case AccessPath::DYNAMIC_INDEX_RANGE_SCAN: + return path->dynamic_index_range_scan().table; + default: + return nullptr; + } } -} -TABLE *ctc_get_basic_table(const AccessPath *path) { - switch (path->type) { - case AccessPath::TABLE_SCAN: - case AccessPath::INDEX_SCAN: - case AccessPath::REF: - case AccessPath::REF_OR_NULL: - case AccessPath::EQ_REF: - case AccessPath::PUSHED_JOIN_REF: - case AccessPath::FULL_TEXT_SEARCH: - case AccessPath::CONST_TABLE: - case AccessPath::MRR: - case AccessPath::FOLLOW_TAIL: - case AccessPath::INDEX_RANGE_SCAN: - case AccessPath::DYNAMIC_INDEX_RANGE_SCAN: - case AccessPath::INDEX_MERGE: - return get_base_table(path); - case AccessPath::FILTER: - return ctc_get_basic_table(path->filter().child); - case AccessPath::TABLE_VALUE_CONSTRUCTOR: - case AccessPath::FAKE_SINGLE_ROW: - case AccessPath::ZERO_ROWS: - case AccessPath::ZERO_ROWS_AGGREGATED: - case AccessPath::MATERIALIZED_TABLE_FUNCTION: - case AccessPath::UNQUALIFIED_COUNT: - case AccessPath::NESTED_LOOP_JOIN: - case AccessPath::BKA_JOIN: - case AccessPath::HASH_JOIN: - case AccessPath::NESTED_LOOP_SEMIJOIN_WITH_DUPLICATE_REMOVAL: - case AccessPath::SORT: - case AccessPath::LIMIT_OFFSET: - case AccessPath::AGGREGATE: - case AccessPath::TEMPTABLE_AGGREGATE: - case AccessPath::STREAM: - case AccessPath::MATERIALIZE: - case AccessPath::MATERIALIZE_INFORMATION_SCHEMA_TABLE: - case AccessPath::APPEND: - case AccessPath::WINDOW: - case AccessPath::WEEDOUT: - case AccessPath::REMOVE_DUPLICATES_ON_INDEX: - case AccessPath::REMOVE_DUPLICATES: - case AccessPath::ALTERNATIVE: - case AccessPath::CACHE_INVALIDATOR: - case AccessPath::DELETE_ROWS: - case AccessPath::UPDATE_ROWS: - case AccessPath::ROWID_INTERSECTION: - case AccessPath::ROWID_UNION: - case AccessPath::INDEX_SKIP_SCAN: - case AccessPath::GROUP_INDEX_SKIP_SCAN: - break; - default: - break; + TABLE *ctc_get_basic_table(const AccessPath *path) + { + switch (path->type) { + case AccessPath::TABLE_SCAN: + case AccessPath::INDEX_SCAN: + case AccessPath::REF: + case AccessPath::REF_OR_NULL: + case AccessPath::EQ_REF: + case AccessPath::PUSHED_JOIN_REF: + case AccessPath::FULL_TEXT_SEARCH: + case AccessPath::CONST_TABLE: + case AccessPath::MRR: + case AccessPath::FOLLOW_TAIL: + case AccessPath::INDEX_RANGE_SCAN: + case AccessPath::DYNAMIC_INDEX_RANGE_SCAN: + case AccessPath::INDEX_MERGE: + return get_base_table(path); + case AccessPath::FILTER: + return ctc_get_basic_table(path->filter().child); + case AccessPath::TABLE_VALUE_CONSTRUCTOR: + case AccessPath::FAKE_SINGLE_ROW: + case AccessPath::ZERO_ROWS: + case AccessPath::ZERO_ROWS_AGGREGATED: + case AccessPath::MATERIALIZED_TABLE_FUNCTION: + case AccessPath::UNQUALIFIED_COUNT: + case AccessPath::NESTED_LOOP_JOIN: + case AccessPath::BKA_JOIN: + case AccessPath::HASH_JOIN: + case AccessPath::NESTED_LOOP_SEMIJOIN_WITH_DUPLICATE_REMOVAL: + case AccessPath::SORT: + case AccessPath::LIMIT_OFFSET: + case AccessPath::AGGREGATE: + case AccessPath::TEMPTABLE_AGGREGATE: + case AccessPath::STREAM: + case AccessPath::MATERIALIZE: + case AccessPath::MATERIALIZE_INFORMATION_SCHEMA_TABLE: + case AccessPath::APPEND: + case AccessPath::WINDOW: + case AccessPath::WEEDOUT: + case AccessPath::REMOVE_DUPLICATES_ON_INDEX: + case AccessPath::REMOVE_DUPLICATES: + case AccessPath::ALTERNATIVE: + case AccessPath::CACHE_INVALIDATOR: + case AccessPath::DELETE_ROWS: + case AccessPath::UPDATE_ROWS: + case AccessPath::ROWID_INTERSECTION: + case AccessPath::ROWID_UNION: + case AccessPath::INDEX_SKIP_SCAN: + case AccessPath::GROUP_INDEX_SKIP_SCAN: + break; + default: + break; + } + return nullptr; } - return nullptr; -} -/** - * Try to find parts of queries which can be pushed down to - * storage engines for faster execution. This is typically - * conditions which can filter out result rows on the SE, - * and/or entire joins between tables. - * - * @param thd Thread context - * @param root_path The AccessPath for the entire query. - * @param join The JOIN struct built for the main query. - * - * @return Possible ret code, '0' if no errors. - */ -static int ctc_push_to_engine(THD *thd, AccessPath *root_path, JOIN *) { - DBUG_TRACE; + /** + * Try to find parts of queries which can be pushed down to + * storage engines for faster execution. This is typically + * conditions which can filter out result rows on the SE, + * and/or entire joins between tables. + * + * @param thd Thread context + * @param root_path The AccessPath for the entire query. + * @param join The JOIN struct built for the main query. + * + * @return Possible ret code, '0' if no errors. + */ + static int ctc_push_to_engine(THD * thd, AccessPath * root_path, JOIN *) + { + DBUG_TRACE; - if (!thd->optimizer_switch_flag(OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN)) { - return 0; - } - - if (thd->lex->all_query_blocks_list && thd->lex->all_query_blocks_list->is_recursive()) { - return 0; - } + if (!thd->optimizer_switch_flag(OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN)) { + return 0; + } - TABLE *table = ctc_get_basic_table(root_path); - if (table == nullptr) { - return 0; - } - - const Item *cond = root_path->type == AccessPath::FILTER ? root_path->filter().condition : nullptr; - if (cond == nullptr) { - return 0; - } + if (thd->lex->all_query_blocks_list && thd->lex->all_query_blocks_list->is_recursive()) { + return 0; + } - ha_ctc *const ctc_handler = dynamic_cast(table->file); - if (ctc_handler == nullptr) { - ctc_log_warning("[ctc_push_to_engine] ctc_handler is nullptr."); - return 0; - } + TABLE *table = ctc_get_basic_table(root_path); + if (table == nullptr) { + return 0; + } - ctc_handler->prep_cond_push(cond); - if (ctc_handler->m_pushed_conds == nullptr) { - return 0; - } + const Item *cond = root_path->type == AccessPath::FILTER ? root_path->filter().condition : nullptr; + if (cond == nullptr) { + return 0; + } - ctc_handler_t *tch = ctc_handler->get_m_tch(); - ctc_handler->m_cond = (ctc_conds *)ctc_alloc_buf(tch, sizeof(ctc_conds)); - if (ctc_handler->m_cond == nullptr) { - ctc_log_warning("[ctc_push_to_engine] alloc mem failed, m_cond size(%lu), pushdown cond is null.", - sizeof(ctc_conds)); - return 0; - } + ha_ctc *const ctc_handler = dynamic_cast(table->file); + if (ctc_handler == nullptr) { + ctc_log_warning("[ctc_push_to_engine] ctc_handler is nullptr."); + return 0; + } - bool no_backslash = false; - if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) { - no_backslash = true; - } - Field **field = table->field; - if (ctc_fill_conds(*tch, ctc_handler->m_pushed_conds, field, ctc_handler->m_cond, no_backslash) != CT_SUCCESS) { - free_m_cond(*tch, &ctc_handler->m_cond); - ctc_handler->m_pushed_conds = nullptr; - ctc_handler->m_remainder_conds = nullptr; - ctc_log_warning("[ctc_push_to_engine] ctc_fill_conds failed."); - return 0; - } + ctc_handler->prep_cond_push(cond); + if (ctc_handler->m_pushed_conds == nullptr) { + return 0; + } - ctc_handler->pushed_cond = ctc_handler->m_pushed_conds; - ctc_handler->m_remainder_conds = const_cast(cond); + ctc_handler_t *tch = ctc_handler->get_m_tch(); + ctc_handler->m_cond = (ctc_conds *)ctc_alloc_buf(tch, sizeof(ctc_conds)); + if (ctc_handler->m_cond == nullptr) { + ctc_log_warning("[ctc_push_to_engine] alloc mem failed, m_cond size(%lu), pushdown cond is null.", + sizeof(ctc_conds)); + return 0; + } - return 0; -} + bool no_backslash = false; + if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) { + no_backslash = true; + } + Field **field = table->field; + if (ctc_fill_conds(*tch, ctc_handler->m_pushed_conds, field, ctc_handler->m_cond, no_backslash) != CT_SUCCESS) { + free_m_cond(*tch, &ctc_handler->m_cond); + ctc_handler->m_pushed_conds = nullptr; + ctc_handler->m_remainder_conds = nullptr; + ctc_log_warning("[ctc_push_to_engine] ctc_fill_conds failed."); + return 0; + } -const handlerton *ha_ctc::hton_supporting_engine_pushdown() { - return ctc_hton; -} + ctc_handler->pushed_cond = ctc_handler->m_pushed_conds; + ctc_handler->m_remainder_conds = const_cast(cond); + + return 0; + } + + const handlerton *ha_ctc::hton_supporting_engine_pushdown() { return ctc_hton; } #endif \ No newline at end of file diff --git a/storage/ctc/ha_ctc_ddl.cc b/storage/ctc/ha_ctc_ddl.cc index 50e2a43..b686533 100644 --- a/storage/ctc/ha_ctc_ddl.cc +++ b/storage/ctc/ha_ctc_ddl.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -14,52 +14,51 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "storage/ctc/ha_ctc.h" #include "storage/ctc/ha_ctc_ddl.h" -#include "storage/ctc/ha_ctcpart.h" #include +#include "storage/ctc/ha_ctc.h" +#include "storage/ctc/ha_ctcpart.h" #include #include +#include "decimal.h" #include "my_sqlcommand.h" +#include "my_time.h" +#include "protobuf/tc_db.pb-c.h" +#include "scope_guard.h" // create_scope_guard #include "sql/create_field.h" #include "sql/dd/collection.h" #include "sql/dd/dd_table.h" -#include "sql/dd/types/table.h" -#include "sql/sql_tablespace.h" -#include "sql/dd/types/tablespace.h" -#include "sql/sql_class.h" -#include "sql/sql_lex.h" -#include "sql/strfunc.h" // find_type2 -#include "protobuf/tc_db.pb-c.h" -#include "scope_guard.h" // create_scope_guard +#include "sql/dd/impl/utils.h" #include "sql/dd/types/foreign_key.h" // dd::Foreign_key #include "sql/dd/types/foreign_key_element.h" // dd::Foreign_key_element #include "sql/dd/types/index.h" // dd::Index #include "sql/dd/types/index_element.h" // dd::Index_element -#include "sql/sql_initialize.h" // opt_initialize_insecure #include "sql/dd/types/partition.h" #include "sql/dd/types/partition_index.h" #include "sql/dd/types/partition_value.h" -#include "sql/dd/types/partition_value.h" -#include "sql/partition_info.h" +#include "sql/dd/types/table.h" +#include "sql/dd/types/tablespace.h" +#include "sql/item_func.h" #include "sql/partition_element.h" -#include "sql/dd/impl/utils.h" -#include "sql/sql_table.h" // primary_key_name +#include "sql/partition_info.h" +#include "sql/sql_class.h" +#include "sql/sql_initialize.h" // opt_initialize_insecure +#include "sql/sql_lex.h" #include "sql/sql_partition.h" -#include "sql/item_func.h" -#include "my_time.h" -#include "decimal.h" +#include "sql/sql_table.h" // primary_key_name +#include "sql/sql_tablespace.h" +#include "sql/strfunc.h" // find_type2 -#include "srv_mq_msg.h" -#include "decimal_convert.h" -#include "datatype_cnvrtr.h" +#include +#include +#include "ctc_ddl_util.h" #include "ctc_error.h" #include "ctc_log.h" #include "ctc_util.h" -#include "ctc_ddl_util.h" -#include -#include +#include "datatype_cnvrtr.h" +#include "decimal_convert.h" +#include "srv_mq_msg.h" using namespace std; @@ -77,8 +76,9 @@ extern handlerton *ctc_hton; size_t ctc_ddl_stack_mem::ctc_ddl_req_msg_mem_max_size = 0; size_t ctc_ddl_stack_mem::ctc_ddl_req_msg_mem_use_heap_cnt = 0; -int fill_delete_table_req(const char *full_path_name, const dd::Table *table_def, - THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) { +int fill_delete_table_req(const char *full_path_name, const dd::Table *table_def, THD *thd, ddl_ctrl_t *ddl_ctrl, + ctc_ddl_stack_mem *stack_mem) +{ TcDb__CtcDDLDropTableDef req; tc_db__ctc_ddldrop_table_def__init(&req); @@ -108,7 +108,7 @@ int fill_delete_table_req(const char *full_path_name, const dd::Table *table_def ddl_ctrl->is_alter_copy = true; } - if (is_tmp_table) { // 删除临时表不需要广播 + if (is_tmp_table) { // 删除临时表不需要广播 req.sql_str = nullptr; } else { drop_sql = string(thd->query().str).substr(0, thd->query().length); @@ -137,25 +137,25 @@ int fill_delete_table_req(const char *full_path_name, const dd::Table *table_def return 0; } -static int ctc_init_create_tablespace_def(TcDb__CtcDDLSpaceDef *req, char **mem_start, - char *mem_end) { +static int ctc_init_create_tablespace_def(TcDb__CtcDDLSpaceDef *req, char **mem_start, char *mem_end) +{ tc_db__ctc_ddlspace_def__init(req); req->n_datafiles_list = 1; req->datafiles_list = (TcDb__CtcDDLDataFileDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLDataFileDef*)); // mysql最多只有一个datafile,此处按1计算 + mem_start, mem_end, sizeof(TcDb__CtcDDLDataFileDef *)); // mysql最多只有一个datafile,此处按1计算 if (req->datafiles_list == NULL) { return HA_ERR_OUT_OF_MEM; } - req->datafiles_list[0] = (TcDb__CtcDDLDataFileDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLDataFileDef)); + req->datafiles_list[0] = + (TcDb__CtcDDLDataFileDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLDataFileDef)); if (req->datafiles_list[0] == NULL) { return HA_ERR_OUT_OF_MEM; } tc_db__ctc_ddldata_file_def__init(req->datafiles_list[0]); TcDb__CtcDDLDataFileDef *datafile = req->datafiles_list[0]; - datafile->autoextend = (TcDb__CtcDDLAutoExtendDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAutoExtendDef)); + datafile->autoextend = + (TcDb__CtcDDLAutoExtendDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLAutoExtendDef)); if (datafile->autoextend == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -163,22 +163,23 @@ static int ctc_init_create_tablespace_def(TcDb__CtcDDLSpaceDef *req, char **mem_ return 0; } -static void ctc_ddl_fill_datafile_by_alter_info(TcDb__CtcDDLDataFileDef *datafile, st_alter_tablespace *alter_info) { +static void ctc_ddl_fill_datafile_by_alter_info(TcDb__CtcDDLDataFileDef *datafile, st_alter_tablespace *alter_info) +{ datafile->name = const_cast(alter_info->data_file_name); - datafile->size = 1024 * 1024; // 8 * 1024 * 1024 + datafile->size = 1024 * 1024; // 8 * 1024 * 1024 datafile->autoextend->enabled = true; - if(alter_info->autoextend_size.has_value()) { + if (alter_info->autoextend_size.has_value()) { datafile->autoextend->nextsize = (uint64_t)alter_info->autoextend_size.value(); } else { - datafile->autoextend->nextsize = 0; + datafile->autoextend->nextsize = 0; } // TODO:其他参数目前不确定如何填写 包含autoextend } -static int ctc_create_tablespace_handler(handlerton *hton, THD *thd, - st_alter_tablespace *alter_info, - dd::Tablespace *dd_space MY_ATTRIBUTE((unused))) { +static int ctc_create_tablespace_handler(handlerton *hton, THD *thd, st_alter_tablespace *alter_info, + dd::Tablespace *dd_space MY_ATTRIBUTE((unused))) +{ if (engine_ddl_passthru(thd)) { return CT_SUCCESS; } @@ -194,7 +195,7 @@ static int ctc_create_tablespace_handler(handlerton *hton, THD *thd, ret = (ct_errno_t)ctc_init_create_tablespace_def(&req, &req_mem_start, req_mem_end); assert(req_mem_start <= req_mem_end); if (ret != 0) { - return ret; + return ret; } // fill parameter for create tablespace @@ -206,7 +207,7 @@ static int ctc_create_tablespace_handler(handlerton *hton, THD *thd, // fill datafile parameter TcDb__CtcDDLDataFileDef *datafile = req.datafiles_list[0]; - if(check_data_file_name(alter_info->data_file_name)) { + if (check_data_file_name(alter_info->data_file_name)) { return HA_ERR_WRONG_FILE_NAME; } @@ -215,7 +216,7 @@ static int ctc_create_tablespace_handler(handlerton *hton, THD *thd, msg_len = tc_db__ctc_ddlspace_def__get_packed_size(&req); stack_mem.set_mem_size(msg_len + sizeof(ddl_ctrl_t)); ctc_ddl_req_msg_mem = stack_mem.get_buf(); - if(ctc_ddl_req_msg_mem == nullptr) { + if (ctc_ddl_req_msg_mem == nullptr) { return HA_ERR_OUT_OF_MEM; } @@ -235,10 +236,9 @@ static int ctc_create_tablespace_handler(handlerton *hton, THD *thd, return ctc_ddl_handle_fault("ctc_create_tablespace", thd, &ddl_ctrl, ret, alter_info->tablespace_name); } -static int ctc_alter_tablespace_handler(handlerton *hton, THD *thd, - st_alter_tablespace *alter_info, - const dd::Tablespace *old_dd_space, - dd::Tablespace *new_dd_space) { +static int ctc_alter_tablespace_handler(handlerton *hton, THD *thd, st_alter_tablespace *alter_info, + const dd::Tablespace *old_dd_space, dd::Tablespace *new_dd_space) +{ // 只支持修改表空间名称 以及设置属性 if (alter_info->ts_alter_tablespace_type != ALTER_TABLESPACE_RENAME && alter_info->ts_alter_tablespace_type != ALTER_TABLESPACE_OPTIONS) { @@ -261,12 +261,10 @@ static int ctc_alter_tablespace_handler(handlerton *hton, THD *thd, // TODO 检测from表名 不能和系统表一致(即不能修改系统表) if (alter_info->ts_alter_tablespace_type == ALTER_TABLESPACE_RENAME && my_strcasecmp(system_charset_info, from, to) == 0) { - my_printf_error(ER_WRONG_TABLESPACE_NAME, - "tablespace name is same for rename", MYF(0)); + my_printf_error(ER_WRONG_TABLESPACE_NAME, "tablespace name is same for rename", MYF(0)); return HA_WRONG_CREATE_OPTION; } - auto ctc_alter_action = - g_ctc_alter_tablespace_map.find(alter_info->ts_alter_tablespace_type); + auto ctc_alter_action = g_ctc_alter_tablespace_map.find(alter_info->ts_alter_tablespace_type); if (ctc_alter_action == g_ctc_alter_tablespace_map.end()) { return ER_ILLEGAL_HA; } @@ -275,7 +273,7 @@ static int ctc_alter_tablespace_handler(handlerton *hton, THD *thd, tc_db__ctc_ddlalter_space_def__init(&req); req.action = ctc_alter_action->second; - + CTC_RETURN_IF_NOT_ZERO(check_ctc_identifier_name(from)); req.name = const_cast(from); CTC_RETURN_IF_NOT_ZERO(check_ctc_identifier_name(to)); @@ -290,7 +288,7 @@ static int ctc_alter_tablespace_handler(handlerton *hton, THD *thd, msg_len = tc_db__ctc_ddlalter_space_def__get_packed_size(&req); stack_mem.set_mem_size(msg_len + sizeof(ddl_ctrl_t)); ctc_ddl_req_msg_mem = stack_mem.get_buf(); - if(ctc_ddl_req_msg_mem == nullptr) { + if (ctc_ddl_req_msg_mem == nullptr) { return HA_ERR_OUT_OF_MEM; } @@ -310,9 +308,9 @@ static int ctc_alter_tablespace_handler(handlerton *hton, THD *thd, return ctc_ddl_handle_fault("ctc_alter_tablespace", thd, &ddl_ctrl, ret); } -static int ctc_drop_tablespace_handler(handlerton *hton, THD *thd, - st_alter_tablespace *alter_info, - const dd::Tablespace *dd_space MY_ATTRIBUTE((unused))) { +static int ctc_drop_tablespace_handler(handlerton *hton, THD *thd, st_alter_tablespace *alter_info, + const dd::Tablespace *dd_space MY_ATTRIBUTE((unused))) +{ if (engine_ddl_passthru(thd)) { return CT_SUCCESS; } @@ -326,16 +324,15 @@ static int ctc_drop_tablespace_handler(handlerton *hton, THD *thd, tc_db__ctc_ddldrop_space_def__init(&req); CTC_RETURN_IF_NOT_ZERO(check_ctc_identifier_name(alter_info->tablespace_name)); req.obj_name = const_cast(alter_info->tablespace_name); - + req.db_name = CTC_GET_THD_DB_NAME(thd); string sql = string(thd->query().str).substr(0, thd->query().length); req.sql_str = const_cast(sql.c_str()); - msg_len = tc_db__ctc_ddldrop_space_def__get_packed_size(&req); stack_mem.set_mem_size(msg_len + sizeof(ddl_ctrl_t)); ctc_ddl_req_msg_mem = stack_mem.get_buf(); - if(ctc_ddl_req_msg_mem == nullptr) { + if (ctc_ddl_req_msg_mem == nullptr) { return HA_ERR_OUT_OF_MEM; } @@ -356,7 +353,6 @@ static int ctc_drop_tablespace_handler(handlerton *hton, THD *thd, return ctc_ddl_handle_fault("ctc_drop_tablespace", thd, &ddl_ctrl, ret, alter_info->tablespace_name); } - /** alter tablespace. @param: hton in, ctc handlerton @@ -364,10 +360,9 @@ static int ctc_drop_tablespace_handler(handlerton *hton, THD *thd, @param: savepoint in, savepoint data @return: 0 if succeeds */ -int ctcbase_alter_tablespace(handlerton *hton, THD *thd, - st_alter_tablespace *alter_info, - const dd::Tablespace *old_ts_def, - dd::Tablespace *new_ts_def) { +int ctcbase_alter_tablespace(handlerton *hton, THD *thd, st_alter_tablespace *alter_info, + const dd::Tablespace *old_ts_def, dd::Tablespace *new_ts_def) +{ DBUG_TRACE; // TODO:只读模式和强制恢复模式不能修改表空间 @@ -401,7 +396,8 @@ int ctcbase_alter_tablespace(handlerton *hton, THD *thd, return HA_ADMIN_NOT_IMPLEMENTED; } -static bool ctc_fill_column_precision_and_scale(TcDb__CtcDDLColumnDef *column, Field *field) { +static bool ctc_fill_column_precision_and_scale(TcDb__CtcDDLColumnDef *column, Field *field) +{ switch (field->real_type()) { case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: { @@ -421,8 +417,8 @@ static bool ctc_fill_column_precision_and_scale(TcDb__CtcDDLColumnDef *column, F column->datatype->precision = f->precision; column->datatype->scale = f->decimals(); if (f->precision > MAX_NUMERIC_BUFF) { - my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast(f->precision), - column->name, static_cast(MAX_NUMERIC_BUFF)); + my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast(f->precision), column->name, + static_cast(MAX_NUMERIC_BUFF)); return false; } break; @@ -448,18 +444,20 @@ static bool ctc_fill_column_precision_and_scale(TcDb__CtcDDLColumnDef *column, F return true; } -static void ctc_set_unsigned_column(Field *field, uint32 *is_unsigned) { - if ((is_numeric_type(field->type()) && field->is_unsigned()) || - field->real_type() == MYSQL_TYPE_ENUM || field->real_type() == MYSQL_TYPE_BIT) { +static void ctc_set_unsigned_column(Field *field, uint32 *is_unsigned) +{ + if ((is_numeric_type(field->type()) && field->is_unsigned()) || field->real_type() == MYSQL_TYPE_ENUM || + field->real_type() == MYSQL_TYPE_BIT) { *is_unsigned = 1; } else { *is_unsigned = 0; } } -static bool ctc_ddl_fill_column_by_field_fill_type(TcDb__CtcDDLColumnDef *column, Field *field) { +static bool ctc_ddl_fill_column_by_field_fill_type(TcDb__CtcDDLColumnDef *column, Field *field) +{ if (!ctc_ddl_get_data_type_from_mysql_type(field, field->type(), &column->datatype->datatype)) { - char info[300]; // max column name length(64) * max_mb_size(4) + redundancy + char info[300]; // max column name length(64) * max_mb_size(4) + redundancy sprintf(info, "column name: %s", field->field_name); my_error(ER_FEATURE_UNSUPPORTED, MYF(0), "*DataType Conversion*", info); return false; @@ -484,7 +482,8 @@ static bool ctc_ddl_fill_column_by_field_fill_type(TcDb__CtcDDLColumnDef *column return true; } -static int ctc_prepare_enum_field_impl(THD *thd, Create_field *sql_field, String *def) { +static int ctc_prepare_enum_field_impl(THD *thd, Create_field *sql_field, String *def) +{ DBUG_TRACE; assert(sql_field->sql_type == MYSQL_TYPE_ENUM); if (!sql_field->charset) { @@ -492,10 +491,10 @@ static int ctc_prepare_enum_field_impl(THD *thd, Create_field *sql_field, String } /* SQL "NULL" maps to NULL */ if (def == nullptr) { - if ((sql_field->flags & NOT_NULL_FLAG) != 0) { - my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - return CTC_ENUM_DEFAULT_NULL; - } + if ((sql_field->flags & NOT_NULL_FLAG) != 0) { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + return CTC_ENUM_DEFAULT_NULL; + } } else { def->length(sql_field->charset->cset->lengthsp(sql_field->charset, def->ptr(), def->length())); TYPELIB *interval = sql_field->interval; @@ -513,8 +512,9 @@ static int ctc_prepare_enum_field_impl(THD *thd, Create_field *sql_field, String return CTC_ENUM_DEFAULT_INVALID; } -static bool ctc_prepare_set_field_impl(THD *thd, Create_field *sql_field, ulonglong *set_bitmap, - String *def, TcDb__CtcDDLColumnDef *column) { +static bool ctc_prepare_set_field_impl(THD *thd, Create_field *sql_field, ulonglong *set_bitmap, String *def, + TcDb__CtcDDLColumnDef *column) +{ DBUG_TRACE; assert(sql_field->sql_type == MYSQL_TYPE_SET); @@ -534,7 +534,7 @@ static bool ctc_prepare_set_field_impl(THD *thd, Create_field *sql_field, ulongl // Comma is an invalid character for SET names char comma_buf[4]; /* 4 bytes for utf32 */ int comma_length = sql_field->charset->cset->wc_mb(sql_field->charset, ',', reinterpret_cast(comma_buf), - reinterpret_cast(comma_buf) + sizeof(comma_buf)); + reinterpret_cast(comma_buf) + sizeof(comma_buf)); assert(comma_length > 0); if (!set_column_datatype(interval->count, column)) { @@ -543,8 +543,8 @@ static bool ctc_prepare_set_field_impl(THD *thd, Create_field *sql_field, ulongl } for (uint i = 0; i < interval->count; i++) { - uint is_default_values = sql_field->charset->coll->strstr(sql_field->charset, interval->type_names[i], - interval->type_lengths[i], comma_buf, comma_length, nullptr, 0); + uint is_default_values = sql_field->charset->coll->strstr( + sql_field->charset, interval->type_names[i], interval->type_lengths[i], comma_buf, comma_length, nullptr, 0); if (is_default_values != 0) { ErrConvString err(interval->type_names[i], interval->type_lengths[i], sql_field->charset); my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", err.ptr()); @@ -577,8 +577,9 @@ static bool ctc_prepare_set_field_impl(THD *thd, Create_field *sql_field, ulongl return true; } -static bool ctc_process_string_default_value(TcDb__CtcDDLColumnDef *column, string &expr_str, - char **mem_start, char *mem_end, bool is_blob_type) { +static bool ctc_process_string_default_value(TcDb__CtcDDLColumnDef *column, string &expr_str, char **mem_start, + char *mem_end, bool is_blob_type) +{ if (!is_blob_type) { boost::algorithm::replace_all(expr_str, "'", "''"); column->default_text = (char *)ctc_ddl_alloc_mem(mem_start, mem_end, expr_str.length() + 1); @@ -603,13 +604,13 @@ static bool ctc_process_string_default_value(TcDb__CtcDDLColumnDef *column, stri return true; } -static bool ctc_get_bit_default_value( - THD *thd, TcDb__CtcDDLColumnDef *column, Field *field, const Create_field *fld, const dd::Column *col_obj, - char **mem_start, char *mem_end, bool is_expr_value) { +static bool ctc_get_bit_default_value(THD *thd, TcDb__CtcDDLColumnDef *column, Field *field, const Create_field *fld, + const dd::Column *col_obj, char **mem_start, char *mem_end, bool is_expr_value) +{ column->is_unsigned = 1; longlong num = 0; if (!is_expr_value) { - char* bit_value_buf = const_cast(col_obj->default_value().data()); + char *bit_value_buf = const_cast(col_obj->default_value().data()); uint32_t bit_value_len = (uint32_t)(col_obj->default_value().length()); Field_bit *bitfield = dynamic_cast(field); Field_bit *new_field = bitfield->clone(thd->mem_root); @@ -635,8 +636,7 @@ static bool ctc_get_bit_default_value( num = 0; } else { int err = 0; - num = my_strntoll(res->charset(), res->ptr(), res->length(), 10, nullptr, - &err); + num = my_strntoll(res->charset(), res->ptr(), res->length(), 10, nullptr, &err); if (err) { string expr_str(res->c_ptr()); return ctc_process_string_default_value(column, expr_str, mem_start, mem_end, false); @@ -657,19 +657,19 @@ static bool ctc_get_bit_default_value( return true; } -static bool ctc_get_datetime_default_value( - TcDb__CtcDDLColumnDef *column, Field *field, const Create_field *fld, const dd::Column *col_obj, - char **mem_start, char *mem_end, ctc_column_option_set_bit *option_set, bool is_expr_value) { +static bool ctc_get_datetime_default_value(TcDb__CtcDDLColumnDef *column, Field *field, const Create_field *fld, + const dd::Column *col_obj, char **mem_start, char *mem_end, + ctc_column_option_set_bit *option_set, bool is_expr_value) +{ if (field->has_insert_default_datetime_value_expression()) { // current_timestamp (or with ON UPDATE CURRENT_TIMESTAMP) - option_set->is_default_func = 1; + option_set->is_default_func = 1; option_set->is_curr_timestamp = 1; column->default_text = const_cast(col_obj->default_value_utf8().data()); return true; } if (field->has_update_default_datetime_value_expression() && - (!col_obj->default_value_utf8().data() || - strlen(col_obj->default_value_utf8().data()) == 0)) { + (!col_obj->default_value_utf8().data() || strlen(col_obj->default_value_utf8().data()) == 0)) { // ON UPDATE CURRENT_TIMESTAMP without default_value return true; } @@ -678,7 +678,7 @@ static bool ctc_get_datetime_default_value( MYSQL_TIME ltime; memset(<ime, 0, sizeof(MYSQL_TIME)); memset(&date_detail, 0, sizeof(date_detail_t)); - const field_cnvrt_aux_t* mysql_info = get_auxiliary_for_field_convert(field, field->type()); + const field_cnvrt_aux_t *mysql_info = get_auxiliary_for_field_convert(field, field->type()); assert(mysql_info != NULL); string expr_str; if (is_expr_value) { @@ -689,8 +689,7 @@ static bool ctc_get_datetime_default_value( expr_str = (field->m_default_val_expr->expr_item->val_str(&str))->c_ptr(); } MYSQL_TIME_STATUS status; - str_to_datetime(expr_str.c_str(), expr_str.length(), <ime, TIME_FRAC_TRUNCATE | TIME_FUZZY_DATE, - &status); + str_to_datetime(expr_str.c_str(), expr_str.length(), <ime, TIME_FRAC_TRUNCATE | TIME_FUZZY_DATE, &status); } else { expr_str = const_cast(col_obj->default_value_utf8().data()); const uchar *mysql_ptr = (const uchar *)(col_obj->default_value().data()); @@ -703,7 +702,7 @@ static bool ctc_get_datetime_default_value( } if (check_zero_date(date_detail)) { - char *tmp_zero_date = const_cast("0000-00-00 00:00:00"); + char *tmp_zero_date = const_cast("0000-00-00 00:00:00"); int len = strlen(tmp_zero_date); column->default_text = (char *)ctc_ddl_alloc_mem(mem_start, mem_end, len + 1); if (column->default_text == nullptr) { @@ -752,12 +751,12 @@ static bool ctc_get_datetime_default_value( return true; } -static int ctc_prepare_enum_field(THD *thd, Field *field, const Create_field *fld, - const CHARSET_INFO *field_cs) { +static int ctc_prepare_enum_field(THD *thd, Field *field, const Create_field *fld, const CHARSET_INFO *field_cs) +{ int is_enum = 0; String default_str; String *def; - Create_field* sql_field; + Create_field *sql_field; // fld == nullptr 为create,此时field_charset 为空值需处理置位 if (fld == nullptr) { Create_field sql_field_local(field, field); @@ -778,7 +777,7 @@ static int ctc_prepare_enum_field(THD *thd, Field *field, const Create_field *fl // 修改ENUM default带charset // 或设置了全局charset找不到enum_index // 判断当前charset与field charset是否一致 - if(field_cs == nullptr || strcmp(def->charset()->csname, field_cs->csname) != 0) { + if (field_cs == nullptr || strcmp(def->charset()->csname, field_cs->csname) != 0) { sql_field->charset = def->charset(); } } @@ -786,9 +785,10 @@ static int ctc_prepare_enum_field(THD *thd, Field *field, const Create_field *fl return is_enum; } -static bool ctc_get_enum_default_value( - THD *thd, TcDb__CtcDDLColumnDef *column, const dd::Column *col_obj, Field *field, const Create_field *fld, - char **mem_start, char *mem_end, const CHARSET_INFO *field_cs) { +static bool ctc_get_enum_default_value(THD *thd, TcDb__CtcDDLColumnDef *column, const dd::Column *col_obj, Field *field, + const Create_field *fld, char **mem_start, char *mem_end, + const CHARSET_INFO *field_cs) +{ int is_enum; column->is_unsigned = 1; column->datatype->datatype = column->datatype->size == 1 ? CTC_DDL_TYPE_TINY : CTC_DDL_TYPE_SHORT; @@ -820,11 +820,12 @@ static bool ctc_get_enum_default_value( } static bool ctc_prepare_set_field(THD *thd, Field *field, const Create_field *fld, const CHARSET_INFO *field_cs, - ulonglong *set_bitmap, TcDb__CtcDDLColumnDef *column) { + ulonglong *set_bitmap, TcDb__CtcDDLColumnDef *column) +{ bool is_get_set_bitmap = 0; String default_str; String *def; - Create_field* sql_field; + Create_field *sql_field; // fld == nullptr 为create,此时field_charset 为空值需处理置位 if (fld == nullptr) { Create_field sql_field_local(field, field); @@ -842,7 +843,7 @@ static bool ctc_prepare_set_field(THD *thd, Field *field, const Create_field *fl def = sql_field->m_default_val_expr->expr_item->val_str(&default_str); } if (fld == nullptr) { - if(field_cs == nullptr || strcmp(def->charset()->csname, field_cs->csname) != 0) { + if (field_cs == nullptr || strcmp(def->charset()->csname, field_cs->csname) != 0) { sql_field->charset = def->charset(); } } @@ -851,9 +852,9 @@ static bool ctc_prepare_set_field(THD *thd, Field *field, const Create_field *fl return is_get_set_bitmap; } -static bool ctc_get_set_default_value( - THD *thd, TcDb__CtcDDLColumnDef *column, Field *field, const Create_field *fld, char **mem_start, - char *mem_end, const CHARSET_INFO *field_cs) { +static bool ctc_get_set_default_value(THD *thd, TcDb__CtcDDLColumnDef *column, Field *field, const Create_field *fld, + char **mem_start, char *mem_end, const CHARSET_INFO *field_cs) +{ ulonglong set_bitmap; bool is_get_set_bitmap = false; if (is_numeric_type(field->type()) && field->is_unsigned()) { @@ -876,12 +877,13 @@ static bool ctc_get_set_default_value( return true; } -static bool ctc_verify_string_default_length(TcDb__CtcDDLColumnDef *column, String* default_str, Field *field, - const Create_field *fld) { +static bool ctc_verify_string_default_length(TcDb__CtcDDLColumnDef *column, String *default_str, Field *field, + const Create_field *fld) +{ if (column->datatype->datatype == CTC_DDL_TYPE_CLOB) { return true; } - const CHARSET_INFO* col_charset = fld ? fld->charset : field->charset(); + const CHARSET_INFO *col_charset = fld ? fld->charset : field->charset(); int max_char_count = column->datatype->size / col_charset->mbmaxlen; int default_str_char_count = default_str->numchars(); if (default_str_char_count > max_char_count) { @@ -891,9 +893,9 @@ static bool ctc_verify_string_default_length(TcDb__CtcDDLColumnDef *column, Stri return true; } -static bool ctc_get_string_default_value( - TcDb__CtcDDLColumnDef *column, Field *field, const dd::Column *col_obj, const Create_field *fld, - char **mem_start, char *mem_end, bool is_blob_type) { +static bool ctc_get_string_default_value(TcDb__CtcDDLColumnDef *column, Field *field, const dd::Column *col_obj, + const Create_field *fld, char **mem_start, char *mem_end, bool is_blob_type) +{ char *field_default_string = nullptr; if (fld == nullptr) { if (!field->m_default_val_expr) { @@ -904,7 +906,7 @@ static bool ctc_get_string_default_value( } } else { String tmp_string; - String* tmp_string_ptr; + String *tmp_string_ptr; assert(field->m_default_val_expr); tmp_string_ptr = field->m_default_val_expr->expr_item->val_str(&tmp_string); if (!is_blob_type && !ctc_verify_string_default_length(column, tmp_string_ptr, field, fld)) { @@ -915,14 +917,14 @@ static bool ctc_get_string_default_value( } else { // for alter table add column String tmp_string; - String* tmp_string_ptr; + String *tmp_string_ptr; if (fld->constant_default != nullptr) { tmp_string_ptr = fld->constant_default->val_str(&tmp_string); } else { tmp_string_ptr = fld->m_default_val_expr->expr_item->val_str(&tmp_string); } if (!ctc_verify_string_default_length(column, tmp_string_ptr, field, fld)) { - return false; + return false; } field_default_string = tmp_string_ptr->c_ptr(); } @@ -930,14 +932,13 @@ static bool ctc_get_string_default_value( return ctc_process_string_default_value(column, expr_str, mem_start, mem_end, is_blob_type); } -static bool ctc_get_numeric_default_value( - TcDb__CtcDDLColumnDef *column, Field *field, const dd::Column *col_obj, const Create_field *fld, - char **mem_start, char *mem_end, bool is_expr_value) +static bool ctc_get_numeric_default_value(TcDb__CtcDDLColumnDef *column, Field *field, const dd::Column *col_obj, + const Create_field *fld, char **mem_start, char *mem_end, bool is_expr_value) { char *field_default_string = nullptr; if (is_expr_value) { String tmp_string; - Item* expr_item; + Item *expr_item; expr_item = fld ? fld->m_default_val_expr->expr_item : field->m_default_val_expr->expr_item; if (expr_item->type() == Item::VARBIN_ITEM) { longlong num = expr_item->val_int(); @@ -973,16 +974,15 @@ static bool ctc_get_numeric_default_value( } static bool ctc_check_expression_default_value(TcDb__CtcDDLColumnDef *column, Field *field, const Create_field *fld, - ctc_column_option_set_bit *option_set, bool* is_expr_value) { - if ((field != nullptr && !field->m_default_val_expr) || - (fld != nullptr && !fld->m_default_val_expr)) { - //排除普通表达式 - option_set->is_default_func = 0; - return true; + ctc_column_option_set_bit *option_set, bool *is_expr_value) +{ + if ((field != nullptr && !field->m_default_val_expr) || (fld != nullptr && !fld->m_default_val_expr)) { + // 排除普通表达式 + option_set->is_default_func = 0; + return true; } - Item *constant_default = fld == nullptr ? field->m_default_val_expr->expr_item : - fld->m_default_val_expr->expr_item; - //default expression + Item *constant_default = fld == nullptr ? field->m_default_val_expr->expr_item : fld->m_default_val_expr->expr_item; + // default expression if (!constant_default->const_for_execution() && constant_default->type() != Item::FUNC_ITEM) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "Current storage engine only support default expression without variable parameters"); @@ -994,7 +994,7 @@ static bool ctc_check_expression_default_value(TcDb__CtcDDLColumnDef *column, Fi for (uint i = 0; i < item_func->arg_count; i++) { if (item_func->get_arg(i)->type() == Item::FIELD_ITEM) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Current storage engine only support default function without variable parameters"); + "Current storage engine only support default function without variable parameters"); return false; } } @@ -1005,13 +1005,14 @@ static bool ctc_check_expression_default_value(TcDb__CtcDDLColumnDef *column, Fi return true; } - -static bool ctc_ddl_fill_column_default_value( - THD *thd, TcDb__CtcDDLColumnDef *column, Field *field, const Create_field *fld, const dd::Column *col_obj, - ctc_column_option_set_bit *option_set, char **mem_start, char *mem_end, const CHARSET_INFO *field_cs) { +static bool ctc_ddl_fill_column_default_value(THD *thd, TcDb__CtcDDLColumnDef *column, Field *field, + const Create_field *fld, const dd::Column *col_obj, + ctc_column_option_set_bit *option_set, char **mem_start, char *mem_end, + const CHARSET_INFO *field_cs) +{ option_set->is_default = true; option_set->is_default_null = false; - + // function except DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP // CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP is described in ctc_get_datetime_default_value option_set->is_default_func = field->has_insert_default_general_value_expression() && @@ -1029,7 +1030,8 @@ static bool ctc_ddl_fill_column_default_value( bool is_blob_type = false; switch (field->real_type()) { case MYSQL_TYPE_BIT: - CTC_RETURN_IF_ERROR(ctc_get_bit_default_value(thd, column, field, fld, col_obj, mem_start, mem_end, is_expr_value), false); + CTC_RETURN_IF_ERROR( + ctc_get_bit_default_value(thd, column, field, fld, col_obj, mem_start, mem_end, is_expr_value), false); break; case MYSQL_TYPE_BLOB: is_blob_type = (column->datatype->datatype != CTC_DDL_TYPE_CLOB); @@ -1047,10 +1049,12 @@ static bool ctc_ddl_fill_column_default_value( } case MYSQL_TYPE_STRING: case MYSQL_TYPE_VARCHAR: - CTC_RETURN_IF_ERROR(ctc_get_string_default_value(column, field, col_obj, fld, mem_start, mem_end, is_blob_type), false); + CTC_RETURN_IF_ERROR(ctc_get_string_default_value(column, field, col_obj, fld, mem_start, mem_end, is_blob_type), + false); break; case MYSQL_TYPE_ENUM: - CTC_RETURN_IF_ERROR(ctc_get_enum_default_value(thd, column, col_obj, field, fld, mem_start, mem_end, field_cs), false); + CTC_RETURN_IF_ERROR(ctc_get_enum_default_value(thd, column, col_obj, field, fld, mem_start, mem_end, field_cs), + false); break; case MYSQL_TYPE_SET: CTC_RETURN_IF_ERROR(ctc_get_set_default_value(thd, column, field, fld, mem_start, mem_end, field_cs), false); @@ -1060,22 +1064,26 @@ static bool ctc_ddl_fill_column_default_value( case MYSQL_TYPE_DATETIME2: case MYSQL_TYPE_TIMESTAMP2: case MYSQL_TYPE_TIME2: - CTC_RETURN_IF_ERROR(ctc_get_datetime_default_value(column, field, fld, col_obj, mem_start, mem_end, option_set, is_expr_value), false); + CTC_RETURN_IF_ERROR( + ctc_get_datetime_default_value(column, field, fld, col_obj, mem_start, mem_end, option_set, is_expr_value), + false); break; default: - CTC_RETURN_IF_ERROR(ctc_get_numeric_default_value(column, field, col_obj, fld, mem_start, mem_end, is_expr_value), false); + CTC_RETURN_IF_ERROR(ctc_get_numeric_default_value(column, field, col_obj, fld, mem_start, mem_end, is_expr_value), + false); break; } return true; } -static void ctc_fill_column_option_set(TcDb__CtcDDLColumnDef *column, Field *field, - TABLE *form, ctc_column_option_set_bit *option_set) { +static void ctc_fill_column_option_set(TcDb__CtcDDLColumnDef *column, Field *field, TABLE *form, + ctc_column_option_set_bit *option_set) +{ column->is_option_set = 0; - option_set->is_option_set= 0; + option_set->is_option_set = 0; option_set->primary = false; option_set->is_default_null = false; - option_set->has_null = true; // 保证nullable的值是准确的 + option_set->has_null = true; // 保证nullable的值是准确的 option_set->nullable = (field->is_flag_set(NOT_NULL_FLAG)) ? 0 : 1; if (field->is_flag_set(PRI_KEY_FLAG)) { @@ -1084,14 +1092,14 @@ static void ctc_fill_column_option_set(TcDb__CtcDDLColumnDef *column, Field *fie option_set->nullable = false; } option_set->unique = field->is_flag_set(UNIQUE_KEY_FLAG); - column->cons_name = option_set->primary ? const_cast("PRIMARY") : - (option_set->unique ? column->name : nullptr); + column->cons_name = + option_set->primary ? const_cast("PRIMARY") : (option_set->unique ? column->name : nullptr); option_set->is_serial = field->is_flag_set(AUTO_INCREMENT_FLAG); option_set->is_comment = field->comment.length > 0; column->comment = option_set->is_comment ? const_cast(field->comment.str) : nullptr; /*处理自增列为unique key的情况*/ - if(option_set->is_serial) { + if (option_set->is_serial) { for (uint i = 0; i < form->s->keys; i++) { if (strcmp(column->name, form->s->keynames.type_names[i]) == 0) { option_set->unique = true; @@ -1107,37 +1115,38 @@ static void ctc_fill_column_option_set(TcDb__CtcDDLColumnDef *column, Field *fie } } -static bool ctc_ddl_fill_column_by_field( - THD *thd, TcDb__CtcDDLColumnDef *column, Field *field, - const dd::Table *table_def, TABLE *form, const Create_field *fld, - ctc_alter_column_alter_mode alter_mode, char **mem_start, char *mem_end, const CHARSET_INFO *field_cs) { +static bool ctc_ddl_fill_column_by_field(THD *thd, TcDb__CtcDDLColumnDef *column, Field *field, + const dd::Table *table_def, TABLE *form, const Create_field *fld, + ctc_alter_column_alter_mode alter_mode, char **mem_start, char *mem_end, + const CHARSET_INFO *field_cs) +{ const dd::Column *col_obj = NULL; - col_obj = table_def ? table_def->get_column(field->field_name) : nullptr; // create view中创临时表,table_def为空 + col_obj = table_def ? table_def->get_column(field->field_name) : nullptr; // create view中创临时表,table_def为空 /* We need this to get default values from the table We have to restore the read_set if we are called from insert in case of row based replication. */ my_bitmap_map *old_map = tmp_use_all_columns(form, form->read_set); - auto grd = create_scope_guard( - [&]() { tmp_restore_column_map(form->read_set, old_map); }); + auto grd = create_scope_guard([&]() { tmp_restore_column_map(form->read_set, old_map); }); if (fld != NULL && fld->change != NULL) { - column->name = const_cast(fld->change); - if (strcmp(fld->change, field->field_name) != 0) { - column->new_name = const_cast(field->field_name); - } + column->name = const_cast(fld->change); + if (strcmp(fld->change, field->field_name) != 0) { + column->new_name = const_cast(field->field_name); + } } else { - column->name = const_cast(field->field_name); + column->name = const_cast(field->field_name); } - + CTC_RETURN_IF_ERROR(ctc_ddl_fill_column_by_field_fill_type(column, field), false); ctc_column_option_set_bit option_set; ctc_fill_column_option_set(column, field, form, &option_set); if (ctc_is_with_default_value(field, col_obj)) { - CTC_RETURN_IF_ERROR(ctc_ddl_fill_column_default_value(thd, column, field, fld, col_obj, - &option_set, mem_start, mem_end, field_cs), false); + CTC_RETURN_IF_ERROR( + ctc_ddl_fill_column_default_value(thd, column, field, fld, col_obj, &option_set, mem_start, mem_end, field_cs), + false); } else { option_set.is_default = 0; option_set.is_default_func = 0; @@ -1146,7 +1155,7 @@ static bool ctc_ddl_fill_column_by_field( } // 这句代码要放在所有设置option_set的后面 column->is_option_set = option_set.is_option_set; - column->alter_mode = alter_mode; // ctc_alter_column_alter_mode + column->alter_mode = alter_mode; // ctc_alter_column_alter_mode return true; } @@ -1163,20 +1172,18 @@ static int ctc_ddl_alter_table_fill_foreign_key_info(TcDb__CtcDDLForeignKeyDef * return HA_ERR_OUT_OF_MEM; } ctc_copy_name(fk_def->referenced_table_schema_name, fk->ref_db.str, buf_len); - fk_def->referenced_table_name = - const_cast(fk->ref_table.str); + fk_def->referenced_table_name = const_cast(fk->ref_table.str); for (uint j = 0; j < fk_def->n_elements; j++) { TcDb__CtcDDLForeignKeyElementDef *fk_ele = fk_def->elements[j]; - fk_ele->src_column_name = - const_cast(fk->columns[j]->get_field_name()); - fk_ele->ref_column_name = - const_cast(fk->ref_columns[j]->get_field_name()); + fk_ele->src_column_name = const_cast(fk->columns[j]->get_field_name()); + fk_ele->ref_column_name = const_cast(fk->ref_columns[j]->get_field_name()); } return CT_SUCCESS; } -static int ctc_ddl_create_table_fill_foreign_key_info(TcDb__CtcDDLCreateTableDef *req, - const dd::Table *table_def, char **mem_start, char *mem_end) { +static int ctc_ddl_create_table_fill_foreign_key_info(TcDb__CtcDDLCreateTableDef *req, const dd::Table *table_def, + char **mem_start, char *mem_end) +{ if (req->n_fk_list == 0) { return CT_SUCCESS; } @@ -1195,49 +1202,43 @@ static int ctc_ddl_create_table_fill_foreign_key_info(TcDb__CtcDDLCreateTableDef return HA_ERR_OUT_OF_MEM; } ctc_copy_name(fk_def->referenced_table_schema_name, fk->referenced_table_schema_name().data(), buf_len); - fk_def->referenced_table_name = - const_cast(fk->referenced_table_name().data()); + fk_def->referenced_table_name = const_cast(fk->referenced_table_name().data()); for (uint j = 0; j < fk_def->n_elements; j++) { TcDb__CtcDDLForeignKeyElementDef *fk_ele = fk_def->elements[j]; const dd::Foreign_key_element *fk_col_obj = fk->elements().at(j); - fk_ele->src_column_name = - const_cast(fk_col_obj->column().name().data()); - fk_ele->ref_column_name = - const_cast(fk_col_obj->referenced_column_name().data()); + fk_ele->src_column_name = const_cast(fk_col_obj->column().name().data()); + fk_ele->ref_column_name = const_cast(fk_col_obj->referenced_column_name().data()); } } return CT_SUCCESS; } -static void ctc_fill_prefix_func_key_part(TcDb__CtcDDLTableKeyPart *req_key_part, - const Field *field, uint16 prefix_len) { +static void ctc_fill_prefix_func_key_part(TcDb__CtcDDLTableKeyPart *req_key_part, const Field *field, uint16 prefix_len) +{ req_key_part->is_func = true; - if (field->real_type() == MYSQL_TYPE_BLOB && field->charset() == &my_charset_bin && - field->is_flag_set(BINARY_FLAG)) { + if (field->real_type() == MYSQL_TYPE_BLOB && field->charset() == &my_charset_bin && field->is_flag_set(BINARY_FLAG)) { req_key_part->func_name = const_cast("substrb"); - snprintf(req_key_part->func_text, FUNC_TEXT_MAX_LEN - 1, "substrb(%s,1,%d)", - field->field_name, prefix_len); + snprintf(req_key_part->func_text, FUNC_TEXT_MAX_LEN - 1, "substrb(%s,1,%d)", field->field_name, prefix_len); } else { req_key_part->func_name = const_cast("substr"); - snprintf(req_key_part->func_text, FUNC_TEXT_MAX_LEN - 1, "substr(%s,1,%d)", - field->field_name, prefix_len); + snprintf(req_key_part->func_text, FUNC_TEXT_MAX_LEN - 1, "substr(%s,1,%d)", field->field_name, prefix_len); } return; } -static uint32_t ctc_fill_func_key_part(TABLE *form, THD *thd, TcDb__CtcDDLTableKeyPart *req_key_part, Value_generator *gcol_info) +static uint32_t ctc_fill_func_key_part(TABLE *form, THD *thd, TcDb__CtcDDLTableKeyPart *req_key_part, + Value_generator *gcol_info) { Item_func *func_expr_item = dynamic_cast(gcol_info->expr_item); if (func_expr_item == nullptr) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "[CTC_CREATE_TABLE]: CTC do not support this functional index."); + "[CTC_CREATE_TABLE]: CTC do not support this functional index."); return CT_ERROR; } uint32_t arg_count = func_expr_item->arg_count; if (arg_count == 0) { - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "[CTC_CREATE_TABLE]: There is no functional index."); + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "[CTC_CREATE_TABLE]: There is no functional index."); return CT_ERROR; } @@ -1249,21 +1250,20 @@ static uint32_t ctc_fill_func_key_part(TABLE *form, THD *thd, TcDb__CtcDDLTableK for (uint32_t i = 0; i < arg_count; i++) { field = ctc_get_field_by_name(form, const_cast(args[i]->item_name.ptr())); if (field && field->is_gcol()) { - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Cantian does not support index on generated column."); + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "Cantian does not support index on generated column."); return CT_ERROR; } if (args[i]->type() == Item::FIELD_ITEM) { if (col_item_count >= 1) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Cantian does not support function indexes with multiple columns of arguments."); + "Cantian does not support function indexes with multiple columns of arguments."); return CT_ERROR; } req_key_part->name = const_cast(args[i]->item_name.ptr()); col_item_count++; } } - + char buffer[FUNC_TEXT_MAX_LEN] = {0}; String gc_expr(buffer, sizeof(buffer), &my_charset_bin); gcol_info->print_expr(thd, &gc_expr); @@ -1275,17 +1275,18 @@ static uint32_t ctc_fill_func_key_part(TABLE *form, THD *thd, TcDb__CtcDDLTableK std::regex reg_char("returning[ ]char[(]\\d+[)]"); std::regex reg_charset("[_][a-z]+[0-9]*[a-z]*[0-9]*['$]"); std::regex reg_charset2("[ ]character[ ]set[ ][a-z]+[0-9]*[a-z]*[0-9]"); - expr_str =std::regex_replace(expr_str, reg_char, "returning CLOB"); - expr_str =std::regex_replace(expr_str, reg_charset, "'"); - //处理char带charset设置 - expr_str =std::regex_replace(expr_str, reg_charset2, ""); + expr_str = std::regex_replace(expr_str, reg_char, "returning CLOB"); + expr_str = std::regex_replace(expr_str, reg_charset, "'"); + // 处理char带charset设置 + expr_str = std::regex_replace(expr_str, reg_charset2, ""); } strncpy(req_key_part->func_text, expr_str.c_str(), FUNC_TEXT_MAX_LEN - 1); return CT_SUCCESS; } -static bool ctc_ddl_create_table_fill_add_key(TcDb__CtcDDLCreateTableDef *req, THD *thd, - const dd::Table *table_def, TABLE *form, char *user) { +static bool ctc_ddl_create_table_fill_add_key(TcDb__CtcDDLCreateTableDef *req, THD *thd, const dd::Table *table_def, + TABLE *form, char *user) +{ if (req->n_key_list == 0) { return true; } @@ -1324,7 +1325,7 @@ static bool ctc_ddl_create_table_fill_add_key(TcDb__CtcDDLCreateTableDef *req, T } else { if (fld->is_virtual_gcol()) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Cantian does not support index on virtual generated column."); + "Cantian does not support index on virtual generated column."); return false; } @@ -1378,7 +1379,7 @@ static bool ctc_ddl_create_table_fill_add_key(TcDb__CtcDDLCreateTableDef *req, T } else { if (fld->is_virtual_gcol()) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Cantian does not support index on virtual generated column."); + "Cantian does not support index on virtual generated column."); return false; } @@ -1404,21 +1405,22 @@ static bool ctc_ddl_create_table_fill_add_key(TcDb__CtcDDLCreateTableDef *req, T } static int ctc_ddl_fill_partition_table_info(const dd::Partition *pt, char **mem_start, char *mem_end, - TcDb__CtcDDLPartitionDef *part_def, uint32_t part_id) + TcDb__CtcDDLPartitionDef *part_def, uint32_t part_id) { TcDb__CtcDDLPartitionTableDef *part_table = part_def->part_table_list[part_id]; part_table->name = const_cast(pt->name().data()); part_table->n_subpart_table_list = pt->subpartitions().size(); if (part_table->n_subpart_table_list > 0) { - part_table->subpart_table_list = - (TcDb__CtcDDLPartitionTableDef **)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef *) * pt->subpartitions().size()); + part_table->subpart_table_list = (TcDb__CtcDDLPartitionTableDef **)ctc_ddl_alloc_mem( + mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef *) * pt->subpartitions().size()); if (part_table->subpart_table_list == NULL) { return HA_ERR_OUT_OF_MEM; } TcDb__CtcDDLPartitionTableDef **subpart_table_list = part_table->subpart_table_list; uint32_t i = 0; for (const dd::Partition *sub_part_obj : pt->subpartitions()) { - subpart_table_list[i] = (TcDb__CtcDDLPartitionTableDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef)); + subpart_table_list[i] = + (TcDb__CtcDDLPartitionTableDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef)); if (subpart_table_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1430,11 +1432,12 @@ static int ctc_ddl_fill_partition_table_info(const dd::Partition *pt, char **mem } return 0; } - + static int ctc_ddl_prepare_create_partition_info(TcDb__CtcDDLCreateTableDef *req, const dd::Table *table_def, - char **mem_start, char *mem_end) + char **mem_start, char *mem_end) { - req->partition_def = (TcDb__CtcDDLPartitionDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionDef)); + req->partition_def = + (TcDb__CtcDDLPartitionDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionDef)); if (req->partition_def == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1451,15 +1454,16 @@ static int ctc_ddl_prepare_create_partition_info(TcDb__CtcDDLCreateTableDef *req req->partition_def->n_part_table_list = table_def->partitions().size(); - req->partition_def->part_table_list = - (TcDb__CtcDDLPartitionTableDef **)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef *) * req->partition_def->n_part_table_list); + req->partition_def->part_table_list = (TcDb__CtcDDLPartitionTableDef **)ctc_ddl_alloc_mem( + mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef *) * req->partition_def->n_part_table_list); if (req->partition_def->part_table_list == NULL) { return HA_ERR_OUT_OF_MEM; } TcDb__CtcDDLPartitionTableDef **part_table_list = req->partition_def->part_table_list; uint32_t i = 0; for (const dd::Partition *pt : table_def->partitions()) { - part_table_list[i] = (TcDb__CtcDDLPartitionTableDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef)); + part_table_list[i] = + (TcDb__CtcDDLPartitionTableDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef)); if (part_table_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1468,26 +1472,26 @@ static int ctc_ddl_prepare_create_partition_info(TcDb__CtcDDLCreateTableDef *req CTC_RETURN_IF_NOT_ZERO(ctc_ddl_fill_partition_table_info(pt, mem_start, mem_end, req->partition_def, i)); i++; } - + return 0; } -static int ctc_ddl_init_column_def(TcDb__CtcDDLCreateTableDef *req, char **mem_start, char *mem_end) { - req->columns = (TcDb__CtcDDLColumnDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDef*) * req->n_columns); +static int ctc_ddl_init_column_def(TcDb__CtcDDLCreateTableDef *req, char **mem_start, char *mem_end) +{ + req->columns = + (TcDb__CtcDDLColumnDef **)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDef *) * req->n_columns); if (req->columns == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_columns; i++) { - req->columns[i] = (TcDb__CtcDDLColumnDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDef)); + req->columns[i] = (TcDb__CtcDDLColumnDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDef)); if (req->columns[i] == NULL) { return HA_ERR_OUT_OF_MEM; } tc_db__ctc_ddlcolumn_def__init(req->columns[i]); TcDb__CtcDDLColumnDef *column = req->columns[i]; - column->datatype = (TcDb__CtcDDLColumnDataTypeDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDataTypeDef)); + column->datatype = + (TcDb__CtcDDLColumnDataTypeDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDataTypeDef)); if (column->datatype == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1498,16 +1502,17 @@ static int ctc_ddl_init_column_def(TcDb__CtcDDLCreateTableDef *req, char **mem_s return 0; } -static int ctc_ddl_init_foreign_key_def(TcDb__CtcDDLCreateTableDef *req, const dd::Table *table_def, - char **mem_start, char *mem_end) { - req->fk_list = (TcDb__CtcDDLForeignKeyDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyDef*) * req->n_fk_list); +static int ctc_ddl_init_foreign_key_def(TcDb__CtcDDLCreateTableDef *req, const dd::Table *table_def, char **mem_start, + char *mem_end) +{ + req->fk_list = (TcDb__CtcDDLForeignKeyDef **)ctc_ddl_alloc_mem(mem_start, mem_end, + sizeof(TcDb__CtcDDLForeignKeyDef *) * req->n_fk_list); if (req->fk_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_fk_list; i++) { - req->fk_list[i] = (TcDb__CtcDDLForeignKeyDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyDef)); + req->fk_list[i] = + (TcDb__CtcDDLForeignKeyDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyDef)); if (req->fk_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1516,8 +1521,7 @@ static int ctc_ddl_init_foreign_key_def(TcDb__CtcDDLCreateTableDef *req, const d const dd::Foreign_key *fk = table_def->foreign_keys().at(i); fk_def->n_elements = fk->elements().size(); fk_def->elements = (TcDb__CtcDDLForeignKeyElementDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, - sizeof(TcDb__CtcDDLForeignKeyElementDef*) * fk_def->n_elements); + mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyElementDef *) * fk_def->n_elements); if (fk_def->elements == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1533,16 +1537,16 @@ static int ctc_ddl_init_foreign_key_def(TcDb__CtcDDLCreateTableDef *req, const d return 0; } -static int ctc_ddl_init_index_def(TcDb__CtcDDLCreateTableDef *req, const dd::Table *table_def, - char **mem_start, char *mem_end) { - req->key_list = (TcDb__CtcDDLTableKey **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey*) * req->n_key_list); +static int ctc_ddl_init_index_def(TcDb__CtcDDLCreateTableDef *req, const dd::Table *table_def, char **mem_start, + char *mem_end) +{ + req->key_list = + (TcDb__CtcDDLTableKey **)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey *) * req->n_key_list); if (req->key_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_key_list; i++) { - req->key_list[i] = (TcDb__CtcDDLTableKey *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey)); + req->key_list[i] = (TcDb__CtcDDLTableKey *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey)); if (req->key_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1552,13 +1556,13 @@ static int ctc_ddl_init_index_def(TcDb__CtcDDLCreateTableDef *req, const dd::Tab assert(idx != NULL); req_key->n_columns = idx->elements().size(); req_key->columns = (TcDb__CtcDDLTableKeyPart **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart*) * req_key->n_columns); + mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart *) * req_key->n_columns); if (req_key->columns == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint j = 0; j < req_key->n_columns; j++) { - req_key->columns[j] = (TcDb__CtcDDLTableKeyPart *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart)); + req_key->columns[j] = + (TcDb__CtcDDLTableKeyPart *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart)); if (req_key->columns[j] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1571,14 +1575,12 @@ static int ctc_ddl_init_index_def(TcDb__CtcDDLCreateTableDef *req, const dd::Tab return 0; } -static int ctc_ddl_init_index_form(TcDb__CtcDDLCreateTableDef *req, TABLE *form, - char **mem_start, char *mem_end) { - +static int ctc_ddl_init_index_form(TcDb__CtcDDLCreateTableDef *req, TABLE *form, char **mem_start, char *mem_end) +{ req->n_key_list = form->s->keys; if (req->n_key_list > 0) { - req->key_list = (TcDb__CtcDDLTableKey **)ctc_ddl_alloc_mem( - mem_start, mem_end, - sizeof(TcDb__CtcDDLTableKey*) * req->n_key_list); + req->key_list = (TcDb__CtcDDLTableKey **)ctc_ddl_alloc_mem(mem_start, mem_end, + sizeof(TcDb__CtcDDLTableKey *) * req->n_key_list); if (req->key_list == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1588,8 +1590,7 @@ static int ctc_ddl_init_index_form(TcDb__CtcDDLCreateTableDef *req, TABLE *form, my_error(ER_WRONG_KEY_COLUMN, MYF(0), key->key_part->field->field_name); return ER_WRONG_KEY_COLUMN; } - req->key_list[i] = (TcDb__CtcDDLTableKey *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey)); + req->key_list[i] = (TcDb__CtcDDLTableKey *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey)); if (req->key_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1597,14 +1598,13 @@ static int ctc_ddl_init_index_form(TcDb__CtcDDLCreateTableDef *req, TABLE *form, tc_db__ctc_ddltable_key__init(req_key); req_key->n_columns = key->user_defined_key_parts; req_key->columns = (TcDb__CtcDDLTableKeyPart **)ctc_ddl_alloc_mem( - mem_start, mem_end, - sizeof(TcDb__CtcDDLTableKeyPart*) * req_key->n_columns); + mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart *) * req_key->n_columns); if (req_key->columns == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint j = 0; j < req_key->n_columns; j++) { - req_key->columns[j] = (TcDb__CtcDDLTableKeyPart *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart)); + req_key->columns[j] = + (TcDb__CtcDDLTableKeyPart *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart)); if (req_key->columns[j] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1618,16 +1618,14 @@ static int ctc_ddl_init_index_form(TcDb__CtcDDLCreateTableDef *req, TABLE *form, return 0; } -static int ctc_ddl_init_create_table_def(TcDb__CtcDDLCreateTableDef *req, - TABLE *form, THD *thd, - const dd::Table *table_def, char **mem_start, - char *mem_end) { +static int ctc_ddl_init_create_table_def(TcDb__CtcDDLCreateTableDef *req, TABLE *form, THD *thd, + const dd::Table *table_def, char **mem_start, char *mem_end) +{ uint fields = form->s->fields; tc_db__ctc_ddlcreate_table_def__init(req); DBUG_EXECUTE_IF("ctc_create_table_max_column", { fields = REC_MAX_N_USER_FIELDS + 1; }); if (fields > REC_MAX_N_USER_FIELDS) { - ctc_log_system("Max filed %d > %d, sql:%s", fields, REC_MAX_N_USER_FIELDS, - thd->query().str); + ctc_log_system("Max filed %d > %d, sql:%s", fields, REC_MAX_N_USER_FIELDS, thd->query().str); return HA_ERR_TOO_MANY_FIELDS; } req->n_columns = fields; @@ -1653,7 +1651,8 @@ static int ctc_ddl_init_create_table_def(TcDb__CtcDDLCreateTableDef *req, uint subpart_num_per_part = table_def->leaf_partitions().size() / table_def->partitions().size(); if (subpart_num_per_part > MAX_SUBPART_NUM) { my_printf_error(ER_TOO_MANY_PARTITIONS_ERROR, - "The number of subpartitions of one parent partition exceeds the maximum %d.", MYF(0), MAX_SUBPART_NUM); + "The number of subpartitions of one parent partition exceeds the maximum %d.", MYF(0), + MAX_SUBPART_NUM); return -1; } int ret = ctc_ddl_prepare_create_partition_info(req, table_def, mem_start, mem_end); @@ -1665,7 +1664,8 @@ static int ctc_ddl_init_create_table_def(TcDb__CtcDDLCreateTableDef *req, return 0; } -int ha_ctc_truncate_table(ctc_handler_t *tch, THD *thd, const char *db_name, const char *table_name, bool is_tmp_table) { +int ha_ctc_truncate_table(ctc_handler_t *tch, THD *thd, const char *db_name, const char *table_name, bool is_tmp_table) +{ assert(thd->lex->sql_command == SQLCOM_TRUNCATE); ct_errno_t ret = CT_SUCCESS; @@ -1675,13 +1675,13 @@ int ha_ctc_truncate_table(ctc_handler_t *tch, THD *thd, const char *db_name, con { TcDb__CtcDDLTruncateTableDef req; tc_db__ctc_ddltruncate_table_def__init(&req); - char user_name[SMALL_RECORD_SIZE] = { 0 }; + char user_name[SMALL_RECORD_SIZE] = {0}; ctc_copy_name(user_name, db_name, SMALL_RECORD_SIZE); req.schema = const_cast(user_name); req.name = const_cast(table_name); req.db_name = CTC_GET_THD_DB_NAME(thd); string sql; - if (is_tmp_table) { // truncate临时表不需要广播 + if (is_tmp_table) { // truncate临时表不需要广播 req.sql_str = nullptr; } else { sql = string(thd->query().str).substr(0, thd->query().length); @@ -1713,7 +1713,9 @@ int ha_ctc_truncate_table(ctc_handler_t *tch, THD *thd, const char *db_name, con } static int fill_create_table_req_base_info(HA_CREATE_INFO *create_info, char *db_name, char *table_name, THD *thd, - TcDb__CtcDDLCreateTableDef *req, bool is_alter_copy, char **mem_start, char *mem_end) { + TcDb__CtcDDLCreateTableDef *req, bool is_alter_copy, char **mem_start, + char *mem_end) +{ req->schema = (char *)ctc_ddl_alloc_mem(mem_start, mem_end, SMALL_RECORD_SIZE); if (req->schema == nullptr) { return HA_ERR_OUT_OF_MEM; @@ -1756,8 +1758,10 @@ static int fill_create_table_req_base_info(HA_CREATE_INFO *create_info, char *db return 0; } -static int fill_create_table_req_columns_info(HA_CREATE_INFO *create_info, dd::Table *table_def, TABLE *form, - THD *thd, ddl_ctrl_t *ddl_ctrl, TcDb__CtcDDLCreateTableDef *req, char **mem_start, char *mem_end) { +static int fill_create_table_req_columns_info(HA_CREATE_INFO *create_info, dd::Table *table_def, TABLE *form, THD *thd, + ddl_ctrl_t *ddl_ctrl, TcDb__CtcDDLCreateTableDef *req, char **mem_start, + char *mem_end) +{ uint32_t ctc_col_idx = 0; uint32_t mysql_col_idx = 0; while (ctc_col_idx < req->n_columns) { @@ -1776,9 +1780,9 @@ static int fill_create_table_req_columns_info(HA_CREATE_INFO *create_info, dd::T TcDb__CtcDDLColumnDef *column = req->columns[ctc_col_idx]; const Create_field *fld_charset = ctc_get_create_field_by_column_name(thd, field->field_name); const CHARSET_INFO *field_cs = fld_charset != nullptr ? get_sql_field_charset(fld_charset, create_info) : nullptr; - CTC_RETURN_IF_ERROR( - ctc_ddl_fill_column_by_field(thd, column, field, table_def, form, NULL, CTC_ALTER_COLUMN_ALTER_ADD_COLUMN, - mem_start, mem_end, field_cs), HA_ERR_WRONG_COMMAND); + CTC_RETURN_IF_ERROR(ctc_ddl_fill_column_by_field(thd, column, field, table_def, form, NULL, + CTC_ALTER_COLUMN_ALTER_ADD_COLUMN, mem_start, mem_end, field_cs), + HA_ERR_WRONG_COMMAND); ctc_col_idx++; mysql_col_idx++; } @@ -1793,7 +1797,8 @@ static int fill_create_table_req_columns_info(HA_CREATE_INFO *create_info, dd::T } int fill_create_table_req(HA_CREATE_INFO *create_info, dd::Table *table_def, char *db_name, char *table_name, - TABLE *form, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) { + TABLE *form, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) +{ lock_guard lock(m_ctc_ddl_protobuf_mem_mutex); char *req_mem_start = ctc_ddl_req_mem; char *req_mem_end = req_mem_start + CTC_DDL_PROTOBUF_MEM_SIZE; @@ -1805,21 +1810,22 @@ int fill_create_table_req(HA_CREATE_INFO *create_info, dd::Table *table_def, cha } string sql; - if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { // 创建临时表不需要广播 + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { // 创建临时表不需要广播 req.sql_str = nullptr; } else { sql = string(thd->query().str).substr(0, thd->query().length); req.sql_str = const_cast(sql.c_str()); } - ret = fill_create_table_req_base_info(create_info, db_name, table_name, thd, &req, - ddl_ctrl->is_alter_copy, &req_mem_start, req_mem_end); + ret = fill_create_table_req_base_info(create_info, db_name, table_name, thd, &req, ddl_ctrl->is_alter_copy, + &req_mem_start, req_mem_end); if (ret != 0) { return ret; } - + assert(form->s->row_type == create_info->row_type); - ret = fill_create_table_req_columns_info(create_info, table_def, form, thd, ddl_ctrl, &req, &req_mem_start, req_mem_end); + ret = fill_create_table_req_columns_info(create_info, table_def, form, thd, ddl_ctrl, &req, &req_mem_start, + req_mem_end); if (ret != 0) { return ret; } @@ -1843,9 +1849,8 @@ int fill_create_table_req(HA_CREATE_INFO *create_info, dd::Table *table_def, cha return 0; } - static int ctc_ddl_fill_add_part_table_info(TcDb__CtcDDLPartitionTableDef *add_part, partition_element &part, - char **mem_start, char *mem_end) + char **mem_start, char *mem_end) { int name_len = strlen(part.partition_name); add_part->name = (char *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(char) * (name_len + 1)); @@ -1855,15 +1860,16 @@ static int ctc_ddl_fill_add_part_table_info(TcDb__CtcDDLPartitionTableDef *add_p strncpy(add_part->name, part.partition_name, name_len + 1); add_part->n_subpart_table_list = part.subpartitions.size(); if (part.subpartitions.size() > 0) { - add_part->subpart_table_list = - (TcDb__CtcDDLPartitionTableDef **)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef *) * part.subpartitions.size()); + add_part->subpart_table_list = (TcDb__CtcDDLPartitionTableDef **)ctc_ddl_alloc_mem( + mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef *) * part.subpartitions.size()); if (add_part->subpart_table_list == NULL) { return HA_ERR_OUT_OF_MEM; } TcDb__CtcDDLPartitionTableDef **subpart_table_list = add_part->subpart_table_list; uint32_t i = 0; for (partition_element sub_part_obj : part.subpartitions) { - subpart_table_list[i] = (TcDb__CtcDDLPartitionTableDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef)); + subpart_table_list[i] = + (TcDb__CtcDDLPartitionTableDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef)); if (subpart_table_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1881,7 +1887,8 @@ static int ctc_ddl_fill_add_part_table_info(TcDb__CtcDDLPartitionTableDef *add_p } static int ctc_prepare_alter_partition_init_part_list(TcDb__CtcDDLAlterTableDef *req, Alter_inplace_info *alter_info, - char **mem_start, char *mem_end) { + char **mem_start, char *mem_end) +{ List part_list = alter_info->modified_part_info->partitions; if (part_list.size() > PART_CURSOR_NUM) { my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0)); @@ -1891,16 +1898,16 @@ static int ctc_prepare_alter_partition_init_part_list(TcDb__CtcDDLAlterTableDef if (req->drop_partition_names == NULL) { return HA_ERR_OUT_OF_MEM; } - req->add_part_list = (TcDb__CtcDDLPartitionTableDef **)ctc_ddl_alloc_mem(mem_start, mem_end, - sizeof(TcDb__CtcDDLPartitionTableDef *) * part_list.size()); + req->add_part_list = (TcDb__CtcDDLPartitionTableDef **)ctc_ddl_alloc_mem( + mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef *) * part_list.size()); if (req->add_part_list == NULL) { return HA_ERR_OUT_OF_MEM; } return 0; } -static int ctc_ddl_prepare_alter_partition_info(TcDb__CtcDDLAlterTableDef *req, - Alter_inplace_info *alter_info, char **mem_start, char *mem_end) +static int ctc_ddl_prepare_alter_partition_info(TcDb__CtcDDLAlterTableDef *req, Alter_inplace_info *alter_info, + char **mem_start, char *mem_end) { req->n_drop_partition_names = 0; req->n_add_part_list = 0; @@ -1913,8 +1920,8 @@ static int ctc_ddl_prepare_alter_partition_info(TcDb__CtcDDLAlterTableDef *req, switch (part.part_state) { case PART_TO_BE_DROPPED: { int name_len = strlen(part.partition_name); - req->drop_partition_names[req->n_drop_partition_names] = (char *)ctc_ddl_alloc_mem(mem_start, mem_end, - sizeof(char) * (name_len + 1)); + req->drop_partition_names[req->n_drop_partition_names] = + (char *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(char) * (name_len + 1)); if (req->drop_partition_names[req->n_drop_partition_names] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1923,8 +1930,8 @@ static int ctc_ddl_prepare_alter_partition_info(TcDb__CtcDDLAlterTableDef *req, break; } case PART_TO_BE_ADDED: { - req->add_part_list[req->n_add_part_list] = (TcDb__CtcDDLPartitionTableDef *)ctc_ddl_alloc_mem(mem_start, mem_end, - sizeof(TcDb__CtcDDLPartitionTableDef)); + req->add_part_list[req->n_add_part_list] = (TcDb__CtcDDLPartitionTableDef *)ctc_ddl_alloc_mem( + mem_start, mem_end, sizeof(TcDb__CtcDDLPartitionTableDef)); if (req->add_part_list[req->n_add_part_list] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1942,22 +1949,24 @@ static int ctc_ddl_prepare_alter_partition_info(TcDb__CtcDDLAlterTableDef *req, case PART_NORMAL: break; default: - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "The current operation on a partitioned table is not supported."); + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), + "The current operation on a partitioned table is not supported."); return 1; } } return 0; } -static int init_drop_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) { +static int init_drop_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) +{ req->drop_list = (TcDb__CtcDDLAlterTableDrop **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableDrop*) * req->n_drop_list); + mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableDrop *) * req->n_drop_list); if (req->drop_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_drop_list; i++) { - req->drop_list[i] = (TcDb__CtcDDLAlterTableDrop *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableDrop)); + req->drop_list[i] = + (TcDb__CtcDDLAlterTableDrop *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableDrop)); if (req->drop_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1966,15 +1975,16 @@ static int init_drop_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **me return 0; } -static int init_alter_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) { +static int init_alter_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) +{ req->alter_list = (TcDb__CtcDDLAlterTableAlterColumn **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableAlterColumn*) * req->n_alter_list); + mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableAlterColumn *) * req->n_alter_list); if (req->alter_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_alter_list; i++) { req->alter_list[i] = (TcDb__CtcDDLAlterTableAlterColumn *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableAlterColumn)); + mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableAlterColumn)); if (req->alter_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -1983,22 +1993,22 @@ static int init_alter_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **m return 0; } -static int init_create_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) { - req->create_list = (TcDb__CtcDDLColumnDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDef*) * req->n_create_list); +static int init_create_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) +{ + req->create_list = (TcDb__CtcDDLColumnDef **)ctc_ddl_alloc_mem(mem_start, mem_end, + sizeof(TcDb__CtcDDLColumnDef *) * req->n_create_list); if (req->create_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_create_list; i++) { - req->create_list[i] = (TcDb__CtcDDLColumnDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDef)); + req->create_list[i] = (TcDb__CtcDDLColumnDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDef)); if (req->create_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } tc_db__ctc_ddlcolumn_def__init(req->create_list[i]); TcDb__CtcDDLColumnDef *column = req->create_list[i]; - column->datatype = (TcDb__CtcDDLColumnDataTypeDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDataTypeDef)); + column->datatype = + (TcDb__CtcDDLColumnDataTypeDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLColumnDataTypeDef)); if (column->datatype == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2009,15 +2019,15 @@ static int init_create_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char ** } static int init_add_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, Alter_inplace_info *ha_alter_info, - char **mem_start, char *mem_end) { - req->add_key_list = (TcDb__CtcDDLTableKey **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey*) * req->n_add_key_list); + char **mem_start, char *mem_end) +{ + req->add_key_list = (TcDb__CtcDDLTableKey **)ctc_ddl_alloc_mem(mem_start, mem_end, + sizeof(TcDb__CtcDDLTableKey *) * req->n_add_key_list); if (req->add_key_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_add_key_list; i++) { - req->add_key_list[i] = (TcDb__CtcDDLTableKey *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey)); + req->add_key_list[i] = (TcDb__CtcDDLTableKey *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLTableKey)); if (req->add_key_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2027,13 +2037,13 @@ static int init_add_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, Alter_ assert(key != NULL); req_key->n_columns = key->user_defined_key_parts; req_key->columns = (TcDb__CtcDDLTableKeyPart **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart*) * req_key->n_columns); + mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart *) * req_key->n_columns); if (req_key->columns == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint j = 0; j < req_key->n_columns; j++) { - req_key->columns[j] = (TcDb__CtcDDLTableKeyPart *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart)); + req_key->columns[j] = + (TcDb__CtcDDLTableKeyPart *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLTableKeyPart)); if (req_key->columns[j] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2048,15 +2058,16 @@ static int init_add_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, Alter_ return 0; } -static int init_drop_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) { +static int init_drop_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) +{ req->drop_key_list = (TcDb__CtcDDLAlterTableDropKey **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableDropKey*) * req->n_drop_key_list); + mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableDropKey *) * req->n_drop_key_list); if (req->drop_key_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_drop_key_list; i++) { - req->drop_key_list[i] = (TcDb__CtcDDLAlterTableDropKey *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableDropKey)); + req->drop_key_list[i] = + (TcDb__CtcDDLAlterTableDropKey *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTableDropKey)); if (req->drop_key_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2066,9 +2077,10 @@ static int init_drop_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char } static int init_foreign_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, Alter_inplace_info *ha_alter_info, - char **mem_start, char *mem_end) { + char **mem_start, char *mem_end) +{ req->add_foreign_key_list = (TcDb__CtcDDLForeignKeyDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyDef*) * ha_alter_info->alter_info->key_list.size()); + mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyDef *) * ha_alter_info->alter_info->key_list.size()); if (req->add_foreign_key_list == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2077,8 +2089,8 @@ static int init_foreign_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, Al if (key->type != KEYTYPE_FOREIGN) { continue; } - req->add_foreign_key_list[req->n_add_foreign_key_list] = (TcDb__CtcDDLForeignKeyDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyDef)); + req->add_foreign_key_list[req->n_add_foreign_key_list] = + (TcDb__CtcDDLForeignKeyDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyDef)); if (req->add_foreign_key_list[req->n_add_foreign_key_list] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2087,7 +2099,7 @@ static int init_foreign_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, Al const Foreign_key_spec *fk = down_cast(key); fk_def->n_elements = fk->columns.size(); fk_def->elements = (TcDb__CtcDDLForeignKeyElementDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyElementDef*) * fk_def->n_elements); + mem_start, mem_end, sizeof(TcDb__CtcDDLForeignKeyElementDef *) * fk_def->n_elements); if (fk_def->elements == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2105,15 +2117,16 @@ static int init_foreign_key_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, Al return 0; } -static int init_alter_index_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) { +static int init_alter_index_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, char **mem_start, char *mem_end) +{ req->alter_index_list = (TcDb__CtcDDLAlterIndexDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterIndexDef) * req->n_alter_index_list); + mem_start, mem_end, sizeof(TcDb__CtcDDLAlterIndexDef) * req->n_alter_index_list); if (req->alter_index_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_alter_index_list; i++) { - req->alter_index_list[i] = (TcDb__CtcDDLAlterIndexDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterIndexDef)); + req->alter_index_list[i] = + (TcDb__CtcDDLAlterIndexDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLAlterIndexDef)); if (req->alter_index_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2122,14 +2135,14 @@ static int init_alter_index_list_4alter_table(TcDb__CtcDDLAlterTableDef *req, ch return 0; } -static int init_ctc_ddl_alter_table_def(TcDb__CtcDDLAlterTableDef *req, Alter_inplace_info *ha_alter_info, - THD *thd, TABLE *altered_table, char **mem_start, char *mem_end, size_t *rename_cols) { +static int init_ctc_ddl_alter_table_def(TcDb__CtcDDLAlterTableDef *req, Alter_inplace_info *ha_alter_info, THD *thd, + TABLE *altered_table, char **mem_start, char *mem_end, size_t *rename_cols) +{ tc_db__ctc_ddlalter_table_def__init(req); uint32_t create_fields = (uint32_t)ha_alter_info->alter_info->create_list.size(); DBUG_EXECUTE_IF("ctc_alter_table_max_column", { create_fields = REC_MAX_N_USER_FIELDS + 1; }); if (create_fields > REC_MAX_N_USER_FIELDS) { - ctc_log_system("Max filed %d > %u, sql:%s", (uint32_t)create_fields, - REC_MAX_N_USER_FIELDS, thd->query().str); + ctc_log_system("Max filed %d > %u, sql:%s", (uint32_t)create_fields, REC_MAX_N_USER_FIELDS, thd->query().str); my_error(ER_TOO_MANY_FIELDS, MYF(0)); return HA_ERR_TOO_MANY_FIELDS; } @@ -2150,12 +2163,11 @@ static int init_ctc_ddl_alter_table_def(TcDb__CtcDDLAlterTableDef *req, Alter_in if (ha_alter_info->modified_part_info != NULL) { CTC_RETURN_IF_NOT_ZERO(ctc_ddl_prepare_alter_partition_info(req, ha_alter_info, mem_start, mem_end)); } - + if (req->n_drop_list > 0) { CTC_RETURN_IF_NOT_ZERO(init_drop_list_4alter_table(req, mem_start, mem_end)); } - if (req->n_alter_list > 0) { CTC_RETURN_IF_NOT_ZERO(init_alter_list_4alter_table(req, mem_start, mem_end)); } @@ -2164,8 +2176,8 @@ static int init_ctc_ddl_alter_table_def(TcDb__CtcDDLAlterTableDef *req, Alter_in CTC_RETURN_IF_NOT_ZERO(init_create_list_4alter_table(req, mem_start, mem_end)); } - req->table_def = (TcDb__CtcDDLAlterTablePorp *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTablePorp)); + req->table_def = + (TcDb__CtcDDLAlterTablePorp *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLAlterTablePorp)); if (req->table_def == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2173,7 +2185,7 @@ static int init_ctc_ddl_alter_table_def(TcDb__CtcDDLAlterTableDef *req, Alter_in // 添加索引 if ((ha_alter_info->handler_flags & Alter_inplace_info::ADD_STORED_BASE_COLUMN) && - thd->lex->sql_command == SQLCOM_ALTER_TABLE) { + thd->lex->sql_command == SQLCOM_ALTER_TABLE) { req->n_add_key_list = 0; } if (req->n_add_key_list > 0) { @@ -2191,9 +2203,9 @@ static int init_ctc_ddl_alter_table_def(TcDb__CtcDDLAlterTableDef *req, Alter_in } // 自增 - if ((altered_table->found_next_number_field != nullptr) - && (ha_alter_info->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) - && (ha_alter_info->create_info->used_fields & HA_CREATE_USED_AUTO)) { + if ((altered_table->found_next_number_field != nullptr) && + (ha_alter_info->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) && + (ha_alter_info->create_info->used_fields & HA_CREATE_USED_AUTO)) { req->new_auto_increment_value = ha_alter_info->create_info->auto_increment_value; } @@ -2211,8 +2223,8 @@ static int init_ctc_ddl_alter_table_def(TcDb__CtcDDLAlterTableDef *req, Alter_in @param idx Field index. */ -static const Create_field *get_field_by_index(Alter_info *alter_info, - uint idx) { +static const Create_field *get_field_by_index(Alter_info *alter_info, uint idx) +{ List_iterator_fast field_it(alter_info->create_list); uint field_idx = 0; const Create_field *field = NULL; @@ -2224,23 +2236,21 @@ static const Create_field *get_field_by_index(Alter_info *alter_info, return field; } -static uint32_t ctc_fill_key_part(THD *thd, - TcDb__CtcDDLTableKeyPart *req_key_part, - TcDb__CtcDDLTableKey *req_key_def, - const Create_field *create_field, - TABLE *form, - const KEY_PART_INFO *key_part) { +static uint32_t ctc_fill_key_part(THD *thd, TcDb__CtcDDLTableKeyPart *req_key_part, TcDb__CtcDDLTableKey *req_key_def, + const Create_field *create_field, TABLE *form, const KEY_PART_INFO *key_part) +{ Field *field = ctc_get_field_by_name(form, create_field->field_name); assert(field != nullptr); bool is_prefix_key = false; if (field->is_field_for_functional_index()) { req_key_def->is_func = true; - CTC_RETURN_IF_ERROR(ctc_fill_func_key_part(form, thd, req_key_part, create_field->gcol_info) == CT_SUCCESS, CT_ERROR); + CTC_RETURN_IF_ERROR(ctc_fill_func_key_part(form, thd, req_key_part, create_field->gcol_info) == CT_SUCCESS, + CT_ERROR); } else { if (field->is_virtual_gcol()) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Cantian does not support index on virtual generated column."); + "Cantian does not support index on virtual generated column."); return CT_ERROR; } @@ -2261,12 +2271,12 @@ static uint32_t ctc_fill_key_part(THD *thd, req_key_part->datatype = CTC_DDL_TYPE_VARCHAR; } req_key_part->length = (uint32_t)create_field->key_length(); - + return CT_SUCCESS; } -bool ctc_ddl_fill_add_key(THD *thd, TABLE *form, TcDb__CtcDDLAlterTableDef *req, - Alter_inplace_info *ha_alter_info, char *user) +bool ctc_ddl_fill_add_key(THD *thd, TABLE *form, TcDb__CtcDDLAlterTableDef *req, Alter_inplace_info *ha_alter_info, + char *user) { for (uint i = 0; i < req->n_add_key_list; i++) { TcDb__CtcDDLTableKey *req_key_def = req->add_key_list[i]; @@ -2279,7 +2289,7 @@ bool ctc_ddl_fill_add_key(THD *thd, TABLE *form, TcDb__CtcDDLAlterTableDef *req, req_key_def->space = NULL; CTC_RETURN_IF_ERROR(get_ctc_key_type(key, &req_key_def->key_type), false); if (req_key_def->key_type == CTC_KEYTYPE_PRIMARY || req_key_def->key_type == CTC_KEYTYPE_UNIQUE) { - req_key_def->is_constraint = true; + req_key_def->is_constraint = true; } CTC_RETURN_IF_ERROR(get_ctc_key_algorithm(key->algorithm, &req_key_def->algorithm), false); for (uint j = 0; j < req_key_def->n_columns; j++) { @@ -2288,16 +2298,14 @@ bool ctc_ddl_fill_add_key(THD *thd, TABLE *form, TcDb__CtcDDLAlterTableDef *req, const Create_field *create_field = get_field_by_index(ha_alter_info->alter_info, key_part->fieldnr); assert(create_field != NULL); CTC_RETURN_IF_ERROR( - (ctc_fill_key_part(thd, req_key_part, req_key_def, create_field, form, - key_part) == CT_SUCCESS), - false); + (ctc_fill_key_part(thd, req_key_part, req_key_def, create_field, form, key_part) == CT_SUCCESS), false); } } return true; } static int ctc_ddl_fill_drop_key(Alter_inplace_info *ha_alter_info, const dd::Table *old_table_def, - TcDb__CtcDDLAlterTableDef *req) + TcDb__CtcDDLAlterTableDef *req) { for (uint ctc_drop_key_idx = 0; ctc_drop_key_idx < req->n_drop_key_list; ctc_drop_key_idx++) { TcDb__CtcDDLAlterTableDropKey *req_drop = req->drop_key_list[ctc_drop_key_idx]; @@ -2309,12 +2317,12 @@ static int ctc_ddl_fill_drop_key(Alter_inplace_info *ha_alter_info, const dd::Ta assert(idx != nullptr); CTC_RETURN_IF_ERROR(ctc_ddl_get_create_key_type(idx->type(), &req_drop->key_type), CT_ERROR); } - + return CT_SUCCESS; } static int fill_ctc_alter_drop_list(Alter_inplace_info *ha_alter_info, const dd::Table *old_table_def, - TcDb__CtcDDLAlterTableDef *req) + TcDb__CtcDDLAlterTableDef *req) { uint32_t ctc_drop_idx = 0; uint32_t mysql_drop_idx = 0; @@ -2347,7 +2355,8 @@ static int fill_ctc_alter_drop_list(Alter_inplace_info *ha_alter_info, const dd: } static int fill_ctc_alter_create_list(THD *thd, TABLE *altered_table, Alter_inplace_info *ha_alter_info, - dd::Table *new_table_def, TcDb__CtcDDLAlterTableDef *req, ddl_ctrl_t *ddl_ctrl, char **mem_start, char *mem_end) + dd::Table *new_table_def, TcDb__CtcDDLAlterTableDef *req, ddl_ctrl_t *ddl_ctrl, + char **mem_start, char *mem_end) { uint32_t ctc_col_idx = 0; uint32_t mysql_col_idx = 0; @@ -2363,8 +2372,7 @@ static int fill_ctc_alter_create_list(THD *thd, TABLE *altered_table, Alter_inpl mysql_col_idx++; continue; } else { - my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), - "Cantian does not support stored generated column."); + my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "Cantian does not support stored generated column."); return HA_ERR_WRONG_COMMAND; } } @@ -2378,13 +2386,14 @@ static int fill_ctc_alter_create_list(THD *thd, TABLE *altered_table, Alter_inpl } const CHARSET_INFO *field_cs = get_sql_field_charset(fld, ha_alter_info->create_info); CTC_RETURN_IF_ERROR(ctc_ddl_fill_column_by_field(thd, req_create_column, altered_table->s->field[mysql_col_idx], - ((const dd::Table *)new_table_def), altered_table, fld, alter_mode, mem_start, mem_end, field_cs), + ((const dd::Table *)new_table_def), altered_table, fld, alter_mode, + mem_start, mem_end, field_cs), CT_ERROR); ctc_col_idx++; mysql_col_idx++; } - //prevent only virtual columns + // prevent only virtual columns if (req->n_create_list == 0) { my_printf_error(ER_DISALLOWED_OPERATION, "%s", MYF(0), "Cantian does not support all columns are generated."); return HA_ERR_WRONG_COMMAND; @@ -2393,7 +2402,8 @@ static int fill_ctc_alter_create_list(THD *thd, TABLE *altered_table, Alter_inpl return CT_SUCCESS; } -static void fill_sys_cur_timestamp(THD *thd, TcDb__CtcDDLAlterTableDef *req) { +static void fill_sys_cur_timestamp(THD *thd, TcDb__CtcDDLAlterTableDef *req) +{ date_detail_t date_detail; MYSQL_TIME ltime; #ifdef FEATURE_X_FOR_MYSQL_32 @@ -2415,12 +2425,14 @@ static void fill_sys_cur_timestamp(THD *thd, TcDb__CtcDDLAlterTableDef *req) { } static void fill_alter_list_4alter_table(dd::Table *new_table_def, Alter_inplace_info *ha_alter_info, - TcDb__CtcDDLAlterTableDef *req, size_t rename_cols, uint32_t thd_id, char **req_mem_start, char *req_mem_end) { + TcDb__CtcDDLAlterTableDef *req, size_t rename_cols, uint32_t thd_id, + char **req_mem_start, char *req_mem_end) +{ TcDb__CtcDDLAlterTableAlterColumn *req_alter = NULL; uint32_t copy_rm_num = 0; for (uint32_t i = 0; i < req->n_alter_list - rename_cols; i++) { req_alter = req->alter_list[i]; - + const Alter_column *alter_column = ha_alter_info->alter_info->alter_list.at((size_t)i); if (alter_column->change_type() == Alter_column::Type::SET_DEFAULT || alter_column->change_type() == Alter_column::Type::DROP_DEFAULT || @@ -2450,7 +2462,8 @@ static void fill_alter_list_4alter_table(dd::Table *new_table_def, Alter_inplace } int fill_alter_table_req(TABLE *altered_table, Alter_inplace_info *ha_alter_info, const dd::Table *old_table_def, - dd::Table *new_table_def, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) { + dd::Table *new_table_def, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) +{ lock_guard lock(m_ctc_ddl_protobuf_mem_mutex); TcDb__CtcDDLAlterTableDef req; @@ -2458,8 +2471,8 @@ int fill_alter_table_req(TABLE *altered_table, Alter_inplace_info *ha_alter_info char *req_mem_end = req_mem_start + CTC_DDL_PROTOBUF_MEM_SIZE; size_t rename_cols = 0; - CTC_RETURN_IF_NOT_ZERO(init_ctc_ddl_alter_table_def(&req, ha_alter_info, thd, - altered_table, &req_mem_start, req_mem_end, &rename_cols)); + CTC_RETURN_IF_NOT_ZERO( + init_ctc_ddl_alter_table_def(&req, ha_alter_info, thd, altered_table, &req_mem_start, req_mem_end, &rename_cols)); assert(req_mem_start <= req_mem_end); char user_name_str[SMALL_RECORD_SIZE]; @@ -2473,25 +2486,24 @@ int fill_alter_table_req(TABLE *altered_table, Alter_inplace_info *ha_alter_info fill_sys_cur_timestamp(thd, &req); CTC_RETURN_IF_ERROR((fill_ctc_alter_drop_list(ha_alter_info, old_table_def, &req) == CT_SUCCESS), CT_ERROR); if (thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS) { - req.options |= CTC_CREATE_TYPE_NO_CHECK_CONS; + req.options |= CTC_CREATE_TYPE_NO_CHECK_CONS; } // 删除索引相关逻辑填充 if (ha_alter_info->index_drop_count) { - assert(ha_alter_info->handler_flags & - (Alter_inplace_info::DROP_INDEX | - Alter_inplace_info::DROP_UNIQUE_INDEX | - Alter_inplace_info::DROP_PK_INDEX)); + assert(ha_alter_info->handler_flags & (Alter_inplace_info::DROP_INDEX | Alter_inplace_info::DROP_UNIQUE_INDEX | + Alter_inplace_info::DROP_PK_INDEX)); CTC_RETURN_IF_ERROR((ctc_ddl_fill_drop_key(ha_alter_info, old_table_def, &req) == CT_SUCCESS), CT_ERROR); } - + if (req.n_alter_list > 0) { - fill_alter_list_4alter_table(new_table_def, ha_alter_info, &req, - rename_cols, ddl_ctrl->tch.thd_id, &req_mem_start, req_mem_end); + fill_alter_list_4alter_table(new_table_def, ha_alter_info, &req, rename_cols, ddl_ctrl->tch.thd_id, &req_mem_start, + req_mem_end); } - CTC_RETURN_IF_ERROR((fill_ctc_alter_create_list(thd, altered_table, ha_alter_info, - new_table_def, &req, ddl_ctrl, &req_mem_start, req_mem_end) == CT_SUCCESS), CT_ERROR); + CTC_RETURN_IF_ERROR((fill_ctc_alter_create_list(thd, altered_table, ha_alter_info, new_table_def, &req, ddl_ctrl, + &req_mem_start, req_mem_end) == CT_SUCCESS), + CT_ERROR); // 创建索引相关逻辑填充 CTC_RETURN_IF_ERROR(ctc_ddl_fill_add_key(thd, altered_table, &req, ha_alter_info, req.user), true); @@ -2499,13 +2511,14 @@ int fill_alter_table_req(TABLE *altered_table, Alter_inplace_info *ha_alter_info // rename索引 for (uint32_t i = 0; i < req.n_alter_index_list; ++i) { - TcDb__CtcDDLAlterIndexDef *req_alter_index_def = req.alter_index_list[i]; + TcDb__CtcDDLAlterIndexDef *req_alter_index_def = req.alter_index_list[i]; - req_alter_index_def->user = user_name_str; - req_alter_index_def->table = const_cast(thd->lex->query_tables->table_name); - req_alter_index_def->name = const_cast(ha_alter_info->index_rename_buffer[i].old_key->name); - req_alter_index_def->new_name = const_cast(ha_alter_info->index_rename_buffer[i].new_key->name); - CTC_RETURN_IF_ERROR(get_ctc_key_type(ha_alter_info->index_rename_buffer[i].old_key, &req_alter_index_def->key_type), true); + req_alter_index_def->user = user_name_str; + req_alter_index_def->table = const_cast(thd->lex->query_tables->table_name); + req_alter_index_def->name = const_cast(ha_alter_info->index_rename_buffer[i].old_key->name); + req_alter_index_def->new_name = const_cast(ha_alter_info->index_rename_buffer[i].new_key->name); + CTC_RETURN_IF_ERROR(get_ctc_key_type(ha_alter_info->index_rename_buffer[i].old_key, &req_alter_index_def->key_type), + true); } req.db_name = CTC_GET_THD_DB_NAME(thd); string sql = string(thd->query().str).substr(0, thd->query().length); @@ -2514,7 +2527,7 @@ int fill_alter_table_req(TABLE *altered_table, Alter_inplace_info *ha_alter_info size_t msg_len = tc_db__ctc_ddlalter_table_def__get_packed_size(&req); stack_mem->set_mem_size(msg_len + sizeof(ddl_ctrl_t)); void *ctc_ddl_req_msg_mem = stack_mem->get_buf(); - if(ctc_ddl_req_msg_mem == nullptr) { + if (ctc_ddl_req_msg_mem == nullptr) { return HA_ERR_OUT_OF_MEM; } @@ -2528,11 +2541,12 @@ int fill_alter_table_req(TABLE *altered_table, Alter_inplace_info *ha_alter_info } static void ctc_fill_rename_constraints(TcDb__CtcDDLRenameTableDef *req, const char *old_cons_name, - const char *new_cons_name, char **mem_start, char *mem_end) { - req->old_constraints_name[req->n_old_constraints_name] = (char *)ctc_ddl_alloc_mem(mem_start, mem_end, - sizeof(char) * (strlen(old_cons_name) + 1)); - req->new_constraints_name[req->n_new_constraints_name] = (char *)ctc_ddl_alloc_mem(mem_start, mem_end, - sizeof(char) * (strlen(new_cons_name) + 1)); + const char *new_cons_name, char **mem_start, char *mem_end) +{ + req->old_constraints_name[req->n_old_constraints_name] = + (char *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(char) * (strlen(old_cons_name) + 1)); + req->new_constraints_name[req->n_new_constraints_name] = + (char *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(char) * (strlen(new_cons_name) + 1)); assert(req->old_constraints_name[req->n_old_constraints_name] != NULL); assert(req->new_constraints_name[req->n_new_constraints_name] != NULL); strcpy(req->old_constraints_name[req->n_old_constraints_name], old_cons_name); @@ -2540,7 +2554,9 @@ static void ctc_fill_rename_constraints(TcDb__CtcDDLRenameTableDef *req, const c } static int init_ctc_ddl_rename_constraints_def(THD *thd, TcDb__CtcDDLRenameTableDef *req, - const dd::Table *from_table_def, dd::Table *to_table_def, char **mem_start, char *mem_end) { + const dd::Table *from_table_def, dd::Table *to_table_def, + char **mem_start, char *mem_end) +{ size_t constraint_size = from_table_def->foreign_keys().size(); handlerton *ctc_handlerton = get_ctc_hton(); size_t generated_cons = 0; // The number of default constraints @@ -2550,13 +2566,11 @@ static int init_ctc_ddl_rename_constraints_def(THD *thd, TcDb__CtcDDLRenameTable return 0; } - const char *from_tbl_name = is_alter_copy ? thd->lex->query_tables->table_name : - from_table_def->name().c_str(); - size_t tbl_name_length = is_alter_copy ? strlen(thd->lex->query_tables->table_name) : - from_table_def->name().length(); - bool is_rename_table = ((thd->lex->sql_command == SQLCOM_RENAME_TABLE) || // sql_command - (from_table_def->tablespace_id() != to_table_def->tablespace_id()) || // copy rename cross db - (strcmp(from_tbl_name, to_table_def->name().c_str()) != 0)); // alter copy(如指定) + const char *from_tbl_name = is_alter_copy ? thd->lex->query_tables->table_name : from_table_def->name().c_str(); + size_t tbl_name_length = is_alter_copy ? strlen(thd->lex->query_tables->table_name) : from_table_def->name().length(); + bool is_rename_table = ((thd->lex->sql_command == SQLCOM_RENAME_TABLE) || // sql_command + (from_table_def->tablespace_id() != to_table_def->tablespace_id()) || // copy rename cross db + (strcmp(from_tbl_name, to_table_def->name().c_str()) != 0)); // alter copy(如指定) for (const dd::Foreign_key *fk : from_table_def->foreign_keys()) { bool is_generated_name = dd::is_generated_foreign_key_name(from_tbl_name, tbl_name_length, ctc_handlerton, *fk); if (is_generated_name && is_rename_table) { @@ -2573,10 +2587,10 @@ static int init_ctc_ddl_rename_constraints_def(THD *thd, TcDb__CtcDDLRenameTable for (const dd::Foreign_key *fk : from_table_def->foreign_keys()) { bool is_generated_name = dd::is_generated_foreign_key_name(from_tbl_name, tbl_name_length, ctc_handlerton, *fk); if (is_generated_name && is_rename_table) { - char new_fk_name[CTC_MAX_CONS_NAME_LEN + 1]; + char new_fk_name[CTC_MAX_CONS_NAME_LEN + 1]; // Construct new name by copying suffix from the old one. - strxnmov(new_fk_name, sizeof(new_fk_name) - 1, to_table_def->name().c_str(), - fk->name().c_str() + tbl_name_length, NullS); + strxnmov(new_fk_name, sizeof(new_fk_name) - 1, to_table_def->name().c_str(), fk->name().c_str() + tbl_name_length, + NullS); ctc_fill_rename_constraints(req, fk->name().c_str(), new_fk_name, mem_start, mem_end); req->n_old_constraints_name++; req->n_new_constraints_name++; @@ -2586,17 +2600,18 @@ static int init_ctc_ddl_rename_constraints_def(THD *thd, TcDb__CtcDDLRenameTable return 0; } -int fill_rename_table_req(const char *from, const char *to, const dd::Table *from_table_def, - dd::Table *to_table_def, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) { - char old_db[SMALL_RECORD_SIZE] = { 0 }; - char new_db[SMALL_RECORD_SIZE] = { 0 }; - char user_name[SMALL_RECORD_SIZE] = { 0 }; - char new_user_name[SMALL_RECORD_SIZE] = { 0 }; +int fill_rename_table_req(const char *from, const char *to, const dd::Table *from_table_def, dd::Table *to_table_def, + THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) +{ + char old_db[SMALL_RECORD_SIZE] = {0}; + char new_db[SMALL_RECORD_SIZE] = {0}; + char user_name[SMALL_RECORD_SIZE] = {0}; + char new_user_name[SMALL_RECORD_SIZE] = {0}; ctc_split_normalized_name(from, old_db, SMALL_RECORD_SIZE, nullptr, 0, nullptr); ctc_split_normalized_name(to, new_db, SMALL_RECORD_SIZE, nullptr, 0, nullptr); ctc_copy_name(user_name, old_db, SMALL_RECORD_SIZE); ctc_copy_name(new_user_name, new_db, SMALL_RECORD_SIZE); - + char *req_mem_start = ctc_ddl_req_mem; char *req_mem_end = req_mem_start + CTC_DDL_PROTOBUF_MEM_SIZE; TcDb__CtcDDLRenameTableDef req; @@ -2621,7 +2636,7 @@ int fill_rename_table_req(const char *from, const char *to, const dd::Table *fro size_t msg_len = tc_db__ctc_ddlrename_table_def__get_packed_size(&req); stack_mem->set_mem_size(msg_len + sizeof(ddl_ctrl_t)); void *ctc_ddl_req_msg_mem = stack_mem->get_buf(); - if(ctc_ddl_req_msg_mem == nullptr) { + if (ctc_ddl_req_msg_mem == nullptr) { return HA_ERR_OUT_OF_MEM; } @@ -2634,18 +2649,19 @@ int fill_rename_table_req(const char *from, const char *to, const dd::Table *fro } static int fill_partition_info_4truncate(TcDb__CtcDDLTruncateTablePartitionDef *req, dd::Table *dd_table, - partition_info *part_info, char **mem_start, char *mem_end) { + partition_info *part_info, char **mem_start, char *mem_end) +{ uint32_t part_num = 0; if (part_info->is_sub_partitioned()) { req->n_subpartition_id = 0; - req->subpartition_id = (uint32_t *)ctc_ddl_alloc_mem( - mem_start, mem_end, dd_table->leaf_partitions()->size() * sizeof(uint32_t)); + req->subpartition_id = + (uint32_t *)ctc_ddl_alloc_mem(mem_start, mem_end, dd_table->leaf_partitions()->size() * sizeof(uint32_t)); if (req->subpartition_id == nullptr) { return HA_ERR_OUT_OF_MEM; } req->n_subpartition_name = 0; - req->subpartition_name = (char **)ctc_ddl_alloc_mem( - mem_start, mem_end, dd_table->leaf_partitions()->size() * sizeof(char *)); + req->subpartition_name = + (char **)ctc_ddl_alloc_mem(mem_start, mem_end, dd_table->leaf_partitions()->size() * sizeof(char *)); if (req->subpartition_name == nullptr) { return HA_ERR_OUT_OF_MEM; } @@ -2679,13 +2695,14 @@ static int fill_partition_info_4truncate(TcDb__CtcDDLTruncateTablePartitionDef * return 0; } -int fill_truncate_partition_req(const char *full_name, partition_info *part_info, - dd::Table *dd_table, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) { +int fill_truncate_partition_req(const char *full_name, partition_info *part_info, dd::Table *dd_table, THD *thd, + ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) +{ lock_guard lock(m_ctc_ddl_protobuf_mem_mutex); char *req_mem_start = ctc_ddl_req_mem; char *req_mem_end = req_mem_start + CTC_DDL_PROTOBUF_MEM_SIZE; - char db_name[SMALL_RECORD_SIZE] = { 0 }; - char user_name[SMALL_RECORD_SIZE] = { 0 }; + char db_name[SMALL_RECORD_SIZE] = {0}; + char user_name[SMALL_RECORD_SIZE] = {0}; const char *table_name_str = dd_table->name().c_str(); ctc_split_normalized_name(full_name, db_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); ctc_copy_name(user_name, db_name, SMALL_RECORD_SIZE); @@ -2698,29 +2715,28 @@ int fill_truncate_partition_req(const char *full_name, partition_info *part_info req.sql_str = const_cast(sql.c_str()); req.n_partition_id = 0; - req.partition_id = (uint32_t *)ctc_ddl_alloc_mem( - &req_mem_start, req_mem_end, dd_table->leaf_partitions()->size() * sizeof(uint32_t)); + req.partition_id = (uint32_t *)ctc_ddl_alloc_mem(&req_mem_start, req_mem_end, + dd_table->leaf_partitions()->size() * sizeof(uint32_t)); if (req.partition_id == nullptr) { return HA_ERR_OUT_OF_MEM; } req.n_partition_name = 0; - req.partition_name = (char **)ctc_ddl_alloc_mem( - &req_mem_start, req_mem_end, dd_table->leaf_partitions()->size() * sizeof(char *)); + req.partition_name = + (char **)ctc_ddl_alloc_mem(&req_mem_start, req_mem_end, dd_table->leaf_partitions()->size() * sizeof(char *)); if (req.partition_name == nullptr) { return HA_ERR_OUT_OF_MEM; } - CTC_RETURN_IF_NOT_ZERO(fill_partition_info_4truncate(&req, dd_table, - part_info, &req_mem_start, req_mem_end)); + CTC_RETURN_IF_NOT_ZERO(fill_partition_info_4truncate(&req, dd_table, part_info, &req_mem_start, req_mem_end)); size_t msg_len = tc_db__ctc_ddltruncate_table_partition_def__get_packed_size(&req); stack_mem->set_mem_size(msg_len + sizeof(ddl_ctrl_t)); void *ctc_ddl_req_msg_mem = stack_mem->get_buf(); - if(ctc_ddl_req_msg_mem == nullptr) { + if (ctc_ddl_req_msg_mem == nullptr) { return HA_ERR_OUT_OF_MEM; } - if (tc_db__ctc_ddltruncate_table_partition_def__pack(&req, (uint8_t *)ctc_ddl_req_msg_mem + sizeof(ddl_ctrl_t)) - != msg_len) { + if (tc_db__ctc_ddltruncate_table_partition_def__pack(&req, (uint8_t *)ctc_ddl_req_msg_mem + sizeof(ddl_ctrl_t)) != + msg_len) { assert(false); } @@ -2729,18 +2745,19 @@ int fill_truncate_partition_req(const char *full_name, partition_info *part_info return 0; } -int init_ctc_optimize_table_def(TcDb__CtcDDLAlterTableDef *req, TABLE *table, char **mem_start, char *mem_end) { +int init_ctc_optimize_table_def(TcDb__CtcDDLAlterTableDef *req, TABLE *table, char **mem_start, char *mem_end) +{ tc_db__ctc_ddlalter_table_def__init(req); req->n_alter_index_list = table->s->keys; if (req->n_alter_index_list > 0) { req->alter_index_list = (TcDb__CtcDDLAlterIndexDef **)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterIndexDef) * req->n_alter_index_list); + mem_start, mem_end, sizeof(TcDb__CtcDDLAlterIndexDef) * req->n_alter_index_list); if (req->alter_index_list == NULL) { return HA_ERR_OUT_OF_MEM; } for (uint i = 0; i < req->n_alter_index_list; i++) { - req->alter_index_list[i] = (TcDb__CtcDDLAlterIndexDef *)ctc_ddl_alloc_mem( - mem_start, mem_end, sizeof(TcDb__CtcDDLAlterIndexDef)); + req->alter_index_list[i] = + (TcDb__CtcDDLAlterIndexDef *)ctc_ddl_alloc_mem(mem_start, mem_end, sizeof(TcDb__CtcDDLAlterIndexDef)); if (req->alter_index_list[i] == NULL) { return HA_ERR_OUT_OF_MEM; } @@ -2750,14 +2767,15 @@ int init_ctc_optimize_table_def(TcDb__CtcDDLAlterTableDef *req, TABLE *table, ch return 0; } -int fill_rebuild_index_req(TABLE *table, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) { +int fill_rebuild_index_req(TABLE *table, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl_stack_mem *stack_mem) +{ int ret; lock_guard lock(m_ctc_ddl_protobuf_mem_mutex); TcDb__CtcDDLAlterTableDef req; char *req_mem_start = ctc_ddl_req_mem; char *req_mem_end = req_mem_start + CTC_DDL_PROTOBUF_MEM_SIZE; - char db_name[SMALL_RECORD_SIZE] = { 0 }; - char table_name[SMALL_RECORD_SIZE] = { 0 }; + char db_name[SMALL_RECORD_SIZE] = {0}; + char table_name[SMALL_RECORD_SIZE] = {0}; ctc_copy_name(db_name, thd->lex->query_tables->get_db_name(), SMALL_RECORD_SIZE); ctc_copy_name(table_name, thd->lex->query_tables->table_name, SMALL_RECORD_SIZE); @@ -2773,7 +2791,7 @@ int fill_rebuild_index_req(TABLE *table, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl TcDb__CtcDDLAlterIndexDef *req_alter_index_def = req.alter_index_list[i]; req_alter_index_def->user = db_name; req_alter_index_def->table = table_name; - req_alter_index_def->name = const_cast (table->key_info[i].name); + req_alter_index_def->name = const_cast(table->key_info[i].name); } req.db_name = CTC_GET_THD_DB_NAME(thd); string sql = string(thd->query().str).substr(0, thd->query().length); @@ -2781,7 +2799,7 @@ int fill_rebuild_index_req(TABLE *table, THD *thd, ddl_ctrl_t *ddl_ctrl, ctc_ddl size_t msg_len = tc_db__ctc_ddlalter_table_def__get_packed_size(&req); stack_mem->set_mem_size(msg_len + sizeof(ddl_ctrl_t)); void *ctc_ddl_req_msg_mem = stack_mem->get_buf(); - if(ctc_ddl_req_msg_mem == nullptr) { + if (ctc_ddl_req_msg_mem == nullptr) { return HA_ERR_OUT_OF_MEM; } diff --git a/storage/ctc/ha_ctcpart.cc b/storage/ctc/ha_ctcpart.cc index aef0003..3764aa1 100644 --- a/storage/ctc/ha_ctcpart.cc +++ b/storage/ctc/ha_ctcpart.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -20,10 +20,10 @@ // this module should use ctc_part_srv rather than knl_intf #include "ha_ctcpart.h" -#include "ha_ctc_ddl.h" #include #include #include +#include "ha_ctc_ddl.h" #include #include @@ -31,6 +31,9 @@ #include #include #include +#include "ctc_cbo.h" +#include "ctc_error.h" +#include "ctc_log.h" #include "field_types.h" #include "my_base.h" #include "my_dbug.h" @@ -39,23 +42,19 @@ #include "my_psi_config.h" #include "mysql/plugin.h" #include "sql/current_thd.h" +#include "sql/dd/properties.h" +#include "sql/dd/string_type.h" +#include "sql/dd/types/partition.h" #include "sql/dd/types/table.h" #include "sql/field.h" +#include "sql/partition_info.h" +#include "sql/sql_alter.h" #include "sql/sql_base.h" // enum_tdc_remove_table_type #include "sql/sql_class.h" #include "sql/sql_lex.h" #include "sql/sql_plugin.h" -#include "sql/partition_info.h" -#include "ctc_error.h" -#include "ctc_log.h" #include "srv_mq_msg.h" -#include #include "typelib.h" -#include "ctc_cbo.h" -#include "sql/sql_alter.h" -#include "sql/dd/properties.h" -#include "sql/dd/types/partition.h" -#include "sql/dd/string_type.h" #define INVALID_PART_ID (uint32)0xFFFFFFFF; @@ -65,22 +64,25 @@ extern uint32_t ctc_update_analyze_time; constexpr uint64 INVALID_VALUE64 = 0xFFFFFFFFFFFFFFFFULL; constexpr int max_prefetch_num = MAX_PREFETCH_REC_NUM; -static uint32_t get_ct_sub_no(uint num_subparts, uint part_id) { +static uint32_t get_ct_sub_no(uint num_subparts, uint part_id) +{ uint sub_no = part_id % num_subparts; return (uint32_t)sub_no; } -static uint32_t get_ct_part_no(uint num_subparts, uint part_id) { +static uint32_t get_ct_part_no(uint num_subparts, uint part_id) +{ uint part_no = part_id / num_subparts; return (uint32_t)part_no; } -static bool get_used_partitions(partition_info *part_info, - uint32_t **part_ids,uint32_t **subpart_ids, uint32_t *used_parts) { +static bool get_used_partitions(partition_info *part_info, uint32_t **part_ids, uint32_t **subpart_ids, + uint32_t *used_parts) +{ *used_parts = part_info->num_partitions_used(); if (*used_parts > 0) { *part_ids = (uint32_t *)my_malloc(PSI_NOT_INSTRUMENTED, (*used_parts) * sizeof(uint32_t), MYF(MY_WME)); - if (*part_ids == NULL) { + if (*part_ids == NULL) { ctc_log_system("Failed to allocate memory for part_ids."); return false; } @@ -91,17 +93,17 @@ static bool get_used_partitions(partition_info *part_info, return false; } uint32_t part_id = part_info->get_first_used_partition(); - if(part_id == MY_BIT_NONE){ + if (part_id == MY_BIT_NONE) { return true; } - if(part_info->num_subparts > 0){ + if (part_info->num_subparts > 0) { // subpartition for (uint32_t i = 0; i < *used_parts; i++) { *(*part_ids + i) = part_id / part_info->num_subparts; *(*subpart_ids + i) = part_id % part_info->num_subparts; part_id = part_info->get_next_used_partition(part_id); } - }else{ + } else { // partition for (uint32_t i = 0; i < *used_parts; i++) { *(*part_ids + i) = part_id; @@ -109,15 +111,15 @@ static bool get_used_partitions(partition_info *part_info, part_id = part_info->get_next_used_partition(part_id); } } - }else{ + } else { ctc_log_system("invalid used_parts :%u", *used_parts); } return true; } ha_ctcpart::ha_ctcpart(handlerton *hton, TABLE_SHARE *table_arg) - : ha_ctc(hton, table_arg), Partition_helper(this), - m_bulk_insert_parts(nullptr), m_part_share(nullptr) { + : ha_ctc(hton, table_arg), Partition_helper(this), m_bulk_insert_parts(nullptr), m_part_share(nullptr) +{ pruned_by_engine = false; ref_length = ROW_ID_LENGTH + PARTITION_BYTES_IN_POS; } @@ -131,8 +133,8 @@ ha_ctcpart::ha_ctcpart(handlerton *hton, TABLE_SHARE *table_arg) @retval 1 if error @retval 0 if success */ -int ha_ctcpart::open(const char *name, int mode, uint test_if_locked, - const dd::Table *table_def) { +int ha_ctcpart::open(const char *name, int mode, uint test_if_locked, const dd::Table *table_def) +{ if (!(m_part_share = get_share())) return HA_ERR_OUT_OF_MEM; if (m_part_info == NULL) { @@ -145,8 +147,7 @@ int ha_ctcpart::open(const char *name, int mode, uint test_if_locked, free_share(); return HA_ERR_INTERNAL_ERROR; } - if (m_part_share->auto_inc_mutex == nullptr && - table->found_next_number_field != nullptr) { + if (m_part_share->auto_inc_mutex == nullptr && table->found_next_number_field != nullptr) { if (m_part_share->init_auto_inc_mutex(table_share)) { unlock_shared_ha_data(); free_share(); @@ -157,7 +158,7 @@ int ha_ctcpart::open(const char *name, int mode, uint test_if_locked, int ret = ha_ctc::open(name, mode, test_if_locked, table_def); m_max_batch_num = m_max_batch_num > MAX_BULK_INSERT_PART_ROWS ? MAX_BULK_INSERT_PART_ROWS : m_max_batch_num; - + if (ret != CT_SUCCESS) { free_share(); return ret; @@ -169,7 +170,8 @@ int ha_ctcpart::open(const char *name, int mode, uint test_if_locked, return ret; } -int ha_ctcpart::close() { +int ha_ctcpart::close() +{ assert(m_part_share); close_partitioning(); free_share(); @@ -180,7 +182,8 @@ int ha_ctcpart::close() { return ha_ctc::close(); } -void ha_ctcpart::set_partition(uint part_id) { +void ha_ctcpart::set_partition(uint part_id) +{ if (m_is_sub_partitioned) { m_tch.part_id = get_ct_part_no(m_part_info->num_subparts, part_id); m_tch.subpart_id = get_ct_sub_no(m_part_info->num_subparts, part_id); @@ -190,18 +193,18 @@ void ha_ctcpart::set_partition(uint part_id) { } } -void ha_ctcpart::reset_partition(uint part_id) { +void ha_ctcpart::reset_partition(uint part_id) +{ m_tch.part_id = INVALID_PART_ID; m_tch.subpart_id = INVALID_PART_ID; m_last_part = part_id; } -void ha_ctcpart::get_auto_increment(ulonglong, ulonglong, ulonglong, - ulonglong *first_value, - ulonglong*) { +void ha_ctcpart::get_auto_increment(ulonglong, ulonglong, ulonglong, ulonglong *first_value, ulonglong *) +{ uint64 inc_value; update_member_tch(m_tch, get_ctc_hton(), ha_thd()); - THD* thd = ha_thd(); + THD *thd = ha_thd(); dml_flag_t flag; flag.auto_inc_offset = thd->variables.auto_increment_increment; flag.auto_inc_step = thd->variables.auto_increment_offset; @@ -215,19 +218,19 @@ void ha_ctcpart::get_auto_increment(ulonglong, ulonglong, ulonglong, *first_value = inc_value; } -void ha_ctcpart::print_error(int error, myf errflag) { +void ha_ctcpart::print_error(int error, myf errflag) +{ if (print_partition_error(error)) { handler::print_error(error, errflag); } } -void ha_ctcpart::part_autoinc_has_expl_non_null_value_update_row(uchar *new_data) { - if (table->found_next_number_field && new_data == table->record[0] && - !table->s->next_number_keypart && - bitmap_is_set(table->write_set, - table->found_next_number_field->field_index())) { - autoinc_has_expl_non_null_value_update_row = true; - } +void ha_ctcpart::part_autoinc_has_expl_non_null_value_update_row(uchar *new_data) +{ + if (table->found_next_number_field && new_data == table->record[0] && !table->s->next_number_keypart && + bitmap_is_set(table->write_set, table->found_next_number_field->field_index())) { + autoinc_has_expl_non_null_value_update_row = true; + } } /** @@ -238,22 +241,22 @@ void ha_ctcpart::part_autoinc_has_expl_non_null_value_update_row(uchar *new_data @param[in] record A row in MySQL format. @return error code. */ -int ha_ctcpart::write_row_in_part(uint part_id, uchar *record) { +int ha_ctcpart::write_row_in_part(uint part_id, uchar *record) +{ bool saved_autoinc_has_expl_non_null = table->autoinc_field_has_explicit_non_null_value; Field *saved_next_number_field = table->next_number_field; THD *thd = ha_thd(); - if (!autoinc_has_expl_non_null_value_update_row && - table->next_number_field && !autoinc_has_expl_non_null_value) { - table->autoinc_field_has_explicit_non_null_value = false; - table->next_number_field->store(0, true); + if (!autoinc_has_expl_non_null_value_update_row && table->next_number_field && !autoinc_has_expl_non_null_value) { + table->autoinc_field_has_explicit_non_null_value = false; + table->next_number_field->store(0, true); } if (table->found_next_number_field && autoinc_has_expl_non_null_value_update_row) { - table->autoinc_field_has_explicit_non_null_value = true; - table->next_number_field = table->found_next_number_field; - if (table->next_number_field->val_int() == 0) { - thd->force_one_auto_inc_interval(0); - } - autoinc_has_expl_non_null_value_update_row = false; + table->autoinc_field_has_explicit_non_null_value = true; + table->next_number_field = table->found_next_number_field; + if (table->next_number_field->val_int() == 0) { + thd->force_one_auto_inc_interval(0); + } + autoinc_has_expl_non_null_value_update_row = false; } set_partition(part_id); @@ -273,22 +276,24 @@ int ha_ctcpart::write_row_in_part(uint part_id, uchar *record) { return ret; } -void ha_ctcpart::start_bulk_insert(ha_rows rows) { +void ha_ctcpart::start_bulk_insert(ha_rows rows) +{ assert(m_rec_buf_4_writing == nullptr); ha_ctc::start_bulk_insert(rows); if (m_rec_buf_4_writing != nullptr) { if (m_bulk_insert_parts == nullptr) { // m_max_batch_num is fixed after open table, if table structrue is changed, it should be closed and reopened - m_bulk_insert_parts = (ctc_part_t *)my_malloc(PSI_NOT_INSTRUMENTED, - m_max_batch_num * sizeof(ctc_part_t), MYF(MY_WME)); + m_bulk_insert_parts = + (ctc_part_t *)my_malloc(PSI_NOT_INSTRUMENTED, m_max_batch_num * sizeof(ctc_part_t), MYF(MY_WME)); } } } -int ha_ctcpart::bulk_insert_low(dml_flag_t flag, uint *dup_offset) { +int ha_ctcpart::bulk_insert_low(dml_flag_t flag, uint *dup_offset) +{ record_info_t record_info = {m_rec_buf_data, (uint16_t)m_cantian_rec_len, nullptr, nullptr}; - return (ct_errno_t)ctc_bulk_write(&m_tch, &record_info, m_rec_buf_4_writing->records(), - dup_offset, flag, m_bulk_insert_parts); + return (ct_errno_t)ctc_bulk_write(&m_tch, &record_info, m_rec_buf_4_writing->records(), dup_offset, flag, + m_bulk_insert_parts); } /** @@ -299,7 +304,8 @@ int ha_ctcpart::bulk_insert_low(dml_flag_t flag, uint *dup_offset) { @param[in] new_row New row in MySQL format. @return error number or 0. */ -int ha_ctcpart::update_row_in_part(uint part_id, const uchar *old_row, uchar *new_row) { +int ha_ctcpart::update_row_in_part(uint part_id, const uchar *old_row, uchar *new_row) +{ if (m_index_sorted) { cursor_set_bit(cursor_set, part_id); m_tch.cursor_addr = cursors[part_id]; @@ -315,7 +321,8 @@ int ha_ctcpart::update_row_in_part(uint part_id, const uchar *old_row, uchar *ne @param[in] new_part_id New partition to write to. @return 0 for success else error code. */ -int ha_ctcpart::write_row_in_new_part(uint new_part_id) { +int ha_ctcpart::write_row_in_new_part(uint new_part_id) +{ UNUSED_PARAM(new_part_id); return 0; } @@ -326,7 +333,8 @@ int ha_ctcpart::write_row_in_new_part(uint new_part_id) { @param[in] record Row to delete in MySQL format. @return error number or 0. */ -int ha_ctcpart::delete_row_in_part(uint part_id, const uchar *record) { +int ha_ctcpart::delete_row_in_part(uint part_id, const uchar *record) +{ if (m_index_sorted) { cursor_set_bit(cursor_set, part_id); m_tch.cursor_addr = cursors[part_id]; @@ -343,7 +351,8 @@ int ha_ctcpart::delete_row_in_part(uint part_id, const uchar *record) { @param[in] scan True for scan else random access. @return error number or 0. */ -int ha_ctcpart::rnd_init_in_part(uint part_id, bool scan) { +int ha_ctcpart::rnd_init_in_part(uint part_id, bool scan) +{ set_partition(part_id); int ret = ha_ctc::rnd_init(scan); reset_partition(part_id); @@ -356,7 +365,8 @@ int ha_ctcpart::rnd_init_in_part(uint part_id, bool scan) { @param[out] buf Next row. @return error number or 0. */ -int ha_ctcpart::rnd_next_in_part(uint part_id, uchar *buf) { +int ha_ctcpart::rnd_next_in_part(uint part_id, uchar *buf) +{ set_partition(part_id); int ret = ha_ctc::rnd_next(buf); reset_partition(part_id); @@ -369,7 +379,8 @@ int ha_ctcpart::rnd_next_in_part(uint part_id, uchar *buf) { @param[in] scan True for scan else random access. @return error number or 0. */ -int ha_ctcpart::rnd_end_in_part(uint part_id, bool scan) { +int ha_ctcpart::rnd_end_in_part(uint part_id, bool scan) +{ UNUSED_PARAM(scan); if (m_tch.cursor_addr == INVALID_VALUE64) { return 0; @@ -385,7 +396,8 @@ int ha_ctcpart::rnd_end_in_part(uint part_id, bool scan) { @param[out] ref_arg Reference (PK if exists else row_id). @param[in] record Record to position. */ -void ha_ctcpart::position_in_last_part(uchar *ref_arg, const uchar *record) { +void ha_ctcpart::position_in_last_part(uchar *ref_arg, const uchar *record) +{ UNUSED_PARAM(record); m_tch.thd_id = ha_thd()->thread_id(); uint part_id = m_last_part; @@ -397,10 +409,10 @@ void ha_ctcpart::position_in_last_part(uchar *ref_arg, const uchar *record) { assert(cur_pos_in_buf < max_prefetch_num); memcpy(ref_arg, &m_rowids[cur_pos_in_buf], ref_length - PARTITION_BYTES_IN_POS); } - + if (ret != 0) { - ctc_log_error("find position failed."); - assert(0); + ctc_log_error("find position failed."); + assert(0); } reset_partition(part_id); } @@ -412,7 +424,8 @@ void ha_ctcpart::position_in_last_part(uchar *ref_arg, const uchar *record) { @param[in] pos Position, given as primary key value or DB_ROW_ID @return 0, HA_ERR_KEY_NOT_FOUND or error code. */ -int ha_ctcpart::rnd_pos(uchar *buf, uchar *pos) { +int ha_ctcpart::rnd_pos(uchar *buf, uchar *pos) +{ DBUG_TRACE; ha_statistic_increment(&System_status_var::ha_read_rnd_count); m_tch.thd_id = ha_thd()->thread_id(); @@ -429,7 +442,8 @@ int ha_ctcpart::rnd_pos(uchar *buf, uchar *pos) { @param[in] sorted True if result MUST be sorted according to index. @return 0 or error number. */ -int ha_ctcpart::index_init(uint index, bool sorted) { +int ha_ctcpart::index_init(uint index, bool sorted) +{ int ret; ret = ph_index_init_setup(index, sorted); if (ret != 0) { @@ -444,7 +458,7 @@ int ha_ctcpart::index_init(uint index, bool sorted) { return ret; } } - + uint part_id = m_part_info->get_first_used_partition(); set_partition(part_id); @@ -464,12 +478,14 @@ int ha_ctcpart::index_init(uint index, bool sorted) { End index cursor. @return 0 or error code. */ -int ha_ctcpart::index_end() { +int ha_ctcpart::index_end() +{ pruned_by_engine = false; if (m_ordered) { destroy_record_priority_queue(); - for (uint i = m_part_info->get_first_used_partition(); i < MY_BIT_NONE; i = m_part_info->get_next_used_partition(i)) { - if (cursor_is_set(cursor_set, i)){ + for (uint i = m_part_info->get_first_used_partition(); i < MY_BIT_NONE; + i = m_part_info->get_next_used_partition(i)) { + if (cursor_is_set(cursor_set, i)) { m_tch.cursor_addr = cursors[i]; ha_ctc::index_end(); cursor_clear_bit(cursor_set, i); @@ -479,7 +495,7 @@ int ha_ctcpart::index_end() { m_tch.subpart_id = INVALID_PART_ID; return 0; } - + ha_ctc::index_end(); m_tch.part_id = INVALID_PART_ID; m_tch.subpart_id = INVALID_PART_ID; @@ -488,8 +504,8 @@ int ha_ctcpart::index_end() { return 0; } -int ha_ctcpart::index_read(uchar *buf, const uchar *key, uint key_len, - ha_rkey_function find_flag) { +int ha_ctcpart::index_read(uchar *buf, const uchar *key, uint key_len, ha_rkey_function find_flag) +{ return ha_ctc::index_read(buf, key, key_len, find_flag); } @@ -499,7 +515,8 @@ int ha_ctcpart::index_read(uchar *buf, const uchar *key, uint key_len, @param[out] record First record in index in the partition. @return error number or 0. */ -int ha_ctcpart::index_first_in_part(uint part_id, uchar *record) { +int ha_ctcpart::index_first_in_part(uint part_id, uchar *record) +{ if (part_id != m_last_part) { ha_ctc::reset_rec_buf(); } @@ -519,7 +536,8 @@ int ha_ctcpart::index_first_in_part(uint part_id, uchar *record) { @param[out] record Last record in index in the partition. @return error number or 0. */ -int ha_ctcpart::index_last_in_part(uint part_id, uchar *record) { +int ha_ctcpart::index_last_in_part(uint part_id, uchar *record) +{ if (part_id != m_last_part) { ha_ctc::reset_rec_buf(); } @@ -539,7 +557,8 @@ int ha_ctcpart::index_last_in_part(uint part_id, uchar *record) { @param[out] record Last record in index in the partition. @return error number or 0. */ -int ha_ctcpart::index_prev_in_part(uint part_id, uchar *record) { +int ha_ctcpart::index_prev_in_part(uint part_id, uchar *record) +{ if (m_index_sorted) { cursor_set_bit(cursor_set, part_id); m_tch.cursor_addr = cursors[part_id]; @@ -556,7 +575,8 @@ int ha_ctcpart::index_prev_in_part(uint part_id, uchar *record) { @param[out] record Last record in index in the partition. @return error number or 0. */ -int ha_ctcpart::index_next_in_part(uint part_id, uchar *record) { +int ha_ctcpart::index_next_in_part(uint part_id, uchar *record) +{ if (m_index_sorted) { cursor_set_bit(cursor_set, part_id); m_tch.cursor_addr = cursors[part_id]; @@ -577,7 +597,8 @@ int ha_ctcpart::index_next_in_part(uint part_id, uchar *record) { @param[in] length Length of key. @return error number or 0. */ -int ha_ctcpart::index_next_same_in_part(uint part_id, uchar *record, const uchar *key, uint length) { +int ha_ctcpart::index_next_same_in_part(uint part_id, uchar *record, const uchar *key, uint length) +{ if (m_index_sorted) { cursor_set_bit(cursor_set, part_id); m_tch.cursor_addr = cursors[part_id]; @@ -599,8 +620,9 @@ int ha_ctcpart::index_next_same_in_part(uint part_id, uchar *record, const uchar @param[in] find_flag Key condition/direction to use. @return error number or 0. */ -int ha_ctcpart::index_read_map_in_part(uint part_id, uchar *record, const uchar *key, - key_part_map keypart_map, enum ha_rkey_function find_flag) { +int ha_ctcpart::index_read_map_in_part(uint part_id, uchar *record, const uchar *key, key_part_map keypart_map, + enum ha_rkey_function find_flag) +{ if (part_id != m_last_part) { ha_ctc::reset_rec_buf(); } @@ -622,8 +644,8 @@ int ha_ctcpart::index_read_map_in_part(uint part_id, uchar *record, const uchar @param[in] keypart_map Which part of the key to use. @return error number or 0. */ -int ha_ctcpart::index_read_last_map_in_part(uint part_id, uchar *record, const uchar *key, - key_part_map keypart_map) { +int ha_ctcpart::index_read_last_map_in_part(uint part_id, uchar *record, const uchar *key, key_part_map keypart_map) +{ if (part_id != m_last_part) { ha_ctc::reset_rec_buf(); } @@ -649,16 +671,17 @@ int ha_ctcpart::index_read_last_map_in_part(uint part_id, uchar *record, const u @param[in] find_flag Key condition/direction to use. @return error number or 0. */ -int ha_ctcpart::index_read_idx_map_in_part(uint part_id, uchar *record, uint index, - const uchar *key, key_part_map keypart_map, - enum ha_rkey_function find_flag) { +int ha_ctcpart::index_read_idx_map_in_part(uint part_id, uchar *record, uint index, const uchar *key, + key_part_map keypart_map, enum ha_rkey_function find_flag) +{ set_partition(part_id); int ret = ha_ctc::index_read_idx_map(record, index, key, keypart_map, find_flag); reset_partition(part_id); return ret; } -bool ha_ctcpart::need_prune_partitions_by_engine(const key_range *start_key, const key_range *end_key) { +bool ha_ctcpart::need_prune_partitions_by_engine(const key_range *start_key, const key_range *end_key) +{ if (start_key == nullptr || end_key == nullptr) { return false; } @@ -682,9 +705,10 @@ bool ha_ctcpart::need_prune_partitions_by_engine(const key_range *start_key, con return true; } -bool ha_ctcpart::equal_range_on_part_field(const key_range *start_key, const key_range *end_key) { +bool ha_ctcpart::equal_range_on_part_field(const key_range *start_key, const key_range *end_key) +{ vector part_field_ids; - for (uint i = 0; i num_columns; i++) { + for (uint i = 0; i < m_part_info->num_columns; i++) { part_field_ids.push_back(m_part_info->part_field_array[i]->field_index()); } @@ -722,9 +746,9 @@ bool ha_ctcpart::equal_range_on_part_field(const key_range *start_key, const key @param[in] sorted Return rows in sorted order. @return error number or 0. */ -int ha_ctcpart::read_range_first_in_part(uint part_id, uchar *record, - const key_range *start_key, - const key_range *end_key, bool sorted) { +int ha_ctcpart::read_range_first_in_part(uint part_id, uchar *record, const key_range *start_key, + const key_range *end_key, bool sorted) +{ UNUSED_PARAM(sorted); uchar *read_record = record; @@ -757,8 +781,7 @@ int ha_ctcpart::read_range_first_in_part(uint part_id, uchar *record, set_partition(part_id); if (m_start_key.key != nullptr) { - ret = index_read(read_record, m_start_key.key, - m_start_key.length, m_start_key.flag); + ret = index_read(read_record, m_start_key.key, m_start_key.length, m_start_key.flag); } else { ret = ha_ctc::index_first(read_record); } @@ -767,7 +790,7 @@ int ha_ctcpart::read_range_first_in_part(uint part_id, uchar *record, } else if (ret == 0 && !in_range_check_pushed_down) { /* compare_key uses table->record[0], so we need to copy the data if not already there. */ - + if (record != nullptr) { memcpy(table->record[0], read_record, m_rec_length); } @@ -791,7 +814,8 @@ int ha_ctcpart::read_range_first_in_part(uint part_id, uchar *record, if NULL use table->record[0] as return buffer. @return error number or 0. */ -int ha_ctcpart::read_range_next_in_part(uint part_id, uchar *record) { +int ha_ctcpart::read_range_next_in_part(uint part_id, uchar *record) +{ uchar *read_record = record; if (read_record == nullptr) { read_record = table->record[0]; @@ -812,37 +836,36 @@ int ha_ctcpart::read_range_next_in_part(uint part_id, uchar *record) { @param[in] part_id Id of partition for which row type to be retrieved @return Partition row type. */ -enum row_type ha_ctcpart::get_partition_row_type(const dd::Table *partition_table, uint part_id) { +enum row_type ha_ctcpart::get_partition_row_type(const dd::Table *partition_table, uint part_id) +{ UNUSED_PARAM(partition_table); UNUSED_PARAM(part_id); return ROW_TYPE_NOT_USED; } -void ha_ctcpart::info_low() { +void ha_ctcpart::info_low() +{ stats.records = 0; if (m_part_share->cbo_stats != nullptr) { - uint part_num = m_is_sub_partitioned ? table->part_info->num_parts * table->part_info->num_subparts : - table->part_info->num_parts; + uint part_num = m_is_sub_partitioned ? table->part_info->num_parts * table->part_info->num_subparts + : table->part_info->num_parts; for (uint part_id = m_part_info->get_first_used_partition(); part_id < part_num; - part_id = m_part_info->get_next_used_partition(part_id)) { - stats.records += m_part_share->cbo_stats->ctc_cbo_stats_table[part_id].estimate_rows; + part_id = m_part_info->get_next_used_partition(part_id)) { + stats.records += m_part_share->cbo_stats->ctc_cbo_stats_table[part_id].estimate_rows; } } } -int ha_ctcpart::info(uint flag) { - return ha_ctc::info(flag); -} - -ha_rows ha_ctcpart::records_in_range(uint inx, key_range *min_key, key_range *max_key) { +int ha_ctcpart::info(uint flag) { return ha_ctc::info(flag); } +ha_rows ha_ctcpart::records_in_range(uint inx, key_range *min_key, key_range *max_key) +{ double density; if (m_part_share && !m_part_share->cbo_stats->is_updated) { ctc_log_debug("table %s has not been analyzed", table->alias); return 1; } - ctc_key ctc_min_key; ctc_key ctc_max_key; set_ctc_range_key(&ctc_min_key, min_key, true); @@ -855,12 +878,11 @@ ha_rows ha_ctcpart::records_in_range(uint inx, key_range *min_key, key_range *ma } uint64_t n_rows_num = 0; - uint part_num = m_is_sub_partitioned ? table->part_info->num_parts * table->part_info->num_subparts : - table->part_info->num_parts; - -for (uint part_id = m_part_info->get_first_used_partition(); part_id < part_num; - part_id = m_part_info->get_next_used_partition(part_id)) { + uint part_num = + m_is_sub_partitioned ? table->part_info->num_parts * table->part_info->num_subparts : table->part_info->num_parts; + for (uint part_id = m_part_info->get_first_used_partition(); part_id < part_num; + part_id = m_part_info->get_next_used_partition(part_id)) { set_ctc_range_key(&ctc_min_key, min_key, true); set_ctc_range_key(&ctc_max_key, max_key, false); if (ctc_max_key.len < ctc_min_key.len) { @@ -903,7 +925,8 @@ int ha_ctcpart::records(ha_rows *num_rows) /*!< out: number of rows */ extern uint32_t ctc_instance_id; /* alter table truncate partition */ -int ha_ctcpart::truncate_partition_low(dd::Table *dd_table) { +int ha_ctcpart::truncate_partition_low(dd::Table *dd_table) +{ THD *thd = ha_thd(); if (engine_ddl_passthru(thd)) { return 0; @@ -913,9 +936,8 @@ int ha_ctcpart::truncate_partition_low(dd::Table *dd_table) { update_member_tch(m_tch, ht, thd); ddl_ctrl_t ddl_ctrl = {{0}, {0}, {0}, 0, 0, m_tch, ctc_instance_id, false, 0}; FILL_USER_INFO_WITH_THD(ddl_ctrl, thd); - ct_errno_t ret = (ct_errno_t)fill_truncate_partition_req( - table->s->normalized_path.str, m_part_info, dd_table, thd, &ddl_ctrl, - &stack_mem); + ct_errno_t ret = (ct_errno_t)fill_truncate_partition_req(table->s->normalized_path.str, m_part_info, dd_table, thd, + &ddl_ctrl, &stack_mem); if (ret != 0) { return convert_ctc_error_code_to_mysql(ret); } @@ -930,7 +952,8 @@ int ha_ctcpart::truncate_partition_low(dd::Table *dd_table) { return ctc_ddl_handle_fault("ctc_truncate_partition", thd, &ddl_ctrl, ret); } -int ha_ctcpart::analyze(THD *thd, HA_CHECK_OPT *opt) { +int ha_ctcpart::analyze(THD *thd, HA_CHECK_OPT *opt) +{ if (engine_ddl_passthru(thd)) { m_part_share->need_fetch_cbo = true; return 0; @@ -949,7 +972,7 @@ int ha_ctcpart::analyze(THD *thd, HA_CHECK_OPT *opt) { bool memory_allocated = false; if (!m_part_info->set_read_partitions(&alter_info->partition_names)) { memory_allocated = get_used_partitions(m_part_info, &part_ids, &subpart_ids, &used_parts); - if(!memory_allocated){ + if (!memory_allocated) { ctc_log_error("Failed to allocate memory !"); return HA_ERR_OUT_OF_MEM; } @@ -983,31 +1006,33 @@ int ha_ctcpart::analyze(THD *thd, HA_CHECK_OPT *opt) { return ret; } -int ha_ctcpart::optimize(THD *thd, HA_CHECK_OPT *opt) { - int ret; - m_tch.part_id = INVALID_PART_ID; - ret = ha_ctc::analyze(thd, opt); - if (ret != 0) { - ctc_log_error("analyze partition error!"); - return ret; - } - m_part_share->need_fetch_cbo = true; - ret = ha_ctc::optimize(thd, opt); - if (ret != 0) { - ctc_log_error("optimize partition error!"); - return ret; - } - return (HA_ADMIN_TRY_ALTER); +int ha_ctcpart::optimize(THD *thd, HA_CHECK_OPT *opt) +{ + int ret; + m_tch.part_id = INVALID_PART_ID; + ret = ha_ctc::analyze(thd, opt); + if (ret != 0) { + ctc_log_error("analyze partition error!"); + return ret; + } + m_part_share->need_fetch_cbo = true; + ret = ha_ctc::optimize(thd, opt); + if (ret != 0) { + ctc_log_error("optimize partition error!"); + return ret; + } + return (HA_ADMIN_TRY_ALTER); } -int ha_ctcpart::initialize_cbo_stats() { +int ha_ctcpart::initialize_cbo_stats() +{ if (m_part_share->cbo_stats != nullptr) { return CT_SUCCESS; } - uint32_t part_num = m_is_sub_partitioned ? table->part_info->num_parts * table->part_info->num_subparts : - table->part_info->num_parts; - - m_part_share->cbo_stats = (ctc_cbo_stats_t*)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(ctc_cbo_stats_t), MYF(MY_WME)); + uint32_t part_num = + m_is_sub_partitioned ? table->part_info->num_parts * table->part_info->num_subparts : table->part_info->num_parts; + + m_part_share->cbo_stats = (ctc_cbo_stats_t *)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(ctc_cbo_stats_t), MYF(MY_WME)); if (m_part_share->cbo_stats == nullptr) { ctc_log_error("alloc mem failed, m_part_share->cbo_stats size(%lu)", sizeof(ctc_cbo_stats_t)); return ERR_ALLOC_MEMORY; @@ -1017,35 +1042,38 @@ int ha_ctcpart::initialize_cbo_stats() { m_part_share->cbo_stats->part_cnt = part_num; m_part_share->cbo_stats->ctc_cbo_stats_table = - (ctc_cbo_stats_table_t*)my_malloc(PSI_NOT_INSTRUMENTED, part_num * sizeof(ctc_cbo_stats_table_t), MYF(MY_WME)); + (ctc_cbo_stats_table_t *)my_malloc(PSI_NOT_INSTRUMENTED, part_num * sizeof(ctc_cbo_stats_table_t), MYF(MY_WME)); if (m_part_share->cbo_stats->ctc_cbo_stats_table == nullptr) { - ctc_log_error("alloc mem failed, m_part_share->cbo_stats->ctc_cbo_stats_table size(%lu)", part_num * sizeof(ctc_cbo_stats_table_t)); + ctc_log_error("alloc mem failed, m_part_share->cbo_stats->ctc_cbo_stats_table size(%lu)", + part_num * sizeof(ctc_cbo_stats_table_t)); return ERR_ALLOC_MEMORY; } m_part_share->cbo_stats->ndv_keys = - (uint32_t*)my_malloc(PSI_NOT_INSTRUMENTED, table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS, MYF(MY_WME)); + (uint32_t *)my_malloc(PSI_NOT_INSTRUMENTED, table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS, MYF(MY_WME)); if (m_part_share->cbo_stats->ndv_keys == nullptr) { - ctc_log_error("alloc mem failed, m_part_share->cbo_stats->ndv_keys size(%lu)", table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS); + ctc_log_error("alloc mem failed, m_part_share->cbo_stats->ndv_keys size(%lu)", + table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS); return ERR_ALLOC_MEMORY; } for (uint i = 0; i < part_num; i++) { m_part_share->cbo_stats->ctc_cbo_stats_table[i].estimate_rows = 0; - m_part_share->cbo_stats->ctc_cbo_stats_table[i].columns = - (ctc_cbo_stats_column_t*)my_malloc(PSI_NOT_INSTRUMENTED, table->s->fields * sizeof(ctc_cbo_stats_column_t), MYF(MY_WME)); + m_part_share->cbo_stats->ctc_cbo_stats_table[i].columns = (ctc_cbo_stats_column_t *)my_malloc( + PSI_NOT_INSTRUMENTED, table->s->fields * sizeof(ctc_cbo_stats_column_t), MYF(MY_WME)); if (m_part_share->cbo_stats->ctc_cbo_stats_table[i].columns == nullptr) { - ctc_log_error("alloc mem failed, m_part_share->cbo_stats->ctc_cbo_stats_table size(%lu)", table->s->fields * sizeof(ctc_cbo_stats_column_t)); - return ERR_ALLOC_MEMORY; + ctc_log_error("alloc mem failed, m_part_share->cbo_stats->ctc_cbo_stats_table size(%lu)", + table->s->fields * sizeof(ctc_cbo_stats_column_t)); + return ERR_ALLOC_MEMORY; } for (uint col_id = 0; col_id < table->s->fields; col_id++) { m_part_share->cbo_stats->ctc_cbo_stats_table[i].columns[col_id].hist_count = 0; } } - + ct_errno_t ret = (ct_errno_t)alloc_str_mysql_mem(m_part_share->cbo_stats, part_num, table); if (ret != CT_SUCCESS) { ctc_log_error("m_part_share:ctc alloc str mysql mem failed, ret:%d", ret); } - + m_part_share->cbo_stats->msg_len = table->s->fields * sizeof(ctc_cbo_stats_column_t); m_part_share->cbo_stats->key_len = table->s->keys * sizeof(uint32_t) * MAX_KEY_COLUMNS; @@ -1059,7 +1087,7 @@ int ha_ctcpart::get_cbo_stats_4share() time_t now = time(nullptr); if (m_part_share->need_fetch_cbo || now - m_part_share->get_cbo_time > ctc_update_analyze_time) { if (m_tch.ctx_addr == INVALID_VALUE64) { - char user_name[SMALL_RECORD_SIZE] = { 0 }; + char user_name[SMALL_RECORD_SIZE] = {0}; ctc_split_normalized_name(table->s->normalized_path.str, user_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); ctc_copy_name(user_name, user_name, SMALL_RECORD_SIZE); update_member_tch(m_tch, get_ctc_hton(), thd); @@ -1070,8 +1098,8 @@ int ha_ctcpart::get_cbo_stats_4share() } } uint32_t str_data_size = m_part_share->cbo_stats->num_str_cols * (STATS_HISTGRAM_MAX_SIZE + 2) * CBO_STRING_MAX_LEN; - uint32_t data_size = m_part_share->cbo_stats->msg_len > str_data_size ? - m_part_share->cbo_stats->msg_len : str_data_size; + uint32_t data_size = + m_part_share->cbo_stats->msg_len > str_data_size ? m_part_share->cbo_stats->msg_len : str_data_size; uint32_t part_cnt = m_part_share->cbo_stats->part_cnt; uint32_t num_part_fetch = MAX_MESSAGE_SIZE / data_size; uint32_t fetch_times = part_cnt / num_part_fetch; @@ -1079,7 +1107,9 @@ int ha_ctcpart::get_cbo_stats_4share() for (uint32_t i = 0; i < fetch_times; i++) { update_member_tch(m_tch, get_ctc_hton(), thd); - ret = ctc_get_cbo_stats(&m_tch, m_part_share->cbo_stats, &m_part_share->cbo_stats->ctc_cbo_stats_table[first_partid], first_partid, num_part_fetch); + ret = + ctc_get_cbo_stats(&m_tch, m_part_share->cbo_stats, + &m_part_share->cbo_stats->ctc_cbo_stats_table[first_partid], first_partid, num_part_fetch); update_sess_ctx_by_tch(m_tch, get_ctc_hton(), thd); if (ret != CT_SUCCESS) { return ret; @@ -1090,10 +1120,12 @@ int ha_ctcpart::get_cbo_stats_4share() num_part_fetch = part_cnt - first_partid; if (num_part_fetch > 0) { update_member_tch(m_tch, get_ctc_hton(), thd); - ret = ctc_get_cbo_stats(&m_tch, m_part_share->cbo_stats, &m_part_share->cbo_stats->ctc_cbo_stats_table[first_partid], first_partid, num_part_fetch); + ret = + ctc_get_cbo_stats(&m_tch, m_part_share->cbo_stats, + &m_part_share->cbo_stats->ctc_cbo_stats_table[first_partid], first_partid, num_part_fetch); update_sess_ctx_by_tch(m_tch, get_ctc_hton(), thd); } - + if (ret == CT_SUCCESS && m_part_share->cbo_stats->is_updated) { m_part_share->need_fetch_cbo = false; ctc_index_stats_update(table, m_part_share->cbo_stats); @@ -1103,13 +1135,14 @@ int ha_ctcpart::get_cbo_stats_4share() return ret; } - -void ha_ctcpart::free_cbo_stats() { + +void ha_ctcpart::free_cbo_stats() +{ if (m_part_share->cbo_stats == nullptr) { - return; + return; } - uint32_t part_num = m_is_sub_partitioned ? table->part_info->num_parts * table->part_info->num_subparts : - table->part_info->num_parts; + uint32_t part_num = + m_is_sub_partitioned ? table->part_info->num_parts * table->part_info->num_subparts : table->part_info->num_parts; bool is_str_first_addr = true; for (uint i = 0; i < part_num; i++) { @@ -1126,10 +1159,7 @@ void ha_ctcpart::free_cbo_stats() { m_part_share->cbo_stats = nullptr; } -int ha_ctcpart::check(THD *, HA_CHECK_OPT *) -{ - return HA_ADMIN_OK; -} +int ha_ctcpart::check(THD *, HA_CHECK_OPT *) { return HA_ADMIN_OK; } int ha_ctcpart::repair(THD *thd, HA_CHECK_OPT *) { @@ -1138,10 +1168,10 @@ int ha_ctcpart::repair(THD *thd, HA_CHECK_OPT *) } ctc_handler_t tch; CTC_RETURN_IF_NOT_ZERO(get_tch_in_handler_data(get_ctc_hton(), thd, tch)); - ctc_ddl_broadcast_request broadcast_req {{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; + ctc_ddl_broadcast_request broadcast_req{{0}, {0}, {0}, {0}, 0, 0, 0, 0, {0}}; string sql = string(thd->query().str).substr(0, thd->query().length); FILL_BROADCAST_BASE_REQ(broadcast_req, sql.c_str(), thd->m_main_security_ctx.priv_user().str, - thd->m_main_security_ctx.priv_host().str, ctc_instance_id, thd->lex->sql_command); + thd->m_main_security_ctx.priv_host().str, ctc_instance_id, thd->lex->sql_command); if (thd->db().str != NULL && thd->db().length > 0) { strncpy(broadcast_req.db_name, thd->db().str, SMALL_RECORD_SIZE - 1); } @@ -1150,10 +1180,10 @@ int ha_ctcpart::repair(THD *thd, HA_CHECK_OPT *) ct_errno_t ret = CT_SUCCESS; if (IS_METADATA_NORMALIZATION()) { ret = (ct_errno_t)ctc_record_sql_for_cantian(&tch, &broadcast_req, false); - assert (ret == CT_SUCCESS); + assert(ret == CT_SUCCESS); } else { ret = (ct_errno_t)ctc_execute_mysql_ddl_sql(&tch, &broadcast_req, false); - assert (ret == CT_SUCCESS); + assert(ret == CT_SUCCESS); } return (int)ret; @@ -1164,10 +1194,11 @@ uint32 ha_ctcpart::calculate_key_hash_value(Field **field_array) return (Partition_helper::ph_calculate_key_hash_value(field_array)); } -bool ha_ctcpart::check_unsupported_indexdir(dd::Table *table_def) { +bool ha_ctcpart::check_unsupported_indexdir(dd::Table *table_def) +{ for (const auto dd_part : *table_def->leaf_partitions()) { dd::String_type index_file_name; - if (dd_part == nullptr){ + if (dd_part == nullptr) { continue; } const dd::Properties &options = dd_part->options(); @@ -1182,8 +1213,8 @@ bool ha_ctcpart::check_unsupported_indexdir(dd::Table *table_def) { return false; } -EXTER_ATTACK int ha_ctcpart::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info, - dd::Table *table_def) { +EXTER_ATTACK int ha_ctcpart::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info, dd::Table *table_def) +{ THD *thd = ha_thd(); if (table_def != nullptr && check_unsupported_indexdir(table_def)) { ctc_log_system("Unsupported operation. sql = %s", thd->query().str); diff --git a/storage/ctc/mysql_cantian_plugin.cc b/storage/ctc/mysql_cantian_plugin.cc index 2eb2b15..ded6c5a 100644 --- a/storage/ctc/mysql_cantian_plugin.cc +++ b/storage/ctc/mysql_cantian_plugin.cc @@ -1,6 +1,6 @@ /* Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. @@ -21,11 +21,13 @@ #include #include #include -#include #include -#include +#include #include +#include "ctc_log.h" +#include "decimal_convert.h" +#include "ha_ctc.h" #include "m_string.h" // strlen #include "my_dbug.h" #include "my_dir.h" @@ -35,27 +37,22 @@ #include "my_sys.h" // my_write, my_malloc #include "my_thread.h" #include "mysql/psi/mysql_memory.h" -#include "sql/sql_plugin.h" // st_plugin_int -#include "sql/sql_initialize.h" // opt_initialize_insecure -#include "ctc_log.h" -#include "ha_ctc.h" -#include "decimal_convert.h" +#include "sql/sql_initialize.h" // opt_initialize_insecure +#include "sql/sql_plugin.h" // st_plugin_int struct mysql_cantian_context { my_thread_handle cantian_startup_thread; }; extern "C" { -const char *cantiand_get_dbversion() -{ - return "NONE"; -} +const char *cantiand_get_dbversion() { return "NONE"; } } extern "C" int cantiand_lib_main(int argc, char *argv[]); extern "C" void ct_singlep_shutdown(); -static std::string get_cantiand_mode() { +static std::string get_cantiand_mode() +{ std::string mode = "nomount"; char *tmp_mode = getenv("CANTIAND_MODE"); if (tmp_mode != NULL && strlen(tmp_mode) > 0) { @@ -65,7 +62,8 @@ static std::string get_cantiand_mode() { return mode; } -static std::string get_cantiand_home_dir() { +static std::string get_cantiand_home_dir() +{ std::string home_dir = "/home/regress/data"; char *tmp_home_dir = getenv("CANTIAND_HOME_DIR"); if (tmp_home_dir != NULL && strlen(tmp_home_dir) > 0) { @@ -75,10 +73,11 @@ static std::string get_cantiand_home_dir() { return home_dir; } -static void *mysql_cantian_startup_thread(void *p) { +static void *mysql_cantian_startup_thread(void *p) +{ DBUG_TRACE; struct mysql_cantian_context *con = (struct mysql_cantian_context *)p; - if(con->cantian_startup_thread.thread == 0) { + if (con->cantian_startup_thread.thread == 0) { ctc_log_error("please create the nomont thread first!"); return nullptr; } @@ -87,26 +86,24 @@ static void *mysql_cantian_startup_thread(void *p) { std::string home_dir = get_cantiand_home_dir(); int ret; if (mode != "open") { - char const *argv[] = {"/home/regress/install/bin/cantiand", mode.c_str(), - "-D", home_dir.c_str()}; + char const *argv[] = {"/home/regress/install/bin/cantiand", mode.c_str(), "-D", home_dir.c_str()}; ret = cantiand_lib_main(4, const_cast(argv)); } else { - char const *argv[] = {"/home/regress/install/bin/cantiand", "-D", - home_dir.c_str()}; + char const *argv[] = {"/home/regress/install/bin/cantiand", "-D", home_dir.c_str()}; ret = cantiand_lib_main(3, const_cast(argv)); } - ctc_log_system("init cantian mode:%s,home_dir:%s, ret:%d", mode.c_str(), - home_dir.c_str(), ret); + ctc_log_system("init cantian mode:%s,home_dir:%s, ret:%d", mode.c_str(), home_dir.c_str(), ret); return nullptr; } struct mysql_cantian_context *cantian_context = NULL; -int daemon_cantian_plugin_init() { +int daemon_cantian_plugin_init() +{ DBUG_TRACE; // mysql with nometa does not need to start cantian startup thread in multiple process when initializing // but single process needs to start up cantian thread in both meat and nometa when initializing - if (!is_single_run_mode()) { + if (!is_single_run_mode()) { if (opt_initialize_insecure) { ctc_log_warning("initialize-insecure mode no need start the cantian startup thread."); return 0; @@ -119,15 +116,14 @@ int daemon_cantian_plugin_init() { return -1; } } - + if (cantian_context != NULL) { ctc_log_error("daemon_cantian_plugin_init cantian_context:%p not NULL", cantian_context); return 0; } - cantian_context = (struct mysql_cantian_context *)my_malloc( - PSI_NOT_INSTRUMENTED, - sizeof(struct mysql_cantian_context), MYF(0)); + cantian_context = + (struct mysql_cantian_context *)my_malloc(PSI_NOT_INSTRUMENTED, sizeof(struct mysql_cantian_context), MYF(0)); if (cantian_context == nullptr) { ctc_log_error("alloc mem failed, cantian_context size(%lu)", sizeof(struct mysql_cantian_context)); return -1; @@ -144,7 +140,8 @@ int daemon_cantian_plugin_init() { return 0; } -int daemon_cantian_plugin_deinit() { +int daemon_cantian_plugin_deinit() +{ DBUG_TRACE; void *dummy_retval; -- Gitee