diff options
-rw-r--r-- | man/perror.1 | 15 | ||||
-rw-r--r-- | mysql-test/t/analyse.test | 6 | ||||
-rw-r--r-- | mysql-test/t/group_by.test | 11 | ||||
-rw-r--r-- | mysql-test/t/select.test | 21 | ||||
-rw-r--r-- | scripts/mysqld_safe.sh | 4 | ||||
-rw-r--r-- | sql/gen_lex_hash.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 11 | ||||
-rw-r--r-- | sql/item.h | 11 | ||||
-rw-r--r-- | sql/sql_analyse.cc | 63 | ||||
-rw-r--r-- | sql/sql_base.cc | 9 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 |
11 files changed, 106 insertions, 53 deletions
diff --git a/man/perror.1 b/man/perror.1 index 38a51593ba1..2c5dd9a295f 100644 --- a/man/perror.1 +++ b/man/perror.1 @@ -1,17 +1,12 @@ .TH perror 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME -.BR perror -can be used to display a description for a system error code, or an MyISAM/ISAM table handler error code. The error messages are mostly system dependent. -.SH USAGE -perror [OPTIONS] [ERRORCODE [ERRORCODE...]] +perror \- describes a system or MySQL error code. .SH SYNOPSIS -.B perror -.RB [ \-? | \-\-help ] -.RB [ \-I | \-\-info ] -.RB [ \-s | \-\-silent ] -.RB [ \-v | \-\-verbose ] -.RB [ \-V | \-\-version ] +perror [OPTIONS] [ERRORCODE [ERRORCODE...]] .SH DESCRIPTION +Can be used to display a description for a system error code, or an MyISAM/ISAM table handler error code. +The error messages are mostly system dependent. +.SH OPTIONS .TP .BR \-? | \-\-help Displays this help and exits. diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test index 3f56b3e47ce..9bf737c9515 100644 --- a/mysql-test/t/analyse.test +++ b/mysql-test/t/analyse.test @@ -3,9 +3,11 @@ # drop table if exists t1,t2; -create table t1 (i int, j int); -insert into t1 values (1,2), (3,4), (5,6), (7,8); +create table t1 (i int, j int, empty_string char(10), bool char(1), d date); +insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6,"","Y","2002-03-04"), (7,8,"","N","2002-03-05"); select * from t1 procedure analyse(); +select * from t1 procedure analyse(2); create table t2 select * from t1 procedure analyse(); select * from t2; drop table t1,t2; + diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index e54c32d0beb..ab5d6062daf 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -68,7 +68,8 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES (1,'1970-01-01','1997-10-17 00:00:00',2529,1,21000,11886,'check',0,'F',16200,6); -!$1056 SELECT COUNT(P.URID),SUM(P.amount),P.method, MIN(PP.recdate+0) > 19980501000000 AS IsNew FROM t1 AS P JOIN t1 as PP WHERE P.URID = PP.URID GROUP BY method,IsNew; +--error 1056 +SELECT COUNT(P.URID),SUM(P.amount),P.method, MIN(PP.recdate+0) > 19980501000000 AS IsNew FROM t1 AS P JOIN t1 as PP WHERE P.URID = PP.URID GROUP BY method,IsNew; drop table t1; @@ -255,6 +256,14 @@ select sql_big_result score,count(*) from t1 group by score desc; drop table t1; # + +# not purely group_by bug, but group_by is involved... + +create table t1 (a date default null, b date default null); +insert t1 values ('1999-10-01','2000-01-10'), ('1997-01-01','1998-10-01'); +select a,min(b) c,count(distinct rand()) from t1 group by a having c<a + interval 1 day; +drop table t1; + # Compare with hash keys # diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 89cc2a57b30..85783e30a82 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1722,11 +1722,27 @@ drop table t4, t3, t2, t1; # # Test of DO +# DO 1; DO benchmark(100,1+1),1,1; # +# random in WHERE clause +# + +CREATE TABLE t1 ( + id mediumint(8) unsigned NOT NULL auto_increment, + pseudo varchar(35) NOT NULL default '', + PRIMARY KEY (id), + UNIQUE KEY pseudo (pseudo) +); +INSERT INTO t1 (pseudo) VALUES ('test'); +INSERT INTO t1 (pseudo) VALUES ('test1'); +SELECT 1 from t1 where rand() > 2; +DROP TABLE t1; + +# # Test of bug with SUM(CASE...) # @@ -1794,10 +1810,11 @@ select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a)); select * from t1 natural join (t1 as t2 left join t1 as t3 using (a)); select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1; drop table t1; -drop table if exists t1,t2; + CREATE TABLE t1 ( aa char(2), id int(11) NOT NULL auto_increment, t2_id int(11) NOT NULL default '0', PRIMARY KEY (id), KEY replace_id (t2_id)) TYPE=MyISAM; INSERT INTO t1 VALUES ("1",8264,2506),("2",8299,2517),("3",8301,2518),("4",8302,2519),("5",8303,2520),("6",8304,2521),("7",8305,2522); CREATE TABLE t2 ( id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) TYPE=MyISAM; INSERT INTO t2 VALUES (2517), (2518), (2519), (2520), (2521), (2522); select * from t1, t2 WHERE t1.t2_id = t2.id and t1.t2_id > 0 order by t1.id LIMIT 0, 5; -drop table if exists t1,t2; +drop table t1,t2; + diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index bc29ac1c555..094b1fbfcd3 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -39,8 +39,8 @@ parse_arguments() { --datadir=*) DATADIR=`echo "$arg" | sed -e "s;--datadir=;;"` ;; --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--pid-file=;;"` ;; --user=*) - if [ $SET_USER == 0 ] - then + if test $SET_USER -eq 0 + then user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1 fi ;; diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 8139cf4fdb0..1f604659272 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -294,7 +294,7 @@ void print_arrays() function_plus,function_mod); int *prva= (int*) my_alloca(sizeof(int)*function_mod); - for (i=0 ; i <= function_mod; i++) + for (i=0 ; i < function_mod; i++) prva[i]= max_symbol; for (i=0;i<size;i++) diff --git a/sql/item.cc b/sql/item.cc index ec9b07c443c..0046f53c6fb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -195,6 +195,17 @@ bool Item_field::get_date(TIME *ltime,bool fuzzydate) return 0; } +bool Item_field::get_date_result(TIME *ltime,bool fuzzydate) +{ + if ((null_value=result_field->is_null()) || + result_field->get_date(ltime,fuzzydate)) + { + bzero((char*) ltime,sizeof(*ltime)); + return 1; + } + return 0; +} + bool Item_field::get_time(TIME *ltime) { if ((null_value=field->is_null()) || field->get_time(ltime)) diff --git a/sql/item.h b/sql/item.h index a72079a6856..5e2c2ccc056 100644 --- a/sql/item.h +++ b/sql/item.h @@ -83,6 +83,8 @@ public: virtual void split_sum_func(List<Item> &fields) {} virtual bool get_date(TIME *ltime,bool fuzzydate); virtual bool get_time(TIME *ltime); + virtual bool get_date_result(TIME *ltime,bool fuzzydate) + { return get_date(ltime,fuzzydate); } virtual bool is_null() { return 0; } virtual unsigned int size_of()= 0; virtual void top_level_item() {} @@ -142,8 +144,9 @@ public: return field->result_type(); } Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; } - bool get_date(TIME *ltime,bool fuzzydate); - bool get_time(TIME *ltime); + bool get_date(TIME *ltime,bool fuzzydate); + bool get_date_result(TIME *ltime,bool fuzzydate); + bool get_time(TIME *ltime); bool is_null() { return field->is_null(); } unsigned int size_of() { return sizeof(*this);} }; @@ -411,8 +414,8 @@ public: return (*ref)->null_value; } bool get_date(TIME *ltime,bool fuzzydate) - { - return (null_value=(*ref)->get_date(ltime,fuzzydate)); + { + return (null_value=(*ref)->get_date_result(ltime,fuzzydate)); } bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); } void make_field(Send_field *field) { (*ref)->make_field(field); } diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index a75b7e304d1..5d3f9a0595c 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -241,14 +241,16 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) } else return 0; -} //test_if_number +} -// Stores the biggest and the smallest value from current 'info' -// to ev_num_info -// If info contains an ulonglong number, which is bigger than -// biggest positive number able to be stored in a longlong variable -// and is marked as negative, function will return 0, else 1. +/* + Stores the biggest and the smallest value from current 'info' + to ev_num_info + If info contains an ulonglong number, which is bigger than + biggest positive number able to be stored in a longlong variable + and is marked as negative, function will return 0, else 1. +*/ bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num) { @@ -276,11 +278,13 @@ void free_string(String *s) s->free(); } + void field_str::add() { char buff[MAX_FIELD_WIDTH], *ptr; String s(buff, sizeof(buff)), *res; ulong length; + TREE_ELEMENT *element; if (!(res = item->val_str(&s))) { @@ -426,9 +430,11 @@ void field_real::add() room_in_tree = 0; // Remove tree, out of RAM ? delete_tree(&tree); } - // if element->count == 1, this element can be found only once from tree - // if element->count == 2, or more, this element is already in tree - else if (element->count == 1 && (tree_elements++) > pc->max_tree_elements) + /* + if element->count == 1, this element can be found only once from tree + if element->count == 2, or more, this element is already in tree + */ + else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements) { room_in_tree = 0; // Remove tree, too many elements delete_tree(&tree); @@ -457,6 +463,7 @@ void field_real::add() } } // field_real::add + void field_longlong::add() { char buff[MAX_FIELD_WIDTH]; @@ -479,9 +486,11 @@ void field_longlong::add() room_in_tree = 0; // Remove tree, out of RAM ? delete_tree(&tree); } - // if element->count == 1, this element can be found only once from tree - // if element->count == 2, or more, this element is already in tree - else if (element->count == 1 && (tree_elements++) > pc->max_tree_elements) + /* + if element->count == 1, this element can be found only once from tree + if element->count == 2, or more, this element is already in tree + */ + else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements) { room_in_tree = 0; // Remove tree, too many elements delete_tree(&tree); @@ -533,9 +542,11 @@ void field_ulonglong::add() room_in_tree = 0; // Remove tree, out of RAM ? delete_tree(&tree); } - // if element->count == 1, this element can be found only once from tree - // if element->count == 2, or more, this element is already in tree - else if (element->count == 1 && (tree_elements++) > pc->max_tree_elements) + /* + if element->count == 1, this element can be found only once from tree + if element->count == 2, or more, this element is already in tree + */ + else if (element->count == 1 && (tree_elements++) >= pc->max_tree_elements) { room_in_tree = 0; // Remove tree, too many elements delete_tree(&tree); @@ -615,14 +626,16 @@ bool analyse::end_of_records() func_items[8]->null_value = 1; else func_items[8]->set(res->ptr(), res->length()); - // count the dots, quotas, etc. in (ENUM("a","b","c"...)) - // if tree has been removed, don't suggest ENUM. - // treemem is used to measure the size of tree for strings, - // tree_elements is used to count the elements in tree in case of numbers. - // max_treemem tells how long the string starting from ENUM("... and - // ending to ..") shall at maximum be. If case is about numbers, - // max_tree_elements will tell the length of the above, now - // every number is considered as length 1 + /* + count the dots, quotas, etc. in (ENUM("a","b","c"...)) + If tree has been removed, don't suggest ENUM. + treemem is used to measure the size of tree for strings, + tree_elements is used to count the elements + max_treemem tells how long the string starting from ENUM("... and + ending to ..") shall at maximum be. If case is about numbers, + max_tree_elements will tell the length of the above, now + every number is considered as length 1 + */ if (((*f)->treemem || (*f)->tree_elements) && (*f)->tree.elements_in_tree && (((*f)->treemem ? max_treemem : max_tree_elements) > @@ -665,6 +678,7 @@ bool analyse::end_of_records() ans.append("DATETIME", 8); break; case FIELD_TYPE_DATE: + case FIELD_TYPE_NEWDATE: ans.append("DATE", 4); break; case FIELD_TYPE_SET: @@ -676,9 +690,6 @@ bool analyse::end_of_records() case FIELD_TYPE_TIME: ans.append("TIME", 4); break; - case FIELD_TYPE_NEWDATE: - ans.append("NEWDATE", 7); - break; case FIELD_TYPE_DECIMAL: ans.append("DECIMAL", 7); // if item is FIELD_ITEM, it _must_be_ Field_num in this case diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4d1e57f0c1e..660b37858b5 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1693,8 +1693,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, else thd->dupp_field=field; } - if (check_grants && !thd->master_access && - check_grant_column(thd,table,name,length)) + if (check_grants && check_grant_column(thd,table,name,length)) return WRONG_GRANT; return field; } @@ -1719,7 +1718,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) { found_table=1; Field *find=find_field_in_table(thd,tables->table,name,length, - grant_option && !thd->master_access,1); + grant_option && + tables->grant.want_privilege ,1); if (find) { if (find == WRONG_GRANT) @@ -1758,8 +1758,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) for (; tables ; tables=tables->next) { Field *field=find_field_in_table(thd,tables->table,name,length, - grant_option && - !thd->master_access, allow_rowid); + grant_option && tables->grant.want_privilege ,allow_rowid); if (field) { if (field == WRONG_GRANT) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ffe20095963..96de43ae55c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2527,6 +2527,12 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { JOIN_TAB *tab=join->join_tab+i; table_map current_map= tab->table->map; + /* + Following force including random expression in last table condition. + It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5 + */ + if (i == join->tables-1) + current_map|= RAND_TABLE_BIT; bool use_quick_range=0; used_tables|=current_map; |