summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-11-25 02:23:13 +0200
committerunknown <bell@sanja.is.com.ua>2004-11-25 02:23:13 +0200
commitf88d01932f4a81682267e21022686d3dea4edb78 (patch)
treeb6370530d805ecddad3284428883cac10256f774
parent5a00a868b74ffb6b220eb72c87ec38696ce9406c (diff)
downloadmariadb-git-f88d01932f4a81682267e21022686d3dea4edb78.tar.gz
post-merge fix
mysql-test/r/view.result: changes in error number, and key in view processing mysql-test/t/view.test: changes in error number, and key in view processing sql/mysql_priv.h: changes functions sql/sp.cc: now we report to setup_tables(), are we setuping SELECT...INSERT sql/sql_base.cc: fixed finding table, taking in account join view, which can have not TABLE pointer now we report to setup_tables(), are we setuping SELECT...INSERT and ennumerete insert table separately sql/sql_delete.cc: now we report to setup_tables(), are we setuping SELECT...INSERT sql/sql_help.cc: now we report to setup_tables(), are we setuping SELECT...INSERT sql/sql_insert.cc: fixed returning value of functions sql/sql_load.cc: now we report to setup_tables(), are we setuping SELECT...INSERT removed second setup_tables call (merge) sql/sql_olap.cc: now we report to setup_tables(), are we setuping SELECT...INSERT sql/sql_parse.cc: UPDATE->MULTIUPDATE switching fixed sql/sql_prepare.cc: UPDATE->MULTIUPDATE switching fixed sql/sql_select.cc: now we report to setup_tables(), are we setuping SELECT...INSERT sql/sql_update.cc: UPDATE->MULTIUPDATE switching fixed sql/sql_view.cc: returning value fixed sql/sql_view.h: returning value fixed
-rw-r--r--mysql-test/r/view.result40
-rw-r--r--mysql-test/t/view.test25
-rw-r--r--sql/mysql_priv.h14
-rw-r--r--sql/sp.cc2
-rw-r--r--sql/sql_base.cc41
-rw-r--r--sql/sql_delete.cc5
-rw-r--r--sql/sql_help.cc2
-rw-r--r--sql/sql_insert.cc38
-rw-r--r--sql/sql_load.cc5
-rw-r--r--sql/sql_olap.cc3
-rw-r--r--sql/sql_parse.cc49
-rw-r--r--sql/sql_prepare.cc27
-rw-r--r--sql/sql_select.cc6
-rw-r--r--sql/sql_update.cc19
-rw-r--r--sql/sql_view.cc13
-rw-r--r--sql/sql_view.h2
16 files changed, 156 insertions, 135 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 1bfbc28935a..e2c6b3f2ae2 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1661,6 +1661,7 @@ check table v1;
Table Op Msg_type Msg_text
test.v1 check error View 'test.v1' references invalid table(s) or column(s)
drop view v1;
+create table t1 (a int);
create table t2 (a int);
create table t3 (a int);
insert into t1 values (1), (2), (3);
@@ -1723,8 +1724,10 @@ a
1
3
create view v2 (a,b) as select t1.b as a, t2.a as b from t1, t2;
-update v2 set a= 10 where a=200;
-ERROR HY000: The target table v2 of the UPDATE is not updatable
+set updatable_views_with_limit=NO;
+update v2 set a= 10 where a=200 limit 1;
+ERROR HY000: The target table t1 of the UPDATE is not updatable
+set updatable_views_with_limit=DEFAULT;
select * from v3;
a b
2 1
@@ -1789,37 +1792,6 @@ a b
10 NULL
2000 NULL
0 NULL
-create view v2 (a,b) as select t1.b as a, t2.a as b from t1, t2;
-insert into v2(a) values (10);
-ERROR HY000: The target table v2 of the INSERT is not updatable
-select * from v3;
-a b
-10 1000
-1000 1000
-10002 1000
-10 10
-1000 10
-10002 10
-10 2000
-1000 2000
-10002 2000
-10 0
-1000 0
-10002 0
-select * from v2;
-a b
-NULL 1000
-NULL 1000
-NULL 1000
-NULL 10
-NULL 10
-NULL 10
-NULL 2000
-NULL 2000
-NULL 2000
-NULL 0
-NULL 0
-NULL 0
delete from v3;
ERROR HY000: Can not delete from join view 'test.v3'
delete v3,t1 from v3,t1;
@@ -1855,5 +1827,5 @@ a b
101 0
300 0
301 0
-drop view v3,v2;
+drop view v3;
drop tables t1,t2;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index bf50800fbe3..92747323336 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -1641,8 +1641,10 @@ select * from t1;
select * from t2;
# view without primary key
create view v2 (a,b) as select t1.b as a, t2.a as b from t1, t2;
+set updatable_views_with_limit=NO;
-- error 1288
-update v2 set a= 10 where a=200;
+update v2 set a= 10 where a=200 limit 1;
+set updatable_views_with_limit=DEFAULT;
# just view selects
select * from v3;
select * from v2;
@@ -1668,14 +1670,14 @@ create table t2 (a int, primary key (a), b int);
insert into t2 values (1000, 2000);
create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
# inserting into join view without field list
--- error 1365
+-- error 1394
insert into v3 values (1,2);
--- error 1365
+-- error 1394
insert into v3 select * from t2;
# inserting in several tables of join view
--- error 1364
+-- error 1393
insert into v3(a,b) values (1,2);
--- error 1364
+-- error 1393
insert into v3(a,b) select * from t2;
# correct inserts into join view
insert into v3(a) values (1);
@@ -1685,17 +1687,10 @@ insert into v3(b) select b from t2;
insert into v3(a) values (1) on duplicate key update a=a+10000+VALUES(a);
select * from t1;
select * from t2;
-# view without primary key
-create view v2 (a,b) as select t1.b as a, t2.a as b from t1, t2;
--- error 1288
-insert into v2(a) values (10);
-# just view selects
-select * from v3;
-select * from v2;
# try delete from join view
--- error 1366
+-- error 1395
delete from v3;
--- error 1366
+-- error 1395
delete v3,t1 from v3,t1;
# delete from t1 just to reduce result set size
delete from t1;
@@ -1714,5 +1709,5 @@ execute stmt1 using @a;
deallocate prepare stmt1;
select * from v3;
-drop view v3,v2;
+drop view v3;
drop tables t1,t2;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 6a0ec13eac2..581d82f2c2b 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -614,10 +614,10 @@ bool mysql_drop_index(THD *thd, TABLE_LIST *table_list,
ALTER_INFO *alter_info);
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
Item **conds, uint order_num, ORDER *order);
-bool mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
- List<Item> &values,COND *conds,
- uint order_num, ORDER *order, ha_rows limit,
- enum enum_duplicates handle_duplicates);
+int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
+ List<Item> &values,COND *conds,
+ uint order_num, ORDER *order, ha_rows limit,
+ enum enum_duplicates handle_duplicates);
bool mysql_multi_update(THD *thd, TABLE_LIST *table_list,
List<Item> *fields, List<Item> *values,
COND *conds, ulong options,
@@ -800,9 +800,11 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
bool insert_fields(THD *thd,TABLE_LIST *tables,
const char *db_name, const char *table_name,
List_iterator<Item> *it, bool any_privileges,
- bool allocate_view_names);
+ bool allocate_view_names,
+ bool select_insert);
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
- TABLE_LIST **leaves, bool refresh_only);
+ TABLE_LIST **leaves, bool refresh_only,
+ bool select_insert);
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num);
bool setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
diff --git a/sql/sp.cc b/sql/sp.cc
index 3b3a307c859..41ce3552292 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -608,7 +608,7 @@ db_show_routine_status(THD *thd, int type, const char *wild)
tables is not VIEW for sure => we can pass 0 as condition
*/
- setup_tables(thd, &tables, 0, &leaves, 0);
+ setup_tables(thd, &tables, 0, &leaves, FALSE, FALSE);
for (used_field= &used_fields[0];
used_field->field_name;
used_field++)
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 9b51c7ecd8a..e2a9ac5680d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -580,7 +580,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
{
for (; table; table= *(TABLE_LIST **) ((char*) table + offset))
{
- if (table->table->tmp_table == NO_TMP_TABLE &&
+ if ((table->table == 0 || table->table->tmp_table == NO_TMP_TABLE) &&
((!strcmp(table->db, db_name) &&
!strcmp(table->real_name, table_name)) ||
(table->view &&
@@ -595,7 +595,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
{
for (; table; table= *(TABLE_LIST **) ((char*) table + offset))
{
- if (table->table->tmp_table == NO_TMP_TABLE &&
+ if ((table->table == 0 || table->table->tmp_table == NO_TMP_TABLE) &&
((!strcmp(table->db, db_name) &&
!strcmp(table->real_name, table_name)) ||
(table->view &&
@@ -2786,14 +2786,14 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
SYNOPSIS
setup_tables()
- thd Thread handler
- tables Table list
- conds Condition of current SELECT (can be changed by VIEW)
- leaves List of join table leaves list
- refresh It is onle refresh for subquery
+ thd Thread handler
+ tables Table list
+ conds Condition of current SELECT (can be changed by VIEW)
+ leaves List of join table leaves list
+ refresh It is onle refresh for subquery
+ select_insert It is SELECT ... INSERT command
NOTE
- Remap table numbers if INSERT ... SELECT
Check also that the 'used keys' and 'ignored keys' exists and set up the
table structure accordingly
Create leaf tables list
@@ -2802,29 +2802,46 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
table->map is not set and all Item_field will be regarded as const items.
RETURN
- 0 ok; In this case *map will includes the choosed index
- 1 error
+ FALSE ok; In this case *map will includes the choosed index
+ TRUE error
*/
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
- TABLE_LIST **leaves, bool refresh)
+ TABLE_LIST **leaves, bool refresh, bool select_insert)
{
DBUG_ENTER("setup_tables");
+ /*
+ this is used for INSERT ... SELECT.
+ For select we setup tables except first (and its underlaying tables)
+ */
+ TABLE_LIST *first_select_table= (select_insert ?
+ tables->next_local:
+ 0);
if (!tables || tables->setup_is_done)
DBUG_RETURN(0);
tables->setup_is_done= 1;
+
if (!(*leaves))
{
make_leaves_list(leaves, tables);
}
- uint tablenr=0;
+ uint tablenr= 0;
for (TABLE_LIST *table_list= *leaves;
table_list;
table_list= table_list->next_leaf, tablenr++)
{
TABLE *table= table_list->table;
+ if (first_select_table &&
+ (table_list->belong_to_view ?
+ table_list->belong_to_view :
+ table_list) == first_select_table)
+ {
+ /* new counting for SELECT of INSERT ... SELECT command */
+ first_select_table= 0;
+ tablenr= 0;
+ }
setup_table_map(table, table_list, tablenr);
table->used_keys= table->keys_for_keyread;
if (table_list->use_index)
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 26ca837bdbd..d4f3cddd4a0 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -296,7 +296,8 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
SELECT_LEX *select_lex= &thd->lex->select_lex;
DBUG_ENTER("mysql_prepare_delete");
- if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables, 0) ||
+ if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables,
+ FALSE, FALSE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
setup_ftfuncs(select_lex))
DBUG_RETURN(TRUE);
@@ -353,7 +354,7 @@ bool mysql_multi_delete_prepare(THD *thd)
lex->query_tables also point on local list of DELETE SELECT_LEX
*/
if (setup_tables(thd, lex->query_tables, &lex->select_lex.where,
- &lex->select_lex.leaf_tables, 0))
+ &lex->select_lex.leaf_tables, FALSE, FALSE))
DBUG_RETURN(TRUE);
/* Fix tables-to-be-deleted-from list to point at opened tables */
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 52548803984..bcde1dc46f2 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -647,7 +647,7 @@ bool mysqld_help(THD *thd, const char *mask)
tables do not contain VIEWs => we can pass 0 as conds
*/
- setup_tables(thd, tables, 0, &leaves, 0);
+ setup_tables(thd, tables, 0, &leaves, FALSE, FALSE);
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
goto error;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index dca2a498d7d..673d7425c36 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -612,25 +612,26 @@ static bool check_view_insertability(TABLE_LIST *view, ulong query_id)
SYNOPSIS
mysql_prepare_insert_check_table()
thd Thread handle
- table_list Table list (only one table)
+ table_list Table list
fields List of fields to be updated
where Pointer to where clause
+ select_insert Check is making for SELECT ... INSERT
RETURN
- 0 ok
- 1 ERROR and message sent to client
- -1 ERROR but message is not sent to client
+ FALSE ok
+ TRUE ERROR
*/
-static int mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
- List<Item> &fields, COND **where)
+static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
+ List<Item> &fields, COND **where,
+ bool select_insert)
{
bool insert_into_view= (table_list->view != 0);
DBUG_ENTER("mysql_prepare_insert_check_table");
if (setup_tables(thd, table_list, where, &thd->lex->select_lex.leaf_tables,
- 0))
- DBUG_RETURN(thd->net.report_error ? -1 : 1);
+ FALSE, select_insert))
+ DBUG_RETURN(TRUE);
if (insert_into_view && !fields.elements)
{
@@ -641,12 +642,12 @@ static int mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
table_list->ancestor && table_list->ancestor->next_local);
my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0),
table_list->view_db.str, table_list->view_name.str);
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
DBUG_RETURN(insert_view_fields(&fields, table_list));
}
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -674,9 +675,12 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
bool res;
DBUG_ENTER("mysql_prepare_insert");
- if ((res= mysql_prepare_insert_check_table(thd, table_list,
- fields, &unused_conds)))
- DBUG_RETURN(res);
+ DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d",
+ (ulong)table_list, (ulong)table,
+ (int)insert_into_view));
+ if (mysql_prepare_insert_check_table(thd, table_list, fields, &unused_conds,
+ FALSE))
+ DBUG_RETURN(TRUE);
if (check_insert_fields(thd, table_list, fields, *values, 1,
!insert_into_view) ||
@@ -689,6 +693,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
setup_fields(thd, 0, table_list, update_values, 1, 0, 0))))
DBUG_RETURN(TRUE);
+ if (!table)
+ table= table_list->table;
+
if (unique_table(table_list, table_list->next_global))
{
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
@@ -1716,8 +1723,9 @@ bool mysql_insert_select_prepare(THD *thd)
lex->query_tables->no_where_clause= 1;
if (mysql_prepare_insert_check_table(thd, lex->query_tables,
lex->field_list,
- &lex->select_lex.where))
- DBUG_RETURN(FALSE);
+ &lex->select_lex.where,
+ TRUE))
+ DBUG_RETURN(TRUE);
/*
setup was done in mysql_insert_select_prepare, but we have to mark
first local table
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index edd72851a21..21dd2318504 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -122,7 +122,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
if (setup_tables(thd, table_list, &unused_conds,
- &thd->lex->select_lex.leaf_tables, 0))
+ &thd->lex->select_lex.leaf_tables, FALSE, FALSE))
DBUG_RETURN(-1);
if (!table_list->table || // do not suport join view
!table_list->updatable || // and derived tables
@@ -147,8 +147,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* TODO: use this conds for 'WITH CHECK OPTIONS' */
Item *unused_conds= 0;
TABLE_LIST *leaves= 0;
- if (setup_tables(thd, table_list, &unused_conds, &leaves, 0) ||
- setup_fields(thd, 0, table_list, fields, 1, 0, 0))
+ if (setup_fields(thd, 0, table_list, fields, 1, 0, 0))
DBUG_RETURN(TRUE);
if (thd->dupp_field)
{
diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc
index c287b9e71e7..07271d40492 100644
--- a/sql/sql_olap.cc
+++ b/sql/sql_olap.cc
@@ -153,7 +153,8 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
if (setup_tables(lex->thd, (TABLE_LIST *)select_lex->table_list.first
- &select_lex->where, &select_lex->leaf_tables, 0) ||
+ &select_lex->where, &select_lex->leaf_tables,
+ FALSE, FALSE) ||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
select_lex->item_list, 1, &all_fields,1) ||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ca19f982826..7089a79124d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2030,6 +2030,7 @@ bool
mysql_execute_command(THD *thd)
{
bool res= FALSE;
+ int result= 0;
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
SELECT_LEX *select_lex= &lex->select_lex;
@@ -2874,33 +2875,33 @@ create_error:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (update_precheck(thd, all_tables))
break;
- res= mysql_update(thd, all_tables,
- select_lex->item_list,
- lex->value_list,
- select_lex->where,
- select_lex->order_list.elements,
- (ORDER *) select_lex->order_list.first,
- select_lex->select_limit,
- lex->duplicates);
- if (res != 2)
+ res= (result= mysql_update(thd, all_tables,
+ select_lex->item_list,
+ lex->value_list,
+ select_lex->where,
+ select_lex->order_list.elements,
+ (ORDER *) select_lex->order_list.first,
+ select_lex->select_limit,
+ lex->duplicates));
+ if (result != 2)
break;
case SQLCOM_UPDATE_MULTI:
- {
- DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (res != 2)
{
- if ((res= multi_update_precheck(thd, all_tables)))
- break;
- }
- else
- res= 0;
-
- res= mysql_multi_update(thd, all_tables,
- &select_lex->item_list,
- &lex->value_list,
- select_lex->where,
- select_lex->options,
- lex->duplicates, unit, select_lex);
+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
+ if (result != 2)
+ {
+ if ((res= multi_update_precheck(thd, all_tables)))
+ break;
+ }
+ else
+ res= 0;
+
+ res= mysql_multi_update(thd, all_tables,
+ &select_lex->item_list,
+ &lex->value_list,
+ select_lex->where,
+ select_lex->options,
+ lex->duplicates, unit, select_lex);
break;
}
case SQLCOM_REPLACE:
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index fed240b865a..bff5a2fc999 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -944,23 +944,36 @@ static int mysql_test_update(Prepared_statement *stmt,
{
int res;
THD *thd= stmt->thd;
+ uint table_count= 0;
SELECT_LEX *select= &stmt->lex->select_lex;
DBUG_ENTER("mysql_test_update");
if (update_precheck(thd, table_list))
DBUG_RETURN(1);
- if (!(res=open_and_lock_tables(thd, table_list)))
+ if (!open_tables(thd, table_list, &table_count))
{
- if (table_list->table == 0)
+ if (table_list->ancestor && table_list->ancestor->next_local)
{
- DBUG_ASSERT(table_list->view &&
- table_list->ancestor && table_list->ancestor->next_local);
- stmt->lex->sql_command= SQLCOM_UPDATE_MULTI;
- DBUG_PRINT("info", ("Switch to multi-update (command replaced)"));
+ DBUG_ASSERT(table_list->view);
+ DBUG_PRINT("info", ("Switch to multi-update"));
+ /* pass counter value */
+ thd->lex->table_count= table_count;
+ /*
+ give correct value to multi_lock_option, because it will be used
+ in multiupdate
+ */
+ thd->lex->multi_lock_option= table_list->lock_type;
/* convert to multiupdate */
return 2;
}
+
+ if (lock_tables(thd, table_list, table_count) ||
+ mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
+ (thd->fill_derived_tables() &&
+ mysql_handle_derived(thd->lex, &mysql_derived_filling)))
+ DBUG_RETURN(1);
+
if (!(res= mysql_prepare_update(thd, table_list,
&select->where,
select->order_list.elements,
@@ -982,6 +995,8 @@ static int mysql_test_update(Prepared_statement *stmt,
}
stmt->lex->unit.cleanup();
}
+ else
+ res= 1;
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN(res);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 433bc147169..ae60eb759d0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -310,7 +310,8 @@ JOIN::prepare(Item ***rref_pointer_array,
/* Check that all tables, fields, conds and order are ok */
- if (setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables, 0) ||
+ if (setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
+ FALSE, FALSE) ||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
select_lex->setup_ref_array(thd, og_num) ||
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
@@ -1081,7 +1082,8 @@ JOIN::reinit()
if (tables_list)
{
tables_list->setup_is_done= 0;
- if (setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables, 1))
+ if (setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
+ TRUE, FALSE))
DBUG_RETURN(1);
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 0927fcfd9bc..a14c20caad8 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -142,13 +142,17 @@ int mysql_update(THD *thd,
if (open_tables(thd, table_list, &table_count))
DBUG_RETURN(1);
- if (table_list->table == 0)
+ if (table_list->ancestor && table_list->ancestor->next_local)
{
- DBUG_ASSERT(table_list->view &&
- table_list->ancestor && table_list->ancestor->next_local);
+ DBUG_ASSERT(table_list->view);
DBUG_PRINT("info", ("Switch to multi-update"));
/* pass counter value */
thd->lex->table_count= table_count;
+ /*
+ give correct value to multi_lock_option, because it will be used
+ in multiupdate
+ */
+ thd->lex->multi_lock_option= table_list->lock_type;
/* convert to multiupdate */
return 2;
}
@@ -559,7 +563,8 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
tables.table= table;
tables.alias= table_list->alias;
- if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables, 0) ||
+ if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables,
+ FALSE, FALSE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
select_lex->setup_ref_array(thd, order_num) ||
setup_order(thd, select_lex->ref_pointer_array,
@@ -630,6 +635,8 @@ bool mysql_multi_update_prepare(THD *thd)
uint table_count= lex->table_count;
const bool using_lock_tables= thd->locked_tables != 0;
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
+ /* following need for prepared statements, to run next time multi-update */
+ thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
DBUG_ENTER("mysql_multi_update_prepare");
/* open tables and create derived ones, but do not lock and fill them */
@@ -643,7 +650,7 @@ bool mysql_multi_update_prepare(THD *thd)
*/
if (setup_tables(thd, table_list, &lex->select_lex.where,
- &lex->select_lex.leaf_tables, 0))
+ &lex->select_lex.leaf_tables, FALSE, FALSE))
DBUG_RETURN(TRUE);
/*
Ensure that we have update privilege for all tables and columns in the
@@ -782,7 +789,7 @@ bool mysql_multi_update_prepare(THD *thd)
table_list->setup_is_done= 0;
if (setup_tables(thd, table_list, &lex->select_lex.where,
- &lex->select_lex.leaf_tables, 0) ||
+ &lex->select_lex.leaf_tables, FALSE, FALSE) ||
(lex->select_lex.no_wrap_view_item= 1,
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
lex->select_lex.no_wrap_view_item= 0,
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index ca9faddb07a..38ab3a3db9f 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -489,6 +489,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
tbl= tbl->next_local)
{
if ((tbl->view && !tbl->updatable_view) || tbl->schema_table)
+ {
view->updatable_view= 0;
break;
}
@@ -1074,18 +1075,18 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
view view for processing
RETURN
- 0 - OK
- -1 - error (is not sent to cliet)
+ FALSE OK
+ TRUE error (is not sent to cliet)
*/
-int insert_view_fields(List<Item> *list, TABLE_LIST *view)
+bool insert_view_fields(List<Item> *list, TABLE_LIST *view)
{
uint elements_in_view= view->view->select_lex.item_list.elements;
Field_translator *trans;
DBUG_ENTER("insert_view_fields");
if (!(trans= view->field_translation))
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
for (uint i= 0; i < elements_in_view; i++)
{
@@ -1095,10 +1096,10 @@ int insert_view_fields(List<Item> *list, TABLE_LIST *view)
else
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "INSERT");
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
}
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
/*
diff --git a/sql/sql_view.h b/sql/sql_view.h
index 8efa9afeccb..4e6aaf7f477 100644
--- a/sql/sql_view.h
+++ b/sql/sql_view.h
@@ -25,7 +25,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode);
bool check_key_in_view(THD *thd, TABLE_LIST * view);
-int insert_view_fields(List<Item> *list, TABLE_LIST *view);
+bool insert_view_fields(List<Item> *list, TABLE_LIST *view);
frm_type_enum mysql_frm_type(char *path);