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