summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2002-09-28 18:34:56 +0300
committerunknown <bell@sanja.is.com.ua>2002-09-28 18:34:56 +0300
commitc9a2b58986635015b3f3867999ef3fafa2bd2728 (patch)
tree6fcd2ba5039822ee13c52903e85f243887bac5ba
parentda891a571e49804e3743bf2776bcf2648a4832da (diff)
downloadmariadb-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.result16
-rw-r--r--mysql-test/t/subselect.test13
-rw-r--r--sql/item_subselect.cc47
-rw-r--r--sql/item_subselect.h12
-rw-r--r--sql/sql_class.cc8
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);