From 342283d00af98f92b3960d49ffdb4e243ecd66ac Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Fri, 30 Jun 2006 09:34:06 +0400 Subject: [PATCH 1/2] BUG#20484: "Partitions: crash with EXPLAIN and UNION" - Don't forget to produce "partitions" column for "UNION RESULT" row of EXPLAIN output --- mysql-test/r/partition_pruning.result | 7 +++++++ mysql-test/t/partition_pruning.test | 7 +++++++ sql/sql_select.cc | 3 +++ 3 files changed, 17 insertions(+) diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index ee294242bf7..3b08f522129 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -697,3 +697,10 @@ ref NULL rows 2 Extra drop table t2; +create table t1 (s1 int); +explain partitions select 1 from t1 union all select 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 PRIMARY t1 NULL system NULL NULL NULL NULL 0 const row not found +2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT NULL ALL NULL NULL NULL NULL NULL +drop table t1; diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test index 976466e1578..8fdfca15eef 100644 --- a/mysql-test/t/partition_pruning.test +++ b/mysql-test/t/partition_pruning.test @@ -590,3 +590,10 @@ explain partitions select * from t2; --horizontal_results drop table t2; + +# BUG#20484 "Partitions: crash with explain and union" +create table t1 (s1 int); +explain partitions select 1 from t1 union all select 2; +drop table t1; + + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 193a29a1fe9..e3ce2b14bf4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13938,6 +13938,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } item_list.push_back(new Item_string(table_name_buffer, len, cs)); } + /* partitions */ + if (join->thd->lex->describe & DESCRIBE_PARTITIONS) + item_list.push_back(item_null); /* type */ item_list.push_back(new Item_string(join_type_str[JT_ALL], strlen(join_type_str[JT_ALL]), From e7db9d454537e9d6fa94b57070995cd9b8022190 Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Mon, 24 Jul 2006 21:58:11 +0400 Subject: [PATCH 2/2] BUG#20257: Fix partition pruning for BIGINT UNSIGNED: - Fix problems in the "Interval walking" partition interval analyzer. --- mysql-test/r/partition_pruning.result | 79 +++++++++++++++++++++++++++ mysql-test/t/partition_pruning.test | 66 ++++++++++++++++++++++ sql/sql_partition.cc | 16 ++++-- 3 files changed, 157 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index 3b08f522129..5e510f5d737 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -704,3 +704,82 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT NULL ALL NULL NULL NULL NULL NULL drop table t1; +create table t1 (a bigint unsigned not null) partition by range(a) ( +partition p0 values less than (10), +partition p1 values less than (100), +partition p2 values less than (1000), +partition p3 values less than (18446744073709551000), +partition p4 values less than (18446744073709551614) +); +insert into t1 values (5),(15),(105),(1005); +insert into t1 values (18446744073709551000+1); +insert into t1 values (18446744073709551614-1); +explain partitions select * from t1 where a < 10; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 system NULL NULL NULL NULL 1 +explain partitions select * from t1 +where a >= 18446744073709551000-1 and a <= 18446744073709551000+1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3,p4 ALL NULL NULL NULL NULL 3 Using where +explain partitions select * from t1 +where a between 18446744073709551001 and 18446744073709551002; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where +explain partitions select * from t1 where a = 18446744073709551000; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where +explain partitions select * from t1 where a = 18446744073709551613; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4 ALL NULL NULL NULL NULL 2 Using where +explain partitions select * from t1 where a = 18446744073709551614; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +drop table t1; +create table t1 (a int) +partition by range((a & 0xFF) << 56) ( +partition p0 values less than (0x40 << 56), +partition p1 values less than (0x80 << 56), +partition p2 values less than (0xFF << 56) +); +insert into t1 values (0x20), (0x20), (0x41), (0x41), (0xFE), (0xFE); +explain partitions select * from t1 where a=0; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where +explain partitions select * from t1 where a=0xFE; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2 ALL NULL NULL NULL NULL 2 Using where +explain partitions select * from t1 where a>0xFE and a<= 0xFF; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +drop table t1; +create table t1(a bigint unsigned not null) partition by range(a+0) ( +partition p1 values less than (10), +partition p2 values less than (20), +partition p3 values less than (2305561538531885056), +partition p4 values less than (2305561538531950591) +); +insert into t1 values (9),(19),(0xFFFF0000FFFF000-1), (0xFFFF0000FFFFFFF-1); +insert into t1 values (9),(19),(0xFFFF0000FFFF000-1), (0xFFFF0000FFFFFFF-1); +explain partitions select * from t1 where +a >= 2305561538531885056-10 and a <= 2305561538531885056-8; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3 ALL NULL NULL NULL NULL 4 Using where +explain partitions select * from t1 where +a > 0xFFFFFFFFFFFFFFEC and a < 0xFFFFFFFFFFFFFFEE; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +explain partitions select * from t1 where a>=0 and a <= 0xFFFFFFFFFFFFFFFF; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p1,p2,p3,p4 ALL NULL NULL NULL NULL 8 Using where +drop table t1; +create table t1 (a bigint) partition by range(a+0) ( +partition p1 values less than (-1000), +partition p2 values less than (-10), +partition p3 values less than (10), +partition p4 values less than (1000) +); +insert into t1 values (-15),(-5),(5),(15),(-15),(-5),(5),(15); +explain partitions select * from t1 where a>-2 and a <=0; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3 ALL NULL NULL NULL NULL 4 Using where +drop table t1; diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test index 8fdfca15eef..752ba8875c2 100644 --- a/mysql-test/t/partition_pruning.test +++ b/mysql-test/t/partition_pruning.test @@ -597,3 +597,69 @@ explain partitions select 1 from t1 union all select 2; drop table t1; +# BUG#20257: partition pruning test coverage for BIGINT UNSIGNED +create table t1 (a bigint unsigned not null) partition by range(a) ( + partition p0 values less than (10), + partition p1 values less than (100), + partition p2 values less than (1000), + partition p3 values less than (18446744073709551000), + partition p4 values less than (18446744073709551614) +); +insert into t1 values (5),(15),(105),(1005); +insert into t1 values (18446744073709551000+1); +insert into t1 values (18446744073709551614-1); + +explain partitions select * from t1 where a < 10; +explain partitions select * from t1 + where a >= 18446744073709551000-1 and a <= 18446744073709551000+1; + +explain partitions select * from t1 + where a between 18446744073709551001 and 18446744073709551002; + +explain partitions select * from t1 where a = 18446744073709551000; +explain partitions select * from t1 where a = 18446744073709551613; +explain partitions select * from t1 where a = 18446744073709551614; +drop table t1; + +create table t1 (a int) + partition by range((a & 0xFF) << 56) ( + partition p0 values less than (0x40 << 56), + partition p1 values less than (0x80 << 56), + partition p2 values less than (0xFF << 56) +); + +insert into t1 values (0x20), (0x20), (0x41), (0x41), (0xFE), (0xFE); +explain partitions select * from t1 where a=0; +explain partitions select * from t1 where a=0xFE; +explain partitions select * from t1 where a>0xFE and a<= 0xFF; +drop table t1; + +create table t1(a bigint unsigned not null) partition by range(a+0) ( + partition p1 values less than (10), + partition p2 values less than (20), + partition p3 values less than (2305561538531885056), + partition p4 values less than (2305561538531950591) +); + +insert into t1 values (9),(19),(0xFFFF0000FFFF000-1), (0xFFFF0000FFFFFFF-1); +insert into t1 values (9),(19),(0xFFFF0000FFFF000-1), (0xFFFF0000FFFFFFF-1); + +explain partitions select * from t1 where + a >= 2305561538531885056-10 and a <= 2305561538531885056-8; + +explain partitions select * from t1 where + a > 0xFFFFFFFFFFFFFFEC and a < 0xFFFFFFFFFFFFFFEE; + +explain partitions select * from t1 where a>=0 and a <= 0xFFFFFFFFFFFFFFFF; +drop table t1; + +create table t1 (a bigint) partition by range(a+0) ( + partition p1 values less than (-1000), + partition p2 values less than (-10), + partition p3 values less than (10), + partition p4 values less than (1000) +); +insert into t1 values (-15),(-5),(5),(15),(-15),(-5),(5),(15); +explain partitions select * from t1 where a>-2 and a <=0; +drop table t1; + diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 44c0b8ffcd9..8350d0b8ffd 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6566,10 +6566,19 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info, store_key_image_to_rec(field, max_value, len); b= field->val_int(); + + /* + Handle a special case where the distance between interval bounds is + exactly 4G-1. This interval is too big for range walking, and if it is an + (x,y]-type interval then the following "b +=..." code will convert it to + an empty interval by "wrapping around" a + 4G-1 + 1 = a. + */ + if ((ulonglong)b - (ulonglong)a == ~0ULL) + return -1; a += test(flags & NEAR_MIN); b += test(!(flags & NEAR_MAX)); - uint n_values= b - a; + ulonglong n_values= b - a; if (n_values > total_parts || n_values > MAX_RANGE_TO_WALK) return -1; @@ -6673,7 +6682,8 @@ static uint32 get_next_partition_via_walking(PARTITION_ITERATOR *part_iter) while (part_iter->field_vals.cur != part_iter->field_vals.end) { longlong dummy; - field->store(part_iter->field_vals.cur++, FALSE); + field->store(part_iter->field_vals.cur++, + ((Field_num*)field)->unsigned_flag); if (part_iter->part_info->is_sub_partitioned() && !part_iter->part_info->get_part_partition_id(part_iter->part_info, &part_id, &dummy) || @@ -6681,8 +6691,6 @@ static uint32 get_next_partition_via_walking(PARTITION_ITERATOR *part_iter) &part_id, &dummy)) return part_id; } - //psergey-todo: return partition(part_func(NULL)) here... - part_iter->field_vals.cur= part_iter->field_vals.start; return NOT_A_PARTITION_ID; }