post-merge fix
This commit is contained in:
parent
072d38eb12
commit
1e3d8b0839
@ -1661,6 +1661,7 @@ check table v1;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.v1 check error View 'test.v1' references invalid table(s) or column(s)
|
test.v1 check error View 'test.v1' references invalid table(s) or column(s)
|
||||||
drop view v1;
|
drop view v1;
|
||||||
|
create table t1 (a int);
|
||||||
create table t2 (a int);
|
create table t2 (a int);
|
||||||
create table t3 (a int);
|
create table t3 (a int);
|
||||||
insert into t1 values (1), (2), (3);
|
insert into t1 values (1), (2), (3);
|
||||||
@ -1723,8 +1724,10 @@ a
|
|||||||
1
|
1
|
||||||
3
|
3
|
||||||
create view v2 (a,b) as select t1.b as a, t2.a as b from t1, t2;
|
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;
|
set updatable_views_with_limit=NO;
|
||||||
ERROR HY000: The target table v2 of the UPDATE is not updatable
|
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;
|
select * from v3;
|
||||||
a b
|
a b
|
||||||
2 1
|
2 1
|
||||||
@ -1789,37 +1792,6 @@ a b
|
|||||||
10 NULL
|
10 NULL
|
||||||
2000 NULL
|
2000 NULL
|
||||||
0 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;
|
delete from v3;
|
||||||
ERROR HY000: Can not delete from join view 'test.v3'
|
ERROR HY000: Can not delete from join view 'test.v3'
|
||||||
delete v3,t1 from v3,t1;
|
delete v3,t1 from v3,t1;
|
||||||
@ -1855,5 +1827,5 @@ a b
|
|||||||
101 0
|
101 0
|
||||||
300 0
|
300 0
|
||||||
301 0
|
301 0
|
||||||
drop view v3,v2;
|
drop view v3;
|
||||||
drop tables t1,t2;
|
drop tables t1,t2;
|
||||||
|
@ -1641,8 +1641,10 @@ select * from t1;
|
|||||||
select * from t2;
|
select * from t2;
|
||||||
# view without primary key
|
# view without primary key
|
||||||
create view v2 (a,b) as select t1.b as a, t2.a as b from t1, t2;
|
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
|
-- 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
|
# just view selects
|
||||||
select * from v3;
|
select * from v3;
|
||||||
select * from v2;
|
select * from v2;
|
||||||
@ -1668,14 +1670,14 @@ create table t2 (a int, primary key (a), b int);
|
|||||||
insert into t2 values (1000, 2000);
|
insert into t2 values (1000, 2000);
|
||||||
create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
|
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
|
# inserting into join view without field list
|
||||||
-- error 1365
|
-- error 1394
|
||||||
insert into v3 values (1,2);
|
insert into v3 values (1,2);
|
||||||
-- error 1365
|
-- error 1394
|
||||||
insert into v3 select * from t2;
|
insert into v3 select * from t2;
|
||||||
# inserting in several tables of join view
|
# inserting in several tables of join view
|
||||||
-- error 1364
|
-- error 1393
|
||||||
insert into v3(a,b) values (1,2);
|
insert into v3(a,b) values (1,2);
|
||||||
-- error 1364
|
-- error 1393
|
||||||
insert into v3(a,b) select * from t2;
|
insert into v3(a,b) select * from t2;
|
||||||
# correct inserts into join view
|
# correct inserts into join view
|
||||||
insert into v3(a) values (1);
|
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);
|
insert into v3(a) values (1) on duplicate key update a=a+10000+VALUES(a);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
select * from t2;
|
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
|
# try delete from join view
|
||||||
-- error 1366
|
-- error 1395
|
||||||
delete from v3;
|
delete from v3;
|
||||||
-- error 1366
|
-- error 1395
|
||||||
delete v3,t1 from v3,t1;
|
delete v3,t1 from v3,t1;
|
||||||
# delete from t1 just to reduce result set size
|
# delete from t1 just to reduce result set size
|
||||||
delete from t1;
|
delete from t1;
|
||||||
@ -1714,5 +1709,5 @@ execute stmt1 using @a;
|
|||||||
deallocate prepare stmt1;
|
deallocate prepare stmt1;
|
||||||
select * from v3;
|
select * from v3;
|
||||||
|
|
||||||
drop view v3,v2;
|
drop view v3;
|
||||||
drop tables t1,t2;
|
drop tables t1,t2;
|
||||||
|
@ -614,10 +614,10 @@ bool mysql_drop_index(THD *thd, TABLE_LIST *table_list,
|
|||||||
ALTER_INFO *alter_info);
|
ALTER_INFO *alter_info);
|
||||||
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
||||||
Item **conds, uint order_num, ORDER *order);
|
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,
|
List<Item> &values,COND *conds,
|
||||||
uint order_num, ORDER *order, ha_rows limit,
|
uint order_num, ORDER *order, ha_rows limit,
|
||||||
enum enum_duplicates handle_duplicates);
|
enum enum_duplicates handle_duplicates);
|
||||||
bool mysql_multi_update(THD *thd, TABLE_LIST *table_list,
|
bool mysql_multi_update(THD *thd, TABLE_LIST *table_list,
|
||||||
List<Item> *fields, List<Item> *values,
|
List<Item> *fields, List<Item> *values,
|
||||||
COND *conds, ulong options,
|
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,
|
bool insert_fields(THD *thd,TABLE_LIST *tables,
|
||||||
const char *db_name, const char *table_name,
|
const char *db_name, const char *table_name,
|
||||||
List_iterator<Item> *it, bool any_privileges,
|
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,
|
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,
|
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||||
List<Item> *sum_func_list, uint wild_num);
|
List<Item> *sum_func_list, uint wild_num);
|
||||||
bool setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
|
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
|
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];
|
for (used_field= &used_fields[0];
|
||||||
used_field->field_name;
|
used_field->field_name;
|
||||||
used_field++)
|
used_field++)
|
||||||
|
@ -580,7 +580,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
|
|||||||
{
|
{
|
||||||
for (; table; table= *(TABLE_LIST **) ((char*) table + offset))
|
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->db, db_name) &&
|
||||||
!strcmp(table->real_name, table_name)) ||
|
!strcmp(table->real_name, table_name)) ||
|
||||||
(table->view &&
|
(table->view &&
|
||||||
@ -595,7 +595,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
|
|||||||
{
|
{
|
||||||
for (; table; table= *(TABLE_LIST **) ((char*) table + offset))
|
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->db, db_name) &&
|
||||||
!strcmp(table->real_name, table_name)) ||
|
!strcmp(table->real_name, table_name)) ||
|
||||||
(table->view &&
|
(table->view &&
|
||||||
@ -2786,14 +2786,14 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
setup_tables()
|
setup_tables()
|
||||||
thd Thread handler
|
thd Thread handler
|
||||||
tables Table list
|
tables Table list
|
||||||
conds Condition of current SELECT (can be changed by VIEW)
|
conds Condition of current SELECT (can be changed by VIEW)
|
||||||
leaves List of join table leaves list
|
leaves List of join table leaves list
|
||||||
refresh It is onle refresh for subquery
|
refresh It is onle refresh for subquery
|
||||||
|
select_insert It is SELECT ... INSERT command
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
Remap table numbers if INSERT ... SELECT
|
|
||||||
Check also that the 'used keys' and 'ignored keys' exists and set up the
|
Check also that the 'used keys' and 'ignored keys' exists and set up the
|
||||||
table structure accordingly
|
table structure accordingly
|
||||||
Create leaf tables list
|
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.
|
table->map is not set and all Item_field will be regarded as const items.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok; In this case *map will includes the choosed index
|
FALSE ok; In this case *map will includes the choosed index
|
||||||
1 error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
|
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");
|
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)
|
if (!tables || tables->setup_is_done)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
tables->setup_is_done= 1;
|
tables->setup_is_done= 1;
|
||||||
|
|
||||||
|
|
||||||
if (!(*leaves))
|
if (!(*leaves))
|
||||||
{
|
{
|
||||||
make_leaves_list(leaves, tables);
|
make_leaves_list(leaves, tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint tablenr=0;
|
uint tablenr= 0;
|
||||||
for (TABLE_LIST *table_list= *leaves;
|
for (TABLE_LIST *table_list= *leaves;
|
||||||
table_list;
|
table_list;
|
||||||
table_list= table_list->next_leaf, tablenr++)
|
table_list= table_list->next_leaf, tablenr++)
|
||||||
{
|
{
|
||||||
TABLE *table= table_list->table;
|
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);
|
setup_table_map(table, table_list, tablenr);
|
||||||
table->used_keys= table->keys_for_keyread;
|
table->used_keys= table->keys_for_keyread;
|
||||||
if (table_list->use_index)
|
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;
|
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||||
DBUG_ENTER("mysql_prepare_delete");
|
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_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||||
setup_ftfuncs(select_lex))
|
setup_ftfuncs(select_lex))
|
||||||
DBUG_RETURN(TRUE);
|
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
|
lex->query_tables also point on local list of DELETE SELECT_LEX
|
||||||
*/
|
*/
|
||||||
if (setup_tables(thd, lex->query_tables, &lex->select_lex.where,
|
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);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/* Fix tables-to-be-deleted-from list to point at opened tables */
|
/* 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
|
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));
|
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
|
||||||
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
|
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -612,25 +612,26 @@ static bool check_view_insertability(TABLE_LIST *view, ulong query_id)
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
mysql_prepare_insert_check_table()
|
mysql_prepare_insert_check_table()
|
||||||
thd Thread handle
|
thd Thread handle
|
||||||
table_list Table list (only one table)
|
table_list Table list
|
||||||
fields List of fields to be updated
|
fields List of fields to be updated
|
||||||
where Pointer to where clause
|
where Pointer to where clause
|
||||||
|
select_insert Check is making for SELECT ... INSERT
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
FALSE ok
|
||||||
1 ERROR and message sent to client
|
TRUE ERROR
|
||||||
-1 ERROR but message is not sent to client
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
|
static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
|
||||||
List<Item> &fields, COND **where)
|
List<Item> &fields, COND **where,
|
||||||
|
bool select_insert)
|
||||||
{
|
{
|
||||||
bool insert_into_view= (table_list->view != 0);
|
bool insert_into_view= (table_list->view != 0);
|
||||||
DBUG_ENTER("mysql_prepare_insert_check_table");
|
DBUG_ENTER("mysql_prepare_insert_check_table");
|
||||||
|
|
||||||
if (setup_tables(thd, table_list, where, &thd->lex->select_lex.leaf_tables,
|
if (setup_tables(thd, table_list, where, &thd->lex->select_lex.leaf_tables,
|
||||||
0))
|
FALSE, select_insert))
|
||||||
DBUG_RETURN(thd->net.report_error ? -1 : 1);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (insert_into_view && !fields.elements)
|
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);
|
table_list->ancestor && table_list->ancestor->next_local);
|
||||||
my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0),
|
my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0),
|
||||||
table_list->view_db.str, table_list->view_name.str);
|
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(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;
|
bool res;
|
||||||
DBUG_ENTER("mysql_prepare_insert");
|
DBUG_ENTER("mysql_prepare_insert");
|
||||||
|
|
||||||
if ((res= mysql_prepare_insert_check_table(thd, table_list,
|
DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d",
|
||||||
fields, &unused_conds)))
|
(ulong)table_list, (ulong)table,
|
||||||
DBUG_RETURN(res);
|
(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,
|
if (check_insert_fields(thd, table_list, fields, *values, 1,
|
||||||
!insert_into_view) ||
|
!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))))
|
setup_fields(thd, 0, table_list, update_values, 1, 0, 0))))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
table= table_list->table;
|
||||||
|
|
||||||
if (unique_table(table_list, table_list->next_global))
|
if (unique_table(table_list, table_list->next_global))
|
||||||
{
|
{
|
||||||
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
|
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;
|
lex->query_tables->no_where_clause= 1;
|
||||||
if (mysql_prepare_insert_check_table(thd, lex->query_tables,
|
if (mysql_prepare_insert_check_table(thd, lex->query_tables,
|
||||||
lex->field_list,
|
lex->field_list,
|
||||||
&lex->select_lex.where))
|
&lex->select_lex.where,
|
||||||
DBUG_RETURN(FALSE);
|
TRUE))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
/*
|
/*
|
||||||
setup was done in mysql_insert_select_prepare, but we have to mark
|
setup was done in mysql_insert_select_prepare, but we have to mark
|
||||||
first local table
|
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))
|
if (open_and_lock_tables(thd, table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
if (setup_tables(thd, table_list, &unused_conds,
|
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);
|
DBUG_RETURN(-1);
|
||||||
if (!table_list->table || // do not suport join view
|
if (!table_list->table || // do not suport join view
|
||||||
!table_list->updatable || // and derived tables
|
!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' */
|
/* TODO: use this conds for 'WITH CHECK OPTIONS' */
|
||||||
Item *unused_conds= 0;
|
Item *unused_conds= 0;
|
||||||
TABLE_LIST *leaves= 0;
|
TABLE_LIST *leaves= 0;
|
||||||
if (setup_tables(thd, table_list, &unused_conds, &leaves, 0) ||
|
if (setup_fields(thd, 0, table_list, fields, 1, 0, 0))
|
||||||
setup_fields(thd, 0, table_list, fields, 1, 0, 0))
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
if (thd->dupp_field)
|
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
|
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,
|
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
||||||
select_lex->item_list, 1, &all_fields,1) ||
|
select_lex->item_list, 1, &all_fields,1) ||
|
||||||
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
|
||||||
|
@ -2030,6 +2030,7 @@ bool
|
|||||||
mysql_execute_command(THD *thd)
|
mysql_execute_command(THD *thd)
|
||||||
{
|
{
|
||||||
bool res= FALSE;
|
bool res= FALSE;
|
||||||
|
int result= 0;
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
|
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
|
||||||
SELECT_LEX *select_lex= &lex->select_lex;
|
SELECT_LEX *select_lex= &lex->select_lex;
|
||||||
@ -2874,33 +2875,33 @@ create_error:
|
|||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
if (update_precheck(thd, all_tables))
|
if (update_precheck(thd, all_tables))
|
||||||
break;
|
break;
|
||||||
res= mysql_update(thd, all_tables,
|
res= (result= mysql_update(thd, all_tables,
|
||||||
select_lex->item_list,
|
select_lex->item_list,
|
||||||
lex->value_list,
|
lex->value_list,
|
||||||
select_lex->where,
|
select_lex->where,
|
||||||
select_lex->order_list.elements,
|
select_lex->order_list.elements,
|
||||||
(ORDER *) select_lex->order_list.first,
|
(ORDER *) select_lex->order_list.first,
|
||||||
select_lex->select_limit,
|
select_lex->select_limit,
|
||||||
lex->duplicates);
|
lex->duplicates));
|
||||||
if (res != 2)
|
if (result != 2)
|
||||||
break;
|
break;
|
||||||
case SQLCOM_UPDATE_MULTI:
|
case SQLCOM_UPDATE_MULTI:
|
||||||
{
|
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
|
||||||
if (res != 2)
|
|
||||||
{
|
{
|
||||||
if ((res= multi_update_precheck(thd, all_tables)))
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
break;
|
if (result != 2)
|
||||||
}
|
{
|
||||||
else
|
if ((res= multi_update_precheck(thd, all_tables)))
|
||||||
res= 0;
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res= 0;
|
||||||
|
|
||||||
res= mysql_multi_update(thd, all_tables,
|
res= mysql_multi_update(thd, all_tables,
|
||||||
&select_lex->item_list,
|
&select_lex->item_list,
|
||||||
&lex->value_list,
|
&lex->value_list,
|
||||||
select_lex->where,
|
select_lex->where,
|
||||||
select_lex->options,
|
select_lex->options,
|
||||||
lex->duplicates, unit, select_lex);
|
lex->duplicates, unit, select_lex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_REPLACE:
|
case SQLCOM_REPLACE:
|
||||||
|
@ -944,23 +944,36 @@ static int mysql_test_update(Prepared_statement *stmt,
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
THD *thd= stmt->thd;
|
THD *thd= stmt->thd;
|
||||||
|
uint table_count= 0;
|
||||||
SELECT_LEX *select= &stmt->lex->select_lex;
|
SELECT_LEX *select= &stmt->lex->select_lex;
|
||||||
DBUG_ENTER("mysql_test_update");
|
DBUG_ENTER("mysql_test_update");
|
||||||
|
|
||||||
if (update_precheck(thd, table_list))
|
if (update_precheck(thd, table_list))
|
||||||
DBUG_RETURN(1);
|
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 &&
|
DBUG_ASSERT(table_list->view);
|
||||||
table_list->ancestor && table_list->ancestor->next_local);
|
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||||
stmt->lex->sql_command= SQLCOM_UPDATE_MULTI;
|
/* pass counter value */
|
||||||
DBUG_PRINT("info", ("Switch to multi-update (command replaced)"));
|
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 */
|
/* convert to multiupdate */
|
||||||
return 2;
|
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,
|
if (!(res= mysql_prepare_update(thd, table_list,
|
||||||
&select->where,
|
&select->where,
|
||||||
select->order_list.elements,
|
select->order_list.elements,
|
||||||
@ -982,6 +995,8 @@ static int mysql_test_update(Prepared_statement *stmt,
|
|||||||
}
|
}
|
||||||
stmt->lex->unit.cleanup();
|
stmt->lex->unit.cleanup();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
res= 1;
|
||||||
/* TODO: here we should send types of placeholders to the client. */
|
/* TODO: here we should send types of placeholders to the client. */
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,8 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
|
|
||||||
/* Check that all tables, fields, conds and order are ok */
|
/* 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) ||
|
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
|
||||||
select_lex->setup_ref_array(thd, og_num) ||
|
select_lex->setup_ref_array(thd, og_num) ||
|
||||||
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
|
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
|
||||||
@ -1081,7 +1082,8 @@ JOIN::reinit()
|
|||||||
if (tables_list)
|
if (tables_list)
|
||||||
{
|
{
|
||||||
tables_list->setup_is_done= 0;
|
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);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,13 +142,17 @@ int mysql_update(THD *thd,
|
|||||||
if (open_tables(thd, table_list, &table_count))
|
if (open_tables(thd, table_list, &table_count))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
if (table_list->table == 0)
|
if (table_list->ancestor && table_list->ancestor->next_local)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table_list->view &&
|
DBUG_ASSERT(table_list->view);
|
||||||
table_list->ancestor && table_list->ancestor->next_local);
|
|
||||||
DBUG_PRINT("info", ("Switch to multi-update"));
|
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||||
/* pass counter value */
|
/* pass counter value */
|
||||||
thd->lex->table_count= table_count;
|
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 */
|
/* convert to multiupdate */
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@ -559,7 +563,8 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
|||||||
tables.table= table;
|
tables.table= table;
|
||||||
tables.alias= table_list->alias;
|
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) ||
|
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||||
select_lex->setup_ref_array(thd, order_num) ||
|
select_lex->setup_ref_array(thd, order_num) ||
|
||||||
setup_order(thd, select_lex->ref_pointer_array,
|
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;
|
uint table_count= lex->table_count;
|
||||||
const bool using_lock_tables= thd->locked_tables != 0;
|
const bool using_lock_tables= thd->locked_tables != 0;
|
||||||
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
|
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");
|
DBUG_ENTER("mysql_multi_update_prepare");
|
||||||
|
|
||||||
/* open tables and create derived ones, but do not lock and fill them */
|
/* 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,
|
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);
|
DBUG_RETURN(TRUE);
|
||||||
/*
|
/*
|
||||||
Ensure that we have update privilege for all tables and columns in the
|
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;
|
table_list->setup_is_done= 0;
|
||||||
|
|
||||||
if (setup_tables(thd, table_list, &lex->select_lex.where,
|
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,
|
(lex->select_lex.no_wrap_view_item= 1,
|
||||||
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
|
res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
|
||||||
lex->select_lex.no_wrap_view_item= 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)
|
tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
if ((tbl->view && !tbl->updatable_view) || tbl->schema_table)
|
if ((tbl->view && !tbl->updatable_view) || tbl->schema_table)
|
||||||
|
{
|
||||||
view->updatable_view= 0;
|
view->updatable_view= 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1074,18 +1075,18 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
|
|||||||
view view for processing
|
view view for processing
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 - OK
|
FALSE OK
|
||||||
-1 - error (is not sent to cliet)
|
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;
|
uint elements_in_view= view->view->select_lex.item_list.elements;
|
||||||
Field_translator *trans;
|
Field_translator *trans;
|
||||||
DBUG_ENTER("insert_view_fields");
|
DBUG_ENTER("insert_view_fields");
|
||||||
|
|
||||||
if (!(trans= view->field_translation))
|
if (!(trans= view->field_translation))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
for (uint i= 0; i < elements_in_view; i++)
|
for (uint i= 0; i < elements_in_view; i++)
|
||||||
{
|
{
|
||||||
@ -1095,10 +1096,10 @@ int insert_view_fields(List<Item> *list, TABLE_LIST *view)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "INSERT");
|
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);
|
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);
|
frm_type_enum mysql_frm_type(char *path);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user