Commit 9802b134 authored by unknown's avatar unknown

new error for unsupported command in PS

fixed IN subselect with basic constant left expression
SQLCOM_CREATE_TABLE, SQLCOM_UPDATE_MULTI, SQLCOM_REPLACE_SELECT, SQLCOM_INSERT_SELECT, QLCOM_DELETE_MULTI fixed to be compatible with PS (BUG#3398, BUG#3406)
fixed multiupdate privelege check (BUG#3408)
fixed multiupdate tables check (BUG#3411)
unchecked commands now is rejected by PS protocol to avoid serever crash
fixed cleunup procedure to be compatible sith DO/SET (BUG#3393)


include/mysqld_error.h:
  new error for unsupported command in PS
mysql-test/r/multi_update.result:
  test sutes (BUG#3408, BUG#3411)
mysql-test/t/multi_update.test:
  test sutes (BUG#3408, BUG#3411)
sql/item_cmpfunc.cc:
  fixed IN subselect with basic constant left expression
sql/mysql_priv.h:
  some function frop sql_parse.h become public
sql/set_var.cc:
  check for SET command via PS
sql/set_var.h:
  check for SET command via PS
sql/share/czech/errmsg.txt:
  new error for unsupported command in PS
sql/share/danish/errmsg.txt:
  new error for unsupported command in PS
sql/share/dutch/errmsg.txt:
  new error for unsupported command in PS
sql/share/english/errmsg.txt:
  new error for unsupported command in PS
sql/share/estonian/errmsg.txt:
  new error for unsupported command in PS
sql/share/french/errmsg.txt:
  new error for unsupported command in PS
sql/share/german/errmsg.txt:
  new error for unsupported command in PS
sql/share/greek/errmsg.txt:
  new error for unsupported command in PS
sql/share/hungarian/errmsg.txt:
  new error for unsupported command in PS
sql/share/italian/errmsg.txt:
  new error for unsupported command in PS
sql/share/japanese/errmsg.txt:
  new error for unsupported command in PS
sql/share/korean/errmsg.txt:
  new error for unsupported command in PS
sql/share/norwegian-ny/errmsg.txt:
  new error for unsupported command in PS
sql/share/norwegian/errmsg.txt:
  new error for unsupported command in PS
sql/share/polish/errmsg.txt:
  new error for unsupported command in PS
sql/share/portuguese/errmsg.txt:
  new error for unsupported command in PS
sql/share/romanian/errmsg.txt:
  new error for unsupported command in PS
sql/share/russian/errmsg.txt:
  new error for unsupported command in PS
sql/share/serbian/errmsg.txt:
  new error for unsupported command in PS
sql/share/slovak/errmsg.txt:
  new error for unsupported command in PS
sql/share/spanish/errmsg.txt:
  new error for unsupported command in PS
sql/share/swedish/errmsg.txt:
  new error for unsupported command in PS
sql/share/ukrainian/errmsg.txt:
  new error for unsupported command in PS
sql/sql_lex.cc:
  first table unlincking procedures for CREATE command
sql/sql_lex.h:
  first table unlincking procedures for CREATE command
sql/sql_parse.cc:
  used function to exclude first table from list
  SQLCOM_CREATE_TABLE, SQLCOM_UPDATE_MULTI, SQLCOM_REPLACE_SELECT, SQLCOM_INSERT_SELECT, QLCOM_DELETE_MULTI fixed to be compatible with PS (BUG#3398, BUG#3406)
  fixed multiupdate privelege check (BUG#3408)
  fixed multiupdate tables check (BUG#3411)
sql/sql_prepare.cc:
  fixed a lot of commands to be compatible with PS
  unchecked commands now is rejected to avoid serever crash
sql/sql_select.cc:
  allow empty result for PS preparing
sql/sql_union.cc:
  fixed cleunup procedure to be compatible sith DO/SET (BUG#3393)
sql/sql_update.cc:
  fixed update to use correct tables lists (BUG#3408)
sql/table.h:
  flag to support multi update tables check (BUG#3408)
tests/client_test.c:
  removed unsupported tables
  fixed show table test
  added new tests
parent a3965451
......@@ -311,4 +311,5 @@
#define ER_TRUNCATED_WRONG_VALUE 1292
#define ER_TOO_MUCH_AUTO_TIMESTAMP_COLS 1293
#define ER_INVALID_ON_UPDATE 1294
#define ER_ERROR_MESSAGES 295
#define ER_UNSUPPORTED_PS 1295
#define ER_ERROR_MESSAGES 296
drop table if exists t1,t2,t3;
drop database if exists mysqltest;
create table t1(id1 int not null auto_increment primary key, t char(12));
create table t2(id2 int not null, t char(12));
create table t3(id3 int not null, t char(12), index(id3));
......@@ -402,7 +403,7 @@ DELETE t1 FROM t1, t2 AS t3;
DELETE t4 FROM t1, t1 AS t4;
DELETE t3 FROM t1 AS t3, t1 AS t4;
DELETE t1 FROM t1 AS t3, t2 AS t4;
ERROR 42000: Not unique table/alias: 't1'
ERROR 42S02: Unknown table 't1' in MULTI DELETE
INSERT INTO t1 values (1),(2);
INSERT INTO t2 values (1),(2);
DELETE t1 FROM t1 AS t2, t2 AS t1 where t1.a=t2.a and t1.a=1;
......@@ -435,3 +436,20 @@ select * from t2;
c2_id c2_p_id c2_note c2_active
1 1 A Note 1
drop table t1, t2;
create database mysqltest;
create table mysqltest.t1 (a int, b int, primary key (a));
create table mysqltest.t2 (a int, b int, primary key (a));
create table mysqltest.t3 (a int, b int, primary key (a));
grant select on mysqltest.* to mysqltest_1@localhost;
grant update on mysqltest.t1 to mysqltest_1@localhost;
update t1, t2 set t1.b=1 where t1.a=t2.a;
update t1, t2 set t1.b=(select t3.b from t3 where t1.a=t3.a) where t1.a=t2.a;
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
drop database mysqltest;
create table t1 (a int, primary key (a));
create table t2 (a int, primary key (a));
create table t3 (a int, primary key (a));
delete t1,t3 from t1,t2 where t1.a=t2.a and t2.a=(select t3.a from t3 where t1.a=t3.a);
ERROR 42S02: Unknown table 't3' in MULTI DELETE
drop table t1, t2, t3;
......@@ -4,6 +4,7 @@
--disable_warnings
drop table if exists t1,t2,t3;
drop database if exists mysqltest;
--enable_warnings
create table t1(id1 int not null auto_increment primary key, t char(12));
......@@ -354,7 +355,7 @@ CREATE TABLE t2 ( a int );
DELETE t1 FROM t1, t2 AS t3;
DELETE t4 FROM t1, t1 AS t4;
DELETE t3 FROM t1 AS t3, t1 AS t4;
--error 1066
--error 1109
DELETE t1 FROM t1 AS t3, t2 AS t4;
INSERT INTO t1 values (1),(2);
INSERT INTO t2 values (1),(2);
......@@ -369,7 +370,6 @@ DROP TABLE t1,t2;
#
# Test update with const tables
#
create table `t1` (`p_id` int(10) unsigned NOT NULL auto_increment, `p_code` varchar(20) NOT NULL default '', `p_active` tinyint(1) unsigned NOT NULL default '1', PRIMARY KEY (`p_id`) );
create table `t2` (`c2_id` int(10) unsigned NULL auto_increment, `c2_p_id` int(10) unsigned NOT NULL default '0', `c2_note` text NOT NULL, `c2_active` tinyint(1) unsigned NOT NULL default '1', PRIMARY KEY (`c2_id`), KEY `c2_p_id` (`c2_p_id`) );
insert into t1 values (0,'A01-Comp',1);
......@@ -379,3 +379,36 @@ update t1 left join t2 on p_id = c2_p_id set c2_note = 'asdf-1' where p_id = 2;
select * from t1;
select * from t2;
drop table t1, t2;
#
# prevelege chexk for multiupdate with other tables
#
connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock);
connection root;
--disable_warnings
create database mysqltest;
--enable_warnings
create table mysqltest.t1 (a int, b int, primary key (a));
create table mysqltest.t2 (a int, b int, primary key (a));
create table mysqltest.t3 (a int, b int, primary key (a));
grant select on mysqltest.* to mysqltest_1@localhost;
grant update on mysqltest.t1 to mysqltest_1@localhost;
connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,master.sock);
connection user1;
update t1, t2 set t1.b=1 where t1.a=t2.a;
update t1, t2 set t1.b=(select t3.b from t3 where t1.a=t3.a) where t1.a=t2.a;
connection root;
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
drop database mysqltest;
#
# multi delete wrong table check
#
create table t1 (a int, primary key (a));
create table t2 (a int, primary key (a));
create table t3 (a int, primary key (a));
-- error 1109
delete t1,t3 from t1,t2 where t1.a=t2.a and t2.a=(select t3.a from t3 where t1.a=t3.a);
drop table t1, t2, t3;
......@@ -477,9 +477,11 @@ bool Item_in_optimizer::fix_left(THD *thd,
struct st_table_list *tables,
Item **ref)
{
if (args[0]->fix_fields(thd, tables, ref) ||
(!cache && !(cache= Item_cache::get_cache(args[0]->result_type()))))
if ((!args[0]->fixed && args[0]->fix_fields(thd, tables, args)))
return 1;
if (!cache && !(cache= Item_cache::get_cache(args[0]->result_type())))
return 1;
cache->setup(args[0]);
cache->store(args[0]);
if (cache->cols() == 1)
......@@ -512,12 +514,12 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
Item ** ref)
{
DBUG_ASSERT(fixed == 0);
if (!args[0]->fixed && fix_left(thd, tables, ref))
if (fix_left(thd, tables, ref))
return 1;
if (args[0]->maybe_null)
maybe_null=1;
if (!args[1]->fixed && args[1]->fix_fields(thd, tables, args))
if (!args[1]->fixed && args[1]->fix_fields(thd, tables, args+1))
return 1;
Item_in_subselect * sub= (Item_in_subselect *)args[1];
if (args[0]->cols() != sub->engine->cols())
......
......@@ -347,6 +347,13 @@ void free_items(Item *item);
void cleanup_items(Item *item);
class THD;
void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
int check_one_table_access(THD *thd, ulong privilege,
TABLE_LIST *tables, bool no_errors);
bool check_merge_table_access(THD *thd, char *db,
TABLE_LIST *table_list);
int multi_update_precheck(THD *thd, TABLE_LIST *tables);
int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count);
int insert_select_precheck(THD *thd, TABLE_LIST *tables);
#include "sql_class.h"
#include "opt_range.h"
......
......@@ -2528,6 +2528,24 @@ int set_var::check(THD *thd)
}
int set_var::light_check(THD *thd)
{
if (var->check_type(type))
{
my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE,
MYF(0),
var->name);
return -1;
}
if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
return 1;
if (value && (value->fix_fields(thd, 0, &value) || value->check_cols(1)))
return -1;
return 0;
}
int set_var::update(THD *thd)
{
if (!value)
......@@ -2555,6 +2573,16 @@ int set_var_user::check(THD *thd)
}
int set_var_user::light_check(THD *thd)
{
/*
Item_func_set_user_var can't substitute something else on its place =>
0 can be passed as last argument (reference on item)
*/
return (user_var_item->fix_fields(thd, 0, (Item**) 0));
}
int set_var_user::update(THD *thd)
{
if (user_var_item->update())
......
......@@ -688,6 +688,8 @@ class set_var_base :public Sql_alloc
virtual ~set_var_base() {}
virtual int check(THD *thd)=0; /* To check privileges etc. */
virtual int update(THD *thd)=0; /* To set the value */
/* light check for PS */
virtual int light_check(THD *thd) { return check(thd); }
};
......@@ -728,6 +730,7 @@ class set_var :public set_var_base
}
int check(THD *thd);
int update(THD *thd);
int light_check(THD *thd);
};
......@@ -742,6 +745,7 @@ class set_var_user: public set_var_base
{}
int check(THD *thd);
int update(THD *thd);
int light_check(THD *thd);
};
/* For SET PASSWORD */
......
......@@ -307,3 +307,4 @@ character-set=latin2
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -301,3 +301,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -309,3 +309,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -298,3 +298,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -303,3 +303,4 @@ character-set=latin7
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -298,3 +298,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -310,3 +310,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -298,3 +298,4 @@ character-set=greek
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -300,3 +300,4 @@ character-set=latin2
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -298,3 +298,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -300,3 +300,4 @@ character-set=ujis
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -298,3 +298,4 @@ character-set=euckr
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -300,3 +300,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -300,3 +300,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -302,3 +302,4 @@ character-set=latin2
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -299,3 +299,4 @@ character-set=latin1
"Truncado errado %-.32s valor: '%-.128s'"
"Incorreta definição de tabela; Pode ter somente uma coluna TIMESTAMP com CURRENT_TIMESTAMP em DEFAULT ou ON UPDATE cláusula"
"Inválida cláusula ON UPDATE para campo '%-.64s'",
"This command is not supported in the prepared statement protocol yet",
......@@ -302,3 +302,4 @@ character-set=latin2
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -300,3 +300,4 @@ character-set=koi8r
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -292,3 +292,4 @@ character-set=cp1250
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -306,3 +306,4 @@ character-set=latin2
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -300,3 +300,4 @@ character-set=latin1
"Equivocado truncado %-.32s valor: '%-.128s'"
"Incorrecta definición de tabla; Solamente debe haber una columna TIMESTAMP con CURRENT_TIMESTAMP en DEFAULT o ON UPDATE cláusula"
"Inválido ON UPDATE cláusula para campo '%-.64s'",
"This command is not supported in the prepared statement protocol yet",
......@@ -298,3 +298,4 @@ character-set=latin1
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -303,3 +303,4 @@ character-set=koi8u
"Truncated wrong %-.32s value: '%-.128s'"
"Incorrect table definition; There can only be one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause"
"Invalid ON UPDATE clause for '%-.64s' field",
"This command is not supported in the prepared statement protocol yet",
......@@ -1634,6 +1634,66 @@ void st_select_lex::print_limit(THD *thd, String *str)
}
}
/*
unlink first table from table lists
SYNOPSIS
unlink_first_table()
tables - global table list
global_first - save first global table passed using this parameter
local_first - save first local table passed using this parameter
RETURN
global list without first table
*/
TABLE_LIST *st_lex::unlink_first_table(TABLE_LIST *tables,
TABLE_LIST **global_first,
TABLE_LIST **local_first)
{
*global_first= tables;
*local_first= (TABLE_LIST*)select_lex.table_list.first;
// exclude from global table list
tables= tables->next;
// and from local list if it is not the same
if (&select_lex != all_selects_list)
select_lex.table_list.first= (gptr)(*local_first)->next;
else
select_lex.table_list.first= (gptr)tables;
(*global_first)->next= 0;
return tables;
}
/*
link unlinked first table back
SYNOPSIS
link_first_table_back()
tables - global table list
global_first - save first global table
local_first - save first local table
RETURN
global list
*/
TABLE_LIST *st_lex::link_first_table_back(TABLE_LIST *tables,
TABLE_LIST *global_first,
TABLE_LIST *local_first)
{
global_first->next= tables;
tables= global_first;
if (&select_lex != all_selects_list)
{
/*
we do not touch local table 'next' field => we need just
put the table in the list
*/
select_lex.table_list.first= (gptr) local_first;
}
else
select_lex.table_list.first= (gptr) tables;
return tables;
}
/*
There are st_select_lex::add_table_to_list &
st_select_lex::set_lock_for_tables are in sql_parse.cc
......
......@@ -603,6 +603,12 @@ typedef struct st_lex
un->uncacheable|= cause;
}
}
TABLE_LIST *unlink_first_table(TABLE_LIST *tables,
TABLE_LIST **global_first,
TABLE_LIST **local_first);
TABLE_LIST *link_first_table_back(TABLE_LIST *tables,
TABLE_LIST *global_first,
TABLE_LIST *local_first);
} LEX;
......
This diff is collapsed.
This diff is collapsed.
......@@ -434,7 +434,7 @@ JOIN::prepare(Item ***rref_pointer_array,
goto err;
}
#endif
if (!procedure && result->prepare(fields_list, unit_arg))
if (!procedure && result && result->prepare(fields_list, unit_arg))
goto err; /* purecov: inspected */
if (select_lex->olap == ROLLUP_TYPE && rollup_init())
......
......@@ -460,13 +460,24 @@ int st_select_lex_unit::cleanup()
table= 0; // Safety
}
JOIN *join;
for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select())
SELECT_LEX *sl= first_select_in_union();
for (; sl; sl= sl->next_select())
{
if ((join= sl->join))
{
error|= sl->join->cleanup();
delete join;
}
else
{
// it can be DO/SET with subqueries
for (SELECT_LEX_UNIT *lex_unit= sl->first_inner_unit();
lex_unit != 0;
lex_unit= lex_unit->next_unit())
{
error|= lex_unit->cleanup();
}
}
}
if (fake_select_lex && (join= fake_select_lex->join))
{
......
......@@ -99,7 +99,7 @@ int mysql_update(THD *thd,
setup_conds(thd,update_table_list,&conds) ||
thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
&tables, all_fields, all_fields, order) ||
update_table_list, all_fields, all_fields, order) ||
setup_ftfuncs(&thd->lex->select_lex))
DBUG_RETURN(-1); /* purecov: inspected */
......@@ -427,6 +427,9 @@ int mysql_multi_update(THD *thd,
int res;
multi_update *result;
TABLE_LIST *tl;
TABLE_LIST *update_list=
(TABLE_LIST*)thd->lex->select_lex.table_list.first;
table_map item_tables= 0, derived_tables= 0;
DBUG_ENTER("mysql_multi_update");
......@@ -439,7 +442,7 @@ int mysql_multi_update(THD *thd,
Ensure that we have update privilege for all tables and columns in the
SET part
*/
for (tl= table_list ; tl ; tl=tl->next)
for (tl= update_list; tl; tl= tl->next)
{
TABLE *table= tl->table;
/*
......@@ -456,14 +459,14 @@ int mysql_multi_update(THD *thd,
{
// Assign table map values to check updatability of derived tables
uint tablenr=0;
for (TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
for (TABLE_LIST *table_list= update_list;
table_list;
table_list= table_list->next, tablenr++)
{
table_list->table->map= (table_map) 1 << tablenr;
}
}
if (setup_fields(thd, 0, table_list, *fields, 1, 0, 0))
if (setup_fields(thd, 0, update_list, *fields, 1, 0, 0))
DBUG_RETURN(-1);
if (thd->lex->derived_tables)
{
......@@ -479,7 +482,7 @@ int mysql_multi_update(THD *thd,
/*
Count tables and setup timestamp handling
*/
for (tl= select_lex->get_table_list() ; tl ; tl= tl->next)
for (tl= update_list; tl; tl= tl->next)
{
TABLE *table= tl->table;
......@@ -496,7 +499,7 @@ int mysql_multi_update(THD *thd,
if (thd->lex->derived_tables && (item_tables & derived_tables))
{
// find derived table which cause error
for (tl= select_lex->get_table_list() ; tl ; tl= tl->next)
for (tl= update_list; tl; tl= tl->next)
{
if (tl->derived && (item_tables & tl->table->map))
{
......
......@@ -193,6 +193,7 @@ typedef struct st_table_list
bool updating; /* for replicate-do/ignore table */
bool force_index; /* Prefer index over table scan */
bool ignore_leaves; /* Preload only non-leaf nodes */
bool checked; /* used in multi-upd privelege check */
bool non_cachable_table; /* stop PS caching */
} TABLE_LIST;
......
......@@ -925,14 +925,6 @@ static void test_prepare_simple()
rc = mysql_query(mysql,"CREATE TABLE test_prepare_simple(id int, name varchar(50))");
myquery(rc);
/* alter table */
strmov(query,"ALTER TABLE test_prepare_simple ADD new char(20)");
stmt = mysql_simple_prepare(mysql, query);
mystmt_init(stmt);
verify_param_count(stmt,0);
mysql_stmt_close(stmt);
/* insert */
strmov(query,"INSERT INTO test_prepare_simple VALUES(?,?)");
stmt = mysql_simple_prepare(mysql, query);
......@@ -1541,22 +1533,25 @@ static void test_select_version()
}
/********************************************************
* to test simple select *
* to test simple show *
*********************************************************/
static void test_select_simple()
static void test_select_show_table()
{
MYSQL_STMT *stmt;
int rc;
int rc, i;
myheader("test_select_simple");
myheader("test_select_show_table");
stmt = mysql_simple_prepare(mysql, "SHOW TABLES FROM mysql");
mystmt_init(stmt);
verify_param_count(stmt,0);
rc = mysql_execute(stmt);
mystmt(stmt, rc);
for (i= 1; i < 3; i++)
{
rc = mysql_execute(stmt);
mystmt(stmt, rc);
}
my_process_stmt_result(stmt);
mysql_stmt_close(stmt);
......@@ -4048,7 +4043,7 @@ static void test_stmt_close()
rc = mysql_query(lmysql,"CREATE TABLE test_stmt_close(id int)");
myquery(rc);
strmov(query,"ALTER TABLE test_stmt_close ADD name varchar(20)");
strmov(query,"DO \"nothing\"");
stmt1= mysql_simple_prepare(lmysql, query);
mystmt_init(stmt1);
......@@ -6452,14 +6447,10 @@ static void test_prepare_grant()
myquery_r(rc);
stmt= mysql_simple_prepare(mysql,"DELETE FROM test_grant");
mystmt_init(stmt);
rc = mysql_execute(stmt);
myquery_r(rc);
mystmt_init_r(stmt);
assert(4 == my_stmt_result("SELECT * FROM test_grant"));
mysql_stmt_close(stmt);
mysql_close(lmysql);
mysql= org_mysql;
......@@ -8214,6 +8205,7 @@ static void test_subqueries()
MYSQL_STMT *stmt;
int rc, i;
const char *query= "SELECT (SELECT SUM(a+b) FROM t2 where t1.b=t2.b GROUP BY t1.a LIMIT 1) as scalar_s, exists (select 1 from t2 where t2.a/2=t1.a) as exists_s, a in (select a+3 from t2) as in_s, (a-1,b-1) in (select a,b from t2) as in_row_s FROM t1, (select a x, b y from t2) tt WHERE x=a";
/* const char *query= "SELECT (SELECT SUM(a+b) FROM t2 where t1.b=t2.b GROUP BY t1.a LIMIT 1) as scalar_s, exists (select 1 from t2 where t2.a/2=t1.a) as exists_s, a in (select a+3 from t2) as in_s FROM t1, (select a x, b y from t2) tt WHERE x=a"; */
myheader("test_subquery");
......@@ -8594,13 +8586,22 @@ static void test_selecttmp()
static void test_create_drop()
{
MYSQL_STMT *stmt_create, *stmt_drop;
MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select;
char *query;
int rc, i;
myheader("test_table_manipulation");
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2");
myquery(rc);
rc= mysql_query(mysql,"create table t2 (a int);");
myquery(rc);
rc= mysql_query(mysql,"create table t1 (a int);");
myquery(rc);
rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);");
myquery(rc);
query= (char*)"create table t1 (a int)";
stmt_create= mysql_prepare(mysql, query, strlen(query));
......@@ -8610,18 +8611,51 @@ static void test_create_drop()
stmt_drop= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_drop);
query= (char*)"select a in (select a from t2) from t1";
stmt_select= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_select);
rc= mysql_query(mysql, "DROP TABLE t1");
myquery(rc);
query= (char*)"create table t1 select a from t2";
stmt_create_select= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_create_select);
for (i= 0; i < 3; i++)
{
rc= mysql_execute(stmt_create);
mystmt(stmt_create, rc);
fprintf(stdout, "created %i\n", i);
rc= mysql_execute(stmt_select);
mystmt(stmt_select, rc);
assert(0 == my_process_stmt_result(stmt_select));
rc= mysql_execute(stmt_drop);
mystmt(stmt_drop, rc);
fprintf(stdout, "droped %i\n", i);
fprintf(stdout, "droped %i\n", i);
rc= mysql_execute(stmt_create_select);
mystmt(stmt_create, rc);
fprintf(stdout, "created select %i\n", i);
rc= mysql_execute(stmt_select);
mystmt(stmt_select, rc);
assert(3 == my_process_stmt_result(stmt_select));
rc= mysql_execute(stmt_drop);
mystmt(stmt_drop, rc);
fprintf(stdout, "droped %i\n", i);
}
mysql_stmt_close(stmt_create);
mysql_stmt_close(stmt_drop);
mysql_stmt_close(stmt_select);
mysql_stmt_close(stmt_create_select);
rc= mysql_query(mysql, "DROP TABLE t2");
myquery(rc);
}
......@@ -8669,6 +8703,166 @@ static void test_rename()
myquery(rc);
}
static void test_do_set()
{
MYSQL_STMT *stmt_do, *stmt_set;
char *query;
int rc, i;
myheader("test_do_set");
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1");
myquery(rc);
rc= mysql_query(mysql,"create table t1 (a int)");
myquery(rc);
query= (char*)"do @var:=(1 in (select * from t1))";
stmt_do= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_do);
query= (char*)"set @var=(1 in (select * from t1))";
stmt_set= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_set);
for (i= 0; i < 3; i++)
{
rc= mysql_execute(stmt_do);
mystmt(stmt_do, rc);
fprintf(stdout, "do %i\n", i);
rc= mysql_execute(stmt_set);
mystmt(stmt_set, rc);
fprintf(stdout, "set %i\n", i);
}
mysql_stmt_close(stmt_do);
mysql_stmt_close(stmt_set);
}
static void test_multi()
{
MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2;
char *query;
MYSQL_BIND bind[1];
int rc, i;
long param= 1, length= 1;
myheader("test_multi");
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&param;
bind[0].buffer_length= 0;
bind[0].is_null= 0;
bind[0].length= &length;
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
myquery(rc);
rc= mysql_query(mysql,"create table t1 (a int, b int)");
myquery(rc);
rc= mysql_query(mysql,"create table t2 (a int, b int)");
myquery(rc);
rc= mysql_query(mysql,"insert into t1 values (3,3), (2,2), (1,1)");
myquery(rc);
rc= mysql_query(mysql,"insert into t2 values (3,3), (2,2), (1,1)");
myquery(rc);
query= (char*)"delete t1,t2 from t1,t2 where t1.a=t2.a and t1.b=10";
stmt_delete= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_delete);
query= (char*)"update t1,t2 set t1.b=10,t2.b=10 where t1.a=t2.a and t1.b=?";
stmt_update= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_update);
query= (char*)"select * from t1";
stmt_select1= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_select1);
query= (char*)"select * from t2";
stmt_select2= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_select2);
for(i= 0; i < 3; i++)
{
rc= mysql_bind_param(stmt_update, bind);
mystmt(stmt_update,rc);
rc= mysql_execute(stmt_update);
mystmt(stmt_update, rc);
fprintf(stdout, "update %ld\n", param);
rc= mysql_execute(stmt_delete);
mystmt(stmt_delete, rc);
fprintf(stdout, "delete %ld\n", param);
rc= mysql_execute(stmt_select1);
mystmt(stmt_select1, rc);
assert((uint)(3-param) == my_process_stmt_result(stmt_select1));
rc= mysql_execute(stmt_select2);
mystmt(stmt_select2, rc);
assert((uint)(3-param) == my_process_stmt_result(stmt_select2));
param++;
}
mysql_stmt_close(stmt_delete);
mysql_stmt_close(stmt_update);
mysql_stmt_close(stmt_select1);
mysql_stmt_close(stmt_select2);
rc= mysql_query(mysql,"drop table t1,t2");
myquery(rc);
}
static void test_insert_select()
{
MYSQL_STMT *stmt_insert, *stmt_select;
char *query;
int rc, i;
myheader("test_insert_select");
rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
myquery(rc);
rc= mysql_query(mysql,"create table t1 (a int)");
myquery(rc);
rc= mysql_query(mysql,"create table t2 (a int)");
myquery(rc);
rc= mysql_query(mysql,"insert into t2 values (1)");
myquery(rc);
query= (char*)"insert into t1 select a from t2";
stmt_insert= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_insert);
query= (char*)"select * from t1";
stmt_select= mysql_prepare(mysql, query, strlen(query));
mystmt_init(stmt_select);
for(i= 0; i < 3; i++)
{
rc= mysql_execute(stmt_insert);
mystmt(stmt_insert, rc);
fprintf(stdout, "insert %u\n", i);
rc= mysql_execute(stmt_select);
mystmt(stmt_select, rc);
assert((i+1) == my_process_stmt_result(stmt_select));
}
mysql_stmt_close(stmt_insert);
mysql_stmt_close(stmt_select);
rc= mysql_query(mysql,"drop table t1,t2");
myquery(rc);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
......@@ -8831,7 +9025,7 @@ int main(int argc, char **argv)
test_select_prepare(); /* prepare select - protocol_prep debug */
test_select(); /* simple select test */
test_select_version(); /* select with variables */
test_select_simple(); /* simple select prepare */
test_select_show_table();/* simple show prepare */
#if NOT_USED
/*
Enable this tests from 4.1.1 when mysql_param_result() is
......@@ -8932,6 +9126,9 @@ int main(int argc, char **argv)
test_selecttmp(); /* temporary table used in select execution */
test_create_drop(); /* some table manipulation BUG#2811 */
test_rename(); /* rename test */
test_do_set(); /* DO & SET commands test BUG#3393 */
test_multi(); /* test of multi delete & update */
test_insert_select(); /* test INSERT ... SELECT */
end_time= time((time_t *)0);
total_time+= difftime(end_time, start_time);
......
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