diff options
author | unknown <bell@sanja.is.com.ua> | 2002-09-28 18:34:56 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2002-09-28 18:34:56 +0300 |
commit | c9a2b58986635015b3f3867999ef3fafa2bd2728 (patch) | |
tree | 6fcd2ba5039822ee13c52903e85f243887bac5ba | |
parent | da891a571e49804e3743bf2776bcf2648a4832da (diff) | |
download | mariadb-git-c9a2b58986635015b3f3867999ef3fafa2bd2728.tar.gz |
fixed bug in string & date types with group function in subselect
mysql-test/r/subselect.result:
test suite of string & date types with group function in subselects
mysql-test/t/subselect.test:
test suite of string & date types with group function in subselects
sql/item_subselect.cc:
fixed bug in string type with group function
sql/item_subselect.h:
fixed bug in string type with group function
sql/sql_class.cc:
fixed bug in date type with group function
-rw-r--r-- | mysql-test/r/subselect.result | 16 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 13 | ||||
-rw-r--r-- | sql/item_subselect.cc | 47 | ||||
-rw-r--r-- | sql/item_subselect.h | 12 | ||||
-rw-r--r-- | sql/sql_class.cc | 8 |
5 files changed, 91 insertions, 5 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 54528f58697..5a96cc08cbf 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -131,4 +131,20 @@ patient_uq clinic_uq 1 1 1 2 2 2 +drop table if exists t1,t2,t3; +CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0'); +INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b'); +CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0'); +INSERT INTO t2 VALUES ('W','1'),('A','3'),('J','2'); +CREATE TABLE t1 (a varchar(20),b date NOT NULL default '0000-00-00'); +INSERT INTO t1 VALUES ('W','1732-02-22'),('A','1735-10-30'),('J','1743-04-13'); +SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1); +a b +W 1732-02-22 +SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2); +a b +W 1 +SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3); +a b +W a drop table t1,t2,t3,t4,t5,attend,clinic; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 68a89796ec3..3ae695c8967 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -53,4 +53,17 @@ insert into clinic values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta" insert into attend values (1,1),(1,2),(2,2),(1,3); select * from attend where exists (select * from clinic where uq = clinic_uq); +# different tipes & group functions +drop table if exists t1,t2,t3; + +CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0'); +INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b'); +CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0'); +INSERT INTO t2 VALUES ('W','1'),('A','3'),('J','2'); +CREATE TABLE t1 (a varchar(20),b date NOT NULL default '0000-00-00'); +INSERT INTO t1 VALUES ('W','1732-02-22'),('A','1735-10-30'),('J','1743-04-13'); +SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1); +SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2); +SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3); + drop table t1,t2,t3,t4,t5,attend,clinic; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index a8909430155..99fc0bcdb67 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -82,7 +82,14 @@ bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0)); return 1; } - return engine->prepare(); + int res= engine->prepare(); + fix_length_and_dec(); + return res; +} + +void Item_subselect::fix_length_and_dec() +{ + engine->fix_length_and_dec(); } inline table_map Item_subselect::used_tables() const @@ -98,6 +105,12 @@ Item_singleval_subselect::Item_singleval_subselect(THD *thd, maybe_null= 1; } +void Item_singleval_subselect::fix_length_and_dec() +{ + engine->fix_length_and_dec(); + res_type= engine->type(); +} + Item::Type Item_subselect::type() const { return SUBSELECT_ITEM; @@ -135,6 +148,12 @@ Item_exists_subselect::Item_exists_subselect(THD *thd, select_lex->select_limit= 1; // we need only 1 row to determinate existence } +void Item_exists_subselect::fix_length_and_dec() +{ + max_length= 1; + +} + double Item_exists_subselect::val () { if (engine->exec()) @@ -221,6 +240,32 @@ int subselect_union_engine::prepare() return unit->prepare(thd, result); } +void subselect_single_select_engine::fix_length_and_dec() +{ + List_iterator_fast<Item> li(select_lex->item_list); + Item *sel_item= li++; + item->max_length= sel_item->max_length; + res_type= sel_item->result_type(); + item->decimals= sel_item->decimals; +} + +void subselect_union_engine::fix_length_and_dec() +{ + uint32 mlen= 0, len; + Item *sel_item= 0; + for(SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) + { + List_iterator_fast<Item> li(sl->item_list); + Item *s_item= li++; + if ((len= s_item->max_length)) + mlen= len; + if (!sel_item) + sel_item= s_item; + } + item->max_length= mlen; + res_type= sel_item->result_type(); + item->decimals= sel_item->decimals; +} int subselect_single_select_engine::exec() { diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 0d8495d3ae8..92839eb0e5f 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -61,6 +61,7 @@ public: bool is_null() { return null_value; } void make_field (Send_field *); bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); + virtual void fix_length_and_dec(); table_map used_tables() const; friend class select_subselect; @@ -100,7 +101,7 @@ public: String *val_str (String *); Item *new_item() { return new Item_singleval_subselect(this); } enum Item_result result_type() const { return res_type; } - + void fix_length_and_dec(); friend class select_singleval_subselect; }; @@ -128,7 +129,7 @@ public: longlong val_int(); double val(); String *val_str(String*); - + void fix_length_and_dec(); friend class select_exists_subselect; }; @@ -138,6 +139,7 @@ protected: select_subselect *result; /* results storage class */ THD *thd; /* pointer to current THD */ Item_subselect *item; /* item, that use this engine */ + enum Item_result res_type; /* type of results */ public: static void *operator new(size_t size) { @@ -150,11 +152,15 @@ public: result= res; item= si; this->thd= thd; + res_type= STRING_RESULT; } + virtual int prepare()= 0; + virtual void fix_length_and_dec()= 0; virtual int exec()= 0; virtual uint cols()= 0; /* return number of columnss in select */ virtual bool depended()= 0; /* depended from outer select */ + enum Item_result type() { return res_type; } }; class subselect_single_select_engine: public subselect_engine @@ -168,6 +174,7 @@ public: select_subselect *result, Item_subselect *item); virtual int prepare(); + virtual void fix_length_and_dec(); virtual int exec(); virtual uint cols(); virtual bool depended(); @@ -182,6 +189,7 @@ public: select_subselect *result, Item_subselect *item); virtual int prepare(); + virtual void fix_length_and_dec(); virtual int exec(); virtual uint cols(); virtual bool depended(); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c090f2336c1..98551fa35ba 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -838,12 +838,16 @@ bool select_singleval_subselect::send_data(List<Item> &items) if ((it->null_value= val_item->is_null())) { it->assign_null(); - } else { + } + else + { it->max_length= val_item->max_length; it->decimals= val_item->decimals; it->binary= val_item->binary; - val_item->val_str(&it->str_value); it->int_value= val_item->val_int(); + String *s= val_item->val_str(&it->str_value); + if (s != &it->str_value) + it->str_value.set(*s, 0, s->length()); it->res_type= val_item->result_type(); } it->assigned(1); |