From 29821a000004c5415a51971bf0129b0e1bfa1bd3 Mon Sep 17 00:00:00 2001 From: hwx Date: Mon, 22 Jul 2024 16:23:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E6=8E=A5mysql=20bit=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mysql-test/enableCases.list | 3 + .../suite/tianchi/r/ctc_bit_analyze.result | 119 +++++++++++++++++ .../suite/tianchi/r/ctc_enum_analyze.result | 30 +++++ .../suite/tianchi/r/ctc_set_analyze.result | 60 +++++++++ .../suite/tianchi/t/ctc_bit_analyze.test | 52 ++++++++ .../suite/tianchi/t/ctc_enum_analyze.test | 19 +++ .../suite/tianchi/t/ctc_set_analyze.test | 44 ++++++ storage/tianchi/datatype_cnvrtr.cc | 2 +- storage/tianchi/tse_cbo.cc | 125 +++++++++++++----- 9 files changed, 421 insertions(+), 33 deletions(-) create mode 100644 mysql-test/suite/tianchi/r/ctc_bit_analyze.result create mode 100644 mysql-test/suite/tianchi/r/ctc_enum_analyze.result create mode 100644 mysql-test/suite/tianchi/r/ctc_set_analyze.result create mode 100644 mysql-test/suite/tianchi/t/ctc_bit_analyze.test create mode 100644 mysql-test/suite/tianchi/t/ctc_enum_analyze.test create mode 100644 mysql-test/suite/tianchi/t/ctc_set_analyze.test diff --git a/mysql-test/enableCases.list b/mysql-test/enableCases.list index c76deb7..bdf99f3 100644 --- a/mysql-test/enableCases.list +++ b/mysql-test/enableCases.list @@ -13,6 +13,9 @@ tianchi.ctc_read_only subselect.test #test_services ctc_datetime_analyze +ctc_enum_analyze +ctc_set_analyze +ctc_bit_analyze # ------ END TEST CASES OF DML ------ # ------ TEST CASES FROM suite/engines/funcs ------ diff --git a/mysql-test/suite/tianchi/r/ctc_bit_analyze.result b/mysql-test/suite/tianchi/r/ctc_bit_analyze.result new file mode 100644 index 0000000..719c090 --- /dev/null +++ b/mysql-test/suite/tianchi/r/ctc_bit_analyze.result @@ -0,0 +1,119 @@ +drop table if exists tbl_bit; +create table tbl_bit (num bit(4), index idx_num(num)); +insert into tbl_bit (num) values (b'0000'), (b'0001'), (b'0010'), (b'0011'); +insert into tbl_bit (num) values (b'0100'), (b'0101'), (b'0110'), (b'0111'); +insert into tbl_bit (num) values (b'1000'), (b'1001'), (b'1010'), (b'1011'); +insert into tbl_bit (num) values (b'1100'), (b'1101'), (b'1110'), (b'1111'); +analyze table tbl_bit; +Table Op Msg_type Msg_text +test.tbl_bit analyze status OK +explain select * from tbl_bit where num < b'0000'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 1 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` < 0x00) +explain select * from tbl_bit where num > b'1111'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 1 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` > 0x0f) +explain select * from tbl_bit where num < b'0001'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 1 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` < 0x01) +explain select * from tbl_bit where num > b'1110'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 1 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` > 0x0e) +explain select * from tbl_bit where num <= b'0001'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 2 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` <= 0x01) +explain select * from tbl_bit where num >= b'1110'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 2 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` >= 0x0e) +explain select * from tbl_bit where num > b'0010' and num < b'1101'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 10 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where ((`test`.`tbl_bit`.`num` > 0x02) and (`test`.`tbl_bit`.`num` < 0x0d)) +explain select * from tbl_bit where num >= b'0010' and num <= b'1101'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL index idx_num idx_num 2 NULL 16 75.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where ((`test`.`tbl_bit`.`num` >= 0x02) and (`test`.`tbl_bit`.`num` <= 0x0d)) +drop table tbl_bit; +create table tbl_bit (num bit(7), index idx_num(num)); +insert into tbl_bit (num) values (1), (2), (3), (4), (5), (6); +insert into tbl_bit (num) values (7), (8), (9), (10), (11), (12); +insert into tbl_bit (num) values (13), (14), (15), (16), (17), (18); +insert into tbl_bit (num) values (19), (20), (21), (22), (23), (24); +insert into tbl_bit (num) values (25), (26), (27), (28), (29), (30); +analyze table tbl_bit; +Table Op Msg_type Msg_text +test.tbl_bit analyze status OK +explain select * from tbl_bit where num < 2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 1 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` < 2) +explain select * from tbl_bit where num > 29; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 1 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` > 29) +explain select * from tbl_bit where num <= 2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 2 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` <= 2) +explain select * from tbl_bit where num >= 29; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 2 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` >= 29) +explain select * from tbl_bit where num > 10 and num < 20; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 9 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where ((`test`.`tbl_bit`.`num` > 10) and (`test`.`tbl_bit`.`num` < 20)) +explain select * from tbl_bit where num >= 10 and num <= 20; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 2 NULL 11 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where ((`test`.`tbl_bit`.`num` >= 10) and (`test`.`tbl_bit`.`num` <= 20)) +drop table tbl_bit; +create table tbl_bit (num bit(64), index idx_num(num)); +create procedure insert_nums_to_tbl_bit() +begin +declare i int default 1; +while i <= 10000 do +insert into tbl_bit (num) values (i); +set i = i + 1; +end while; +end// +call insert_nums_to_tbl_bit(); +analyze table tbl_bit; +Table Op Msg_type Msg_text +test.tbl_bit analyze status OK +explain select * from tbl_bit where num < 100; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 9 NULL 79 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` < 100) +explain select * from tbl_bit where num > 9900; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 9 NULL 79 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where (`test`.`tbl_bit`.`num` > 9900) +explain select * from tbl_bit where num > 333 and num <= 966; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tbl_bit NULL range idx_num idx_num 9 NULL 630 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`tbl_bit`.`num` AS `num` from `test`.`tbl_bit` where ((`test`.`tbl_bit`.`num` > 333) and (`test`.`tbl_bit`.`num` <= 966)) +drop table tbl_bit; diff --git a/mysql-test/suite/tianchi/r/ctc_enum_analyze.result b/mysql-test/suite/tianchi/r/ctc_enum_analyze.result new file mode 100644 index 0000000..da25d99 --- /dev/null +++ b/mysql-test/suite/tianchi/r/ctc_enum_analyze.result @@ -0,0 +1,30 @@ +drop table if exists t1; +create table t1 (c enum('xxx1','xxx2','xxx3'), index idx_c(c)); +insert into t1 values ('xxx1'); +insert into t1 values ('xxx1'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx3'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain select * from t1 where c = 'xxx1'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref idx_c idx_c 2 const 2 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` = 'xxx1') +explain select * from t1 where c = 'xxx2'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref idx_c idx_c 2 const 3 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` = 'xxx2') +explain select * from t1 where c = 'xxx3'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref idx_c idx_c 2 const 4 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` = 'xxx3') +drop table t1; diff --git a/mysql-test/suite/tianchi/r/ctc_set_analyze.result b/mysql-test/suite/tianchi/r/ctc_set_analyze.result new file mode 100644 index 0000000..788509e --- /dev/null +++ b/mysql-test/suite/tianchi/r/ctc_set_analyze.result @@ -0,0 +1,60 @@ +drop table if exists t1; +create table t1 (c set('xxx1','xxx2','xxx3'), index idx_c(c)); +insert into t1 values ('xxx1'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx1,xxx2'); +insert into t1 values ('xxx1,xxx2'); +insert into t1 values ('xxx2,xxx3'); +insert into t1 values ('xxx2,xxx3'); +insert into t1 values ('xxx2,xxx3'); +insert into t1 values ('xxx1,xxx2,xxx3'); +insert into t1 values ('xxx1,xxx2,xxx3'); +insert into t1 values ('xxx1,xxx2,xxx3'); +insert into t1 values ('xxx1,xxx2,xxx3'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain select * from t1 where c = 'xxx1,xxx2'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref idx_c idx_c 2 const 2 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` = 'xxx1,xxx2') +explain select * from t1 where c = 'xxx2,xxx3'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref idx_c idx_c 2 const 3 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` = 'xxx2,xxx3') +explain select * from t1 where c = 'xxx1,xxx2,xxx3'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref idx_c idx_c 2 const 4 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` = 'xxx1,xxx2,xxx3') +drop table t1; +create table t1 (c set('xxx1','xxx2','xxx3','xxx4','xxx5','xxx6','xxx7','xxx8', +'xxx9','xxx10','xxx11','xxx12','xxx13','xxx14','xxx15','xxx16', +'xxx17','xxx18','xxx19','xxx20','xxx21','xxx22','xxx23','xxx24', +'xxx25','xxx26','xxx27','xxx28','xxx29','xxx30','xxx31','xxx32', +'xxx33','xxx34','xxx35','xxx36','xxx37','xxx38','xxx39','xxx40'), index idx_c(c)); +insert into t1 values ('xxx1'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx4'); +insert into t1 values ('xxx5'); +insert into t1 values ('xxx6'); +insert into t1 values ('xxx7'); +insert into t1 values ('xxx8'); +insert into t1 values ('xxx9'); +insert into t1 values ('xxx1,xxx9,xxx17,xxx25,xxx40'); +insert into t1 values ('xxx1,xxx9,xxx17,xxx25,xxx40'); +insert into t1 values ('xxx1,xxx9,xxx17,xxx25,xxx40'); +insert into t1 values ('xxx1,xxx9,xxx17,xxx25,xxx40'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain select * from t1 where c = 'xxx1,xxx9,xxx17,xxx25,xxx40'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref idx_c idx_c 9 const 4 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `c` from `test`.`t1` where (`test`.`t1`.`c` = 'xxx1,xxx9,xxx17,xxx25,xxx40') +drop table t1; diff --git a/mysql-test/suite/tianchi/t/ctc_bit_analyze.test b/mysql-test/suite/tianchi/t/ctc_bit_analyze.test new file mode 100644 index 0000000..3cb3326 --- /dev/null +++ b/mysql-test/suite/tianchi/t/ctc_bit_analyze.test @@ -0,0 +1,52 @@ +--disable_warnings +drop table if exists tbl_bit; +--enable_warnings + +create table tbl_bit (num bit(4), index idx_num(num)); +insert into tbl_bit (num) values (b'0000'), (b'0001'), (b'0010'), (b'0011'); +insert into tbl_bit (num) values (b'0100'), (b'0101'), (b'0110'), (b'0111'); +insert into tbl_bit (num) values (b'1000'), (b'1001'), (b'1010'), (b'1011'); +insert into tbl_bit (num) values (b'1100'), (b'1101'), (b'1110'), (b'1111'); +analyze table tbl_bit; +explain select * from tbl_bit where num < b'0000'; +explain select * from tbl_bit where num > b'1111'; +explain select * from tbl_bit where num < b'0001'; +explain select * from tbl_bit where num > b'1110'; +explain select * from tbl_bit where num <= b'0001'; +explain select * from tbl_bit where num >= b'1110'; +explain select * from tbl_bit where num > b'0010' and num < b'1101'; +explain select * from tbl_bit where num >= b'0010' and num <= b'1101'; +drop table tbl_bit; + +create table tbl_bit (num bit(7), index idx_num(num)); +insert into tbl_bit (num) values (1), (2), (3), (4), (5), (6); +insert into tbl_bit (num) values (7), (8), (9), (10), (11), (12); +insert into tbl_bit (num) values (13), (14), (15), (16), (17), (18); +insert into tbl_bit (num) values (19), (20), (21), (22), (23), (24); +insert into tbl_bit (num) values (25), (26), (27), (28), (29), (30); +analyze table tbl_bit; +explain select * from tbl_bit where num < 2; +explain select * from tbl_bit where num > 29; +explain select * from tbl_bit where num <= 2; +explain select * from tbl_bit where num >= 29; +explain select * from tbl_bit where num > 10 and num < 20; +explain select * from tbl_bit where num >= 10 and num <= 20; +drop table tbl_bit; + +create table tbl_bit (num bit(64), index idx_num(num)); +delimiter //; +create procedure insert_nums_to_tbl_bit() +begin +declare i int default 1; +while i <= 10000 do +insert into tbl_bit (num) values (i); +set i = i + 1; +end while; +end// +delimiter ;// +call insert_nums_to_tbl_bit(); +analyze table tbl_bit; +explain select * from tbl_bit where num < 100; +explain select * from tbl_bit where num > 9900; +explain select * from tbl_bit where num > 333 and num <= 966; +drop table tbl_bit; \ No newline at end of file diff --git a/mysql-test/suite/tianchi/t/ctc_enum_analyze.test b/mysql-test/suite/tianchi/t/ctc_enum_analyze.test new file mode 100644 index 0000000..122b30a --- /dev/null +++ b/mysql-test/suite/tianchi/t/ctc_enum_analyze.test @@ -0,0 +1,19 @@ +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (c enum('xxx1','xxx2','xxx3'), index idx_c(c)); +insert into t1 values ('xxx1'); +insert into t1 values ('xxx1'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx3'); +analyze table t1; +explain select * from t1 where c = 'xxx1'; +explain select * from t1 where c = 'xxx2'; +explain select * from t1 where c = 'xxx3'; +drop table t1; \ No newline at end of file diff --git a/mysql-test/suite/tianchi/t/ctc_set_analyze.test b/mysql-test/suite/tianchi/t/ctc_set_analyze.test new file mode 100644 index 0000000..4c03554 --- /dev/null +++ b/mysql-test/suite/tianchi/t/ctc_set_analyze.test @@ -0,0 +1,44 @@ +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (c set('xxx1','xxx2','xxx3'), index idx_c(c)); +insert into t1 values ('xxx1'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx1,xxx2'); +insert into t1 values ('xxx1,xxx2'); +insert into t1 values ('xxx2,xxx3'); +insert into t1 values ('xxx2,xxx3'); +insert into t1 values ('xxx2,xxx3'); +insert into t1 values ('xxx1,xxx2,xxx3'); +insert into t1 values ('xxx1,xxx2,xxx3'); +insert into t1 values ('xxx1,xxx2,xxx3'); +insert into t1 values ('xxx1,xxx2,xxx3'); +analyze table t1; +explain select * from t1 where c = 'xxx1,xxx2'; +explain select * from t1 where c = 'xxx2,xxx3'; +explain select * from t1 where c = 'xxx1,xxx2,xxx3'; +drop table t1; + +create table t1 (c set('xxx1','xxx2','xxx3','xxx4','xxx5','xxx6','xxx7','xxx8', + 'xxx9','xxx10','xxx11','xxx12','xxx13','xxx14','xxx15','xxx16', + 'xxx17','xxx18','xxx19','xxx20','xxx21','xxx22','xxx23','xxx24', + 'xxx25','xxx26','xxx27','xxx28','xxx29','xxx30','xxx31','xxx32', + 'xxx33','xxx34','xxx35','xxx36','xxx37','xxx38','xxx39','xxx40'), index idx_c(c)); +insert into t1 values ('xxx1'); +insert into t1 values ('xxx2'); +insert into t1 values ('xxx3'); +insert into t1 values ('xxx4'); +insert into t1 values ('xxx5'); +insert into t1 values ('xxx6'); +insert into t1 values ('xxx7'); +insert into t1 values ('xxx8'); +insert into t1 values ('xxx9'); +insert into t1 values ('xxx1,xxx9,xxx17,xxx25,xxx40'); +insert into t1 values ('xxx1,xxx9,xxx17,xxx25,xxx40'); +insert into t1 values ('xxx1,xxx9,xxx17,xxx25,xxx40'); +insert into t1 values ('xxx1,xxx9,xxx17,xxx25,xxx40'); +analyze table t1; +explain select * from t1 where c = 'xxx1,xxx9,xxx17,xxx25,xxx40'; +drop table t1; \ No newline at end of file diff --git a/storage/tianchi/datatype_cnvrtr.cc b/storage/tianchi/datatype_cnvrtr.cc index 85705d9..a5e8f4f 100644 --- a/storage/tianchi/datatype_cnvrtr.cc +++ b/storage/tianchi/datatype_cnvrtr.cc @@ -775,7 +775,7 @@ int convert_numeric_to_cantian(const field_cnvrt_aux_t *mysql_info, const uchar *(double *)cantian_ptr = *(const double *)mysql_ptr; break; case MYSQL_TYPE_BIT: - *(int64_t *)cantian_ptr = bit_cnvt_mysql_cantian(mysql_ptr, mysql_field); + *(uint64_t *)cantian_ptr = (uint64_t)bit_cnvt_mysql_cantian(mysql_ptr, mysql_field); break; case MYSQL_TYPE_LONGLONG: *(int64_t *)cantian_ptr = *(const int64_t *)mysql_ptr; diff --git a/storage/tianchi/tse_cbo.cc b/storage/tianchi/tse_cbo.cc index c378e6d..2754e3d 100644 --- a/storage/tianchi/tse_cbo.cc +++ b/storage/tianchi/tse_cbo.cc @@ -22,6 +22,29 @@ #include "datatype_cnvrtr.h" #include "tse_util.h" +#define BYTE 1 + +static inline void convert_enum_or_set_key_to_variant(cache_variant_t *ret_val, const uchar *key, Field *field) +{ + switch (field->pack_length()) { + case 1 * BYTE: + ret_val->v_uint32 = *(uint8_t *)const_cast(key); + break; + case 2 * BYTE: + ret_val->v_uint32 = *(uint16_t *)const_cast(key); + break; + case 3 * BYTE: + ret_val->v_uint32 = uint3korr(key); + break; + case 4 * BYTE: + ret_val->v_uint32 = *(uint32_t *)const_cast(key); + break; + case 8 * BYTE: + default: + ret_val->v_ubigint = *(uint64_t *)const_cast(key); + } +} + void r_key2variant(tse_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) { @@ -45,6 +68,13 @@ void r_key2variant(tse_key *rKey, KEY_PART_INFO *cur_index_part, cache_variant_t uchar tmp_ptr[TSE_BYTE_8] = {0}; const field_cnvrt_aux_t *mysql_info = get_auxiliary_for_field_convert(field, field->type()); switch(field->real_type()) { + case MYSQL_TYPE_SET: + case MYSQL_TYPE_ENUM: + convert_enum_or_set_key_to_variant(ret_val, key, field); + break; + case MYSQL_TYPE_BIT: + ret_val->v_ubigint = bit_cnvt_mysql_cantian(key, field); + break; case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: @@ -106,10 +136,26 @@ double datetime_compare(const uchar *datetime1, const uchar *datetime2) return datetime1_int - datetime2_int; } -en_tse_compare_type compare(cache_variant_t *right, cache_variant_t *left, enum_field_types field_type) +template +static inline en_tse_compare_type two_nums_compare(T a, T b) { + if (a > b) { return GREAT; } + if (a < b) { return LESS; } + return EQUAL; +} + +static en_tse_compare_type compare(cache_variant_t *right, cache_variant_t *left, Field *field) { double compare_value = 0; - switch(field_type) { + switch(field->real_type()) { + case MYSQL_TYPE_SET: + if (field->pack_length() <= 4) { + return two_nums_compare(right->v_uint32, left->v_uint32); + } + return two_nums_compare(right->v_ubigint, left->v_ubigint); + case MYSQL_TYPE_ENUM: + return two_nums_compare(right->v_uint32, left->v_uint32); + case MYSQL_TYPE_BIT: + return two_nums_compare(right->v_ubigint, left->v_ubigint); case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: @@ -168,14 +214,14 @@ double eval_density_result(double density) } static double calc_frequency_hist_equal_density(tse_cbo_stats_column_t *col_stat, cache_variant_t *val, - enum_field_types field_type) + Field *field) { en_tse_compare_type cmp_result; int64 result = 0; double density = col_stat->density; tse_cbo_column_hist_t *hist_infos = col_stat->column_hist; for (uint32 i = 0; i < col_stat->hist_count; i++) { - cmp_result = compare(&hist_infos[i].ep_value, val, field_type); + cmp_result = compare(&hist_infos[i].ep_value, val, field); if (cmp_result == EQUAL) { result = (i == 0) ? hist_infos[i].ep_number : hist_infos[i].ep_number - hist_infos[i - 1].ep_number; @@ -196,13 +242,13 @@ static double calc_frequency_hist_equal_density(tse_cbo_stats_column_t *col_stat } static double calc_balance_hist_equal_density(tse_cbo_stats_column_t *col_stat, cache_variant_t *val, - enum_field_types field_type) + Field *field) { uint32 popular_count = 0; en_tse_compare_type cmp_result; tse_cbo_column_hist_t *hist_infos = col_stat->column_hist; for (uint32 i = 0; i < col_stat->hist_count; i++) { - cmp_result = compare(&hist_infos[i].ep_value, val, field_type); + cmp_result = compare(&hist_infos[i].ep_value, val, field); if (cmp_result == EQUAL) { // ep_number is different from oracle, when compress balance histogram, need to change this @@ -228,7 +274,7 @@ static double calc_equal_null_density(tse_cbo_stats_table_t *cbo_stats, uint32 c } double calc_hist_equal_density(tse_cbo_stats_table_t *cbo_stats, cache_variant_t *val, - uint32 col_id, enum_field_types field_type) + uint32 col_id, Field* field) { tse_cbo_stats_column_t *col_stat = &cbo_stats->columns[col_id]; double density = col_stat->density; @@ -238,15 +284,15 @@ double calc_hist_equal_density(tse_cbo_stats_table_t *cbo_stats, cache_variant_t } if (col_stat->hist_type == FREQUENCY_HIST) { // HISTOGRAM_FREQUENCY - density = calc_frequency_hist_equal_density(col_stat, val, field_type); + density = calc_frequency_hist_equal_density(col_stat, val, field); } else { // HISTOGRAM_BALANCE - density = calc_balance_hist_equal_density(col_stat, val, field_type); + density = calc_balance_hist_equal_density(col_stat, val, field); } return density; } -static double calc_hist_between_frequency(tse_cbo_stats_table_t *cbo_stats, field_stats_val stats_val, enum_field_types field_type, uint32 col_id) +static double calc_hist_between_frequency(tse_cbo_stats_table_t *cbo_stats, field_stats_val stats_val, Field* field, uint32 col_id) { tse_cbo_stats_column_t *col_stat = &cbo_stats->columns[col_id]; double density = col_stat->density; @@ -265,7 +311,7 @@ static double calc_hist_between_frequency(tse_cbo_stats_table_t *cbo_stats, fiel // HISTOGRAM_FREQUNCEY for (uint32 i = 0; i < hist_count; i++) { - cmp_result = compare(&hist_infos[i].ep_value, stats_val.min_key_val, field_type); + cmp_result = compare(&hist_infos[i].ep_value, stats_val.min_key_val, field); 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) { @@ -278,7 +324,7 @@ static double calc_hist_between_frequency(tse_cbo_stats_table_t *cbo_stats, fiel for (uint32 i = 0; i < hist_count; i++) { - cmp_result = compare(&hist_infos[i].ep_value, stats_val.max_key_val, field_type); + cmp_result = compare(&hist_infos[i].ep_value, stats_val.max_key_val, field); 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)) { @@ -295,15 +341,31 @@ static double calc_hist_between_frequency(tse_cbo_stats_table_t *cbo_stats, fiel } -double percent_in_bucket(tse_cbo_stats_column_t *col_stat, uint32 high, - cache_variant_t *key, enum_field_types field_type) +static double percent_in_bucket(tse_cbo_stats_column_t *col_stat, uint32 high, + cache_variant_t *key, Field *field) { double percent = 0.0D; tse_cbo_column_hist_t *hist_infos = col_stat->column_hist; cache_variant_t *ep_high = high >= col_stat->hist_count ? &col_stat->high_value : &hist_infos[high].ep_value; cache_variant_t *ep_low = high < 1 ? &col_stat->low_value : &hist_infos[high - 1].ep_value; double denominator; - switch(field_type) { + switch(field->real_type()) { + case MYSQL_TYPE_SET: + if (field->pack_length() <= 4) { + if (ep_high->v_uint32 > ep_low->v_uint32) { + percent = (double)(ep_high->v_uint32 - key->v_uint32) / (ep_high->v_uint32 - ep_low->v_uint32); + } + } else { + if (ep_high->v_ubigint > ep_low->v_ubigint) { + percent = (double)(ep_high->v_ubigint - key->v_ubigint) / (ep_high->v_ubigint - ep_low->v_ubigint); + } + } + break; + case MYSQL_TYPE_ENUM: + if (ep_high->v_uint32 > ep_low->v_uint32) { + percent = (double)(ep_high->v_uint32 - key->v_uint32) / (ep_high->v_uint32 - ep_low->v_uint32); + } + break; case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: @@ -356,7 +418,7 @@ double percent_in_bucket(tse_cbo_stats_column_t *col_stat, uint32 high, return percent; } -static int calc_hist_range_boundary(field_stats_val stats_val, enum_field_types field_type, tse_cbo_stats_column_t *col_stat, +static int calc_hist_range_boundary(field_stats_val stats_val, Field *field, tse_cbo_stats_column_t *col_stat, double *percent) { en_tse_compare_type cmp_result; @@ -367,7 +429,7 @@ static int calc_hist_range_boundary(field_stats_val stats_val, enum_field_types lo_pos = hi_pos = hist_count - 1; for (i = 0; i < hist_count; i++) { - cmp_result = compare(&hist_infos[i].ep_value, stats_val.min_key_val, field_type); + cmp_result = compare(&hist_infos[i].ep_value, stats_val.min_key_val, field); if (cmp_result == GREAT) { lo_pos = i; break; @@ -375,10 +437,10 @@ static int calc_hist_range_boundary(field_stats_val stats_val, enum_field_types } // calc the part of value below lo_pos - *percent += percent_in_bucket(col_stat, i, stats_val.min_key_val, field_type); + *percent += percent_in_bucket(col_stat, i, stats_val.min_key_val, field); for (i = lo_pos; i < hist_count; i++) { - cmp_result = compare(&hist_infos[i].ep_value, stats_val.max_key_val, field_type); + cmp_result = compare(&hist_infos[i].ep_value, stats_val.max_key_val, field); if (cmp_result == GREAT || cmp_result == EQUAL) { hi_pos = i; break; @@ -386,25 +448,25 @@ static int calc_hist_range_boundary(field_stats_val stats_val, enum_field_types } // calc the part of value below hi_pos - *percent -= percent_in_bucket(col_stat, i, stats_val.max_key_val, field_type); + *percent -= percent_in_bucket(col_stat, i, stats_val.max_key_val, field); if (col_stat->num_buckets > 0) { *percent = *percent / col_stat->num_buckets; } if (stats_val.min_type == CMP_TYPE_CLOSE_INTERNAL) { - *percent += calc_balance_hist_equal_density(col_stat, stats_val.min_key_val, field_type); + *percent += calc_balance_hist_equal_density(col_stat, stats_val.min_key_val, field); } if (stats_val.max_type == CMP_TYPE_CLOSE_INTERNAL) { - *percent += calc_balance_hist_equal_density(col_stat, stats_val.max_key_val, field_type); + *percent += calc_balance_hist_equal_density(col_stat, stats_val.max_key_val, field); } // return complete bucket number return hi_pos - lo_pos; } -static double calc_hist_between_balance(tse_cbo_stats_table_t *cbo_stats, field_stats_val stats_val, enum_field_types field_type, uint32 col_id) +static double calc_hist_between_balance(tse_cbo_stats_table_t *cbo_stats, field_stats_val stats_val, Field *field, uint32 col_id) { tse_cbo_stats_column_t *col_stat = &cbo_stats->columns[col_id]; double density = col_stat->density; @@ -414,7 +476,7 @@ static double calc_hist_between_balance(tse_cbo_stats_table_t *cbo_stats, field_ } double percent = 0; - int bucket_range = calc_hist_range_boundary(stats_val, field_type, col_stat, &percent); + int bucket_range = calc_hist_range_boundary(stats_val, field, col_stat, &percent); if (col_stat->num_buckets > 0) { density = (double)bucket_range / col_stat->num_buckets + percent; @@ -425,16 +487,16 @@ static double calc_hist_between_balance(tse_cbo_stats_table_t *cbo_stats, field_ } static double calc_hist_between_density(tse_cbo_stats_table_t *cbo_stats, - uint32 col_id, enum_field_types field_type, field_stats_val stats_val) + uint32 col_id, Field *field, field_stats_val stats_val) { double density; tse_cbo_stats_column_t *col_stat = &cbo_stats->columns[col_id]; if (col_stat->hist_type == FREQUENCY_HIST) { // HISTOGRAM_FREQUENCY - density = calc_hist_between_frequency(cbo_stats, stats_val, field_type, col_id); + density = calc_hist_between_frequency(cbo_stats, stats_val, field, col_id); } else { // HISTOGRAM_BALANCE - density = calc_hist_between_balance(cbo_stats, stats_val, field_type, col_id); + density = calc_hist_between_balance(cbo_stats, stats_val, field, col_id); } return density; } @@ -467,14 +529,13 @@ double calc_density_by_cond(tse_cbo_stats_table_t *cbo_stats, KEY_PART_INFO cur_ cache_variant_t max_key_val; r_key2variant(min_key, &cur_index_part, &min_key_val, low_val, key_offset); r_key2variant(max_key, &cur_index_part, &max_key_val, high_val, key_offset); - enum_field_types field_type = cur_index_part.field->real_type(); - if (compare(&max_key_val, low_val, field_type) == LESS || compare(&min_key_val, high_val, field_type) == GREAT) { + if (compare(&max_key_val, low_val, cur_index_part.field) == LESS || compare(&min_key_val, high_val, cur_index_part.field) == GREAT) { return 0; } - en_tse_compare_type comapare_value = compare(&max_key_val, &min_key_val, field_type); + en_tse_compare_type comapare_value = compare(&max_key_val, &min_key_val, cur_index_part.field); if (comapare_value == EQUAL && min_key->cmp_type == CMP_TYPE_CLOSE_INTERNAL && max_key->cmp_type == CMP_TYPE_CLOSE_INTERNAL) { - return calc_hist_equal_density(cbo_stats, &max_key_val, col_id, field_type); + return calc_hist_equal_density(cbo_stats, &max_key_val, col_id, cur_index_part.field); } else if (comapare_value == UNCOMPARABLE) { return DEFAULT_RANGE_DENSITY; } else if (comapare_value == LESS) { @@ -482,7 +543,7 @@ double calc_density_by_cond(tse_cbo_stats_table_t *cbo_stats, KEY_PART_INFO cur_ } field_stats_val stats_val = {min_key->cmp_type, max_key->cmp_type, &max_key_val, &min_key_val}; - density = calc_hist_between_density(cbo_stats, col_id, field_type, stats_val); + density = calc_hist_between_density(cbo_stats, col_id, cur_index_part.field, stats_val); return density; } -- Gitee