diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index c8078a0604e..730e180cbd9 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2024,3 +2024,26 @@ f1 sb 2005-01-01 12:00:00 2005-01-01 10:58:59 drop view v1; drop table t1; +CREATE TABLE t1 ( +aid int PRIMARY KEY, +fn varchar(20) NOT NULL, +ln varchar(20) NOT NULL +); +CREATE TABLE t2 ( +aid int NOT NULL, +pid int NOT NULL +); +INSERT INTO t1 VALUES(1,'a','b'), (2,'c','d'); +INSERT INTO t2 values (1,1), (2,1), (2,2); +CREATE VIEW v1 AS SELECT t1.*,t2.pid FROM t1,t2 WHERE t1.aid = t2.aid; +SELECT pid,GROUP_CONCAT(CONCAT(fn,' ',ln) ORDER BY 1) FROM t1,t2 +WHERE t1.aid = t2.aid GROUP BY pid; +pid GROUP_CONCAT(CONCAT(fn,' ',ln) ORDER BY 1) +1 a b,c d +2 c d +SELECT pid,GROUP_CONCAT(CONCAT(fn,' ',ln) ORDER BY 1) FROM v1 GROUP BY pid; +pid GROUP_CONCAT(CONCAT(fn,' ',ln) ORDER BY 1) +1 a b,c d +2 c d +DROP VIEW v1; +DROP TABLE t1,t2; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 16a94820596..5454b3409da 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1862,4 +1862,28 @@ insert into t1 values('2005.01.01 12:0:0'); create view v1 as select f1, subtime(f1, '1:1:1') as sb from t1; select * from v1; drop view v1; -drop table t1; +drop table t1; + +# +# Test for bug #11412: query over a multitable view with GROUP_CONCAT +# +CREATE TABLE t1 ( + aid int PRIMARY KEY, + fn varchar(20) NOT NULL, + ln varchar(20) NOT NULL +); +CREATE TABLE t2 ( + aid int NOT NULL, + pid int NOT NULL +); +INSERT INTO t1 VALUES(1,'a','b'), (2,'c','d'); +INSERT INTO t2 values (1,1), (2,1), (2,2); + +CREATE VIEW v1 AS SELECT t1.*,t2.pid FROM t1,t2 WHERE t1.aid = t2.aid; + +SELECT pid,GROUP_CONCAT(CONCAT(fn,' ',ln) ORDER BY 1) FROM t1,t2 + WHERE t1.aid = t2.aid GROUP BY pid; +SELECT pid,GROUP_CONCAT(CONCAT(fn,' ',ln) ORDER BY 1) FROM v1 GROUP BY pid; + +DROP VIEW v1; +DROP TABLE t1,t2; diff --git a/mysys/charset.c b/mysys/charset.c index 4920e7806a2..fbdfa12c7a1 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -383,26 +383,28 @@ static my_bool init_available_charsets(myf myflags) while we may changing the cs_info_table */ pthread_mutex_lock(&THR_LOCK_charset); - - bzero(&all_charsets,sizeof(all_charsets)); - init_compiled_charsets(myflags); - - /* Copy compiled charsets */ - for (cs=all_charsets; - cs < all_charsets+array_elements(all_charsets)-1 ; - cs++) + if (!charset_initialized) { - if (*cs) + bzero(&all_charsets,sizeof(all_charsets)); + init_compiled_charsets(myflags); + + /* Copy compiled charsets */ + for (cs=all_charsets; + cs < all_charsets+array_elements(all_charsets)-1 ; + cs++) { - if (cs[0]->ctype) - if (init_state_maps(*cs)) - *cs= NULL; + if (*cs) + { + if (cs[0]->ctype) + if (init_state_maps(*cs)) + *cs= NULL; + } } + + strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); + error= my_read_charset_file(fname,myflags); + charset_initialized=1; } - - strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); - error= my_read_charset_file(fname,myflags); - charset_initialized=1; pthread_mutex_unlock(&THR_LOCK_charset); } return error; diff --git a/sql/item.h b/sql/item.h index 108deeb7440..a17c2af2823 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1473,7 +1473,13 @@ public: void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } enum Item_result result_type () const { return (*ref)->result_type(); } enum_field_types field_type() const { return (*ref)->field_type(); } - Field *get_tmp_table_field() { return result_field; } + Field *get_tmp_table_field() + { return result_field ? result_field : (*ref)->get_tmp_table_field(); } + Item *get_tmp_table_item(THD *thd) + { + return (result_field ? new Item_field(result_field) : + (*ref)->get_tmp_table_item(thd)); + } table_map used_tables() const { return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables(); @@ -1711,7 +1717,7 @@ class Cached_item_field :public Cached_item public: Cached_item_field(Item_field *item) { - field=item->field; + field= item->field; buff= (char*) sql_calloc(length=field->pack_length()); } bool cmp(void); diff --git a/sql/item_buff.cc b/sql/item_buff.cc index a67e420170a..9db2f465080 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -25,9 +25,9 @@ Cached_item *new_Cached_item(THD *thd, Item *item) { - if (item->type() == Item::FIELD_ITEM && - !(((Item_field *) item)->field->flags & BLOB_FLAG)) - return new Cached_item_field((Item_field *) item); + if (item->real_item()->type() == Item::FIELD_ITEM && + !(((Item_field *) (item->real_item()))->field->flags & BLOB_FLAG)) + return new Cached_item_field((Item_field *) (item->real_item())); switch (item->result_type()) { case STRING_RESULT: return new Cached_item_str(thd, (Item_field *) item); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 05fb2d4d83e..117e16a2db3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8026,6 +8026,12 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, bool table_cant_handle_bit_fields, uint convert_blob_length) { + Item *org_item= item; + if (item->real_item()->type() == Item::FIELD_ITEM) + { + item= item->real_item(); + type= item->type(); + } switch (type) { case Item::SUM_FUNC_ITEM: { @@ -8038,30 +8044,22 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::FIELD_ITEM: case Item::DEFAULT_VALUE_ITEM: { - Item_field *field= (Item_field*) item; - if (table_cant_handle_bit_fields && field->field->type() == FIELD_TYPE_BIT) - return create_tmp_field_from_item(thd, item, table, copy_func, - modify_item, convert_blob_length); - return create_tmp_field_from_field(thd, (*from_field= field->field), - item->name, table, - modify_item ? (Item_field*) item : NULL, - convert_blob_length); - } - case Item::REF_ITEM: - { - Item *tmp_item; - if ((tmp_item= item->real_item())->type() == Item::FIELD_ITEM) + if (org_item->type() != Item::REF_ITEM || + !((Item_ref *)org_item)->depended_from) { - Item_field *field= (Item_field*) tmp_item; - Field *new_field= create_tmp_field_from_field(thd, - (*from_field= field->field), - item->name, table, - NULL, - convert_blob_length); - if (modify_item) - item->set_result_field(new_field); - return new_field; + Item_field *field= (Item_field*) item; + if (table_cant_handle_bit_fields && + field->field->type() == FIELD_TYPE_BIT) + return create_tmp_field_from_item(thd, item, table, copy_func, + modify_item, convert_blob_length); + return create_tmp_field_from_field(thd, (*from_field= field->field), + item->name, table, + modify_item ? (Item_field*) item : + NULL, + convert_blob_length); } + else + item= org_item; } case Item::FUNC_ITEM: case Item::COND_ITEM: @@ -8074,6 +8072,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::REAL_ITEM: case Item::DECIMAL_ITEM: case Item::STRING_ITEM: + case Item::REF_ITEM: case Item::NULL_ITEM: case Item::VARBIN_ITEM: return create_tmp_field_from_item(thd, item, table, copy_func, modify_item, @@ -10904,12 +10903,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, usable_keys.set_all(); for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next) { - if ((*tmp_order->item)->type() != Item::FIELD_ITEM) + if ((*tmp_order->item)->real_item()->type() != Item::FIELD_ITEM) { usable_keys.clear_all(); DBUG_RETURN(0); } - usable_keys.intersect(((Item_field*) (*tmp_order->item))-> + usable_keys.intersect(((Item_field*) (*tmp_order->item)->real_item())-> field->part_of_sortkey); if (usable_keys.is_clear_all()) DBUG_RETURN(0); // No usable keys