From 2d8ecd06f0e05e5a8db951a077706cb189985f5e Mon Sep 17 00:00:00 2001 From: yuanyazhi Date: Fri, 21 Jun 2024 12:15:54 +0800 Subject: [PATCH] fix --- storage/tianchi/datatype_cnvrtr.cc | 41 ++++++++++++---- storage/tianchi/ha_tse.cc | 64 ++++++++++++++++++------ storage/tianchi/ha_tse_ddl.cc | 10 ++-- storage/tianchi/tse_log.h | 7 +++ storage/tianchi/tse_util.cc | 79 ++++++++++++++++++++++-------- 5 files changed, 151 insertions(+), 50 deletions(-) diff --git a/storage/tianchi/datatype_cnvrtr.cc b/storage/tianchi/datatype_cnvrtr.cc index 92fafec..b1d0558 100644 --- a/storage/tianchi/datatype_cnvrtr.cc +++ b/storage/tianchi/datatype_cnvrtr.cc @@ -364,7 +364,8 @@ int decimal_mysql_to_cantian(const uint8_t *mysql_ptr, uchar *cantian_ptr, Field { int ret = 0; const int scale = mysql_field->decimals(); - Field_new_decimal *f = (Field_new_decimal *)mysql_field; + Field_new_decimal *f = dynamic_cast(mysql_field); + TSE_RET_ERR_IF_NULL(f); const int prec = f->precision; my_decimal d; ret = binary2my_decimal(E_DEC_FATAL_ERROR, mysql_ptr, &d, prec, scale); @@ -408,7 +409,13 @@ void decimal_cantian_to_mysql(uint8_t *mysql_ptr, uchar *cantian_ptr, Field *mys assert(0); } - const int prec = ((Field_new_decimal *)mysql_field)->precision; + Field_new_decimal *f = dynamic_cast(mysql_field); + if (f == nullptr) { + tse_log_error("[cantian2mysql]Decimal data type convert my_decimal to binary failed!"); + assert(0); + } + + const int prec = f->precision; const int scale = mysql_field->decimals(); if (my_decimal2binary(E_DEC_FATAL_ERROR, &decimal_value, mysql_ptr, prec, scale) != E_DEC_OK) { tse_log_error("[cantian2mysql]Decimal data type convert my_decimal to binary failed!"); @@ -420,7 +427,8 @@ int decimal_mysql_to_double(const uint8_t *mysql_ptr, uchar *double_ptr, Field * { int ret = 0; const int scale = mysql_field->decimals(); - Field_new_decimal *f = (Field_new_decimal *)mysql_field; + Field_new_decimal *f = dynamic_cast(mysql_field); + TSE_RET_ERR_IF_NULL(f); const int prec = f->precision; my_decimal d; ret = binary2my_decimal(E_DEC_FATAL_ERROR, mysql_ptr, &d, prec, scale); @@ -535,9 +543,9 @@ void convert_json_to_mysql(Field *mysql_field) { // json binary serialize if (mysql_field->type() == MYSQL_TYPE_JSON) { - Field_json *json = (Field_json *)mysql_field; + Field_json *json = dynamic_cast(mysql_field); Json_wrapper wr; - if (bitmap_is_set(json->table->read_set, mysql_field->field_index()) && json->val_json(&wr)) { + if (json == nullptr || (bitmap_is_set(json->table->read_set, mysql_field->field_index()) && json->val_json(&wr))) { tse_log_error("[convert_json_to_mysql] get json value failed"); assert(0); } @@ -663,7 +671,11 @@ void cal_gcol_cnts_for_update(Field **field, uint column_id, uint32_t *virtual_g longlong bit_cnvt_mysql_cantian(const uchar *ptr, Field *mysql_field) { ulonglong bits = 0; - Field_bit *field = (Field_bit *)mysql_field; + Field_bit *field = dynamic_cast(mysql_field); + if (field == nullptr) { + tse_log_error("bit_cnvt_mysql_cantian failed!"); + assert(0); + } uint bytes_in_rec = field->bytes_in_rec; if (field->bit_len) { bits = get_rec_bits(field->bit_ptr, field->bit_ofs, field->bit_len); @@ -694,7 +706,12 @@ longlong bit_cnvt_mysql_cantian(const uchar *ptr, Field *mysql_field) void bit_cnvt_cantian_mysql(const uchar *cantian_ptr, uchar *mysql_ptr, Field *mysql_field) { ulonglong bits = 0; - Field_bit *field = (Field_bit *)mysql_field; + Field_bit *field = dynamic_cast(mysql_field); + if (field == nullptr) { + tse_log_error("bit_cnvt_cantian_mysql failed!"); + assert(0); + return; + } uint bytes_in_rec = field->bytes_in_rec; if (field->bit_len) { bits = get_rec_bits(field->bit_ptr, field->bit_ofs, field->bit_len); @@ -1314,7 +1331,12 @@ static uint32_t calculate_variable_len(const field_cnvrt_aux_t* mysql_info, Fiel case MYSQL_TYPE_NEWDECIMAL: { // field_len indicates the max bytes occupied by the decimal(prec,scale) column of Cantian int scale = mysql_field->decimals(); - Field_new_decimal *f = (Field_new_decimal *)mysql_field; + Field_new_decimal *f = dynamic_cast(mysql_field); + if (f == nullptr) { + tse_log_error("[mysql2cantian calculate length]unknow data type: %d", mysql_info->mysql_field_type); + data_offset = 0; + break; + } int prec = f->precision; // the number of cells(dec4_t) used to store the decimal(prec,scale) = (Integer part + decimal part) int ncells = ALIGN_UP(prec - scale, 4) + ALIGN_UP(scale, 4); @@ -1838,7 +1860,8 @@ int get_cantian_record_length(const TABLE *table) break; case MYSQL_TYPE_NEWDECIMAL: { int scale = mysql_field->decimals(); - Field_new_decimal *f = (Field_new_decimal *)mysql_field; + Field_new_decimal *f = dynamic_cast(mysql_field); + TSE_RET_ERR_IF_NULL(f); 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); diff --git a/storage/tianchi/ha_tse.cc b/storage/tianchi/ha_tse.cc index 703d903..18f48ad 100644 --- a/storage/tianchi/ha_tse.cc +++ b/storage/tianchi/ha_tse.cc @@ -489,24 +489,46 @@ static bool is_lock_table(MYSQL_THD thd) { } static bool check_cmp_result(Item *term) { - Item_field *item_field = (Item_field *)(((Item_func *)term)->arguments()[0]); - Item_field *item_field_next = (Item_field *)(((Item_func *)term)->arguments()[1]); - Item::Type type = (((Item_func *)term)->arguments()[1])->type(); + Item_func *item_func = dynamic_cast(term); + if (item_func == nullptr) { + return false; + } + + Item_field *item_field = dynamic_cast(item_func->arguments()[0]); + Item_result cmp_context_next = item_func->arguments()[1]->cmp_context; + if (item_field == nullptr) { + return false; + } + + Item::Type type = item_func->arguments()[1]->type(); if (type == Item::NULL_ITEM) { return true; } if (item_field->data_type() == MYSQL_TYPE_YEAR) { - return type == Item::INT_ITEM && item_field_next->cmp_context == INT_RESULT; + return type == Item::INT_ITEM && cmp_context_next == INT_RESULT; } if (is_temporal_type(item_field->data_type())) { - if (!((((Item_func *)term)->arguments()[1])->basic_const_item() && item_field_next->cmp_context == INT_RESULT)) { + if (!((item_func->arguments()[1])->basic_const_item() && cmp_context_next == INT_RESULT)) { return false; } if (item_field->data_type() == MYSQL_TYPE_TIMESTAMP) { MYSQL_TIME ltime; - if (((Item_date_literal *)(((Item_func_eq *)term)->arguments()[1]))->get_date(<ime, TIME_FUZZY_DATE)) { + Item_func_comparison *item_func_comparison = dynamic_cast(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; + } + Item_date_literal *item_date_literal = (Item_date_literal *)(item_date_func); + if (item_date_literal == nullptr) { + return false; + } + if (item_date_literal->get_date(<ime, TIME_FUZZY_DATE)) { return false; } if (non_zero_date(ltime)) { @@ -517,15 +539,15 @@ static bool check_cmp_result(Item *term) { } if (is_string_type(item_field->data_type())) { - return type == Item::STRING_ITEM && item_field_next->cmp_context == STRING_RESULT; + return type == Item::STRING_ITEM && cmp_context_next == STRING_RESULT; } if (is_integer_type(item_field->data_type())) { - return (type == Item::INT_ITEM && item_field_next->cmp_context == INT_RESULT) || type == Item::CACHE_ITEM; + return (type == Item::INT_ITEM && cmp_context_next == INT_RESULT) || type == Item::CACHE_ITEM; } if (is_numeric_type(item_field->data_type())) { - return (type == Item::REAL_ITEM || type == Item::DECIMAL_ITEM) && item_field_next->cmp_context != STRING_RESULT; + return (type == Item::REAL_ITEM || type == Item::DECIMAL_ITEM) && cmp_context_next != STRING_RESULT; } return false; @@ -551,7 +573,11 @@ static bool is_supported_datatype_cond(enum_field_types datatype) { } static bool is_supported_func_item(Item *term) { - Item_func::Functype functype = ((Item_func *)term)->functype(); + 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 && @@ -566,13 +592,16 @@ static bool is_supported_func_item(Item *term) { return false; } - Item::Type type = (((Item_func *)term)->arguments()[0])->type(); + Item::Type type = (item_func->arguments()[0])->type(); // filter expressions if (type != Item::FIELD_ITEM) { return false; } - Item_field *item_field = (Item_field *)(((Item_func *)term)->arguments()[0]); + Item_field *item_field = dynamic_cast(item_func->arguments()[0]); + if (item_field == nullptr) { + return false; + } // filter generated column if (item_field->field->is_gcol() || !item_field->field->part_of_prefixkey.is_clear_all()) { @@ -596,8 +625,8 @@ static bool is_supported_func_item(Item *term) { } if (functype == Item_func::LIKE_FUNC) { - Item_func_like *like_func = (Item_func_like *)((Item_func *)term); - if (like_func->escape_was_used_in_parsing() || !is_string_type(item_field->data_type())) { + Item_func_like *like_func = dynamic_cast(item_func); + if (like_func == nullptr || like_func->escape_was_used_in_parsing() || !is_string_type(item_field->data_type())) { return false; } } @@ -677,7 +706,10 @@ void cond_push_boolean_term(Item *term, Item *&pushed_cond, Item *&remainder_con if (term->type() == Item::COND_ITEM) { List pushed_list; List remainder_list; - Item_cond *cond = (Item_cond *)term; + Item_cond *cond = dynamic_cast(term); + if (cond == nullptr) { + return; + } if (cond->functype() == Item_func::COND_AND_FUNC) { List_iterator li(*cond->argument_list()); Item *boolean_term; @@ -2352,7 +2384,7 @@ EXTER_ATTACK int ha_tse::open(const char *name, int, uint test_if_locked, const } m_cantian_rec_len = get_cantian_record_length(table); - assert(m_cantian_rec_len <= CT_MAX_RECORD_LENGTH); + assert(m_cantian_rec_len >= 0 && m_cantian_rec_len <= CT_MAX_RECORD_LENGTH); m_max_batch_num = MAX_RECORD_SIZE / m_cantian_rec_len; m_max_batch_num = m_max_batch_num > UINT_MAX ? UINT_MAX : m_max_batch_num; // restricted by uint32 diff --git a/storage/tianchi/ha_tse_ddl.cc b/storage/tianchi/ha_tse_ddl.cc index ee1bc4d..b4c50ee 100644 --- a/storage/tianchi/ha_tse_ddl.cc +++ b/storage/tianchi/ha_tse_ddl.cc @@ -410,13 +410,14 @@ static bool tse_fill_column_precision_and_scale(TcDb__TseDDLColumnDef *column, F column->datatype->precision = CT_UNSPECIFIED_NUM_PREC; } else { column->datatype->scale = field->decimals(); - column->datatype->precision = ((Field_real *)field)->max_display_length(); + Field_real *field_real = dynamic_cast(field); + column->datatype->precision = field_real->max_display_length(); } break; } case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: { - Field_new_decimal *f = (Field_new_decimal *)field; + Field_new_decimal *f = dynamic_cast(field); column->datatype->precision = f->precision; column->datatype->scale = f->decimals(); if (f->precision > MAX_NUMERIC_BUFF) { @@ -434,7 +435,8 @@ static bool tse_fill_column_precision_and_scale(TcDb__TseDDLColumnDef *column, F } case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: { - column->datatype->precision = ((Field_enum *)field)->typelib->count; + Field_enum *field_enum = dynamic_cast(field); + column->datatype->precision = field_enum->typelib->count; break; } case MYSQL_TYPE_BIT: @@ -948,7 +950,7 @@ static bool tse_check_expression_default_value(TcDb__TseDDLColumnDef *column, Fi return false; } else if (constant_default->type() == Item::FUNC_ITEM) { // default function - Item_func *item_func = (Item_func *)constant_default; + Item_func *item_func = dynamic_cast(constant_default); column->default_func_name = const_cast(item_func->func_name()); for (uint i = 0; i < item_func->arg_count; i++) { if (item_func->get_arg(i)->type() == Item::FIELD_ITEM) { diff --git a/storage/tianchi/tse_log.h b/storage/tianchi/tse_log.h index 81b4507..6b96dc6 100644 --- a/storage/tianchi/tse_log.h +++ b/storage/tianchi/tse_log.h @@ -149,4 +149,11 @@ void tse_log_print(enum loglevel loglevel, const char *fmt, ...) { } \ } while (0) +#define TSE_RET_ERR_IF_NULL(var) \ + do { \ + if (var == NULL) { \ + return CT_ERROR; \ + } \ + } while (0) + #endif // __TSE_LOG_H__ diff --git a/storage/tianchi/tse_util.cc b/storage/tianchi/tse_util.cc index 4d8619d..1d98f46 100644 --- a/storage/tianchi/tse_util.cc +++ b/storage/tianchi/tse_util.cc @@ -167,28 +167,43 @@ int tse_fill_cond_field_data_num(tianchi_handler_t m_tch, Item *items, Field *my int ret = CT_SUCCESS; void *data = nullptr; bool is_alloc_data = CT_FALSE; + Item_func_comparison *item_func_comparison = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_func_comparison); switch (mysql_info->ddl_field_type) { case TSE_DDL_TYPE_LONG: case TSE_DDL_TYPE_LONGLONG: { - if ((((Item_func *)items)->arguments()[1])->type() == Item::CACHE_ITEM) { - longlong val = ((Item_cache_int *)(((Item_func *)items)->arguments()[1]))->val_int(); + Item_func *item_func = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_func); + if ((item_func->arguments()[1])->type() == Item::CACHE_ITEM) { + Item_cache_int *item_cache_int = dynamic_cast(item_func_comparison->arguments()[1]); + TSE_RET_ERR_IF_NULL(item_cache_int); + longlong val = item_cache_int->val_int(); data = (uchar *)malloc(sizeof(longlong)); is_alloc_data = CT_TRUE; memcpy(data, &val, sizeof(longlong)); } else { - data = &((Item_int *)(((Item_func_eq *)items)->arguments()[1]))->value; + Item_int *item_int = dynamic_cast(item_func_comparison->arguments()[1]); + TSE_RET_ERR_IF_NULL(item_int); + data = &item_int->value; } break; } - case TSE_DDL_TYPE_DOUBLE: - data = &((Item_float *)(((Item_func_eq *)items)->arguments()[1]))->value; + case TSE_DDL_TYPE_DOUBLE: { + Item_float *item_float = dynamic_cast(item_func_comparison->arguments()[1]); + TSE_RET_ERR_IF_NULL(item_float); + data = &item_float->value; break; + } case TSE_DDL_TYPE_NEWDECIMAL: { const int scale = mysql_field->decimals(); - const int prec = ((Field_new_decimal *)mysql_field)->precision; + Field_new_decimal *field_new_decimal = dynamic_cast(mysql_field); + TSE_RET_ERR_IF_NULL(field_new_decimal); + const int prec = field_new_decimal->precision; int binary_size = my_decimal_get_binary_size(prec, scale); uchar *buff = new uchar[binary_size]; - my_decimal *d = ((Item_decimal *)(((Item_func_eq *)items)->arguments()[1]))->val_decimal(nullptr); + Item_decimal *item_decimal = dynamic_cast(item_func_comparison->arguments()[1]); + TSE_RET_ERR_IF_NULL(item_decimal); + my_decimal *d = item_decimal->val_decimal(nullptr); my_decimal2binary(E_DEC_FATAL_ERROR, d, buff, prec, scale); data = (uchar *)malloc(binary_size); is_alloc_data = CT_TRUE; @@ -315,15 +330,18 @@ int tse_fill_cond_field_data_string(tianchi_handler_t m_tch, Item_func *item_fun cond->field_info.null_value = true; return CT_SUCCESS; } - Item_field *item_field = (Item_field *)((item_func)->arguments()[0]); + Item_field *item_field = dynamic_cast((item_func)->arguments()[0]); + TSE_RET_ERR_IF_NULL(item_field); uint cslen = item_field->collation.collation->mbminlen; cond->field_info.collate_id = tse_get_column_cs(item_field->collation.collation); if (no_backslash) { cond->field_info.no_backslash = true; } - String *item_string = ((Item_string *)(item_func->arguments()[1]))->val_str(nullptr); - cond->field_info.field_size = item_string->length(); - void *data = item_string->ptr(); + Item_string *item_string = dynamic_cast(item_func->arguments()[1]); + TSE_RET_ERR_IF_NULL(item_string); + String *item_str = item_string->val_str(nullptr); + cond->field_info.field_size = item_str->length(); + void *data = item_str->ptr(); cond->field_info.field_value = tse_alloc_buf(&m_tch, cond->field_info.field_size); if (cond->field_info.field_size > 0 && cond->field_info.field_value == nullptr) { tse_log_error("tse_fill_cond_field: alloc field_data error, size(%u).", cond->field_info.field_size); @@ -340,11 +358,16 @@ int tse_fill_cond_field_data_string(tianchi_handler_t m_tch, Item_func *item_fun int tse_fill_cond_field_data(tianchi_handler_t m_tch, Item *items, Field *mysql_field, const field_cnvrt_aux_t *mysql_info, tse_conds *cond) { int ret = CT_SUCCESS; - Item_func *item_func = (Item_func *)items; + Item_func *item_func = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_func); + Item_func_comparison *item_func_comparison = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_func_comparison); if ((item_func->arguments()[1])->type() == Item::CACHE_ITEM) { - cond->field_info.null_value = !((Item_cache *)((item_func)->arguments()[1]))->has_value(); + Item_cache *item_cache = dynamic_cast(item_func_comparison->arguments()[1]); + TSE_RET_ERR_IF_NULL(item_cache); + cond->field_info.null_value = !item_cache->has_value(); } else { - cond->field_info.null_value = ((Item_func_eq *)items)->arguments()[1]->null_value; + cond->field_info.null_value = item_func_comparison->arguments()[1]->null_value; } if (cond->field_info.null_value) { return CT_SUCCESS; @@ -358,8 +381,12 @@ int tse_fill_cond_field_data(tianchi_handler_t m_tch, Item *items, Field *mysql_ MYSQL_TIME ltime; date_detail_t date_detail; memset(&date_detail, 0, sizeof(date_detail_t)); + Item_func_comparison *item_func_comparison = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_func_comparison); if (mysql_info->mysql_field_type == MYSQL_TYPE_YEAR) { - ltime.year = ((Item_int *)(((Item_func_eq *)items)->arguments()[1]))->value; + Item_int *item_int = dynamic_cast(item_func_comparison->arguments()[1]); + TSE_RET_ERR_IF_NULL(item_int); + ltime.year = item_int->value; ltime.month = 1; ltime.day = 1; ltime.hour = 0; @@ -367,8 +394,14 @@ int tse_fill_cond_field_data(tianchi_handler_t m_tch, Item *items, Field *mysql_ ltime.second = 0; ltime.second_part = 0; ltime.neg = false; - } else if (((Item_date_literal *)(((Item_func_eq *)items)->arguments()[1]))->get_date(<ime, TIME_FUZZY_DATE)) { - return CT_ERROR; + } else { + Item_func *item_date_func = dynamic_cast(item_func->arguments()[1]); + TSE_RET_ERR_IF_NULL(item_date_func); + Item_date_literal *item_date_literal = (Item_date_literal *)(item_date_func); + TSE_RET_ERR_IF_NULL(item_date_literal); + if (item_date_literal->get_date(<ime, TIME_FUZZY_DATE)) { + return CT_ERROR; + } } ret = tse_fill_cond_field_data_date(m_tch, mysql_info, ltime, &date_detail, cond); break; @@ -387,7 +420,8 @@ int tse_fill_cond_field_data(tianchi_handler_t m_tch, Item *items, Field *mysql_ } int tse_fill_cond_field(tianchi_handler_t m_tch, Item *items, Field **field, tse_conds *cond, bool no_backslash) { - Item_func *item_func = (Item_func *)items; + Item_func *item_func = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_func); const char *field_name = item_func->arguments()[0]->item_name.ptr(); cond->field_info.field_no = tse_get_column_by_field(field, field_name); if (cond->field_info.field_no == INVALID_MAX_COLUMN) { @@ -422,7 +456,8 @@ int tse_fill_cond_field(tianchi_handler_t m_tch, Item *items, Field **field, tse int tse_push_cond_list(tianchi_handler_t m_tch, Item *items, Field **field, tse_cond_list *list, bool no_backslash) { - Item_cond *item_cond = (Item_cond *)items; + Item_cond *item_cond = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_cond); List *argument_list = item_cond->argument_list(); uint16_t size = argument_list->size(); list_node *node = argument_list->first_node(); @@ -452,7 +487,8 @@ int tse_push_cond_list(tianchi_handler_t m_tch, Item *items, Field **field, int tse_push_cond_args(tianchi_handler_t m_tch, Item *items, Field **field, tse_cond_list *list, bool no_backslash) { - Item_func *item_func = (Item_func *)items; + Item_func *item_func = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_func); Item **args = item_func->arguments(); uint16_t size = item_func->argument_count(); @@ -512,7 +548,8 @@ tse_func_type_t item_func_to_tse_func(Item_func::Functype fc) { } int dfs_fill_conds(tianchi_handler_t m_tch, Item *items, Field **field, tse_conds *conds, bool no_backslash) { - Item_func *item_func = (Item_func *)items; + Item_func *item_func = dynamic_cast(items); + TSE_RET_ERR_IF_NULL(item_func); Item_func::Functype fc = item_func->functype(); conds->func_type = item_func_to_tse_func(fc); int ret = CT_SUCCESS; -- Gitee