mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
fixed problem with groupping by view (BUG#7116)
mysql-test/r/view.result: view and group_concat() mysql-test/t/view.test: view and group_concat() sql/item.cc: comments added sql/sql_select.cc: fixed ORDER/GROUP BY processing for view support
This commit is contained in:
parent
ba98de430c
commit
c02f4c5b6c
4 changed files with 57 additions and 7 deletions
|
@ -1758,3 +1758,16 @@ SELECT * FROM v2;
|
|||
C1
|
||||
drop view v2, v1;
|
||||
drop table t1, t2;
|
||||
create table t1 (col1 char(5),col2 int,col3 int);
|
||||
insert into t1 values ('one',10,25), ('two',10,50), ('two',10,50), ('one',20,25), ('one',30,25);
|
||||
create view v1 as select * from t1;
|
||||
select col1,group_concat(col2,col3) from t1 group by col1;
|
||||
col1 group_concat(col2,col3)
|
||||
one 1025,2025,3025
|
||||
two 1050,1050
|
||||
select col1,group_concat(col2,col3) from v1 group by col1;
|
||||
col1 group_concat(col2,col3)
|
||||
two 1025,2025,3025
|
||||
two 1050,1050
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
|
|
@ -1690,3 +1690,14 @@ CREATE VIEW v2 AS SELECT C1 FROM t1 LEFT OUTER JOIN v1 USING (C2);
|
|||
SELECT * FROM v2;
|
||||
drop view v2, v1;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# view and group_concat() (BUG#7116)
|
||||
#
|
||||
create table t1 (col1 char(5),col2 int,col3 int);
|
||||
insert into t1 values ('one',10,25), ('two',10,50), ('two',10,50), ('one',20,25), ('one',30,25);
|
||||
create view v1 as select * from t1;
|
||||
select col1,group_concat(col2,col3) from t1 group by col1;
|
||||
select col1,group_concat(col2,col3) from v1 group by col1;
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
|
14
sql/item.cc
14
sql/item.cc
|
@ -1853,6 +1853,11 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
{
|
||||
bool upward_lookup= FALSE;
|
||||
Field *from_field= (Field *)not_found_field;
|
||||
/*
|
||||
In case of view, find_field_in_tables() write pointer to view field
|
||||
expression to 'reference', i.e. it substitute that expression instead
|
||||
of this Item_field
|
||||
*/
|
||||
if ((from_field= find_field_in_tables(thd, this, tables, reference,
|
||||
IGNORE_EXCEPT_NON_UNIQUE,
|
||||
!any_privileges)) ==
|
||||
|
@ -1898,6 +1903,10 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
Check table fields only if the subquery is used somewhere out of
|
||||
HAVING, or the outer SELECT does not use grouping (i.e. tables are
|
||||
accessible).
|
||||
|
||||
In case of view, find_field_in_tables() write pointer to view
|
||||
field expression to 'reference', i.e. it substitute that
|
||||
expression instead of this Item_field
|
||||
*/
|
||||
if ((place != IN_HAVING ||
|
||||
(outer_sel->with_sum_func == 0 &&
|
||||
|
@ -2951,6 +2960,11 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
(!outer_sel->with_sum_func &&
|
||||
outer_sel->group_list.elements == 0)))
|
||||
{
|
||||
/*
|
||||
In case of view, find_field_in_tables() write pointer to view
|
||||
field expression to 'reference', i.e. it substitute that
|
||||
expression instead of this Item_ref
|
||||
*/
|
||||
if ((from_field= find_field_in_tables(thd, this, table_list,
|
||||
reference,
|
||||
IGNORE_EXCEPT_NON_UNIQUE,
|
||||
|
|
|
@ -11351,22 +11351,24 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||
/* Check whether the resolved field is not ambiguos. */
|
||||
if (select_item != not_found_item)
|
||||
{
|
||||
Item *view_ref= NULL;
|
||||
/*
|
||||
If we have found field not by its alias in select list but by its
|
||||
original field name, we should additionaly check if we have conflict
|
||||
for this name (in case if we would perform lookup in all tables).
|
||||
*/
|
||||
if (unaliased && !order_item->fixed && order_item->fix_fields(thd, tables, order->item))
|
||||
if (unaliased && !order_item->fixed && order_item->fix_fields(thd, tables,
|
||||
order->item))
|
||||
return 1;
|
||||
|
||||
/* Lookup the current GROUP field in the FROM clause. */
|
||||
order_item_type= order_item->type();
|
||||
if (is_group_field &&
|
||||
order_item_type == Item::FIELD_ITEM || order_item_type == Item::REF_ITEM)
|
||||
order_item_type == Item::FIELD_ITEM ||
|
||||
order_item_type == Item::REF_ITEM)
|
||||
{
|
||||
Item **view_ref= NULL;
|
||||
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
|
||||
view_ref, IGNORE_ERRORS, TRUE);
|
||||
&view_ref, IGNORE_ERRORS, TRUE);
|
||||
if(!from_field)
|
||||
from_field= (Field*) not_found_field;
|
||||
}
|
||||
|
@ -11374,9 +11376,19 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||
from_field= (Field*) not_found_field;
|
||||
|
||||
if (from_field == not_found_field ||
|
||||
from_field && from_field != view_ref_found &&
|
||||
(*select_item)->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*) (*select_item))->field->eq(from_field))
|
||||
from_field &&
|
||||
(from_field != view_ref_found ?
|
||||
/* it is field of base table => check that fields are same */
|
||||
((*select_item)->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*) (*select_item))->field->eq(from_field)) :
|
||||
/*
|
||||
in is field of view table => check that references on translation
|
||||
table are same
|
||||
*/
|
||||
((*select_item)->type() == Item::Item::REF_ITEM &&
|
||||
view_ref->type() == Item::Item::REF_ITEM &&
|
||||
((Item_ref *) (*select_item))->ref ==
|
||||
((Item_ref *) view_ref)->ref)))
|
||||
/*
|
||||
If there is no such field in the FROM clause, or it is the same field as
|
||||
the one found in the SELECT clause, then use the Item created for the
|
||||
|
|
Loading…
Reference in a new issue