Commit c65515d8 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

fixed bug in string & date types with group function in subselect

parent 6c672693
...@@ -131,4 +131,20 @@ patient_uq clinic_uq ...@@ -131,4 +131,20 @@ patient_uq clinic_uq
1 1 1 1
1 2 1 2
2 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; drop table t1,t2,t3,t4,t5,attend,clinic;
...@@ -53,4 +53,17 @@ insert into clinic values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta" ...@@ -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); insert into attend values (1,1),(1,2),(2,2),(1,3);
select * from attend where exists (select * from clinic where uq = clinic_uq); 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; 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) ...@@ -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)); my_message(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0));
return 1; 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 inline table_map Item_subselect::used_tables() const
...@@ -98,6 +105,12 @@ Item_singleval_subselect::Item_singleval_subselect(THD *thd, ...@@ -98,6 +105,12 @@ Item_singleval_subselect::Item_singleval_subselect(THD *thd,
maybe_null= 1; 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 Item::Type Item_subselect::type() const
{ {
return SUBSELECT_ITEM; return SUBSELECT_ITEM;
...@@ -135,6 +148,12 @@ Item_exists_subselect::Item_exists_subselect(THD *thd, ...@@ -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 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 () double Item_exists_subselect::val ()
{ {
if (engine->exec()) if (engine->exec())
...@@ -221,6 +240,32 @@ int subselect_union_engine::prepare() ...@@ -221,6 +240,32 @@ int subselect_union_engine::prepare()
return unit->prepare(thd, result); 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() int subselect_single_select_engine::exec()
{ {
......
...@@ -61,6 +61,7 @@ public: ...@@ -61,6 +61,7 @@ public:
bool is_null() { return null_value; } bool is_null() { return null_value; }
void make_field (Send_field *); void make_field (Send_field *);
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref); bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
virtual void fix_length_and_dec();
table_map used_tables() const; table_map used_tables() const;
friend class select_subselect; friend class select_subselect;
...@@ -100,7 +101,7 @@ public: ...@@ -100,7 +101,7 @@ public:
String *val_str (String *); String *val_str (String *);
Item *new_item() { return new Item_singleval_subselect(this); } Item *new_item() { return new Item_singleval_subselect(this); }
enum Item_result result_type() const { return res_type; } enum Item_result result_type() const { return res_type; }
void fix_length_and_dec();
friend class select_singleval_subselect; friend class select_singleval_subselect;
}; };
...@@ -128,7 +129,7 @@ public: ...@@ -128,7 +129,7 @@ public:
longlong val_int(); longlong val_int();
double val(); double val();
String *val_str(String*); String *val_str(String*);
void fix_length_and_dec();
friend class select_exists_subselect; friend class select_exists_subselect;
}; };
...@@ -138,6 +139,7 @@ protected: ...@@ -138,6 +139,7 @@ protected:
select_subselect *result; /* results storage class */ select_subselect *result; /* results storage class */
THD *thd; /* pointer to current THD */ THD *thd; /* pointer to current THD */
Item_subselect *item; /* item, that use this engine */ Item_subselect *item; /* item, that use this engine */
enum Item_result res_type; /* type of results */
public: public:
static void *operator new(size_t size) static void *operator new(size_t size)
{ {
...@@ -150,11 +152,15 @@ public: ...@@ -150,11 +152,15 @@ public:
result= res; result= res;
item= si; item= si;
this->thd= thd; this->thd= thd;
res_type= STRING_RESULT;
} }
virtual int prepare()= 0; virtual int prepare()= 0;
virtual void fix_length_and_dec()= 0;
virtual int exec()= 0; virtual int exec()= 0;
virtual uint cols()= 0; /* return number of columnss in select */ virtual uint cols()= 0; /* return number of columnss in select */
virtual bool depended()= 0; /* depended from outer select */ virtual bool depended()= 0; /* depended from outer select */
enum Item_result type() { return res_type; }
}; };
class subselect_single_select_engine: public subselect_engine class subselect_single_select_engine: public subselect_engine
...@@ -168,6 +174,7 @@ public: ...@@ -168,6 +174,7 @@ public:
select_subselect *result, select_subselect *result,
Item_subselect *item); Item_subselect *item);
virtual int prepare(); virtual int prepare();
virtual void fix_length_and_dec();
virtual int exec(); virtual int exec();
virtual uint cols(); virtual uint cols();
virtual bool depended(); virtual bool depended();
...@@ -182,6 +189,7 @@ public: ...@@ -182,6 +189,7 @@ public:
select_subselect *result, select_subselect *result,
Item_subselect *item); Item_subselect *item);
virtual int prepare(); virtual int prepare();
virtual void fix_length_and_dec();
virtual int exec(); virtual int exec();
virtual uint cols(); virtual uint cols();
virtual bool depended(); virtual bool depended();
......
...@@ -838,12 +838,16 @@ bool select_singleval_subselect::send_data(List<Item> &items) ...@@ -838,12 +838,16 @@ bool select_singleval_subselect::send_data(List<Item> &items)
if ((it->null_value= val_item->is_null())) if ((it->null_value= val_item->is_null()))
{ {
it->assign_null(); it->assign_null();
} else { }
else
{
it->max_length= val_item->max_length; it->max_length= val_item->max_length;
it->decimals= val_item->decimals; it->decimals= val_item->decimals;
it->binary= val_item->binary; it->binary= val_item->binary;
val_item->val_str(&it->str_value);
it->int_value= val_item->val_int(); 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->res_type= val_item->result_type();
} }
it->assigned(1); 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