From fa1438cbf4307731a54ea4137d5f7d4b744cdfbc Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 27 Oct 2015 11:17:52 +0100 Subject: [PATCH] MDEV-8913 Derived queries with same column names as final projection causes issues when using Order By find_item_in_list() now recognize view fields like a fields even if they rever to an expression. The problem of schema name do not taken into account for field with it and derived table fixed. Duplicating code removed --- mysql-test/r/view.result | 41 ++++++++++++++++++++++++++++++++++++++++ mysql-test/t/view.test | 32 +++++++++++++++++++++++++++++++ sql/sql_base.cc | 35 +++++----------------------------- 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index f697f63ca76..347d2841081 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5699,6 +5699,47 @@ idAlbum strAlbum strMusicBrainzAlbumID strArtists strGenres iYear strMoods strSt 1 strAlbum1 strMusicBrainzAlbumID1 strArtists1 strGenres1 2000 NULL NULL NULL NULL NULL NULL NULL NULL 0 0 album 1 1 strArtist1 strMusicBrainzArtistID 0 0 drop view v1,v2; drop table t1,t2,t3,t4; +# +# MDEV-8913: Derived queries with same column names as final +# projection causes issues when using Order By +# +create table t1 (field int); +insert into t1 values (10),(5),(3),(8),(20); +SELECT sq.f2 AS f1, sq.f1 AS f2 +FROM ( SELECT field AS f1, 1 AS f2 FROM t1) AS sq +ORDER BY sq.f1; +f1 f2 +1 3 +1 5 +1 8 +1 10 +1 20 +create view v1 as SELECT field AS f1, 1 AS f2 FROM t1; +SELECT sq.f2 AS f1, sq.f1 AS f2 +FROM v1 AS sq +ORDER BY sq.f1; +f1 f2 +1 3 +1 5 +1 8 +1 10 +1 20 +drop view v1; +create table t2 SELECT field AS f1, 1 AS f2 FROM t1; +SELECT +sq.f2 AS f1, +sq.f1 AS f2 +FROM t2 AS sq +ORDER BY sq.f1; +f1 f2 +1 3 +1 5 +1 8 +1 10 +1 20 +drop table t1, t2; +SELECT 1 FROM (SELECT 1 as a) AS b HAVING (SELECT `SOME_GARBAGE`.b.a)=1; +ERROR 42S22: Unknown column 'SOME_GARBAGE.b.a' in 'field list' # ----------------------------------------------------------------- # -- End of 10.0 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 773df49de6f..6c99d2217c2 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5602,6 +5602,38 @@ SELECT v1.*,v2.* FROM v1 LEFT JOIN v2 ON v1.idAlbum = v2.idAlbum WHERE v1.idAlbu drop view v1,v2; drop table t1,t2,t3,t4; +--echo # +--echo # MDEV-8913: Derived queries with same column names as final +--echo # projection causes issues when using Order By +--echo # +create table t1 (field int); +insert into t1 values (10),(5),(3),(8),(20); + +SELECT sq.f2 AS f1, sq.f1 AS f2 +FROM ( SELECT field AS f1, 1 AS f2 FROM t1) AS sq +ORDER BY sq.f1; + +create view v1 as SELECT field AS f1, 1 AS f2 FROM t1; + +SELECT sq.f2 AS f1, sq.f1 AS f2 +FROM v1 AS sq +ORDER BY sq.f1; + +drop view v1; + +create table t2 SELECT field AS f1, 1 AS f2 FROM t1; + +SELECT + sq.f2 AS f1, + sq.f1 AS f2 +FROM t2 AS sq +ORDER BY sq.f1; + +drop table t1, t2; + +--error ER_BAD_FIELD_ERROR +SELECT 1 FROM (SELECT 1 as a) AS b HAVING (SELECT `SOME_GARBAGE`.b.a)=1; + --echo # ----------------------------------------------------------------- --echo # -- End of 10.0 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8f222761c60..807ec93f4cb 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -6423,6 +6423,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, */ table_name && table_name[0] && (my_strcasecmp(table_alias_charset, table_list->alias, table_name) || + (db_name && db_name[0] && (!table_list->db || !table_list->db[0])) || (db_name && db_name[0] && table_list->db && table_list->db[0] && (table_list->schema_table ? my_strcasecmp(system_charset_info, db_name, table_list->db) : @@ -6896,7 +6897,10 @@ find_item_in_list(Item *find, List &items, uint *counter, for (uint i= 0; (item=li++); i++) { - if (field_name && item->real_item()->type() == Item::FIELD_ITEM) + if (field_name && + (item->real_item()->type() == Item::FIELD_ITEM || + ((item->type() == Item::REF_ITEM) && + (((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF)))) { Item_ident *item_field= (Item_ident*) item; @@ -7022,35 +7026,6 @@ find_item_in_list(Item *find, List &items, uint *counter, break; } } - else if (table_name && item->type() == Item::REF_ITEM && - ((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF) - { - /* - TODO:Here we process prefixed view references only. What we should - really do is process all types of Item_refs. But this will currently - lead to a clash with the way references to outer SELECTs (from the - HAVING clause) are handled in e.g. : - SELECT 1 FROM t1 AS t1_o GROUP BY a - HAVING (SELECT t1_o.a FROM t1 AS t1_i GROUP BY t1_i.a LIMIT 1). - Processing all Item_refs here will cause t1_o.a to resolve to itself. - We still need to process the special case of Item_direct_view_ref - because in the context of views they have the same meaning as - Item_field for tables. - */ - Item_ident *item_ref= (Item_ident *) item; - if (field_name && item_ref->name && item_ref->table_name && - !my_strcasecmp(system_charset_info, item_ref->name, field_name) && - !my_strcasecmp(table_alias_charset, item_ref->table_name, - table_name) && - (!db_name || (item_ref->db_name && - !strcmp (item_ref->db_name, db_name)))) - { - found= li.ref(); - *counter= i; - *resolution= RESOLVED_IGNORING_ALIAS; - break; - } - } } if (!found) {