Commit c9a2b589 authored by unknown's avatar unknown

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
parent da891a57
......@@ -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;
......@@ -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;
......@@ -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()
{
......
......@@ -61,6 +61,7 @@ class Item_subselect :public Item
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 @@ class Item_singleval_subselect :public Item_subselect
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 @@ class Item_exists_subselect :public Item_subselect
longlong val_int();
double val();
String *val_str(String*);
void fix_length_and_dec();
friend class select_exists_subselect;
};
......@@ -138,6 +139,7 @@ class subselect_engine
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 @@ class subselect_engine
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 @@ class subselect_single_select_engine: public subselect_engine
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 @@ class subselect_union_engine: public subselect_engine
select_subselect *result,
Item_subselect *item);
virtual int prepare();
virtual void fix_length_and_dec();
virtual int exec();
virtual uint cols();
virtual bool depended();
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment