diff options
author | unknown <bell@sanja.is.com.ua> | 2004-11-25 02:23:13 +0200 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-11-25 02:23:13 +0200 |
commit | f88d01932f4a81682267e21022686d3dea4edb78 (patch) | |
tree | b6370530d805ecddad3284428883cac10256f774 | |
parent | 5a00a868b74ffb6b220eb72c87ec38696ce9406c (diff) | |
download | mariadb-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.result | 40 | ||||
-rw-r--r-- | mysql-test/t/view.test | 25 | ||||
-rw-r--r-- | sql/mysql_priv.h | 14 | ||||
-rw-r--r-- | sql/sp.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 41 | ||||
-rw-r--r-- | sql/sql_delete.cc | 5 | ||||
-rw-r--r-- | sql/sql_help.cc | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 38 | ||||
-rw-r--r-- | sql/sql_load.cc | 5 | ||||
-rw-r--r-- | sql/sql_olap.cc | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 49 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 27 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 | ||||
-rw-r--r-- | sql/sql_update.cc | 19 | ||||
-rw-r--r-- | sql/sql_view.cc | 13 | ||||
-rw-r--r-- | sql/sql_view.h | 2 |
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); |