Commit f6ffd3a1 authored by unknown's avatar unknown

5.0 -> 5.1 merge


configure.in:
  Auto merged
mysql-test/lib/mtr_timer.pl:
  Auto merged
mysql-test/r/information_schema.result:
  Auto merged
mysql-test/r/information_schema_db.result:
  Auto merged
mysql-test/r/query_cache_notembedded.result:
  Auto merged
mysql-test/t/information_schema.test:
  Auto merged
mysql-test/t/query_cache_notembedded.test:
  Auto merged
scripts/make_binary_distribution.sh:
  Auto merged
sql/sql_acl.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
storage/ndb/src/kernel/blocks/backup/Backup.cpp:
  Auto merged
sql/ha_innodb.cc:
  manual merge
sql/sql_insert.cc:
  manual merge
parents c8caeebf 53862e60
...@@ -294,6 +294,13 @@ sub1 sub1 ...@@ -294,6 +294,13 @@ sub1 sub1
select count(*) from information_schema.ROUTINES; select count(*) from information_schema.ROUTINES;
count(*) count(*)
2 2
create view v1 as select routine_schema, routine_name from information_schema.routines
order by routine_schema, routine_name;
select * from v1;
routine_schema routine_name
test sel2
test sub1
drop view v1;
select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES;
ROUTINE_NAME ROUTINE_DEFINITION ROUTINE_NAME ROUTINE_DEFINITION
show create function sub1; show create function sub1;
......
...@@ -33,4 +33,18 @@ create database `inf%`; ...@@ -33,4 +33,18 @@ create database `inf%`;
use `inf%`; use `inf%`;
show tables; show tables;
Tables_in_inf% Tables_in_inf%
grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost';
create table t1 (f1 int);
create function func1(curr_int int) returns int
begin
declare ret_val int;
select max(f1) from t1 into ret_val;
return ret_val;
end|
create view v1 as select f1 from t1 where f1 = func1(f1);
select * from information_schema.tables;
drop user mysqltest_1@localhost;
drop view v1;
drop function func1;
drop table t1;
drop database `inf%`; drop database `inf%`;
...@@ -314,4 +314,34 @@ drop procedure f2; ...@@ -314,4 +314,34 @@ drop procedure f2;
drop procedure f3; drop procedure f3;
drop procedure f4; drop procedure f4;
drop table t1; drop table t1;
reset query cache;
drop function if exists f1;
create table t1 (id int);
create function f1 ()
returns int
begin
declare i_var int;
set i_var = sleep(3);
insert into t1 values(3);
set i_var = sleep(3);
return 0;
end;|
select f1();
select sleep(4);
sleep(4)
0
select * from t1;
id
3
f1()
0
select * from t1;
id
3
reset query cache;
select * from t1;
id
3
drop table t1;
drop function f1;
set GLOBAL query_cache_size=0; set GLOBAL query_cache_size=0;
...@@ -146,6 +146,11 @@ select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a, ...@@ -146,6 +146,11 @@ select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a,
mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8) order by 1; mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8) order by 1;
select count(*) from information_schema.ROUTINES; select count(*) from information_schema.ROUTINES;
create view v1 as select routine_schema, routine_name from information_schema.routines
order by routine_schema, routine_name;
select * from v1;
drop view v1;
connect (user1,localhost,mysqltest_1,,); connect (user1,localhost,mysqltest_1,,);
connection user1; connection user1;
select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES;
......
...@@ -8,4 +8,35 @@ show tables from INFORMATION_SCHEMA like 'T%'; ...@@ -8,4 +8,35 @@ show tables from INFORMATION_SCHEMA like 'T%';
create database `inf%`; create database `inf%`;
use `inf%`; use `inf%`;
show tables; show tables;
#
# Bug#18113 SELECT * FROM information_schema.xxx crashes server
# Crash happened when one selected data from one of INFORMATION_SCHEMA
# tables and in order to build its contents server had to open view which
# used stored function and table or view on which one had not global or
# database-level privileges (e.g. had only table-level or had no
# privileges at all).
#
grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost';
create table t1 (f1 int);
delimiter |;
create function func1(curr_int int) returns int
begin
declare ret_val int;
select max(f1) from t1 into ret_val;
return ret_val;
end|
delimiter ;|
create view v1 as select f1 from t1 where f1 = func1(f1);
connect (user1,localhost,mysqltest_1,,);
connection user1;
--disable_result_log
select * from information_schema.tables;
--enable_result_log
connection default;
drop user mysqltest_1@localhost;
drop view v1;
drop function func1;
drop table t1;
drop database `inf%`; drop database `inf%`;
...@@ -180,5 +180,45 @@ drop procedure f3; ...@@ -180,5 +180,45 @@ drop procedure f3;
drop procedure f4; drop procedure f4;
drop table t1; drop table t1;
#
# bug#14767: INSERT in SF + concurrent SELECT with query cache
#
reset query cache;
--disable_warnings
drop function if exists f1;
--enable_warnings
create table t1 (id int);
delimiter |;
create function f1 ()
returns int
begin
declare i_var int;
set i_var = sleep(3);
insert into t1 values(3);
set i_var = sleep(3);
return 0;
end;|
delimiter ;|
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connection con1;
send select f1();
connection con2;
select sleep(4);
select * from t1;
connection con1;
reap;
connection con2;
# This gives wrong result i.e. 't' table seems to be empty
select * from t1;
reset query cache;
select * from t1;
drop table t1;
drop function f1;
disconnect con1;
disconnect con2;
connection default;
set GLOBAL query_cache_size=0; set GLOBAL query_cache_size=0;
...@@ -539,6 +539,13 @@ convert_error_code_to_mysql( ...@@ -539,6 +539,13 @@ convert_error_code_to_mysql(
return(HA_ERR_NO_SAVEPOINT); return(HA_ERR_NO_SAVEPOINT);
} else if (error == (int) DB_LOCK_TABLE_FULL) { } else if (error == (int) DB_LOCK_TABLE_FULL) {
/* Since we rolled back the whole transaction, we must
tell it also to MySQL so that MySQL knows to empty the
cached binlog for this transaction */
if (thd) {
ha_rollback(thd);
}
return(HA_ERR_LOCK_TABLE_FULL); return(HA_ERR_LOCK_TABLE_FULL);
} else { } else {
...@@ -6960,8 +6967,8 @@ ha_innobase::store_lock( ...@@ -6960,8 +6967,8 @@ ha_innobase::store_lock(
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
&& lock_type <= TL_WRITE) && lock_type <= TL_WRITE)
&& (!thd->in_lock_tables && !(thd->in_lock_tables
|| thd->lex->sql_command == SQLCOM_CALL) && thd->lex->sql_command == SQLCOM_LOCK_TABLES)
&& !thd->tablespace_op && !thd->tablespace_op
&& thd->lex->sql_command != SQLCOM_TRUNCATE && thd->lex->sql_command != SQLCOM_TRUNCATE
&& thd->lex->sql_command != SQLCOM_OPTIMIZE && thd->lex->sql_command != SQLCOM_OPTIMIZE
......
...@@ -3668,6 +3668,13 @@ my_bool grant_reload(THD *thd) ...@@ -3668,6 +3668,13 @@ my_bool grant_reload(THD *thd)
RETURN RETURN
0 ok 0 ok
1 Error: User did not have the requested privileges 1 Error: User did not have the requested privileges
NOTE
This functions assumes that either number of tables to be inspected
by it is limited explicitly (i.e. is is not UINT_MAX) or table list
used and thd->lex->query_tables_own_last value correspond to each
other (the latter should be either 0 or point to next_global member
of one of elements of this table list).
****************************************************************************/ ****************************************************************************/
bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
......
...@@ -272,6 +272,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -272,6 +272,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
bool log_on= (thd->options & OPTION_BIN_LOG) || bool log_on= (thd->options & OPTION_BIN_LOG) ||
(!(thd->security_ctx->master_access & SUPER_ACL)); (!(thd->security_ctx->master_access & SUPER_ACL));
bool transactional_table, joins_freed= FALSE; bool transactional_table, joins_freed= FALSE;
bool changed;
uint value_count; uint value_count;
ulong counter = 1; ulong counter = 1;
ulonglong id; ulonglong id;
...@@ -558,20 +559,17 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -558,20 +559,17 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
else if (table->next_number_field && info.copied) else if (table->next_number_field && info.copied)
id=table->next_number_field->val_int(); // Return auto_increment value id=table->next_number_field->val_int(); // Return auto_increment value
transactional_table= table->file->has_transactions();
if ((changed= (info.copied || info.deleted || info.updated)))
{
/* /*
Invalidate the table in the query cache if something changed. Invalidate the table in the query cache if something changed.
For the transactional algorithm to work the invalidation must be For the transactional algorithm to work the invalidation must be
before binlog writing and ha_autocommit_or_rollback before binlog writing and ha_autocommit_or_rollback
*/ */
if (info.copied || info.deleted || info.updated)
{
query_cache_invalidate3(thd, table_list, 1); query_cache_invalidate3(thd, table_list, 1);
} if (error <= 0 || !transactional_table)
transactional_table= table->file->has_transactions();
if ((info.copied || info.deleted || info.updated) &&
(error <= 0 || !transactional_table))
{ {
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
{ {
...@@ -588,12 +586,23 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -588,12 +586,23 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (!transactional_table) if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
} }
}
if (transactional_table) if (transactional_table)
error=ha_autocommit_or_rollback(thd,error); error=ha_autocommit_or_rollback(thd,error);
if (thd->lock) if (thd->lock)
{ {
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
/*
Invalidate the table in the query cache if something changed
after unlocking when changes become fisible.
TODO: this is workaround. right way will be move invalidating in
the unlock procedure.
*/
if (lock_type == TL_WRITE_CONCURRENT_INSERT && changed)
{
query_cache_invalidate3(thd, table_list, 1);
}
thd->lock=0; thd->lock=0;
} }
} }
......
...@@ -3351,6 +3351,19 @@ mysql_execute_command(THD *thd) ...@@ -3351,6 +3351,19 @@ mysql_execute_command(THD *thd)
select_lex->context.table_list= select_lex->context.table_list=
select_lex->context.first_name_resolution_table= second_table; select_lex->context.first_name_resolution_table= second_table;
res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE); res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
/*
Invalidate the table in the query cache if something changed
after unlocking when changes become visible.
TODO: this is workaround. right way will be move invalidating in
the unlock procedure.
*/
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
query_cache_invalidate3(thd, first_table, 1);
thd->lock=0;
}
delete result; delete result;
} }
/* revert changes for SP */ /* revert changes for SP */
......
...@@ -476,7 +476,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, ...@@ -476,7 +476,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
table_list.table_name= file->name; table_list.table_name= file->name;
table_list.table_name_length= strlen(file->name); table_list.table_name_length= strlen(file->name);
table_list.grant.privilege=col_access; table_list.grant.privilege=col_access;
if (check_grant(thd, TABLE_ACLS, &table_list, 1, UINT_MAX, 1)) if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1))
continue; continue;
} }
#endif #endif
...@@ -4664,7 +4664,8 @@ bool get_schema_tables_result(JOIN *join) ...@@ -4664,7 +4664,8 @@ bool get_schema_tables_result(JOIN *join)
TABLE_LIST *table_list= tab->table->pos_in_table_list; TABLE_LIST *table_list= tab->table->pos_in_table_list;
if (table_list->schema_table && thd->fill_derived_tables()) if (table_list->schema_table && thd->fill_derived_tables())
{ {
bool is_subselect= (&lex->unit != lex->current_select->master_unit()); bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
lex->current_select->master_unit()->item);
/* /*
The schema table is already processed and The schema table is already processed and
the statement is not a subselect. the statement is not a subselect.
......
...@@ -7821,7 +7821,19 @@ replace: ...@@ -7821,7 +7821,19 @@ replace:
; ;
insert_lock_option: insert_lock_option:
/* empty */ { $$= TL_WRITE_CONCURRENT_INSERT; } /* empty */
{
#ifdef HAVE_QUERY_CACHE
/*
If it is SP we do not allow insert optimisation whan result of
insert visible only after the table unlocking but everyone can
read table.
*/
$$= (Lex->sphead ? TL_WRITE :TL_WRITE_CONCURRENT_INSERT);
#else
$$= TL_WRITE_CONCURRENT_INSERT;
#endif
}
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; } | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
| DELAYED_SYM { $$= TL_WRITE_DELAYED; } | DELAYED_SYM { $$= TL_WRITE_DELAYED; }
| HIGH_PRIORITY { $$= TL_WRITE; } | HIGH_PRIORITY { $$= TL_WRITE; }
...@@ -8740,7 +8752,16 @@ opt_local: ...@@ -8740,7 +8752,16 @@ opt_local:
load_data_lock: load_data_lock:
/* empty */ { $$= YYTHD->update_lock_default; } /* empty */ { $$= YYTHD->update_lock_default; }
| CONCURRENT { $$= TL_WRITE_CONCURRENT_INSERT ; } | CONCURRENT
{
#ifdef HAVE_QUERY_CACHE
/*
Ignore this option in SP to avoid problem with query cache
*/
if (Lex->sphead != 0)
#endif
$$= TL_WRITE_CONCURRENT_INSERT;
}
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }; | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; };
......
...@@ -560,14 +560,20 @@ int vio_close_shared_memory(Vio * vio) ...@@ -560,14 +560,20 @@ int vio_close_shared_memory(Vio * vio)
Close all handlers. UnmapViewOfFile and CloseHandle return non-zero Close all handlers. UnmapViewOfFile and CloseHandle return non-zero
result if they are success. result if they are success.
*/ */
r= UnmapViewOfFile(vio->handle_map) || CloseHandle(vio->event_server_wrote) || if (UnmapViewOfFile(vio->handle_map) == 0)
CloseHandle(vio->event_server_read) || CloseHandle(vio->event_client_wrote) || DBUG_PRINT("vio_error", ("UnmapViewOfFile() failed"));
CloseHandle(vio->event_client_read) || CloseHandle(vio->handle_file_map); if (CloseHandle(vio->event_server_wrote) == 0)
if (!r) DBUG_PRINT("vio_error", ("CloseHandle(vio->esw) failed"));
{ if (CloseHandle(vio->event_server_read) == 0)
DBUG_PRINT("vio_error", ("close() failed, error: %d",r)); DBUG_PRINT("vio_error", ("CloseHandle(vio->esr) failed"));
/* FIXME: error handling (not critical for MySQL) */ if (CloseHandle(vio->event_client_wrote) == 0)
} DBUG_PRINT("vio_error", ("CloseHandle(vio->ecw) failed"));
if (CloseHandle(vio->event_client_read) == 0)
DBUG_PRINT("vio_error", ("CloseHandle(vio->ecr) failed"));
if (CloseHandle(vio->handle_file_map) == 0)
DBUG_PRINT("vio_error", ("CloseHandle(vio->hfm) failed"));
if (CloseHandle(vio->event_conn_closed) == 0)
DBUG_PRINT("vio_error", ("CloseHandle(vio->ecc) failed"));
} }
vio->type= VIO_CLOSED; vio->type= VIO_CLOSED;
vio->sd= -1; vio->sd= -1;
......
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