Commit 09b316f0 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

updateability of field with collation support (BUG#5506)

parent d24f2936
......@@ -1311,3 +1311,19 @@ a a a
3 3 3
drop view v1;
drop table t1;
create table t1 (s1 char);
create view v1 as select s1 collate latin1_german1_ci as s1 from t1;
insert into v1 values ('a');
select * from v1;
s1
a
update v1 set s1='b';
select * from v1;
s1
b
update v1,t1 set v1.s1='c' where t1.s1=v1.s1;
select * from v1;
s1
c
drop view v1;
drop table t1;
......@@ -1271,3 +1271,17 @@ select * from t1 left join (t2 as t, v1) on v1.a=t1.a;
select * from t1 left join (t2 as t, t2) on t2.a=t1.a;
drop view v1;
drop table t1;
#
# Collation with view update
#
create table t1 (s1 char);
create view v1 as select s1 collate latin1_german1_ci as s1 from t1;
insert into v1 values ('a');
select * from v1;
update v1 set s1='b';
select * from v1;
update v1,t1 set v1.s1='c' where t1.s1=v1.s1;
select * from v1;
drop view v1;
drop table t1;
......@@ -22,6 +22,7 @@
class Protocol;
struct st_table_list;
void item_init(void); /* Init item functions */
class Item_field;
/*
......@@ -276,6 +277,7 @@ public:
virtual void bring_value() {}
Field *tmp_table_field_from_field_type(TABLE *table);
virtual Item_field *filed_for_view_update() { return 0; }
virtual Item *neg_transformer(THD *thd) { return NULL; }
void delete_self()
......@@ -496,6 +498,7 @@ public:
Item *get_tmp_table_item(THD *thd);
void cleanup();
inline uint32 max_disp_length() { return field->max_length(); }
Item_field *filed_for_view_update() { return this; }
friend class Item_default_value;
friend class Item_insert_value;
friend class st_select_lex_unit;
......
......@@ -636,6 +636,11 @@ public:
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "collate"; }
void print(String *str);
Item_field *filed_for_view_update()
{
/* this function is transparent for view updating */
return args[0]->filed_for_view_update();
}
};
class Item_func_charset :public Item_str_func
......
......@@ -490,13 +490,13 @@ static bool check_view_insertability(TABLE_LIST *view, ulong query_id)
{
Item_field *field;
/* simple SELECT list entry (field without expression) */
if ((*trans)->type() != Item::FIELD_ITEM)
if (!(field= (*trans)->filed_for_view_update()))
DBUG_RETURN(TRUE);
field= (Item_field *)(*trans);
if (field->field->unireg_check == Field::NEXT_NUMBER)
view->contain_auto_increment= 1;
/* prepare unique test */
field->field->query_id= other_query_id;
*trans= field; // remove collation if we have it
}
/* unique test */
for (trans= trans_start; trans != trans_end; trans++)
......
......@@ -67,9 +67,10 @@ static bool check_fields(THD *thd, List<Item> &items)
{
List_iterator<Item> it(items);
Item *item;
Item_field *field;
while ((item= it++))
{
if (item->type() != Item::FIELD_ITEM)
if (!(field= item->filed_for_view_update()))
{
/* as far as item comes from VIEW select list it has name */
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
......@@ -79,7 +80,7 @@ static bool check_fields(THD *thd, List<Item> &items)
we make temporary copy of Item_field, to avoid influence of changing
result_field on Item_ref which refer on this field
*/
Item_field *field= new Item_field(thd, (Item_field *)item);
field= new Item_field(thd, field);
it.replace(field);
((Item_field *)item)->register_item_tree_changing(it.ref());
}
......
......@@ -148,8 +148,9 @@ int mysql_create_view(THD *thd,
Item *item;
while ((item= it++))
{
if (item->type() == Item::FIELD_ITEM)
((Item_field *)item)->any_privileges= 1;
Item_field *field;
if ((field= item->filed_for_view_update()))
field->any_privileges= 1;
}
}
#endif
......@@ -237,12 +238,12 @@ int mysql_create_view(THD *thd,
view->real_name);
while ((item= it++))
{
Item_field *fld;
uint priv= (get_column_grant(thd, &view->grant, db,
view->real_name, item->name) &
VIEW_ANY_ACL);
if (item->type() == Item::FIELD_ITEM)
if ((fld= item->filed_for_view_update()))
{
Item_field *fld= (Item_field *)item;
/*
There are no any privileges on VIEW column or there are
some other privileges then we have for underlaying table
......@@ -903,8 +904,9 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
uint k;
for (k= 0; k < elements_in_view; k++)
{
if (trans[k]->type() == Item::FIELD_ITEM &&
((Item_field *)trans[k])->field == key_part->field)
Item_field *field;
if ((field= trans[k]->filed_for_view_update()) &&
field->field == key_part->field)
break;
}
if (k == elements_in_view)
......@@ -923,8 +925,9 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
{
for (i= 0; i < elements_in_view; i++)
{
if (trans[i]->type() == Item::FIELD_ITEM &&
((Item_field *)trans[i])->field == *field_ptr)
Item_field *field;
if ((field= trans[i]->filed_for_view_update()) &&
field->field == *field_ptr)
break;
}
if (i == elements_in_view) // If field didn't exists
......@@ -976,8 +979,9 @@ void insert_view_fields(List<Item> *list, TABLE_LIST *view)
for (uint i= 0; i < elements_in_view; i++)
{
if (trans[i]->type() == Item::FIELD_ITEM)
list->push_back(trans[i]);
Item_field *fld;
if ((fld= trans[i]->filed_for_view_update()))
list->push_back(fld);
}
DBUG_VOID_RETURN;
}
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