From 058d22967ffb666bb1cd22b58fe074042e5eff80 Mon Sep 17 00:00:00 2001 From: "evgen@sunlight.local" <> Date: Fri, 15 Sep 2006 02:18:30 +0400 Subject: [PATCH 1/5] type_date.result: Added the test case for bug#21677: Wrong result when comparing a DATE and a DATETIME in BETWEEN Corrected a test case after removal of fix for bug#16377 query_cache.result, func_time.test, view.result, view.test, func_time.result: Corrected a test case after removal of fix for bug#16377 type_date.test: Added the test case for bug#21677: Wrong result when comparing a DATE and a DATETIME in BETWEEN Corrected a test case after removal of fix for bug#16377 item_cmpfunc.cc: Removed changes to the Item_func_between::fix_length_and_dec() made in the fix for bug#16377 --- mysql-test/r/func_time.result | 25 +++--- mysql-test/r/query_cache.result | 12 +-- mysql-test/r/type_date.result | 10 ++- mysql-test/r/view.result | 4 +- mysql-test/t/func_time.test | 22 ++--- mysql-test/t/type_date.test | 11 ++- mysql-test/t/view.test | 4 +- sql/item_cmpfunc.cc | 151 ++++++-------------------------- 8 files changed, 78 insertions(+), 161 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index dc6a4561531..36f1166c7be 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -840,39 +840,36 @@ drop table t1; create table t1(f1 date, f2 time, f3 datetime); insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01"); insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02"); -select f1 from t1 where f1 between "2006-1-1" and 20060101; +select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date); f1 2006-01-01 -select f1 from t1 where f1 between "2006-1-1" and "2006.1.1"; +select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date); f1 2006-01-01 -select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1"; +select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as date); f1 2006-01-01 -select f2 from t1 where f2 between "12:1:2" and "12:2:2"; +select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time); f2 12:01:02 -select f2 from t1 where time(f2) between "12:1:2" and "12:2:2"; +select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as time); f2 12:01:02 -select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2"; +select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime); f3 2006-01-01 12:01:01 -select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2"; +select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime); f3 2006-01-01 12:01:01 -select f1 from t1 where "2006-1-1" between f1 and f3; +select f1 from t1 where cast("2006-1-1" as date) between f1 and f3; f1 2006-01-01 -select f1 from t1 where "2006-1-1" between date(f1) and date(f3); +select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3); f1 2006-01-01 -select f1 from t1 where "2006-1-1" between f1 and 'zzz'; +select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz'; f1 -Warnings: -Warning 1292 Incorrect date value: 'zzz' for column 'f1' at row 1 -Warning 1292 Truncated incorrect DOUBLE value: 'zzz' -Warning 1292 Truncated incorrect DOUBLE value: 'zzz' +2006-01-01 select f1 from t1 where makedate(2006,1) between date(f1) and date(f3); f1 2006-01-01 diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index a735b52a26f..5224280e134 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -947,24 +947,24 @@ COUNT(*) Warnings: Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 -Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' -Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' +Warning 1292 Truncated incorrect INTEGER value: '20050327 invalid' +Warning 1292 Truncated incorrect INTEGER value: '20050327 invalid' SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid'; COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 -Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid' -Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid' +Warning 1292 Truncated incorrect INTEGER value: '20050328 invalid' +Warning 1292 Truncated incorrect INTEGER value: '20050328 invalid' SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid'; COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 -Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' -Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' +Warning 1292 Truncated incorrect INTEGER value: '20050327 invalid' +Warning 1292 Truncated incorrect INTEGER value: '20050327 invalid' show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index e88eebffb55..ed15293bb45 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -27,12 +27,12 @@ INSERT INTO t1 VALUES ( "2000-1-2" ); INSERT INTO t1 VALUES ( "2000-1-3" ); INSERT INTO t1 VALUES ( "2000-1-4" ); INSERT INTO t1 VALUES ( "2000-1-5" ); -SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4"; +SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as date); datum 2000-01-02 2000-01-03 2000-01-04 -SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY; +SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100 DAY; datum DROP TABLE t1; CREATE TABLE t1 ( @@ -104,3 +104,9 @@ SELECT * FROM t1; y 0000 DROP TABLE t1; +create table t1(start_date date, end_date date); +insert into t1 values ('2000-01-01','2000-01-02'); +select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date; +1 +1 +drop table t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index f70547cd4a8..f9c68235e19 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2586,13 +2586,13 @@ INSERT INTO t1 VALUES (4, '2005-01-03'), (5, '2005-01-04'), (6, '2005-01-05'), (7, '2005-01-05'), (8, '2005-01-05'), (9, '2005-01-06'); CREATE VIEW v1 AS SELECT * FROM t1; -SELECT * FROM t1 WHERE td BETWEEN '2005.01.02' AND '2005.01.04'; +SELECT * FROM t1 WHERE td BETWEEN CAST('2005.01.02' AS DATE) AND CAST('2005.01.04' AS DATE); id td 2 2005-01-02 3 2005-01-02 4 2005-01-03 5 2005-01-04 -SELECT * FROM v1 WHERE td BETWEEN '2005.01.02' AND '2005.01.04'; +SELECT * FROM v1 WHERE td BETWEEN CAST('2005.01.02' AS DATE) AND CAST('2005.01.04' AS DATE); id td 2 2005-01-02 3 2005-01-02 diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index be09b00ad46..fe34480d5d3 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -419,20 +419,20 @@ drop table t1; # # Bug#16377 result of DATE/TIME functions were compared as strings which # can lead to a wrong result. -# +# Now wrong dates should be compared only with CAST() create table t1(f1 date, f2 time, f3 datetime); insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01"); insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02"); -select f1 from t1 where f1 between "2006-1-1" and 20060101; -select f1 from t1 where f1 between "2006-1-1" and "2006.1.1"; -select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1"; -select f2 from t1 where f2 between "12:1:2" and "12:2:2"; -select f2 from t1 where time(f2) between "12:1:2" and "12:2:2"; -select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2"; -select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2"; -select f1 from t1 where "2006-1-1" between f1 and f3; -select f1 from t1 where "2006-1-1" between date(f1) and date(f3); -select f1 from t1 where "2006-1-1" between f1 and 'zzz'; +select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date); +select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date); +select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as date); +select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time); +select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as time); +select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime); +select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime); +select f1 from t1 where cast("2006-1-1" as date) between f1 and f3; +select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3); +select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz'; select f1 from t1 where makedate(2006,1) between date(f1) and date(f3); select f1 from t1 where makedate(2006,2) between date(f1) and date(f3); drop table t1; diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 78bdd9b8a80..c6050753943 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -36,8 +36,8 @@ INSERT INTO t1 VALUES ( "2000-1-2" ); INSERT INTO t1 VALUES ( "2000-1-3" ); INSERT INTO t1 VALUES ( "2000-1-4" ); INSERT INTO t1 VALUES ( "2000-1-5" ); -SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4"; -SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY; +SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as date); +SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100 DAY; DROP TABLE t1; # @@ -115,4 +115,11 @@ INSERT INTO t1 VALUES ('abc'); SELECT * FROM t1; DROP TABLE t1; +# +# Bug#21677: Wrong result when comparing a DATE and a DATETIME in BETWEEN +# +create table t1(start_date date, end_date date); +insert into t1 values ('2000-01-01','2000-01-02'); +select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date; +drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index edff38274c4..90d0c6b3f8d 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2449,8 +2449,8 @@ INSERT INTO t1 VALUES CREATE VIEW v1 AS SELECT * FROM t1; -SELECT * FROM t1 WHERE td BETWEEN '2005.01.02' AND '2005.01.04'; -SELECT * FROM v1 WHERE td BETWEEN '2005.01.02' AND '2005.01.04'; +SELECT * FROM t1 WHERE td BETWEEN CAST('2005.01.02' AS DATE) AND CAST('2005.01.04' AS DATE); +SELECT * FROM v1 WHERE td BETWEEN CAST('2005.01.02' AS DATE) AND CAST('2005.01.04' AS DATE); DROP VIEW v1; DROP TABLE t1; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 919a23ed65d..67b9d30d98d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -77,131 +77,14 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems) This function aggregates result types from the array of items. Found type supposed to be used later for comparison of values of these items. Aggregation itself is performed by the item_cmp_type() function. - - NOTES - Aggregation rules: - If there are DATE/TIME fields/functions in the list and no string - fields/functions in the list then: - The INT_RESULT type will be used for aggregation instead of original - result type of any DATE/TIME field/function in the list - All constant items in the list will be converted to a DATE/TIME using - found field or result field of found function. - - Implementation notes: - The code is equivalent to: - 1. Check the list for presence of a STRING field/function. - Collect the is_const flag. - 2. Get a Field* object to use for type coercion - 3. Perform type conversion. - 1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME - field/function and checks presence of a STRING field/function. - The second loop works only if a DATE/TIME field/function is found. - It checks presence of a STRING field/function in the rest of the list. - - TODO - 1) The current implementation can produce false comparison results for - expressions like: - date_time_field BETWEEN string_field_with_dates AND string_constant - if the string_constant will omit some of leading zeroes. - In order to fully implement correct comparison of DATE/TIME the new - DATETIME_RESULT result type should be introduced and agg_cmp_type() - should return the DATE/TIME field used for the conversion. Later - this field can be used by comparison functions like Item_func_between to - convert string values to ints on the fly and thus return correct results. - This modification will affect functions BETWEEN, IN and CASE. - - 2) If in the list a DATE field/function and a DATETIME field/function - are present in the list then the first found field/function will be - used for conversion. This may lead to wrong results and probably should - be fixed. */ static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) { uint i; - Item::Type res= (Item::Type)0; - /* Used only for date/time fields, max_length = 19 */ - char buff[20]; - uchar null_byte; - Field *field= NULL; - - /* - Do not convert items while creating a or showing a view in order - to store/display the original query in these cases. - */ - if (thd->lex->sql_command != SQLCOM_CREATE_VIEW && - thd->lex->sql_command != SQLCOM_SHOW_CREATE) - { - /* Search for date/time fields/functions */ - for (i= 0; i < nitems; i++) - { - if (!items[i]->result_as_longlong()) - { - /* Do not convert anything if a string field/function is present */ - if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT) - { - i= nitems; - break; - } - continue; - } - if ((res= items[i]->real_item()->type()) == Item::FIELD_ITEM && - items[i]->result_type() != INT_RESULT) - { - field= ((Item_field *)items[i]->real_item())->field; - break; - } - else if (res == Item::FUNC_ITEM) - { - field= items[i]->tmp_table_field_from_field_type(0); - if (field) - field->move_field(buff, &null_byte, 0); - break; - } - } - } - if (field) - { - /* Check the rest of the list for presence of a string field/function. */ - for (i++ ; i < nitems; i++) - { - if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT && - !items[i]->result_as_longlong()) - { - if (res == Item::FUNC_ITEM) - delete field; - field= 0; - break; - } - } - } - /* - If the first item is a date/time function then its result should be - compared as int - */ - if (field) - /* Suppose we are comparing dates */ - type[0]= INT_RESULT; - else - type[0]= items[0]->result_type(); - - for (i= 0; i < nitems ; i++) - { - Item_result result= items[i]->result_type(); - /* - Use INT_RESULT as result type for DATE/TIME fields/functions and - for constants successfully converted to DATE/TIME - */ - if (field && - ((!items[i]->const_item() && items[i]->result_as_longlong()) || - (items[i]->const_item() && convert_constant_item(thd, field, - &items[i])))) - result= INT_RESULT; - type[0]= item_cmp_type(type[0], result); - } - - if (res == Item::FUNC_ITEM && field) - delete field; + type[0]= items[0]->result_type(); + for (i= 1 ; i < nitems ; i++) + type[0]= item_cmp_type(type[0], items[i]->result_type()); } @@ -1222,8 +1105,32 @@ void Item_func_between::fix_length_and_dec() agg_cmp_type(thd, &cmp_type, args, 3); args[0]->cmp_context= args[1]->cmp_context= args[2]->cmp_context= cmp_type; - if (cmp_type == STRING_RESULT) - agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1); + if (cmp_type == STRING_RESULT && + agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1)) + return; + + /* + Make a special case of compare with date/time and longlong fields. + They are compared as integers, so for const item this time-consuming + conversion can be done only once, not for every single comparison + */ + if (args[0]->type() == FIELD_ITEM && + thd->lex->sql_command != SQLCOM_CREATE_VIEW && + thd->lex->sql_command != SQLCOM_SHOW_CREATE) + { + Field *field=((Item_field*) args[0])->field; + if (field->can_be_compared_as_longlong()) + { + /* + The following can't be recoded with || as convert_constant_item + changes the argument + */ + if (convert_constant_item(thd, field,&args[1])) + cmp_type=INT_RESULT; // Works for all types. + if (convert_constant_item(thd, field,&args[2])) + cmp_type=INT_RESULT; // Works for all types. + } + } } From a039376c4359beaa89259f0b4c2eb6ecc9156432 Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/gluh.(none)" <> Date: Wed, 27 Sep 2006 17:49:16 +0500 Subject: [PATCH 2/5] Patch for bug#21432 is reverted --- include/mysql_com.h | 3 --- mysql-test/r/ctype_utf8.result | 12 ------------ mysql-test/t/ctype_utf8.test | 16 ---------------- sql-common/client.c | 6 +++--- sql/sql_acl.cc | 6 +----- sql/sql_parse.cc | 4 ++-- sql/table.cc | 6 ++---- 7 files changed, 8 insertions(+), 45 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index 28c3f86701f..56c7f7d2ab5 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -26,9 +26,6 @@ #define USERNAME_LENGTH 16 #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 -#define SYSTEM_CHARSET_MBMAXLEN 3 -#define NAME_BYTE_LEN NAME_LEN*SYSTEM_CHARSET_MBMAXLEN -#define USERNAME_BYTE_LENGTH USERNAME_LENGTH*SYSTEM_CHARSET_MBMAXLEN #define LOCAL_HOST "localhost" #define LOCAL_HOST_NAMEDPIPE "." diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 941b834a733..5a175ba1713 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1340,15 +1340,3 @@ select a from t1 group by a; a e drop table t1; -set names utf8; -grant select on test.* to юзер_юзер@localhost; -user() -юзер_юзер@localhost -revoke all on test.* from юзер_юзер@localhost; -drop user юзер_юзер@localhost; -create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -select database(); -database() -имя_базы_в_кодировке_утф8_длиной_больше_чем_45 -drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 7272cb79089..eb395680cc9 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1072,20 +1072,4 @@ explain select a from t1 group by a; select a from t1 group by a; drop table t1; -# -# Bug#20393: User name truncation in mysql client -# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte -# -set names utf8; -#create user юзер_юзер@localhost; -grant select on test.* to юзер_юзер@localhost; ---exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()" -revoke all on test.* from юзер_юзер@localhost; -drop user юзер_юзер@localhost; - -create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; -select database(); -drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; - # End of 4.1 tests diff --git a/sql-common/client.c b/sql-common/client.c index 4d37b850bcb..ff5f1ef150a 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1618,7 +1618,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket,ulong client_flag) { - char buff[NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+100]; + char buff[NAME_LEN+USERNAME_LENGTH+100]; char *end,*host_info; my_socket sock; in_addr_t ip_addr; @@ -2063,7 +2063,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->server_status, client_flag)); /* This needs to be changed as it's not useful with big packets */ if (user && user[0]) - strmake(end,user,USERNAME_BYTE_LENGTH); /* Max user name */ + strmake(end,user,USERNAME_LENGTH); /* Max user name */ else read_user_name((char*) end); @@ -2093,7 +2093,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, /* Add database if needed */ if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) { - end= strmake(end, db, NAME_BYTE_LEN) + 1; + end= strmake(end, db, NAME_LEN) + 1; mysql->db= my_strdup(db,MYF(MY_WME)); db= 0; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 6ede19d0e96..0ad5432f3eb 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2640,11 +2640,7 @@ int mysql_grant(THD *thd, const char *db, List &list, while ((Str = str_list++)) { if (Str->host.length > HOSTNAME_LENGTH || - system_charset_info->cset->charpos(system_charset_info, - Str->user.str, - Str->user.str + - Str->user.length, - USERNAME_LENGTH) < Str->user.length) + Str->user.length > USERNAME_LENGTH) { my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); result= -1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 59c4026ba7f..98199ed22f1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -902,8 +902,8 @@ static int check_connection(THD *thd) char *user= end; char *passwd= strend(user)+1; char *db= passwd; - char db_buff[NAME_BYTE_LEN + 1]; // buffer to store db in utf8 - char user_buff[USERNAME_BYTE_LENGTH + 1]; // buffer to store user in utf8 + char db_buff[NAME_LEN + 1]; // buffer to store db in utf8 + char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8 uint dummy_errors; /* diff --git a/sql/table.cc b/sql/table.cc index 7587531b2f9..04d68a92bd7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1413,7 +1413,7 @@ char *get_field(MEM_ROOT *mem, Field *field) bool check_db_name(char *name) { - uint name_length= 0; // name length in symbols + char *start= name; /* Used to catch empty names and names with end space */ bool last_char_is_space= TRUE; @@ -1430,7 +1430,6 @@ bool check_db_name(char *name) name+system_charset_info->mbmaxlen); if (len) { - name_length++; name += len; continue; } @@ -1438,13 +1437,12 @@ bool check_db_name(char *name) #else last_char_is_space= *name==' '; #endif - name_length++; if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR || *name == FN_EXTCHAR) return 1; name++; } - return (last_char_is_space || name_length > NAME_LEN); + return last_char_is_space || (uint) (name - start) > NAME_LEN; } From c3d63bef2b871ba7ab904f1b41a148d4e176d9f9 Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/gluh.(none)" <> Date: Wed, 27 Sep 2006 19:21:29 +0500 Subject: [PATCH 3/5] after merge fix --- include/mysql_com.h | 2 +- sql/slave.h | 2 +- sql/sp.cc | 8 ++++---- sql/sp_head.cc | 6 +++--- sql/sql_acl.cc | 21 ++++++++++----------- sql/sql_class.h | 2 +- sql/sql_parse.cc | 2 +- sql/sql_repl.h | 2 +- 8 files changed, 22 insertions(+), 23 deletions(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index b3a632802c1..4c7640376a6 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -33,7 +33,7 @@ MySQL standard format: user_name_part@host_name_part\0 */ -#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_BYTE_LENGTH + 2 +#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2 #define LOCAL_HOST "localhost" #define LOCAL_HOST_NAMEDPIPE "." diff --git a/sql/slave.h b/sql/slave.h index dee134aaa0c..c355f7172a9 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -406,7 +406,7 @@ typedef struct st_master_info /* the variables below are needed because we can change masters on the fly */ char master_log_name[FN_REFLEN]; char host[HOSTNAME_LENGTH+1]; - char user[USERNAME_BYTE_LENGTH+1]; + char user[USERNAME_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; my_bool ssl; // enables use of SSL connection if true char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN]; diff --git a/sql/sp.cc b/sql/sp.cc index 63175b110fa..fc72822c15e 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -404,16 +404,16 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, { LEX *old_lex= thd->lex, newlex; String defstr; - char old_db_buf[NAME_BYTE_LEN+1]; + char old_db_buf[NAME_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; ulong old_sql_mode= thd->variables.sql_mode; ha_rows old_select_limit= thd->variables.select_limit; sp_rcontext *old_spcont= thd->spcont; - char definer_user_name_holder[USERNAME_BYTE_LENGTH + 1]; + char definer_user_name_holder[USERNAME_LENGTH + 1]; LEX_STRING_WITH_INIT definer_user_name(definer_user_name_holder, - USERNAME_BYTE_LENGTH); + USERNAME_LENGTH); char definer_host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING_WITH_INIT definer_host_name(definer_host_name_holder, @@ -511,7 +511,7 @@ db_create_routine(THD *thd, int type, sp_head *sp) int ret; TABLE *table; char definer[USER_HOST_BUFF_SIZE]; - char old_db_buf[NAME_BYTE_LEN+1]; + char old_db_buf[NAME_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; DBUG_ENTER("db_create_routine"); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index e5b0b1e606e..9761de625be 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -924,7 +924,7 @@ bool sp_head::execute(THD *thd) { DBUG_ENTER("sp_head::execute"); - char old_db_buf[NAME_BYTE_LEN+1]; + char old_db_buf[NAME_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; sp_rcontext *ctx; @@ -1957,8 +1957,8 @@ sp_head::set_info(longlong created, longlong modified, void sp_head::set_definer(const char *definer, uint definerlen) { - char user_name_holder[USERNAME_BYTE_LENGTH + 1]; - LEX_STRING_WITH_INIT user_name(user_name_holder, USERNAME_BYTE_LENGTH); + char user_name_holder[USERNAME_LENGTH + 1]; + LEX_STRING_WITH_INIT user_name(user_name_holder, USERNAME_LENGTH); char host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING_WITH_INIT host_name(host_name_holder, HOSTNAME_LENGTH); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 1786ad5972d..e6170cae994 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -54,7 +54,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length, } #define IP_ADDR_STRLEN (3+1+3+1+3+1+3) -#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_BYTE_LEN+1+USERNAME_BYTE_LENGTH+1) +#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1) static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs; static MEM_ROOT mem, memex; @@ -197,7 +197,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) READ_RECORD read_record_info; my_bool return_val= 1; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; - char tmp_name[NAME_BYTE_LEN+1]; + char tmp_name[NAME_LEN+1]; int password_length; DBUG_ENTER("acl_load"); @@ -2264,7 +2264,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, const char *user, const char *tname, bool exact) { - char helping [NAME_BYTE_LEN*2+USERNAME_BYTE_LENGTH+3]; + char helping [NAME_LEN*2+USERNAME_LENGTH+3]; uint len; GRANT_NAME *grant_name,*found=0; HASH_SEARCH_STATE state; @@ -3167,7 +3167,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, { List_iterator str_list (list); LEX_USER *Str, *tmp_Str; - char tmp_db[NAME_BYTE_LEN+1]; + char tmp_db[NAME_LEN+1]; bool create_new_users=0; TABLE_LIST tables[2]; DBUG_ENTER("mysql_grant"); @@ -3231,12 +3231,11 @@ bool mysql_grant(THD *thd, const char *db, List &list, { result= TRUE; continue; - } - if ((replace_user_table(thd, - tables[0].table, - *Str, - (!db ? rights : 0), revoke_grant, - create_new_users))) + } + if (replace_user_table(thd, tables[0].table, *Str, + (!db ? rights : 0), revoke_grant, create_new_users, + test(thd->variables.sql_mode & + MODE_NO_AUTO_CREATE_USER))) result= -1; else if (db) { @@ -3868,7 +3867,7 @@ err2: bool check_grant_db(THD *thd,const char *db) { Security_context *sctx= thd->security_ctx; - char helping [NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+2]; + char helping [NAME_LEN+USERNAME_LENGTH+2]; uint len; bool error= 1; diff --git a/sql/sql_class.h b/sql/sql_class.h index ed9f4b57f56..039c133e885 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -200,7 +200,7 @@ class MYSQL_LOG: public TC_LOG IO_CACHE log_file; IO_CACHE index_file; char *name; - char time_buff[20],db[NAME_BYTE_LEN+1]; + char time_buff[20],db[NAME_LEN+1]; char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN]; /* The max size before rotation (usable only if log_type == LOG_BIN: binary diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 86407b71427..077de261628 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1662,7 +1662,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, password. New clients send the size (1 byte) + string (not null terminated, so also '\0' for empty string). */ - char db_buff[NAME_BYTE_LEN+1]; // buffer to store db in utf8 + char db_buff[NAME_LEN+1]; // buffer to store db in utf8 char *db= passwd; uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ? *passwd++ : strlen(passwd); diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 6b1e5e6b447..9eb6456ee20 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -22,7 +22,7 @@ typedef struct st_slave_info uint32 server_id; uint32 rpl_recovery_rank, master_id; char host[HOSTNAME_LENGTH+1]; - char user[USERNAME_BYTE_LENGTH+1]; + char user[USERNAME_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; uint16 port; THD* thd; From 4aaf7e34ff45f084234b007b68fb4e0f892ca625 Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/gluh.(none)" <> Date: Wed, 27 Sep 2006 20:11:11 +0500 Subject: [PATCH 4/5] additional 'after merge' fix --- sql/mysql_priv.h | 2 +- sql/sql_parse.cc | 11 +++++------ sql/sql_yacc.yy | 6 +++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f293c769d75..2c8c7d7cc00 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -567,7 +567,7 @@ void get_default_definer(THD *thd, LEX_USER *definer); LEX_USER *create_default_definer(THD *thd); LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name); LEX_USER *get_current_user(THD *thd, LEX_USER *user); -bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str, +bool check_string_length(LEX_STRING *str, const char *err_msg, uint max_length); enum enum_mysql_completiontype { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 077de261628..18d048df393 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7565,7 +7565,6 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user) SYNOPSIS check_string_length() - cs string charset str string to be checked err_msg error message to be displayed if the string is too long max_length max length @@ -7575,13 +7574,13 @@ LEX_USER *get_current_user(THD *thd, LEX_USER *user) TRUE the passed string is longer than max_length */ -bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str, - const char *err_msg, uint max_length) +bool check_string_length(LEX_STRING *str, const char *err_msg, + uint max_length) { - if (cs->cset->charpos(cs, str->str, str->str + str->length, - max_length) >= str->length) - return FALSE; + if (str->length <= max_length) + return FALSE; my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_length); + return TRUE; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 32f618e9601..764b6dd53c1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7523,7 +7523,7 @@ user: $$->host.str= (char *) "%"; $$->host.length= 1; - if (check_string_length(system_charset_info, &$$->user, + if (check_string_length(&$$->user, ER(ER_USERNAME), USERNAME_LENGTH)) YYABORT; } @@ -7534,9 +7534,9 @@ user: YYABORT; $$->user = $1; $$->host=$3; - if (check_string_length(system_charset_info, &$$->user, + if (check_string_length(&$$->user, ER(ER_USERNAME), USERNAME_LENGTH) || - check_string_length(&my_charset_latin1, &$$->host, + check_string_length(&$$->host, ER(ER_HOSTNAME), HOSTNAME_LENGTH)) YYABORT; } From 353c5bd1545ae76e408e59be8a4a01ba040906eb Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/gluh.(none)" <> Date: Thu, 28 Sep 2006 18:00:44 +0500 Subject: [PATCH 5/5] after merge fix --- sql/log.h | 2 +- sql/sp.cc | 4 ++-- sql/sp_head.cc | 2 +- sql/table.cc | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sql/log.h b/sql/log.h index 2b33f70392a..8f75601f02b 100644 --- a/sql/log.h +++ b/sql/log.h @@ -177,7 +177,7 @@ public: pthread_mutex_t LOCK_log; char *name; char log_file_name[FN_REFLEN]; - char time_buff[20], db[NAME_BYTE_LEN + 1]; + char time_buff[20], db[NAME_LEN + 1]; bool write_error, inited; IO_CACHE log_file; enum_log_type log_type; diff --git a/sql/sp.cc b/sql/sp.cc index f0a748cf8a2..7f2cada61c8 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -414,8 +414,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, sp_rcontext *old_spcont= thd->spcont; char definer_user_name_holder[USERNAME_LENGTH + 1]; - LEX_STRING_WITH_INIT definer_user_name(definer_user_name_holder, - USERNAME_LENGTH); + LEX_STRING definer_user_name= { definer_user_name_holder, + USERNAME_LENGTH }; char definer_host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING definer_host_name= { definer_host_name_holder, HOSTNAME_LENGTH }; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 274999a3521..a061ae12dd1 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2011,7 +2011,7 @@ void sp_head::set_definer(const char *definer, uint definerlen) { char user_name_holder[USERNAME_LENGTH + 1]; - LEX_STRING_WITH_INIT user_name(user_name_holder, USERNAME_LENGTH); + LEX_STRING user_name= { user_name_holder, USERNAME_LENGTH }; char host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING host_name= { host_name_holder, HOSTNAME_LENGTH }; diff --git a/sql/table.cc b/sql/table.cc index 74100f34964..5b41ad48696 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2277,7 +2277,6 @@ bool check_db_name(char *name) name += len; continue; } - name_length++; } #else last_char_is_space= *name==' ';