diff --git a/mysql-test/suite/ctc/r/ctc_dml_ignore.result b/mysql-test/suite/ctc/r/ctc_dml_ignore.result index 3f8f3da558a80c3ec94dd4c6d2bcb65f449f7ef7..0cd793db695fa7104756f1934af38540babadfe8 100644 --- a/mysql-test/suite/ctc/r/ctc_dml_ignore.result +++ b/mysql-test/suite/ctc/r/ctc_dml_ignore.result @@ -468,6 +468,98 @@ count(*) 3 drop table t1; drop table t2; +CREATE TABLE `t2` ( +id int, +a int, +b int, +KEY `idx_a` (a), +KEY `idx_b` (b) +) +PARTITION BY RANGE (`id`) +(PARTITION p0 VALUES LESS THAN (10) ENGINE = CTC, +PARTITION p1 VALUES LESS THAN (20) ENGINE = CTC, +PARTITION p2 VALUES LESS THAN (30) ENGINE = CTC, +PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = CTC); +insert into t2 values(30, 2, 3), (20, 1, 3), (10, 1, 3), (null, 1, 3); +explain select /*+ INDEX_MERGE(t2 idx_a, idx_b) */ count(*) from t2 where a = 1 and b = 3; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 p0,p1,p2,p4 index_merge idx_a,idx_b idx_a,idx_b 5,5 NULL 1 100.00 Using intersect(idx_a,idx_b); Using where; Using pushed condition ((`test`.`t2`.`b` = 3) and (`test`.`t2`.`a` = 1)); Using index +Warnings: +Note 1003 /* select#1 */ select /*+ INDEX_MERGE(`t2`@`select#1` `idx_a`, `idx_b`) */ count(0) AS `count(*)` from `test`.`t2` where ((`test`.`t2`.`b` = 3) and (`test`.`t2`.`a` = 1)) +select /*+ INDEX_MERGE(t2 idx_a, idx_b) */ count(*) from t2 where a = 1 and b = 3; +count(*) +3 +explain select count(*) from t2 ignore index(idx_b) where a = 1 and b = 3; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 p0,p1,p2,p4 ref idx_a idx_a 5 const 1 33.33 Using where; Using pushed condition (`test`.`t2`.`b` = 3) +Warnings: +Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t2` IGNORE INDEX (`idx_b`) where ((`test`.`t2`.`b` = 3) and (`test`.`t2`.`a` = 1)) +select count(*) from t2 ignore index(idx_b) where a = 1 and b = 3; +count(*) +3 +explain select /*+ INDEX_MERGE(t2 idx_a, idx_b) */ count(*) from t2 where a = 1 or b = 3; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 p0,p1,p2,p4 index_merge idx_a,idx_b idx_a,idx_b 5,5 NULL 2 100.00 Using union(idx_a,idx_b); Using where; Using pushed condition ((`test`.`t2`.`a` = 1) or (`test`.`t2`.`b` = 3)) +Warnings: +Note 1003 /* select#1 */ select /*+ INDEX_MERGE(`t2`@`select#1` `idx_a`, `idx_b`) */ count(0) AS `count(*)` from `test`.`t2` where ((`test`.`t2`.`a` = 1) or (`test`.`t2`.`b` = 3)) +select /*+ INDEX_MERGE(t2 idx_a, idx_b) */ count(*) from t2 where a = 1 or b = 3; +count(*) +4 +explain select count(*) from t2 ignore index(idx_b) where a = 1 or b = 3; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 p0,p1,p2,p4 ALL idx_a NULL NULL NULL 3 55.56 Using where; Using pushed condition ((`test`.`t2`.`a` = 1) or (`test`.`t2`.`b` = 3)) +Warnings: +Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t2` IGNORE INDEX (`idx_b`) where ((`test`.`t2`.`a` = 1) or (`test`.`t2`.`b` = 3)) +select count(*) from t2 ignore index(idx_b) where a = 1 or b = 3; +count(*) +4 +drop table t2; +create table t8( +id int, +char_col char(20), +enum_col enum('x-small','small','medium','large','x-large'), +primary key (id), +key idx_char_col (char_col), +key idx_enum_col (enum_col)) +PARTITION BY RANGE (`id`) +(PARTITION p0 VALUES LESS THAN (90) ENGINE = CTC, +PARTITION p1 VALUES LESS THAN (420) ENGINE = CTC, +PARTITION p2 VALUES LESS THAN (510) ENGINE = CTC, +PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = CTC); +insert into t8 values(84, 'apple', 'x-large'), (417, 'apple' , 'x-large'), (439, 'qpple', 'x-large'), (847, 'apple', 'x-large'); +explain select /*+ INDEX_MERGE(t8 idx_char_col, idx_enum_col) */ count(*) from t8 where enum_col = 'x-large' and char_col = 'apple'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t8 p0,p1,p2,p4 index_merge idx_char_col,idx_enum_col idx_char_col,idx_enum_col 81,2 NULL 1 100.00 Using intersect(idx_char_col,idx_enum_col); Using where; Using pushed condition (`test`.`t8`.`char_col` = 'apple'); Using index +Warnings: +Note 1003 /* select#1 */ select /*+ INDEX_MERGE(`t8`@`select#1` `idx_char_col`, `idx_enum_col`) */ count(0) AS `count(*)` from `test`.`t8` where ((`test`.`t8`.`char_col` = 'apple') and (`test`.`t8`.`enum_col` = 'x-large')) +select /*+ INDEX_MERGE(t8 idx_char_col, idx_enum_col) */ count(*) from t8 where enum_col = 'x-large' and char_col = 'apple'; +count(*) +3 +explain select count(*) from t8 ignore index(idx_enum_col) where enum_col = 'x-large' and char_col = 'apple'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t8 p0,p1,p2,p4 ref idx_char_col idx_char_col 81 const 1 33.33 Using where; Using pushed condition (`test`.`t8`.`char_col` = 'apple') +Warnings: +Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t8` IGNORE INDEX (`idx_enum_col`) where ((`test`.`t8`.`char_col` = 'apple') and (`test`.`t8`.`enum_col` = 'x-large')) +select count(*) from t8 ignore index(idx_enum_col) where enum_col = 'x-large' and char_col = 'apple'; +count(*) +3 +explain select /*+ INDEX_MERGE(t8 idx_char_col, idx_enum_col) */ count(*) from t8 where enum_col = 'x-large' or char_col = 'apple'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t8 p0,p1,p2,p4 index_merge idx_char_col,idx_enum_col idx_enum_col,idx_char_col 2,81 NULL 2 100.00 Using union(idx_enum_col,idx_char_col); Using where +Warnings: +Note 1003 /* select#1 */ select /*+ INDEX_MERGE(`t8`@`select#1` `idx_char_col`, `idx_enum_col`) */ count(0) AS `count(*)` from `test`.`t8` where ((`test`.`t8`.`enum_col` = 'x-large') or (`test`.`t8`.`char_col` = 'apple')) +select /*+ INDEX_MERGE(t8 idx_char_col, idx_enum_col) */ count(*) from t8 where enum_col = 'x-large' or char_col = 'apple'; +count(*) +4 +explain select count(*) from t8 ignore index(idx_enum_col) where enum_col = 'x-large' or char_col = 'apple'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t8 p0,p1,p2,p4 ALL idx_char_col NULL NULL NULL 3 55.56 Using where +Warnings: +Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t8` IGNORE INDEX (`idx_enum_col`) where ((`test`.`t8`.`enum_col` = 'x-large') or (`test`.`t8`.`char_col` = 'apple')) +select count(*) from t8 ignore index(idx_enum_col) where enum_col = 'x-large' or char_col = 'apple'; +count(*) +4 +drop table t8; CREATE TABLE `test` ( `a` int NOT NULL, `b` int NOT NULL, diff --git a/mysql-test/suite/ctc/t/ctc_dml_ignore.test b/mysql-test/suite/ctc/t/ctc_dml_ignore.test index 57c833fbd9dee2e6fb256050ffa19e0a19a239ac..fb464b691795fdcd5d65ea6e74a01eee9c17dd9f 100644 --- a/mysql-test/suite/ctc/t/ctc_dml_ignore.test +++ b/mysql-test/suite/ctc/t/ctc_dml_ignore.test @@ -221,6 +221,52 @@ select /*+ INDEX_MERGE(t2 idx_char_col,idx_enum_col) */ count(*) from t2 where e drop table t1; drop table t2; +CREATE TABLE `t2` ( + id int, + a int, + b int, + KEY `idx_a` (a), + KEY `idx_b` (b) +) +PARTITION BY RANGE (`id`) +(PARTITION p0 VALUES LESS THAN (10) ENGINE = CTC, +PARTITION p1 VALUES LESS THAN (20) ENGINE = CTC, +PARTITION p2 VALUES LESS THAN (30) ENGINE = CTC, +PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = CTC); +insert into t2 values(30, 2, 3), (20, 1, 3), (10, 1, 3), (null, 1, 3); +explain select /*+ INDEX_MERGE(t2 idx_a, idx_b) */ count(*) from t2 where a = 1 and b = 3; +select /*+ INDEX_MERGE(t2 idx_a, idx_b) */ count(*) from t2 where a = 1 and b = 3; +explain select count(*) from t2 ignore index(idx_b) where a = 1 and b = 3; +select count(*) from t2 ignore index(idx_b) where a = 1 and b = 3; +explain select /*+ INDEX_MERGE(t2 idx_a, idx_b) */ count(*) from t2 where a = 1 or b = 3; +select /*+ INDEX_MERGE(t2 idx_a, idx_b) */ count(*) from t2 where a = 1 or b = 3; +explain select count(*) from t2 ignore index(idx_b) where a = 1 or b = 3; +select count(*) from t2 ignore index(idx_b) where a = 1 or b = 3; +drop table t2; + +create table t8( + id int, + char_col char(20), + enum_col enum('x-small','small','medium','large','x-large'), + primary key (id), + key idx_char_col (char_col), + key idx_enum_col (enum_col)) +PARTITION BY RANGE (`id`) +(PARTITION p0 VALUES LESS THAN (90) ENGINE = CTC, +PARTITION p1 VALUES LESS THAN (420) ENGINE = CTC, +PARTITION p2 VALUES LESS THAN (510) ENGINE = CTC, +PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = CTC); +insert into t8 values(84, 'apple', 'x-large'), (417, 'apple' , 'x-large'), (439, 'qpple', 'x-large'), (847, 'apple', 'x-large'); +explain select /*+ INDEX_MERGE(t8 idx_char_col, idx_enum_col) */ count(*) from t8 where enum_col = 'x-large' and char_col = 'apple'; +select /*+ INDEX_MERGE(t8 idx_char_col, idx_enum_col) */ count(*) from t8 where enum_col = 'x-large' and char_col = 'apple'; +explain select count(*) from t8 ignore index(idx_enum_col) where enum_col = 'x-large' and char_col = 'apple'; +select count(*) from t8 ignore index(idx_enum_col) where enum_col = 'x-large' and char_col = 'apple'; +explain select /*+ INDEX_MERGE(t8 idx_char_col, idx_enum_col) */ count(*) from t8 where enum_col = 'x-large' or char_col = 'apple'; +select /*+ INDEX_MERGE(t8 idx_char_col, idx_enum_col) */ count(*) from t8 where enum_col = 'x-large' or char_col = 'apple'; +explain select count(*) from t8 ignore index(idx_enum_col) where enum_col = 'x-large' or char_col = 'apple'; +select count(*) from t8 ignore index(idx_enum_col) where enum_col = 'x-large' or char_col = 'apple'; +drop table t8; + CREATE TABLE `test` ( `a` int NOT NULL, `b` int NOT NULL, diff --git a/storage/ctc/ha_ctcpart.cc b/storage/ctc/ha_ctcpart.cc index 183fa4a77c3f0507aae6e558ee084817a079134a..b8145402a9f7cdab95cb97c7d0a10b6866e368a3 100644 --- a/storage/ctc/ha_ctcpart.cc +++ b/storage/ctc/ha_ctcpart.cc @@ -404,6 +404,32 @@ void ha_ctcpart::position_in_last_part(uchar *ref_arg, const uchar *record) { reset_partition(part_id); } +int ha_ctcpart::key_and_rowid_cmp(KEY **key_info, uchar *a, uchar *b) { + int cmp = key_rec_cmp(key_info, a, b); + if (cmp != 0) { + return (cmp); + } + + /* We must compare by rowid, which is added before the record, in the priority queue. */ + return (ctc_cmp_cantian_rowid((rowid_t *)(a - ROW_ID_LENGTH), (rowid_t *)(b - ROW_ID_LENGTH))); +} + +int ha_ctcpart::extra(enum ha_extra_function operation) { + if (operation == HA_EXTRA_SECONDARY_SORT_ROWID) { + m_ref_usage = Partition_helper::REF_USED_FOR_SORT; + m_queue->m_fun = key_and_rowid_cmp; + return (0); + } + return (ha_ctc::extra(operation)); +} + +int ha_ctcpart::cmp_ref(const uchar *ref1, const uchar *ref2) const { + DBUG_TRACE; + int cmp = ha_ctc::cmp_ref(ref1 + PARTITION_BYTES_IN_POS, ref2 + PARTITION_BYTES_IN_POS); + + return (cmp); +} + /** Get a row from a position. Fetches a row from the table based on a row reference. diff --git a/storage/ctc/ha_ctcpart.h b/storage/ctc/ha_ctcpart.h index 8f010e1e55bc69d6f15315894c38b23b1f399302..e4c99ac18a7381879413c908a3d9f7a2d24382c9 100644 --- a/storage/ctc/ha_ctcpart.h +++ b/storage/ctc/ha_ctcpart.h @@ -213,6 +213,12 @@ class ha_ctcpart : public ha_ctc, const uchar *key, key_part_map keypart_map, enum ha_rkey_function find_flag) override; + static int key_and_rowid_cmp(KEY **key_info, uchar *a, uchar *b); + + int extra(enum ha_extra_function operation) override; + + int cmp_ref(const uchar *ref1, const uchar *ref2) const override; + /** Open an CTC table. @param[in] name table name @param[in] mode access mode