Commit db3a21e7 authored by msvensson@neptunus.(none)'s avatar msvensson@neptunus.(none)

Merge bk-internal:/home/bk/mysql-5.0-maint

into  neptunus.(none):/home/msvensson/mysql/mysql-5.0-maint
parents e36384fd a13e3ebe
...@@ -1264,13 +1264,30 @@ int mi_enable_indexes(MI_INFO *info) ...@@ -1264,13 +1264,30 @@ int mi_enable_indexes(MI_INFO *info)
RETURN RETURN
0 indexes are not disabled 0 indexes are not disabled
1 all indexes are disabled 1 all indexes are disabled
[2 non-unique indexes are disabled - NOT YET IMPLEMENTED] 2 non-unique indexes are disabled
*/ */
int mi_indexes_are_disabled(MI_INFO *info) int mi_indexes_are_disabled(MI_INFO *info)
{ {
MYISAM_SHARE *share= info->s; MYISAM_SHARE *share= info->s;
return (! mi_is_any_key_active(share->state.key_map) && share->base.keys); /*
No keys or all are enabled. keys is the number of keys. Left shifted
gives us only one bit set. When decreased by one, gives us all all bits
up to this one set and it gets unset.
*/
if (!share->base.keys ||
(mi_is_all_keys_active(share->state.key_map, share->base.keys)))
return 0;
/* All are disabled */
if (mi_is_any_key_active(share->state.key_map))
return 1;
/*
We have keys. Some enabled, some disabled.
Don't check for any non-unique disabled but return directly 2
*/
return 2;
} }
...@@ -2923,6 +2923,8 @@ static void flush_bits(void) ...@@ -2923,6 +2923,8 @@ static void flush_bits(void)
bits-= 8; bits-= 8;
*file_buffer.pos++= (uchar) (bit_buffer >> bits); *file_buffer.pos++= (uchar) (bit_buffer >> bits);
} }
if (file_buffer.pos >= file_buffer.end)
VOID(flush_buffer(~ (ulong) 0));
file_buffer.bits= BITS_SAVED; file_buffer.bits= BITS_SAVED;
file_buffer.bitbucket= 0; file_buffer.bitbucket= 0;
} }
......
...@@ -541,6 +541,127 @@ create table t1 ( a timestamp ); ...@@ -541,6 +541,127 @@ create table t1 ( a timestamp );
alter table t1 add unique ( a(1) ); alter table t1 add unique ( a(1) );
ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys
drop table t1; drop table t1;
drop table if exists t1;
create table t1 (a int, key(a));
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE
"this used not to disable the index"
alter table t1 modify a int, disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
alter table t1 enable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE
alter table t1 modify a bigint, disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
alter table t1 enable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE
alter table t1 add b char(10), disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
alter table t1 add c decimal(10,2), enable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE
"this however did"
alter table t1 disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
desc t1;
Field Type Null Key Default Extra
a bigint(20) YES MUL NULL
b char(10) YES NULL
c decimal(10,2) YES NULL
alter table t1 add d decimal(15,5);
"The key should still be disabled"
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
drop table t1;
"Now will test with one unique index"
create table t1(a int, b char(10), unique(a));
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
alter table t1 disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
alter table t1 enable keys;
"If no copy on noop change, this won't touch the data file"
"Unique index, no change"
alter table t1 modify a int, disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
"Change the type implying data copy"
"Unique index, no change"
alter table t1 modify a bigint, disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
alter table t1 modify a bigint;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
alter table t1 modify a int;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
drop table t1;
"Now will test with one unique and one non-unique index"
create table t1(a int, b char(10), unique(a), key(b));
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 1 b 1 b A NULL NULL NULL YES BTREE
alter table t1 disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 1 b 1 b A NULL NULL NULL YES BTREE disabled
alter table t1 enable keys;
"If no copy on noop change, this won't touch the data file"
"The non-unique index will be disabled"
alter table t1 modify a int, disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 1 b 1 b A NULL NULL NULL YES BTREE disabled
alter table t1 enable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 1 b 1 b A NULL NULL NULL YES BTREE
"Change the type implying data copy"
"The non-unique index will be disabled"
alter table t1 modify a bigint, disable keys;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 1 b 1 b A NULL NULL NULL YES BTREE disabled
"Change again the type, but leave the indexes as_is"
alter table t1 modify a int;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 1 b 1 b A NULL NULL NULL YES BTREE disabled
"Try the same. When data is no copied on similar tables, this is noop"
alter table t1 modify a int;
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 a 1 a A NULL NULL NULL YES BTREE
t1 1 b 1 b A NULL NULL NULL YES BTREE disabled
drop table t1;
create database mysqltest; create database mysqltest;
create table t1 (c1 int); create table t1 (c1 int);
alter table t1 rename mysqltest.t1; alter table t1 rename mysqltest.t1;
......
...@@ -1027,7 +1027,7 @@ CREATE PROCEDURE p1 () ...@@ -1027,7 +1027,7 @@ CREATE PROCEDURE p1 ()
BEGIN BEGIN
SELECT 'foo' FROM DUAL; SELECT 'foo' FROM DUAL;
END | END |
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' ERROR 42000: Unknown database 'information_schema'
select ROUTINE_NAME from routines; select ROUTINE_NAME from routines;
ROUTINE_NAME ROUTINE_NAME
grant all on information_schema.* to 'user1'@'localhost'; grant all on information_schema.* to 'user1'@'localhost';
......
...@@ -467,6 +467,7 @@ DROP FUNCTION f1; ...@@ -467,6 +467,7 @@ DROP FUNCTION f1;
drop table t1; drop table t1;
set global log_bin_trust_function_creators=0; set global log_bin_trust_function_creators=0;
set global log_bin_trust_function_creators=0; set global log_bin_trust_function_creators=0;
reset master;
drop database if exists mysqltest; drop database if exists mysqltest;
drop database if exists mysqltest2; drop database if exists mysqltest2;
create database mysqltest; create database mysqltest;
...@@ -475,19 +476,15 @@ use mysqltest2; ...@@ -475,19 +476,15 @@ use mysqltest2;
create table t ( t integer ); create table t ( t integer );
create procedure mysqltest.test() begin end; create procedure mysqltest.test() begin end;
insert into t values ( 1 ); insert into t values ( 1 );
show binlog events in 'master-bin.000001' from 8186; show binlog events in 'master-bin.000001' from 98;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 8186 Query 1 8317 use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION f1() RETURNS INT RETURN 0 master-bin.000001 98 Query 1 199 drop database if exists mysqltest
master-bin.000001 8317 Query 1 8397 use `test`; DROP PROCEDURE p1 master-bin.000001 199 Query 1 302 drop database if exists mysqltest2
master-bin.000001 8397 Query 1 8476 use `test`; DROP FUNCTION f1 master-bin.000001 302 Query 1 395 create database mysqltest
master-bin.000001 8476 Query 1 8552 use `test`; drop table t1 master-bin.000001 395 Query 1 490 create database mysqltest2
master-bin.000001 8552 Query 1 8653 drop database if exists mysqltest master-bin.000001 490 Query 1 587 use `mysqltest2`; create table t ( t integer )
master-bin.000001 8653 Query 1 8756 drop database if exists mysqltest2 master-bin.000001 587 Query 1 726 use `mysqltest2`; CREATE DEFINER=`root`@`localhost` procedure mysqltest.test() begin end
master-bin.000001 8756 Query 1 8849 create database mysqltest master-bin.000001 726 Query 1 821 use `mysqltest2`; insert into t values ( 1 )
master-bin.000001 8849 Query 1 8944 create database mysqltest2
master-bin.000001 8944 Query 1 9041 use `mysqltest2`; create table t ( t integer )
master-bin.000001 9041 Query 1 9180 use `mysqltest2`; CREATE DEFINER=`root`@`localhost` procedure mysqltest.test() begin end
master-bin.000001 9180 Query 1 9275 use `mysqltest2`; insert into t values ( 1 )
create procedure `\\`.test() begin end; create procedure `\\`.test() begin end;
ERROR 42000: Incorrect database name '\\' ERROR 42000: Incorrect database name '\\'
drop database mysqltest; drop database mysqltest;
......
...@@ -371,6 +371,103 @@ create table t1 ( a timestamp ); ...@@ -371,6 +371,103 @@ create table t1 ( a timestamp );
alter table t1 add unique ( a(1) ); alter table t1 add unique ( a(1) );
drop table t1; drop table t1;
#
# Bug #24395: ALTER TABLE DISABLE KEYS doesn't work when modifying the table
#
# This problem happens if the data change is compatible.
# Changing to the same type is compatible for example.
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int, key(a));
show indexes from t1;
--echo "this used not to disable the index"
alter table t1 modify a int, disable keys;
show indexes from t1;
alter table t1 enable keys;
show indexes from t1;
alter table t1 modify a bigint, disable keys;
show indexes from t1;
alter table t1 enable keys;
show indexes from t1;
alter table t1 add b char(10), disable keys;
show indexes from t1;
alter table t1 add c decimal(10,2), enable keys;
show indexes from t1;
--echo "this however did"
alter table t1 disable keys;
show indexes from t1;
desc t1;
alter table t1 add d decimal(15,5);
--echo "The key should still be disabled"
show indexes from t1;
drop table t1;
--echo "Now will test with one unique index"
create table t1(a int, b char(10), unique(a));
show indexes from t1;
alter table t1 disable keys;
show indexes from t1;
alter table t1 enable keys;
--echo "If no copy on noop change, this won't touch the data file"
--echo "Unique index, no change"
alter table t1 modify a int, disable keys;
show indexes from t1;
--echo "Change the type implying data copy"
--echo "Unique index, no change"
alter table t1 modify a bigint, disable keys;
show indexes from t1;
alter table t1 modify a bigint;
show indexes from t1;
alter table t1 modify a int;
show indexes from t1;
drop table t1;
--echo "Now will test with one unique and one non-unique index"
create table t1(a int, b char(10), unique(a), key(b));
show indexes from t1;
alter table t1 disable keys;
show indexes from t1;
alter table t1 enable keys;
--echo "If no copy on noop change, this won't touch the data file"
--echo "The non-unique index will be disabled"
alter table t1 modify a int, disable keys;
show indexes from t1;
alter table t1 enable keys;
show indexes from t1;
--echo "Change the type implying data copy"
--echo "The non-unique index will be disabled"
alter table t1 modify a bigint, disable keys;
show indexes from t1;
--echo "Change again the type, but leave the indexes as_is"
alter table t1 modify a int;
show indexes from t1;
--echo "Try the same. When data is no copied on similar tables, this is noop"
alter table t1 modify a int;
show indexes from t1;
drop table t1;
# #
# Bug#11493 - Alter table rename to default database does not work without # Bug#11493 - Alter table rename to default database does not work without
# db name qualifying # db name qualifying
......
...@@ -715,7 +715,7 @@ create temporary table schemata(f1 char(10)); ...@@ -715,7 +715,7 @@ create temporary table schemata(f1 char(10));
# Bug #10708 SP's can use INFORMATION_SCHEMA as ROUTINE_SCHEMA # Bug #10708 SP's can use INFORMATION_SCHEMA as ROUTINE_SCHEMA
# #
delimiter |; delimiter |;
--error 1044 --error ER_BAD_DB_ERROR
CREATE PROCEDURE p1 () CREATE PROCEDURE p1 ()
BEGIN BEGIN
SELECT 'foo' FROM DUAL; SELECT 'foo' FROM DUAL;
......
...@@ -528,6 +528,7 @@ set global log_bin_trust_function_creators=0; ...@@ -528,6 +528,7 @@ set global log_bin_trust_function_creators=0;
# Bug22043: MySQL don't add "USE <DATABASE>" before "DROP PROCEDURE IF EXISTS" # Bug22043: MySQL don't add "USE <DATABASE>" before "DROP PROCEDURE IF EXISTS"
# #
connection master; connection master;
reset master;
--disable_warnings --disable_warnings
drop database if exists mysqltest; drop database if exists mysqltest;
drop database if exists mysqltest2; drop database if exists mysqltest2;
...@@ -538,7 +539,7 @@ use mysqltest2; ...@@ -538,7 +539,7 @@ use mysqltest2;
create table t ( t integer ); create table t ( t integer );
create procedure mysqltest.test() begin end; create procedure mysqltest.test() begin end;
insert into t values ( 1 ); insert into t values ( 1 );
show binlog events in 'master-bin.000001' from 8186; show binlog events in 'master-bin.000001' from 98;
--error ER_WRONG_DB_NAME --error ER_WRONG_DB_NAME
create procedure `\\`.test() begin end; create procedure `\\`.test() begin end;
# Clean up # Clean up
......
...@@ -4244,11 +4244,10 @@ end_with_restore_list: ...@@ -4244,11 +4244,10 @@ end_with_restore_list:
{ {
uint namelen; uint namelen;
char *name; char *name;
int result; int result= SP_INTERNAL_ERROR;
DBUG_ASSERT(lex->sphead != 0); DBUG_ASSERT(lex->sphead != 0);
DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */ DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
/* /*
Verify that the database name is allowed, optionally Verify that the database name is allowed, optionally
lowercase it. lowercase it.
...@@ -4256,37 +4255,26 @@ end_with_restore_list: ...@@ -4256,37 +4255,26 @@ end_with_restore_list:
if (check_db_name(lex->sphead->m_db.str)) if (check_db_name(lex->sphead->m_db.str))
{ {
my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str); my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str);
delete lex->sphead; goto create_sp_error;
lex->sphead= 0;
goto error;
} }
/* /*
Check that a database with this name Check that a database directory with this name
exists. exists. Design note: This won't work on virtual databases
like information_schema.
*/ */
if (check_db_dir_existence(lex->sphead->m_db.str)) if (check_db_dir_existence(lex->sphead->m_db.str))
{ {
my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str); my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
delete lex->sphead; goto create_sp_error;
lex->sphead= 0;
goto error;
} }
if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0, if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
is_schema_db(lex->sphead->m_db.str))) is_schema_db(lex->sphead->m_db.str)))
{ goto create_sp_error;
delete lex->sphead;
lex->sphead= 0;
goto error;
}
if (end_active_trans(thd)) if (end_active_trans(thd))
{ goto create_sp_error;
delete lex->sphead;
lex->sphead= 0;
goto error;
}
name= lex->sphead->name(&namelen); name= lex->sphead->name(&namelen);
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
...@@ -4296,10 +4284,8 @@ end_with_restore_list: ...@@ -4296,10 +4284,8 @@ end_with_restore_list:
if (udf) if (udf)
{ {
my_error(ER_UDF_EXISTS, MYF(0), name); my_error(ER_UDF_EXISTS, MYF(0), name);
delete lex->sphead; goto create_sp_error;
lex->sphead= 0;
goto error;
} }
} }
#endif #endif
...@@ -4307,7 +4293,7 @@ end_with_restore_list: ...@@ -4307,7 +4293,7 @@ end_with_restore_list:
/* /*
If the definer is not specified, this means that CREATE-statement missed If the definer is not specified, this means that CREATE-statement missed
DEFINER-clause. DEFINER-clause can be missed in two cases: DEFINER-clause. DEFINER-clause can be missed in two cases:
- The user submitted a statement w/o the clause. This is a normal - The user submitted a statement w/o the clause. This is a normal
case, we should assign CURRENT_USER as definer. case, we should assign CURRENT_USER as definer.
...@@ -4316,7 +4302,7 @@ end_with_restore_list: ...@@ -4316,7 +4302,7 @@ end_with_restore_list:
CURRENT_USER as definer here, but also we should mark this routine CURRENT_USER as definer here, but also we should mark this routine
as NON-SUID. This is essential for the sake of backward as NON-SUID. This is essential for the sake of backward
compatibility. compatibility.
The problem is the slave thread is running under "special" user (@), The problem is the slave thread is running under "special" user (@),
that actually does not exist. In the older versions we do not fail that actually does not exist. In the older versions we do not fail
execution of a stored routine if its definer does not exist and execution of a stored routine if its definer does not exist and
...@@ -4341,13 +4327,9 @@ end_with_restore_list: ...@@ -4341,13 +4327,9 @@ end_with_restore_list:
if (ps_arena) if (ps_arena)
thd->restore_active_arena(ps_arena, &original_arena); thd->restore_active_arena(ps_arena, &original_arena);
/* Error has been already reported. */
if (res) if (res)
{ goto create_sp_error;
/* Error has been already reported. */
delete lex->sphead;
lex->sphead= 0;
goto error;
}
if (thd->slave_thread) if (thd->slave_thread)
lex->sphead->m_chistics->suid= SP_IS_NOT_SUID; lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
...@@ -4358,7 +4340,7 @@ end_with_restore_list: ...@@ -4358,7 +4340,7 @@ end_with_restore_list:
that the current user has SUPER privilege (in order to create a stored that the current user has SUPER privilege (in order to create a stored
routine under another user one must have SUPER privilege). routine under another user one must have SUPER privilege).
*/ */
else if (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) || else if (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
my_strcasecmp(system_charset_info, my_strcasecmp(system_charset_info,
lex->definer->host.str, lex->definer->host.str,
...@@ -4367,9 +4349,7 @@ end_with_restore_list: ...@@ -4367,9 +4349,7 @@ end_with_restore_list:
if (check_global_access(thd, SUPER_ACL)) if (check_global_access(thd, SUPER_ACL))
{ {
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
delete lex->sphead; goto create_sp_error;
lex->sphead= 0;
goto error;
} }
} }
...@@ -4389,54 +4369,51 @@ end_with_restore_list: ...@@ -4389,54 +4369,51 @@ end_with_restore_list:
#endif /* NO_EMBEDDED_ACCESS_CHECKS */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
res= (result= lex->sphead->create(thd)); res= (result= lex->sphead->create(thd));
if (result == SP_OK) switch (result) {
{ case SP_OK:
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
/* only add privileges if really neccessary */ /* only add privileges if really neccessary */
if (sp_automatic_privileges && !opt_noacl && if (sp_automatic_privileges && !opt_noacl &&
check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS, check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
lex->sphead->m_db.str, name, lex->sphead->m_db.str, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1)) lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
{ {
close_thread_tables(thd);
if (sp_grant_privileges(thd, lex->sphead->m_db.str, name, if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE)) lex->sql_command == SQLCOM_CREATE_PROCEDURE))
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_GRANT_FAIL, ER_PROC_AUTO_GRANT_FAIL,
ER(ER_PROC_AUTO_GRANT_FAIL)); ER(ER_PROC_AUTO_GRANT_FAIL));
close_thread_tables(thd);
} }
#endif #endif
lex->unit.cleanup();
delete lex->sphead;
lex->sphead= 0;
send_ok(thd);
}
else
{
switch (result) {
case SP_WRITE_ROW_FAILED:
my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
break;
case SP_NO_DB_ERROR:
my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
break;
case SP_BAD_IDENTIFIER:
my_error(ER_TOO_LONG_IDENT, MYF(0), name);
break;
case SP_BODY_TOO_LONG:
my_error(ER_TOO_LONG_BODY, MYF(0), name);
break;
default:
my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
break;
}
lex->unit.cleanup();
delete lex->sphead;
lex->sphead= 0;
goto error;
}
break; break;
} case SP_WRITE_ROW_FAILED:
my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
break;
case SP_BAD_IDENTIFIER:
my_error(ER_TOO_LONG_IDENT, MYF(0), name);
break;
case SP_BODY_TOO_LONG:
my_error(ER_TOO_LONG_BODY, MYF(0), name);
break;
default:
my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
break;
} /* end switch */
/*
Capture all errors within this CASE and
clean up the environment.
*/
create_sp_error:
lex->unit.cleanup();
delete lex->sphead;
lex->sphead= 0;
if (result != SP_OK )
goto error;
send_ok(thd);
break; /* break super switch */
} /* end case group bracket */
case SQLCOM_CALL: case SQLCOM_CALL:
{ {
sp_head *sp; sp_head *sp;
......
...@@ -37,7 +37,9 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); ...@@ -37,7 +37,9 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
static int copy_data_between_tables(TABLE *from,TABLE *to, static int copy_data_between_tables(TABLE *from,TABLE *to,
List<create_field> &create, bool ignore, List<create_field> &create, bool ignore,
uint order_num, ORDER *order, uint order_num, ORDER *order,
ha_rows *copied,ha_rows *deleted); ha_rows *copied,ha_rows *deleted,
enum enum_enable_or_disable keys_onoff);
static bool prepare_blob_field(THD *thd, create_field *sql_field); static bool prepare_blob_field(THD *thd, create_field *sql_field);
static bool check_engine(THD *thd, const char *table_name, static bool check_engine(THD *thd, const char *table_name,
enum db_type *new_engine); enum db_type *new_engine);
...@@ -2933,6 +2935,54 @@ err: ...@@ -2933,6 +2935,54 @@ err:
} }
/*
Manages enabling/disabling of indexes for ALTER TABLE
SYNOPSIS
alter_table_manage_keys()
table Target table
indexes_were_disabled Whether the indexes of the from table
were disabled
keys_onoff ENABLE | DISABLE | LEAVE_AS_IS
RETURN VALUES
FALSE OK
TRUE Error
*/
static
bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
enum enum_enable_or_disable keys_onoff)
{
int error= 0;
DBUG_ENTER("alter_table_manage_keys");
DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
table, indexes_were_disabled, keys_onoff));
switch (keys_onoff) {
case ENABLE:
error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
break;
case LEAVE_AS_IS:
if (!indexes_were_disabled)
break;
/* fall-through: disabled indexes */
case DISABLE:
error= table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
}
if (error == HA_ERR_WRONG_COMMAND)
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), table->s->table_name);
error= 0;
} else if (error)
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
/* /*
Alter table Alter table
*/ */
...@@ -3586,8 +3636,20 @@ view_err: ...@@ -3586,8 +3636,20 @@ view_err:
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
new_table->next_number_field=new_table->found_next_number_field; new_table->next_number_field=new_table->found_next_number_field;
error=copy_data_between_tables(table, new_table, create_list, ignore, error=copy_data_between_tables(table, new_table, create_list, ignore,
order_num, order, &copied, &deleted); order_num, order, &copied, &deleted,
alter_info->keys_onoff);
} }
else if (!new_table)
{
VOID(pthread_mutex_lock(&LOCK_open));
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
table->file->external_lock(thd, F_WRLCK);
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
alter_info->keys_onoff);
table->file->external_lock(thd, F_UNLCK);
VOID(pthread_mutex_unlock(&LOCK_open));
}
thd->last_insert_id=next_insert_id; // Needed for correct log thd->last_insert_id=next_insert_id; // Needed for correct log
thd->count_cuted_fields= CHECK_FIELD_IGNORE; thd->count_cuted_fields= CHECK_FIELD_IGNORE;
...@@ -3815,7 +3877,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3815,7 +3877,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
bool ignore, bool ignore,
uint order_num, ORDER *order, uint order_num, ORDER *order,
ha_rows *copied, ha_rows *copied,
ha_rows *deleted) ha_rows *deleted,
enum enum_enable_or_disable keys_onoff)
{ {
int error; int error;
Copy_field *copy,*copy_end; Copy_field *copy,*copy_end;
...@@ -3848,6 +3911,9 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -3848,6 +3911,9 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (to->file->external_lock(thd, F_WRLCK)) if (to->file->external_lock(thd, F_WRLCK))
DBUG_RETURN(-1); DBUG_RETURN(-1);
/* We need external lock before we can disable/enable keys */
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
/* We can abort alter table for any table type */ /* We can abort alter table for any table type */
thd->no_trans_update= 0; thd->no_trans_update= 0;
thd->abort_on_warning= !ignore && test(thd->variables.sql_mode & thd->abort_on_warning= !ignore && test(thd->variables.sql_mode &
......
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