mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fix for BUG#14662: view column in ORDER BY considered ambiguous if SELECT contains
the same column as an aliased and as a non-aliased column. The problem was that Item_direct_view_ref::eq() was first comparing view columns by name, and in this case the name of one of them is different since it is aliased. mysql-test/r/select.result: Added test for BUG#14662. mysql-test/t/select.test: Added test for BUG#14662. sql/item.cc: Changed the way view column refenreces are compared. Two view columns are equal if they resolve to the same result field of a view.
This commit is contained in:
@ -3241,3 +3241,45 @@ f1 f2
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
|
Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (f1 int, f2 int);
|
||||||
|
insert into t1 values (1, 30), (2, 20), (3, 10);
|
||||||
|
create algorithm=merge view v1 as select f1, f2 from t1;
|
||||||
|
create algorithm=merge view v2 (f2, f1) as select f1, f2 from t1;
|
||||||
|
create algorithm=merge view v3 as select t1.f1 as f2, t1.f2 as f1 from t1;
|
||||||
|
select t1.f1 as x1, f1 from t1 order by t1.f1;
|
||||||
|
x1 f1
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
select v1.f1 as x1, f1 from v1 order by v1.f1;
|
||||||
|
x1 f1
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
select v2.f1 as x1, f1 from v2 order by v2.f1;
|
||||||
|
x1 f1
|
||||||
|
10 10
|
||||||
|
20 20
|
||||||
|
30 30
|
||||||
|
select v3.f1 as x1, f1 from v3 order by v3.f1;
|
||||||
|
x1 f1
|
||||||
|
10 10
|
||||||
|
20 20
|
||||||
|
30 30
|
||||||
|
select f1, f2, v1.f1 as x1 from v1 order by v1.f1;
|
||||||
|
f1 f2 x1
|
||||||
|
1 30 1
|
||||||
|
2 20 2
|
||||||
|
3 10 3
|
||||||
|
select f1, f2, v2.f1 as x1 from v2 order by v2.f1;
|
||||||
|
f1 f2 x1
|
||||||
|
10 3 10
|
||||||
|
20 2 20
|
||||||
|
30 1 30
|
||||||
|
select f1, f2, v3.f1 as x1 from v3 order by v3.f1;
|
||||||
|
f1 f2 x1
|
||||||
|
10 3 10
|
||||||
|
20 2 20
|
||||||
|
30 1 30
|
||||||
|
drop table t1;
|
||||||
|
drop view v1, v2, v3;
|
||||||
|
@ -2729,3 +2729,23 @@ select * from t1 where f2 >= '2005-09-3a';
|
|||||||
select * from t1 where f2 <= '2005-09-31';
|
select * from t1 where f2 <= '2005-09-31';
|
||||||
select * from t1 where f2 <= '2005-09-3a';
|
select * from t1 where f2 <= '2005-09-3a';
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug ##14662 ORDER BY on column of a view, with an alias of the same
|
||||||
|
# column causes ambiguous
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (f1 int, f2 int);
|
||||||
|
insert into t1 values (1, 30), (2, 20), (3, 10);
|
||||||
|
create algorithm=merge view v1 as select f1, f2 from t1;
|
||||||
|
create algorithm=merge view v2 (f2, f1) as select f1, f2 from t1;
|
||||||
|
create algorithm=merge view v3 as select t1.f1 as f2, t1.f2 as f1 from t1;
|
||||||
|
select t1.f1 as x1, f1 from t1 order by t1.f1;
|
||||||
|
select v1.f1 as x1, f1 from v1 order by v1.f1;
|
||||||
|
select v2.f1 as x1, f1 from v2 order by v2.f1;
|
||||||
|
select v3.f1 as x1, f1 from v3 order by v3.f1;
|
||||||
|
select f1, f2, v1.f1 as x1 from v1 order by v1.f1;
|
||||||
|
select f1, f2, v2.f1 as x1 from v2 order by v2.f1;
|
||||||
|
select f1, f2, v3.f1 as x1 from v3 order by v3.f1;
|
||||||
|
drop table t1;
|
||||||
|
drop view v1, v2, v3;
|
||||||
|
31
sql/item.cc
31
sql/item.cc
@ -4938,8 +4938,7 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Compare view field's name with item's name before call to referenced
|
Compare two view column references for equality.
|
||||||
item's eq()
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
Item_direct_view_ref::eq()
|
Item_direct_view_ref::eq()
|
||||||
@ -4947,12 +4946,13 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
binary_cmp make binary comparison
|
binary_cmp make binary comparison
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Consider queries:
|
A view column reference is considered equal to another column
|
||||||
create view v1 as select t1.f1 as f2, t1.f2 as f1 from t1;
|
reference if the second one is a view column and if both column
|
||||||
select * from v1 order by f1;
|
references point to the same field. For views 'same field' means
|
||||||
In order to choose right field for sorting we need to compare
|
the same Item_field object in the view translation table, where
|
||||||
given item's name (f1) to view field's name prior to calling
|
the view translation table contains all result columns of the
|
||||||
referenced item's eq().
|
view. This definition ensures that view columns are resolved
|
||||||
|
in the same manner as table columns.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
TRUE Referenced item is equal to given item
|
TRUE Referenced item is equal to given item
|
||||||
@ -4962,9 +4962,18 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
|
|
||||||
bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
|
bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
|
||||||
{
|
{
|
||||||
Item *it= ((Item *) item)->real_item();
|
if (item->type() == REF_ITEM)
|
||||||
return (!it->name || !my_strcasecmp(system_charset_info, it->name,
|
{
|
||||||
field_name)) && ref && (*ref)->real_item()->eq(it, binary_cmp);
|
Item_ref *item_ref= (Item_ref*) item;
|
||||||
|
if (item_ref->ref_type() == VIEW_REF)
|
||||||
|
{
|
||||||
|
Item *item_ref_ref= *(item_ref->ref);
|
||||||
|
DBUG_ASSERT((*ref)->type() == FIELD_ITEM &&
|
||||||
|
(item_ref_ref->type() == FIELD_ITEM));
|
||||||
|
return (*ref == item_ref_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Item_null_helper::print(String *str)
|
void Item_null_helper::print(String *str)
|
||||||
|
Reference in New Issue
Block a user