Commit 04b6bf2c authored by unknown's avatar unknown

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
parent d40bdbd4
......@@ -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,7 +614,7 @@ 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,
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);
......@@ -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 &&
......@@ -2791,9 +2791,9 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
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,20 +2875,20 @@ mysql_execute_command(THD *thd)
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (update_precheck(thd, all_tables))
break;
res= mysql_update(thd, all_tables,
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 (res != 2)
lex->duplicates));
if (result != 2)
break;
case SQLCOM_UPDATE_MULTI:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (res != 2)
if (result != 2)
{
if ((res= multi_update_precheck(thd, all_tables)))
break;
......
......@@ -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);
......
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