From d2c977a9355f69311d0007f5e1b2eac958e5084d Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@macbook.gmz" <> Date: Wed, 7 Mar 2007 14:51:45 +0200 Subject: [PATCH 1/5] Bug #26672: DATE/DATETIME values are out of the currently supported 4 basic value types (INT,STRING,REAL and DECIMAL). So expressions (not fields) of compile type DATE/DATETIME are generally considered as STRING values. This is not so when they are compared : then they are compared as INTEGER values. But the rule for comparison as INTEGERS must be checked explicitly each time when a comparison is to be performed. filesort is one such place. However there the check was not done and hence the expressions (not fields) of type DATE/DATETIME were sorted by their string representation. Fixed to compare them as INTEGER values for filesort. --- mysql-test/r/order_by.result | 22 ++++++++++++++++++++++ mysql-test/t/order_by.test | 15 +++++++++++++++ sql/filesort.cc | 5 ++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 0b1edfd3e8f..2093b5cd465 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -934,3 +934,25 @@ a ratio 19 1.3333 9 2.6667 drop table t1; +CREATE TABLE t1 (a INT UNSIGNED NOT NULL, b TIME); +INSERT INTO t1 (a) VALUES (100000), (0), (100), (1000000),(10000), (1000), (10); +UPDATE t1 SET b = SEC_TO_TIME(a); +SELECT a, b FROM t1 ORDER BY b DESC; +a b +1000000 277:46:40 +100000 27:46:40 +10000 02:46:40 +1000 00:16:40 +100 00:01:40 +10 00:00:10 +0 00:00:00 +SELECT a, b FROM t1 ORDER BY SEC_TO_TIME(a) DESC; +a b +1000000 277:46:40 +100000 27:46:40 +10000 02:46:40 +1000 00:16:40 +100 00:01:40 +10 00:00:10 +0 00:00:00 +DROP TABLE t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index a3aa2c0081d..2de6f791cfa 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -648,3 +648,18 @@ create table t1 (a int, b int, c int); insert into t1 values (1,2,3), (9,8,3), (19,4,3), (1,4,9); select a,(sum(b)/sum(c)) as ratio from t1 group by a order by sum(b)/sum(c) asc; drop table t1; + +# +# Bug#26672: Incorrect SEC_TO_TIME() casting in ORDER BY +# +CREATE TABLE t1 (a INT UNSIGNED NOT NULL, b TIME); +INSERT INTO t1 (a) VALUES (100000), (0), (100), (1000000),(10000), (1000), (10); +UPDATE t1 SET b = SEC_TO_TIME(a); + +-- Correct ORDER +SELECT a, b FROM t1 ORDER BY b DESC; + +-- must be ordered as the above +SELECT a, b FROM t1 ORDER BY SEC_TO_TIME(a) DESC; + +DROP TABLE t1; diff --git a/sql/filesort.cc b/sql/filesort.cc index e40c492fe8e..23d652cb8cc 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1298,7 +1298,10 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, } else { - switch ((sortorder->result_type=sortorder->item->result_type())) { + sortorder->result_type= sortorder->item->result_type(); + if (sortorder->item->result_as_longlong()) + sortorder->result_type= INT_RESULT; + switch (sortorder->result_type) { case STRING_RESULT: sortorder->length=sortorder->item->max_length; set_if_smaller(sortorder->length, thd->variables.max_sort_length); From e7284ace4f0f25fef34a72c16e34c30e11fdf6b4 Mon Sep 17 00:00:00 2001 From: "igor@olga.mysql.com" <> Date: Sun, 11 Mar 2007 23:34:40 -0700 Subject: [PATCH 2/5] Fixed bug #26963: invalid optimization of the pushdown conditions after single-row table substitution could lead to a wrong result set. The bug happened because the function Item_field::replace_equal_field erroniously assumed that any field included in a multiple equality with a constant has been already substituted for this constant. This not true for fields becoming constant after row substitutions for constant tables. --- mysql-test/r/select.result | 38 ++++++++++++++++++++++++++++++ mysql-test/t/select.test | 47 ++++++++++++++++++++++++++++++++++++++ sql/item.cc | 15 ++++++++++-- 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index c3132a1b5f6..ae32607973a 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3933,4 +3933,42 @@ cc cc 7 aa aa 2 aa aa 2 DROP TABLE t1,t2; +CREATE TABLE t1 ( +access_id int NOT NULL default '0', +name varchar(20) default NULL, +rank int NOT NULL default '0', +KEY idx (access_id) +); +CREATE TABLE t2 ( +faq_group_id int NOT NULL default '0', +faq_id int NOT NULL default '0', +access_id int default NULL, +UNIQUE KEY idx1 (faq_id), +KEY idx2 (faq_group_id,faq_id) +); +INSERT INTO t1 VALUES +(1,'Everyone',2),(2,'Help',3),(3,'Technical Support',1),(4,'Chat User',4); +INSERT INTO t2 VALUES +(261,265,1),(490,494,1); +SELECT t2.faq_id +FROM t1 INNER JOIN t2 IGNORE INDEX (idx1) +ON (t1.access_id = t2.access_id) +LEFT JOIN t2 t +ON (t.faq_group_id = t2.faq_group_id AND +find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4')) +WHERE +t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265); +faq_id +265 +SELECT t2.faq_id +FROM t1 INNER JOIN t2 +ON (t1.access_id = t2.access_id) +LEFT JOIN t2 t +ON (t.faq_group_id = t2.faq_group_id AND +find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4')) +WHERE +t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265); +faq_id +265 +DROP TABLE t1,t2; End of 5.0 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index ea5fadb2e1b..8442a073620 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3299,4 +3299,51 @@ SELECT * FROM t1 LEFT JOIN t2 ON t1.name=t2.name; DROP TABLE t1,t2; + +# +# Bug #26963: join with predicates that contain fields from equalities evaluated +# to constants after constant table substitution +# + +CREATE TABLE t1 ( + access_id int NOT NULL default '0', + name varchar(20) default NULL, + rank int NOT NULL default '0', + KEY idx (access_id) +); + +CREATE TABLE t2 ( + faq_group_id int NOT NULL default '0', + faq_id int NOT NULL default '0', + access_id int default NULL, + UNIQUE KEY idx1 (faq_id), + KEY idx2 (faq_group_id,faq_id) +); + +INSERT INTO t1 VALUES + (1,'Everyone',2),(2,'Help',3),(3,'Technical Support',1),(4,'Chat User',4); +INSERT INTO t2 VALUES + (261,265,1),(490,494,1); + + +SELECT t2.faq_id + FROM t1 INNER JOIN t2 IGNORE INDEX (idx1) + ON (t1.access_id = t2.access_id) + LEFT JOIN t2 t + ON (t.faq_group_id = t2.faq_group_id AND + find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4')) + WHERE + t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265); + +SELECT t2.faq_id + FROM t1 INNER JOIN t2 + ON (t1.access_id = t2.access_id) + LEFT JOIN t2 t + ON (t.faq_group_id = t2.faq_group_id AND + find_in_set(t.access_id, '1,4') < find_in_set(t2.access_id, '1,4')) + WHERE + t2.access_id IN (1,4) AND t.access_id IS NULL AND t2.faq_id in (265); + +DROP TABLE t1,t2; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index ec33bf1ddc7..11a5039ca19 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4075,7 +4075,9 @@ bool Item_field::set_no_const_sub(byte *arg) DESCRIPTION The function returns a pointer to an item that is taken from the very beginning of the item_equal list which the Item_field - object refers to (belongs to). + object refers to (belongs to) unless item_equal contains a constant + item. In this case the function returns this constant item, + (if the substitution does not require conversion). If the Item_field object does not refer any Item_equal object 'this' is returned @@ -4084,7 +4086,8 @@ bool Item_field::set_no_const_sub(byte *arg) of the thransformer method. RETURN VALUES - pointer to a replacement Item_field if there is a better equal item; + pointer to a replacement Item_field if there is a better equal item or + a pointer to a constant equal item; this - otherwise. */ @@ -4092,6 +4095,14 @@ Item *Item_field::replace_equal_field(byte *arg) { if (item_equal) { + Item *const_item= item_equal->get_const(); + if (const_item) + { + if (cmp_context != (Item_result)-1 && + const_item->cmp_context != cmp_context) + return this; + return const_item; + } Item_field *subst= item_equal->get_first(); if (subst && !field->eq(subst->field)) return subst; From 06a315ded67a5751b46dd6295780e85e3e68de28 Mon Sep 17 00:00:00 2001 From: "igor@olga.mysql.com" <> Date: Mon, 12 Mar 2007 01:39:57 -0700 Subject: [PATCH 3/5] Fixed bug #26738: incomplete string values in a result set column when the column is to be read from a derived table column which was specified as a concatenation of string literals. The bug happened because the Item_string::append did not adjust the value of Item_string::max_length. As a result of it the temporary table column defined to store the concatenation of literals was not wide enough to hold the whole value. --- mysql-test/r/subselect.result | 13 +++++++++++++ mysql-test/t/subselect.test | 13 +++++++++++++ sql/item.h | 6 +++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 71dbff65e7d..f2d41bd44ae 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3867,3 +3867,16 @@ id_1 DROP TABLE t1; DROP TABLE t2; DROP TABLE t1xt2; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (3), (1), (2); +SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1; +col1 col2 +this is a test. 3 +this is a test. 1 +this is a test. 2 +SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t; +col1 t2 +this is a test. 3 +this is a test. 1 +this is a test. 2 +DROP table t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1deda2a4382..1655422c51e 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2729,3 +2729,16 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t1xt2; +# +# Bug #26728: derived table with concatanation of literals in select list +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (3), (1), (2); + +SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1; +SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t; + +DROP table t1; + + diff --git a/sql/item.h b/sql/item.h index fb1a87d54fa..c2084fb727c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1713,7 +1713,11 @@ public: str_value.length(), collation.collation); } Item *safe_charset_converter(CHARSET_INFO *tocs); - inline void append(char *str, uint length) { str_value.append(str, length); } + inline void append(char *str, uint length) + { + str_value.append(str, length); + max_length= str_value.numchars() * collation.collation->mbmaxlen; + } void print(String *str); // to prevent drop fixed flag (no need parent cleanup call) void cleanup() {} From 8c1f70aef6ed0abc70da2892d6c2b53f04d63265 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@magare.gmz" <> Date: Wed, 14 Mar 2007 11:54:20 +0200 Subject: [PATCH 4/5] Bug #26794: Different set of conditions is used to verify the validity of index definitions over a GEOMETRY column in ALTER TABLE and CREATE TABLE. The difference was on how sub-keys notion validity is checked. Fixed by extending the CREATE TABLE condition to support the cases allowed in ALTER TABLE. Made the SHOW CREATE TABLE not to display spatial indexes using the sub-key notion. --- mysql-test/r/alter_table.result | 34 +++++++++++++++++++++++++++++++++ mysql-test/r/gis-rtree.result | 4 ++-- mysql-test/t/alter_table.test | 23 ++++++++++++++++++++++ sql/field.cc | 1 + sql/sql_show.cc | 2 +- sql/sql_table.cc | 4 +++- 6 files changed, 64 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index d8de2655c6c..82c35ff963a 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -826,3 +826,37 @@ create table t1 (t varchar(255) default null, key t (t(80))) engine=myisam default charset=latin1; alter table t1 change t t text; drop table t1; +CREATE TABLE t1 (a varchar(500)); +ALTER TABLE t1 ADD b GEOMETRY NOT NULL, ADD SPATIAL INDEX(b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(500) default NULL, + `b` geometry NOT NULL, + SPATIAL KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 ADD KEY(b(50)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(500) default NULL, + `b` geometry NOT NULL, + SPATIAL KEY `b` (`b`), + KEY `b_2` (`b`(50)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 ADD c POINT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(500) default NULL, + `b` geometry NOT NULL, + `c` point default NULL, + SPATIAL KEY `b` (`b`), + KEY `b_2` (`b`(50)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +CREATE TABLE t2 (a INT, KEY (a(20))); +ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys +ALTER TABLE t1 ADD d INT; +ALTER TABLE t1 ADD KEY (d(20)); +ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys +DROP TABLE t1; diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index 05d0d5634e6..4ca2bc98d82 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -10,7 +10,7 @@ t1 CREATE TABLE `t1` ( `fid` int(11) NOT NULL auto_increment, `g` geometry NOT NULL, PRIMARY KEY (`fid`), - SPATIAL KEY `g` (`g`(32)) + SPATIAL KEY `g` (`g`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)')); @@ -293,7 +293,7 @@ t2 CREATE TABLE `t2` ( `fid` int(11) NOT NULL auto_increment, `g` geometry NOT NULL, PRIMARY KEY (`fid`), - SPATIAL KEY `g` (`g`(32)) + SPATIAL KEY `g` (`g`) ) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 SELECT count(*) FROM t2; count(*) diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 01f55931ca4..307138added 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -613,3 +613,26 @@ create table t1 (t varchar(255) default null, key t (t(80))) engine=myisam default charset=latin1; alter table t1 change t t text; drop table t1; + +# +# Bug #26794: Adding an index with a prefix on a SPATIAL type breaks ALTER +# TABLE +# +CREATE TABLE t1 (a varchar(500)); + +ALTER TABLE t1 ADD b GEOMETRY NOT NULL, ADD SPATIAL INDEX(b); +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD KEY(b(50)); +SHOW CREATE TABLE t1; + +ALTER TABLE t1 ADD c POINT; +SHOW CREATE TABLE t1; + +--error ER_WRONG_SUB_KEY +CREATE TABLE t2 (a INT, KEY (a(20))); + +ALTER TABLE t1 ADD d INT; +--error ER_WRONG_SUB_KEY +ALTER TABLE t1 ADD KEY (d(20)); + +DROP TABLE t1; diff --git a/sql/field.cc b/sql/field.cc index 981a877783f..0f8103b4046 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1011,6 +1011,7 @@ bool Field::type_can_have_key_part(enum enum_field_types type) case MYSQL_TYPE_BLOB: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: + case MYSQL_TYPE_GEOMETRY: return TRUE; default: return FALSE; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c4b06934fc3..24aef80626f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -992,7 +992,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) if (key_part->field && (key_part->length != table->field[key_part->fieldnr-1]->key_length() && - !(key_info->flags & HA_FULLTEXT))) + !(key_info->flags & (HA_FULLTEXT | HA_SPATIAL)))) { buff[0] = '('; char* end=int10_to_str((long) key_part->length / diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 512d990347f..38a22c47f12 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1344,6 +1344,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } else if (!f_is_geom(sql_field->pack_flag) && (column->length > length || + !Field::type_can_have_key_part (sql_field->sql_type) || ((f_is_packed(sql_field->pack_flag) || ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) && (key_info->flags & HA_NOSAME))) && @@ -3470,7 +3471,8 @@ view_err: checking whether cfield->length < key_part_length (in chars). */ if (!Field::type_can_have_key_part(cfield->field->type()) || - !Field::type_can_have_key_part(cfield->sql_type) || + (!Field::type_can_have_key_part(cfield->sql_type) && + !f_is_geom (cfield->pack_flag)) || (cfield->field->field_length == key_part_length && !f_is_blob(key_part->key_type)) || (cfield->length && (cfield->length < key_part_length / From 2525db66fa72538135a0da3225d71f7b854b6d89 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@magare.gmz" <> Date: Wed, 14 Mar 2007 15:58:14 +0200 Subject: [PATCH 5/5] Bug #26794: fixed valgrind warning --- sql/sql_table.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 38a22c47f12..14b9e0aa25d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3471,8 +3471,7 @@ view_err: checking whether cfield->length < key_part_length (in chars). */ if (!Field::type_can_have_key_part(cfield->field->type()) || - (!Field::type_can_have_key_part(cfield->sql_type) && - !f_is_geom (cfield->pack_flag)) || + !Field::type_can_have_key_part(cfield->sql_type) || (cfield->field->field_length == key_part_length && !f_is_blob(key_part->key_type)) || (cfield->length && (cfield->length < key_part_length /