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
This commit is contained in:
parent
5a00a868b7
commit
f88d01932f
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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++)
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
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);
|
||||
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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user