summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-07-23 09:25:08 +0300
committerunknown <bell@sanja.is.com.ua>2004-07-23 09:25:08 +0300
commit8b30e4a7f588ba1b14ceeda73d23c991ac522aa1 (patch)
tree92c67af83d58a219cbccc4da3f50af08c32235d2
parent24241c8c7a4025524e391e2c59e8658227dcc83d (diff)
parent1b98202be7544b34f79b99cbf22e4b29090e4f9f (diff)
downloadmariadb-git-8b30e4a7f588ba1b14ceeda73d23c991ac522aa1.tar.gz
merge
sql/sql_base.cc: Auto merged
-rw-r--r--mysql-test/r/view.result15
-rw-r--r--mysql-test/t/view.test11
-rw-r--r--sql/item.h11
-rw-r--r--sql/sql_base.cc20
-rw-r--r--sql/sql_insert.cc9
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_update.cc42
-rw-r--r--sql/table.cc5
9 files changed, 100 insertions, 16 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index cc7bbfd2e0c..d42c2a24df5 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -999,3 +999,18 @@ select b from v1 use index (some_index) where b=1;
ERROR 42000: Key column 'some_index' doesn't exist in table
drop view v1;
drop table t1;
+create table t1 (col1 char(5),col2 char(5));
+create view v1 (col1,col2) as select col1,col2 from t1;
+insert into v1 values('s1','p1'),('s1','p2'),('s1','p3'),('s1','p4'),('s2','p1'),('s3','p2'),('s4','p4');
+select distinct first.col2 from t1 first where first.col2 in (select second.col2 from t1 second where second.col1<>first.col1);
+col2
+p1
+p2
+p4
+select distinct first.col2 from v1 first where first.col2 in (select second.col2 from t1 second where second.col1<>first.col1);
+col2
+p1
+p2
+p4
+drop view v1;
+drop table t1;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 6a14c2d573e..f9ff64e2e5b 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -932,3 +932,14 @@ create view v1 as select a, sum(b) from t1 group by a;
select b from v1 use index (some_index) where b=1;
drop view v1;
drop table t1;
+
+#
+# using VIEW fields several times in query resolved via temporary tables
+#
+create table t1 (col1 char(5),col2 char(5));
+create view v1 (col1,col2) as select col1,col2 from t1;
+insert into v1 values('s1','p1'),('s1','p2'),('s1','p3'),('s1','p4'),('s2','p1'),('s3','p2'),('s4','p4');
+select distinct first.col2 from t1 first where first.col2 in (select second.col2 from t1 second where second.col1<>first.col1);
+select distinct first.col2 from v1 first where first.col2 in (select second.col2 from t1 second where second.col1<>first.col1);
+drop view v1;
+drop table t1;
diff --git a/sql/item.h b/sql/item.h
index 583b17ca1df..afa439dff32 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -887,15 +887,15 @@ public:
Item *orig_item; /* things in 'cleanup()' */
Item_ref(Item **hook, Item *original,const char *db_par,
const char *table_name_par, const char *field_name_par)
- :Item_ident(db_par,table_name_par,field_name_par),ref(0), hook_ptr(hook),
- orig_item(original) {}
- Item_ref(Item **item, Item **hook,
+ :Item_ident(db_par, table_name_par, field_name_par), result_field(0),
+ ref(0), hook_ptr(hook), orig_item(original) {}
+ Item_ref(Item **item, Item **hook,
const char *table_name_par, const char *field_name_par)
- :Item_ident(NullS,table_name_par,field_name_par),
+ :Item_ident(NullS, table_name_par, field_name_par), result_field(0),
ref(item), hook_ptr(hook), orig_item(hook ? *hook:0) {}
// Constructor need to process subselect with temporary tables (see Item)
Item_ref(THD *thd, Item_ref *item, Item **hook)
- :Item_ident(thd, item), ref(item->ref),
+ :Item_ident(thd, item), result_field(item->result_field), ref(item->ref),
hook_ptr(hook), orig_item(hook ? *hook : 0) {}
enum Type type() const { return REF_ITEM; }
bool eq(const Item *item, bool binary_cmp) const
@@ -940,6 +940,7 @@ public:
return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
}
void set_result_field(Field *field) { result_field= field; }
+ Field *get_tmp_table_field() { return result_field; }
bool is_result_field() { return 1; }
void save_in_result_field(bool no_conversions)
{
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ec50a30c953..6ff50b32f50 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1955,7 +1955,6 @@ Field *find_field_in_table(THD *thd, TABLE_LIST *table_list,
{
if (strcmp(trans[i]->name, name) == 0)
{
- *ref= trans[i];
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_grants_view &&
check_grant_column(thd, &table_list->grant,
@@ -1964,6 +1963,21 @@ Field *find_field_in_table(THD *thd, TABLE_LIST *table_list,
name, length))
return WRONG_GRANT;
#endif
+ if (thd->lex->current_select->no_wrap_view_item)
+ *ref= trans[i];
+ else
+ {
+ Item_arena *arena= thd->current_arena, backup;
+ if (arena)
+ thd->set_n_backup_item_arena(arena, &backup);
+ *ref= new Item_ref(trans + i, 0, table_list->view_name.str,
+ name);
+ if (arena)
+ thd->restore_backup_item_arena(arena, &backup);
+ /* as far as Item_ref have defined refernce it do not need tables */
+ if (*ref)
+ (*ref)->fix_fields(thd, 0, ref);
+ }
return (Field*) view_ref_found;
}
}
@@ -2441,6 +2455,7 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
{
reg2 Item *item;
List_iterator<Item> it(fields);
+ SELECT_LEX *select_lex= thd->lex->current_select;
DBUG_ENTER("setup_fields");
thd->set_query_id=set_query_id;
@@ -2452,7 +2467,10 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
{
if (!item->fixed && item->fix_fields(thd, tables, it.ref()) ||
(item= *(it.ref()))->check_cols(1))
+ {
+ select_lex->no_wrap_view_item= 0;
DBUG_RETURN(-1); /* purecov: inspected */
+ }
if (ref)
*(ref++)= item;
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index a9a7d9b4d5a..b43c4d31b34 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -76,6 +76,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List<Item> &fields,
else
{ // Part field list
TABLE_LIST *save_next= table_list->next_local;
+ int res;
if (fields.elements != values.elements)
{
my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW,
@@ -86,12 +87,14 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List<Item> &fields,
table_list->next_local= 0;
thd->dupp_field=0;
- if (setup_fields(thd, 0, table_list, fields, 1, 0, 0))
+ thd->lex->select_lex.no_wrap_view_item= 1;
+ res= setup_fields(thd, 0, table_list, fields, 1, 0, 0);
+ thd->lex->select_lex.no_wrap_view_item= 0;
+ table_list->next_local= save_next;
+ if (res)
{
- table_list->next_local= save_next;
return -1;
}
- table_list->next_local= save_next;
if (check_unique && thd->dupp_field)
{
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index aa1c44b8e73..c4390ce0f9a 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1005,6 +1005,7 @@ void st_select_lex::init_query()
first_execution= 1;
first_cond_optimization= 1;
parsing_place= SELECT_LEX_NODE::NO_MATTER;
+ no_wrap_view_item= 0;
}
void st_select_lex::init_select()
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 5bf6e49abb0..d25381072a5 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -478,6 +478,8 @@ public:
bool subquery_in_having;
bool first_execution; /* first execution in SP or PS */
bool first_cond_optimization;
+ /* do not wrap view fields with Item_ref */
+ bool no_wrap_view_item;
/*
SELECT for SELECT command st_select_lex. Used to privent scaning
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 7d49c422194..61fb4b97200 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -53,6 +53,7 @@ static bool compare_record(TABLE *table, ulong query_id)
SYNOPSIS
check_fields()
+ thd thread handler
items Items for check
RETURN
@@ -60,9 +61,9 @@ static bool compare_record(TABLE *table, ulong query_id)
FALSE Items are OK
*/
-static bool check_fields(List<Item> &items)
+static bool check_fields(THD *thd, List<Item> &items)
{
- List_iterator_fast<Item> it(items);
+ List_iterator<Item> it(items);
Item *item;
while ((item= it++))
{
@@ -72,6 +73,13 @@ static bool check_fields(List<Item> &items)
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name);
return TRUE;
}
+ /*
+ 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);
+ it.replace(field);
+ ((Item_field *)item)->register_item_tree_changing(it.ref());
}
return FALSE;
}
@@ -139,9 +147,14 @@ int mysql_update(THD *thd,
#ifndef NO_EMBEDDED_ACCESS_CHECKS
table_list->grant.want_privilege= table->grant.want_privilege= want_privilege;
#endif
- if (setup_fields(thd, 0, table_list, fields, 1, 0, 0))
- DBUG_RETURN(-1); /* purecov: inspected */
- if (check_fields(fields))
+ {
+ thd->lex->select_lex.no_wrap_view_item= 1;
+ int res= setup_fields(thd, 0, table_list, fields, 1, 0, 0);
+ thd->lex->select_lex.no_wrap_view_item= 0;
+ if (res)
+ DBUG_RETURN(-1); /* purecov: inspected */
+ }
+ if (table_list->view && check_fields(thd, fields))
{
DBUG_RETURN(-1);
}
@@ -521,6 +534,8 @@ int mysql_multi_update_prepare(THD *thd)
List<Item> *fields= &lex->select_lex.item_list;
TABLE_LIST *tl;
table_map tables_for_update= 0, readonly_tables= 0;
+ int res;
+ bool update_view= 0;
DBUG_ENTER("mysql_multi_update_prepare");
/*
Ensure that we have update privilege for all tables and columns in the
@@ -545,9 +560,22 @@ int mysql_multi_update_prepare(THD *thd)
time.
*/
if (setup_tables(thd, table_list, &lex->select_lex.where) ||
- setup_fields(thd, 0, table_list, *fields, 1, 0, 0))
+ (thd->lex->select_lex.no_wrap_view_item= 1,
+ res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
+ thd->lex->select_lex.no_wrap_view_item= 0,
+ res))
DBUG_RETURN(-1);
- if (check_fields(*fields))
+
+ for (tl= table_list; tl ; tl= tl->next_local)
+ {
+ if (tl->view)
+ {
+ update_view= 1;
+ break;
+ }
+ }
+
+ if (update_view && check_fields(thd, *fields))
{
DBUG_RETURN(-1);
}
diff --git a/sql/table.cc b/sql/table.cc
index 0dc3c77e6a5..097dc8aabf6 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1505,6 +1505,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
List_iterator_fast<Item> it(select->item_list);
uint i= 0;
bool save_set_query_id= thd->set_query_id;
+ bool save_wrapper= thd->lex->select_lex.no_wrap_view_item;
DBUG_ENTER("st_table_list::setup_ancestor");
if (ancestor->ancestor &&
@@ -1542,6 +1543,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
/* prevent look up in SELECTs tree */
thd->lex->current_select= &thd->lex->select_lex;
+ thd->lex->select_lex.no_wrap_view_item= 1;
+
/*
Resolve all view items against ancestor table.
@@ -1596,6 +1599,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
}
ok:
+ thd->lex->select_lex.no_wrap_view_item= save_wrapper;
thd->lex->current_select= current_select_save;
thd->set_query_id= save_set_query_id;
DBUG_RETURN(0);
@@ -1607,6 +1611,7 @@ err:
thd->clear_error();
my_error(ER_VIEW_INVALID, MYF(0), view_db.str, view_name.str);
}
+ thd->lex->select_lex.no_wrap_view_item= save_wrapper;
thd->lex->current_select= current_select_save;
thd->set_query_id= save_set_query_id;
DBUG_RETURN(1);