Commit 58263844 authored by unknown's avatar unknown

Fix for BUG#13410 - qualified reference to a view column in the HAVING clause cannot be resolved.

The problem was then when a column reference was resolved to a view column, the new Item
created for this column contained the name of the view, and not the view alias.


mysql-test/r/view.result:
  Additional test for BUG#13410.
mysql-test/t/view.test:
  Additional test for BUG#13410.
sql/item.cc:
  Correctly cast 'cur_field' to Item_ident because if the original item is
  an Item_field, the cur_field is either an Item_field or an Item_ref.
  Thus we have to cast cur_field to a common super-class of both.
sql/item.h:
  - real_item() may be called before Item_ref::ref is set
    (i.e. the Item_ref object was resolved).
  - To avoid a crash and to return some meaningful value
    in such cases we return 'this'.
sql/sql_base.cc:
  - 'item' may be an Item_ref, so we test for the type of the actual
    referenced item.
  - Correctly cast 'cur_field' to Item_ident because if the original
    item is an Item_field, the cur_field is either an Item_field or an
    Item_ref. Thus we have to cast cur_field to a common super-class
    of both.
sql/table.cc:
  - When creating a new Item for a reference to a view column, use the view alias,
    and not the real view name.
  - Removed old code
parent 3a806cd6
...@@ -2286,5 +2286,15 @@ SELECT v1.a FROM v1 GROUP BY v1.a HAVING v1.a > 1; ...@@ -2286,5 +2286,15 @@ SELECT v1.a FROM v1 GROUP BY v1.a HAVING v1.a > 1;
a a
2 2
3 3
SELECT t_1.a FROM t1 AS t_1 GROUP BY t_1.a HAVING t_1.a IN (1,2,3);
a
1
2
3
SELECT v_1.a FROM v1 AS v_1 GROUP BY v_1.a HAVING v_1.a IN (1,2,3);
a
1
2
3
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
...@@ -2162,6 +2162,8 @@ INSERT INTO t1 VALUES (1,1),(2,2),(3,3); ...@@ -2162,6 +2162,8 @@ INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
CREATE VIEW v1 AS SELECT a,b FROM t1; CREATE VIEW v1 AS SELECT a,b FROM t1;
SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a > 1; SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a > 1;
SELECT v1.a FROM v1 GROUP BY v1.a HAVING v1.a > 1; SELECT v1.a FROM v1 GROUP BY v1.a HAVING v1.a > 1;
SELECT t_1.a FROM t1 AS t_1 GROUP BY t_1.a HAVING t_1.a IN (1,2,3);
SELECT v_1.a FROM v1 AS v_1 GROUP BY v_1.a HAVING v_1.a IN (1,2,3);
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
...@@ -2973,7 +2973,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) ...@@ -2973,7 +2973,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
const char *field_name; const char *field_name;
ORDER *found_group= NULL; ORDER *found_group= NULL;
int found_match_degree= 0; int found_match_degree= 0;
Item_field *cur_field; Item_ident *cur_field;
int cur_match_degree= 0; int cur_match_degree= 0;
if (find_item->type() == Item::FIELD_ITEM || if (find_item->type() == Item::FIELD_ITEM ||
...@@ -2992,7 +2992,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) ...@@ -2992,7 +2992,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
{ {
if ((*(cur_group->item))->real_item()->type() == Item::FIELD_ITEM) if ((*(cur_group->item))->real_item()->type() == Item::FIELD_ITEM)
{ {
cur_field= (Item_field*) *cur_group->item; cur_field= (Item_ident*) *cur_group->item;
cur_match_degree= 0; cur_match_degree= 0;
DBUG_ASSERT(cur_field->field_name != 0); DBUG_ASSERT(cur_field->field_name != 0);
......
...@@ -1619,7 +1619,7 @@ public: ...@@ -1619,7 +1619,7 @@ public:
} }
Item *real_item() Item *real_item()
{ {
return (*ref)->real_item(); return (ref && *ref) ? (*ref)->real_item() : this;
} }
bool walk(Item_processor processor, byte *arg) bool walk(Item_processor processor, byte *arg)
{ return (*ref)->walk(processor, arg); } { return (*ref)->walk(processor, arg); }
......
...@@ -3357,9 +3357,9 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, ...@@ -3357,9 +3357,9 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
for (uint i= 0; (item=li++); i++) for (uint i= 0; (item=li++); i++)
{ {
if (field_name && item->type() == Item::FIELD_ITEM) if (field_name && item->real_item()->type() == Item::FIELD_ITEM)
{ {
Item_field *item_field= (Item_field*) item; Item_ident *item_field= (Item_ident*) item;
/* /*
In case of group_concat() with ORDER BY condition in the QUERY In case of group_concat() with ORDER BY condition in the QUERY
......
...@@ -2424,22 +2424,6 @@ Field *Natural_join_column::field() ...@@ -2424,22 +2424,6 @@ Field *Natural_join_column::field()
const char *Natural_join_column::table_name() const char *Natural_join_column::table_name()
{ {
return table_ref->alias; return table_ref->alias;
/*
TODO:
I think that it is sufficient to return just
table->alias, which is correctly set to either
the view name, the table name, or the alias to
the table reference (view or stored table).
*/
#ifdef NOT_YET
if (view_field)
return table_ref->view_name.str;
DBUG_ASSERT(!strcmp(table_ref->table_name,
table_ref->table->s->table_name));
return table_ref->table_name;
}
#endif
} }
...@@ -2575,7 +2559,7 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref, ...@@ -2575,7 +2559,7 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
DBUG_RETURN(field); DBUG_RETURN(field);
} }
Item *item= new Item_direct_view_ref(&view->view->select_lex.context, Item *item= new Item_direct_view_ref(&view->view->select_lex.context,
field_ref, view->view_name.str, field_ref, view->alias,
name); name);
DBUG_RETURN(item); DBUG_RETURN(item);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment