Merge bodhi.netgear:/opt/local/work/tmp_merge
into bodhi.netgear:/opt/local/work/mysql-5.1-runtime-merge-with-5.0
This commit is contained in:
commit
01bc761690
@ -163,7 +163,7 @@ extern gptr my_realloc(gptr oldpoint,uint Size,myf MyFlags);
|
|||||||
extern void my_no_flags_free(gptr ptr);
|
extern void my_no_flags_free(gptr ptr);
|
||||||
extern gptr my_memdup(const byte *from,uint length,myf MyFlags);
|
extern gptr my_memdup(const byte *from,uint length,myf MyFlags);
|
||||||
extern char *my_strdup(const char *from,myf MyFlags);
|
extern char *my_strdup(const char *from,myf MyFlags);
|
||||||
extern char *my_strndup(const byte *from, uint length,
|
extern char *my_strndup(const char *from, uint length,
|
||||||
myf MyFlags);
|
myf MyFlags);
|
||||||
/* we do use FG (as a no-op) in below so that a typo on FG is caught */
|
/* we do use FG (as a no-op) in below so that a typo on FG is caught */
|
||||||
#define my_free(PTR,FG) ((void)FG,my_no_flags_free(PTR))
|
#define my_free(PTR,FG) ((void)FG,my_no_flags_free(PTR))
|
||||||
|
@ -620,7 +620,7 @@ create database mysqltest;
|
|||||||
use mysqltest;
|
use mysqltest;
|
||||||
drop database mysqltest;
|
drop database mysqltest;
|
||||||
create table test.t1 like x;
|
create table test.t1 like x;
|
||||||
ERROR 42000: Incorrect database name 'NULL'
|
ERROR 3D000: No database selected
|
||||||
drop table if exists test.t1;
|
drop table if exists test.t1;
|
||||||
create database mysqltest;
|
create database mysqltest;
|
||||||
use mysqltest;
|
use mysqltest;
|
||||||
|
@ -1158,3 +1158,108 @@ Warnings:
|
|||||||
Error 1146 Table 'test.t4' doesn't exist
|
Error 1146 Table 'test.t4' doesn't exist
|
||||||
deallocate prepare stmt;
|
deallocate prepare stmt;
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
create database mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
use test;
|
||||||
|
create table t1 (i int);
|
||||||
|
prepare stmt from "alter table test.t1 rename t1";
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
execute stmt;
|
||||||
|
show tables like 't1';
|
||||||
|
Tables_in_mysqltest_long_database_name_to_thrash_heap (t1)
|
||||||
|
prepare stmt from "alter table test.t1 rename t1";
|
||||||
|
use test;
|
||||||
|
execute stmt;
|
||||||
|
show tables like 't1';
|
||||||
|
Tables_in_test (t1)
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
show tables like 't1';
|
||||||
|
Tables_in_mysqltest_long_database_name_to_thrash_heap (t1)
|
||||||
|
t1
|
||||||
|
deallocate prepare stmt;
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
prepare stmt_create from "create table t1 (i int)";
|
||||||
|
prepare stmt_insert from "insert into t1 (i) values (1)";
|
||||||
|
prepare stmt_update from "update t1 set i=2";
|
||||||
|
prepare stmt_delete from "delete from t1 where i=2";
|
||||||
|
prepare stmt_select from "select * from t1";
|
||||||
|
prepare stmt_alter from "alter table t1 add column (b int)";
|
||||||
|
prepare stmt_alter1 from "alter table t1 drop column b";
|
||||||
|
prepare stmt_analyze from "analyze table t1";
|
||||||
|
prepare stmt_optimize from "optimize table t1";
|
||||||
|
prepare stmt_show from "show tables like 't1'";
|
||||||
|
prepare stmt_truncate from "truncate table t1";
|
||||||
|
prepare stmt_drop from "drop table t1";
|
||||||
|
drop table t1;
|
||||||
|
use test;
|
||||||
|
execute stmt_create;
|
||||||
|
show tables like 't1';
|
||||||
|
Tables_in_test (t1)
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
show tables like 't1';
|
||||||
|
Tables_in_mysqltest_long_database_name_to_thrash_heap (t1)
|
||||||
|
t1
|
||||||
|
use test;
|
||||||
|
execute stmt_insert;
|
||||||
|
select * from mysqltest_long_database_name_to_thrash_heap.t1;
|
||||||
|
i
|
||||||
|
1
|
||||||
|
execute stmt_update;
|
||||||
|
select * from mysqltest_long_database_name_to_thrash_heap.t1;
|
||||||
|
i
|
||||||
|
2
|
||||||
|
execute stmt_delete;
|
||||||
|
execute stmt_select;
|
||||||
|
i
|
||||||
|
execute stmt_alter;
|
||||||
|
show columns from mysqltest_long_database_name_to_thrash_heap.t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
i int(11) YES NULL
|
||||||
|
b int(11) YES NULL
|
||||||
|
execute stmt_alter1;
|
||||||
|
show columns from mysqltest_long_database_name_to_thrash_heap.t1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
i int(11) YES NULL
|
||||||
|
execute stmt_analyze;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
mysqltest_long_database_name_to_thrash_heap.t1 analyze status Table is already up to date
|
||||||
|
execute stmt_optimize;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
mysqltest_long_database_name_to_thrash_heap.t1 optimize status Table is already up to date
|
||||||
|
execute stmt_show;
|
||||||
|
Tables_in_mysqltest_long_database_name_to_thrash_heap (t1)
|
||||||
|
t1
|
||||||
|
execute stmt_truncate;
|
||||||
|
execute stmt_drop;
|
||||||
|
show tables like 't1';
|
||||||
|
Tables_in_test (t1)
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
show tables like 't1';
|
||||||
|
Tables_in_mysqltest_long_database_name_to_thrash_heap (t1)
|
||||||
|
drop database mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
prepare stmt_create from "create table t1 (i int)";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_insert from "insert into t1 (i) values (1)";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_update from "update t1 set i=2";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_delete from "delete from t1 where i=2";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_select from "select * from t1";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_alter from "alter table t1 add column (b int)";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_alter1 from "alter table t1 drop column b";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_analyze from "analyze table t1";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_optimize from "optimize table t1";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_show from "show tables like 't1'";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_truncate from "truncate table t1";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
prepare stmt_drop from "drop table t1";
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
create temporary table t1 (i int);
|
||||||
|
ERROR 3D000: No database selected
|
||||||
|
use test;
|
||||||
|
@ -5000,6 +5000,52 @@ CALL bug18037_p2()|
|
|||||||
DROP FUNCTION bug18037_f1|
|
DROP FUNCTION bug18037_f1|
|
||||||
DROP PROCEDURE bug18037_p1|
|
DROP PROCEDURE bug18037_p1|
|
||||||
DROP PROCEDURE bug18037_p2|
|
DROP PROCEDURE bug18037_p2|
|
||||||
|
use test|
|
||||||
|
create table t3 (i int)|
|
||||||
|
insert into t3 values (1), (2)|
|
||||||
|
create database mysqltest1|
|
||||||
|
use mysqltest1|
|
||||||
|
create function bug17199() returns varchar(2) deterministic return 'ok'|
|
||||||
|
use test|
|
||||||
|
select *, mysqltest1.bug17199() from t3|
|
||||||
|
i mysqltest1.bug17199()
|
||||||
|
1 ok
|
||||||
|
2 ok
|
||||||
|
use mysqltest1|
|
||||||
|
create function bug18444(i int) returns int no sql deterministic return i + 1|
|
||||||
|
use test|
|
||||||
|
select mysqltest1.bug18444(i) from t3|
|
||||||
|
mysqltest1.bug18444(i)
|
||||||
|
2
|
||||||
|
3
|
||||||
|
drop database mysqltest1|
|
||||||
|
create database mysqltest1 charset=utf8|
|
||||||
|
create database mysqltest2 charset=utf8|
|
||||||
|
create procedure mysqltest1.p1()
|
||||||
|
begin
|
||||||
|
-- alters the default collation of database test
|
||||||
|
alter database character set koi8r;
|
||||||
|
end|
|
||||||
|
use mysqltest1|
|
||||||
|
call p1()|
|
||||||
|
show create database mysqltest1|
|
||||||
|
Database Create Database
|
||||||
|
mysqltest1 CREATE DATABASE `mysqltest1` /*!40100 DEFAULT CHARACTER SET koi8r */
|
||||||
|
show create database mysqltest2|
|
||||||
|
Database Create Database
|
||||||
|
mysqltest2 CREATE DATABASE `mysqltest2` /*!40100 DEFAULT CHARACTER SET utf8 */
|
||||||
|
alter database mysqltest1 character set utf8|
|
||||||
|
use mysqltest2|
|
||||||
|
call mysqltest1.p1()|
|
||||||
|
show create database mysqltest1|
|
||||||
|
Database Create Database
|
||||||
|
mysqltest1 CREATE DATABASE `mysqltest1` /*!40100 DEFAULT CHARACTER SET koi8r */
|
||||||
|
show create database mysqltest2|
|
||||||
|
Database Create Database
|
||||||
|
mysqltest2 CREATE DATABASE `mysqltest2` /*!40100 DEFAULT CHARACTER SET utf8 */
|
||||||
|
drop database mysqltest1|
|
||||||
|
drop database mysqltest2|
|
||||||
|
use test|
|
||||||
drop table if exists t3|
|
drop table if exists t3|
|
||||||
drop procedure if exists bug15217|
|
drop procedure if exists bug15217|
|
||||||
create table t3 as select 1|
|
create table t3 as select 1|
|
||||||
|
@ -521,7 +521,7 @@ DROP TABLE t12913;
|
|||||||
create database mysqltest;
|
create database mysqltest;
|
||||||
use mysqltest;
|
use mysqltest;
|
||||||
drop database mysqltest;
|
drop database mysqltest;
|
||||||
--error 1102
|
--error ER_NO_DB_ERROR
|
||||||
create table test.t1 like x;
|
create table test.t1 like x;
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists test.t1;
|
drop table if exists test.t1;
|
||||||
|
@ -1146,4 +1146,122 @@ execute stmt;
|
|||||||
execute stmt;
|
execute stmt;
|
||||||
deallocate prepare stmt;
|
deallocate prepare stmt;
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#17199 "Table not found" error occurs if the query contains a call
|
||||||
|
# to a function from another database.
|
||||||
|
# Test prepared statements- related behaviour.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# ALTER TABLE RENAME and Prepared Statements: wrong DB name buffer was used
|
||||||
|
# in ALTER ... RENAME which caused memory corruption in prepared statements.
|
||||||
|
# No need to fix this problem in 4.1 as ALTER TABLE is not allowed in
|
||||||
|
# Prepared Statements in 4.1.
|
||||||
|
#
|
||||||
|
create database mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
use test;
|
||||||
|
create table t1 (i int);
|
||||||
|
prepare stmt from "alter table test.t1 rename t1";
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
execute stmt;
|
||||||
|
show tables like 't1';
|
||||||
|
prepare stmt from "alter table test.t1 rename t1";
|
||||||
|
use test;
|
||||||
|
execute stmt;
|
||||||
|
show tables like 't1';
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
show tables like 't1';
|
||||||
|
deallocate prepare stmt;
|
||||||
|
#
|
||||||
|
# Check that a prepared statement initializes its current database at
|
||||||
|
# PREPARE, and then works correctly even if the current database has been
|
||||||
|
# changed.
|
||||||
|
#
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
# Necessary for preparation of INSERT/UPDATE/DELETE to succeed
|
||||||
|
prepare stmt_create from "create table t1 (i int)";
|
||||||
|
prepare stmt_insert from "insert into t1 (i) values (1)";
|
||||||
|
prepare stmt_update from "update t1 set i=2";
|
||||||
|
prepare stmt_delete from "delete from t1 where i=2";
|
||||||
|
prepare stmt_select from "select * from t1";
|
||||||
|
prepare stmt_alter from "alter table t1 add column (b int)";
|
||||||
|
prepare stmt_alter1 from "alter table t1 drop column b";
|
||||||
|
prepare stmt_analyze from "analyze table t1";
|
||||||
|
prepare stmt_optimize from "optimize table t1";
|
||||||
|
prepare stmt_show from "show tables like 't1'";
|
||||||
|
prepare stmt_truncate from "truncate table t1";
|
||||||
|
prepare stmt_drop from "drop table t1";
|
||||||
|
# Drop the table that was used to prepare INSERT/UPDATE/DELETE: we will
|
||||||
|
# create a new one by executing stmt_create
|
||||||
|
drop table t1;
|
||||||
|
# Switch the current database
|
||||||
|
use test;
|
||||||
|
# Check that all prepared statements operate on the database that was
|
||||||
|
# active at PREPARE
|
||||||
|
execute stmt_create;
|
||||||
|
# should return empty set
|
||||||
|
show tables like 't1';
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
show tables like 't1';
|
||||||
|
use test;
|
||||||
|
execute stmt_insert;
|
||||||
|
select * from mysqltest_long_database_name_to_thrash_heap.t1;
|
||||||
|
execute stmt_update;
|
||||||
|
select * from mysqltest_long_database_name_to_thrash_heap.t1;
|
||||||
|
execute stmt_delete;
|
||||||
|
execute stmt_select;
|
||||||
|
execute stmt_alter;
|
||||||
|
show columns from mysqltest_long_database_name_to_thrash_heap.t1;
|
||||||
|
execute stmt_alter1;
|
||||||
|
show columns from mysqltest_long_database_name_to_thrash_heap.t1;
|
||||||
|
execute stmt_analyze;
|
||||||
|
execute stmt_optimize;
|
||||||
|
execute stmt_show;
|
||||||
|
execute stmt_truncate;
|
||||||
|
execute stmt_drop;
|
||||||
|
show tables like 't1';
|
||||||
|
use mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
show tables like 't1';
|
||||||
|
#
|
||||||
|
# Attempt a statement PREPARE when there is no current database:
|
||||||
|
# is expected to return an error.
|
||||||
|
#
|
||||||
|
drop database mysqltest_long_database_name_to_thrash_heap;
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_create from "create table t1 (i int)";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_insert from "insert into t1 (i) values (1)";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_update from "update t1 set i=2";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_delete from "delete from t1 where i=2";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_select from "select * from t1";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_alter from "alter table t1 add column (b int)";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_alter1 from "alter table t1 drop column b";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_analyze from "analyze table t1";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_optimize from "optimize table t1";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_show from "show tables like 't1'";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_truncate from "truncate table t1";
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
prepare stmt_drop from "drop table t1";
|
||||||
|
#
|
||||||
|
# The above has automatically deallocated all our statements.
|
||||||
|
#
|
||||||
|
# Attempt to CREATE a temporary table when no DB used: it should fail
|
||||||
|
# This proves that no table can be used without explicit specification of
|
||||||
|
# its database if there is no current database.
|
||||||
|
#
|
||||||
|
--error ER_NO_DB_ERROR
|
||||||
|
create temporary table t1 (i int);
|
||||||
|
#
|
||||||
|
# Restore the old environemnt
|
||||||
|
#
|
||||||
|
use test;
|
||||||
# End of 5.0 tests
|
# End of 5.0 tests
|
||||||
|
@ -5893,6 +5893,52 @@ DROP FUNCTION bug18037_f1|
|
|||||||
DROP PROCEDURE bug18037_p1|
|
DROP PROCEDURE bug18037_p1|
|
||||||
DROP PROCEDURE bug18037_p2|
|
DROP PROCEDURE bug18037_p2|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#17199: "Table not found" error occurs if the query contains a call
|
||||||
|
# to a function from another database.
|
||||||
|
# See also ps.test for an additional test case for this bug.
|
||||||
|
#
|
||||||
|
use test|
|
||||||
|
create table t3 (i int)|
|
||||||
|
insert into t3 values (1), (2)|
|
||||||
|
create database mysqltest1|
|
||||||
|
use mysqltest1|
|
||||||
|
create function bug17199() returns varchar(2) deterministic return 'ok'|
|
||||||
|
use test|
|
||||||
|
select *, mysqltest1.bug17199() from t3|
|
||||||
|
#
|
||||||
|
# Bug#18444: Fully qualified stored function names don't work correctly
|
||||||
|
# in select statements
|
||||||
|
#
|
||||||
|
use mysqltest1|
|
||||||
|
create function bug18444(i int) returns int no sql deterministic return i + 1|
|
||||||
|
use test|
|
||||||
|
select mysqltest1.bug18444(i) from t3|
|
||||||
|
drop database mysqltest1|
|
||||||
|
#
|
||||||
|
# Check that current database has no influence to a stored procedure
|
||||||
|
#
|
||||||
|
create database mysqltest1 charset=utf8|
|
||||||
|
create database mysqltest2 charset=utf8|
|
||||||
|
create procedure mysqltest1.p1()
|
||||||
|
begin
|
||||||
|
-- alters the default collation of database test
|
||||||
|
alter database character set koi8r;
|
||||||
|
end|
|
||||||
|
use mysqltest1|
|
||||||
|
call p1()|
|
||||||
|
show create database mysqltest1|
|
||||||
|
show create database mysqltest2|
|
||||||
|
alter database mysqltest1 character set utf8|
|
||||||
|
use mysqltest2|
|
||||||
|
call mysqltest1.p1()|
|
||||||
|
show create database mysqltest1|
|
||||||
|
show create database mysqltest2|
|
||||||
|
drop database mysqltest1|
|
||||||
|
drop database mysqltest2|
|
||||||
|
#
|
||||||
|
# Restore the old environemnt
|
||||||
|
use test|
|
||||||
#
|
#
|
||||||
# Bug#15217 "Using a SP cursor on a table created with PREPARE fails with
|
# Bug#15217 "Using a SP cursor on a table created with PREPARE fails with
|
||||||
# weird error". Check that the code that is supposed to work at
|
# weird error". Check that the code that is supposed to work at
|
||||||
|
@ -83,7 +83,7 @@ char *my_strdup(const char *from, myf my_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *my_strndup(const byte *from, uint length, myf my_flags)
|
char *my_strndup(const char *from, uint length, myf my_flags)
|
||||||
{
|
{
|
||||||
gptr ptr;
|
gptr ptr;
|
||||||
if ((ptr=my_malloc(length+1,my_flags)) != 0)
|
if ((ptr=my_malloc(length+1,my_flags)) != 0)
|
||||||
|
@ -525,9 +525,8 @@ char *_my_strdup(const char *from, const char *filename, uint lineno,
|
|||||||
} /* _my_strdup */
|
} /* _my_strdup */
|
||||||
|
|
||||||
|
|
||||||
char *_my_strndup(const byte *from, uint length,
|
char *_my_strndup(const char *from, uint length, const char *filename,
|
||||||
const char *filename, uint lineno,
|
uint lineno, myf MyFlags)
|
||||||
myf MyFlags)
|
|
||||||
{
|
{
|
||||||
gptr ptr;
|
gptr ptr;
|
||||||
if ((ptr=_mymalloc(length+1,filename,lineno,MyFlags)) != 0)
|
if ((ptr=_mymalloc(length+1,filename,lineno,MyFlags)) != 0)
|
||||||
|
@ -629,10 +629,8 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table,
|
|||||||
DBUG_PRINT("info", ("Length: %d", table->s->connect_string.length));
|
DBUG_PRINT("info", ("Length: %d", table->s->connect_string.length));
|
||||||
DBUG_PRINT("info", ("String: '%.*s'", table->s->connect_string.length,
|
DBUG_PRINT("info", ("String: '%.*s'", table->s->connect_string.length,
|
||||||
table->s->connect_string.str));
|
table->s->connect_string.str));
|
||||||
share->scheme= my_strndup((const byte*)table->s->
|
share->scheme= my_strndup(table->s->connect_string.str,
|
||||||
connect_string.str,
|
table->s->connect_string.length, MYF(0));
|
||||||
table->s->connect_string.length,
|
|
||||||
MYF(0));
|
|
||||||
|
|
||||||
// Add a null for later termination of table name
|
// Add a null for later termination of table name
|
||||||
share->scheme[table->s->connect_string.length]= 0;
|
share->scheme[table->s->connect_string.length]= 0;
|
||||||
|
@ -1667,13 +1667,13 @@ String *Item_func_database::val_str(String *str)
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
if (!thd->db)
|
if (thd->db == NULL)
|
||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
str->copy((const char*) thd->db,(uint) strlen(thd->db),system_charset_info);
|
str->copy(thd->db, thd->db_length, system_charset_info);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1928,9 +1928,10 @@ end:
|
|||||||
don't suffer from these assignments to 0 as DROP TEMPORARY
|
don't suffer from these assignments to 0 as DROP TEMPORARY
|
||||||
TABLE uses the db.table syntax.
|
TABLE uses the db.table syntax.
|
||||||
*/
|
*/
|
||||||
thd->db= thd->catalog= 0; // prevent db from being freed
|
thd->catalog= 0;
|
||||||
|
thd->reset_db(NULL, 0); // prevent db from being freed
|
||||||
thd->query= 0; // just to be sure
|
thd->query= 0; // just to be sure
|
||||||
thd->query_length= thd->db_length =0;
|
thd->query_length= 0;
|
||||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
|
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
|
||||||
@ -2954,7 +2955,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
|
|||||||
|
|
||||||
TABLE_LIST tables;
|
TABLE_LIST tables;
|
||||||
bzero((char*) &tables,sizeof(tables));
|
bzero((char*) &tables,sizeof(tables));
|
||||||
tables.db = thd->db;
|
tables.db= thd->strmake(thd->db, thd->db_length);
|
||||||
tables.alias = tables.table_name = (char*) table_name;
|
tables.alias = tables.table_name = (char*) table_name;
|
||||||
tables.lock_type = TL_WRITE;
|
tables.lock_type = TL_WRITE;
|
||||||
tables.updating= 1;
|
tables.updating= 1;
|
||||||
@ -3049,7 +3050,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
|
|||||||
ex.skip_lines = skip_lines;
|
ex.skip_lines = skip_lines;
|
||||||
List<Item> field_list;
|
List<Item> field_list;
|
||||||
thd->main_lex.select_lex.context.resolve_in_table_list_only(&tables);
|
thd->main_lex.select_lex.context.resolve_in_table_list_only(&tables);
|
||||||
set_fields(thd->db, field_list, &thd->main_lex.select_lex.context);
|
set_fields(tables.db, field_list, &thd->main_lex.select_lex.context);
|
||||||
thd->variables.pseudo_thread_id= thread_id;
|
thd->variables.pseudo_thread_id= thread_id;
|
||||||
List<Item> set_fields;
|
List<Item> set_fields;
|
||||||
if (net)
|
if (net)
|
||||||
@ -3096,11 +3097,12 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
thd->net.vio = 0;
|
thd->net.vio = 0;
|
||||||
char *save_db= thd->db;
|
const char *remember_db= thd->db;
|
||||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||||
thd->db= thd->catalog= 0;
|
thd->catalog= 0;
|
||||||
|
thd->reset_db(NULL, 0);
|
||||||
thd->query= 0;
|
thd->query= 0;
|
||||||
thd->query_length= thd->db_length= 0;
|
thd->query_length= 0;
|
||||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
if (thd->query_error)
|
if (thd->query_error)
|
||||||
@ -3117,7 +3119,7 @@ error:
|
|||||||
}
|
}
|
||||||
slave_print_msg(ERROR_LEVEL, rli, sql_errno,"\
|
slave_print_msg(ERROR_LEVEL, rli, sql_errno,"\
|
||||||
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
|
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
|
||||||
err, (char*)table_name, print_slave_db_safe(save_db));
|
err, (char*)table_name, print_slave_db_safe(remember_db));
|
||||||
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
|
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -3127,7 +3129,7 @@ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
|
|||||||
{
|
{
|
||||||
slave_print_msg(ERROR_LEVEL, rli, ER_UNKNOWN_ERROR, "\
|
slave_print_msg(ERROR_LEVEL, rli, ER_UNKNOWN_ERROR, "\
|
||||||
Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'",
|
Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'",
|
||||||
(char*)table_name, print_slave_db_safe(save_db));
|
(char*)table_name, print_slave_db_safe(remember_db));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3202,8 +3204,7 @@ Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
|
|||||||
llstr(pos_arg, buff), flags));
|
llstr(pos_arg, buff), flags));
|
||||||
#endif
|
#endif
|
||||||
if (flags & DUP_NAME)
|
if (flags & DUP_NAME)
|
||||||
new_log_ident= my_strndup((const byte*) new_log_ident_arg,
|
new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
|
||||||
ident_len, MYF(MY_WME));
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -3226,9 +3227,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
|
|||||||
(header_size+post_header_len));
|
(header_size+post_header_len));
|
||||||
ident_offset = post_header_len;
|
ident_offset = post_header_len;
|
||||||
set_if_smaller(ident_len,FN_REFLEN-1);
|
set_if_smaller(ident_len,FN_REFLEN-1);
|
||||||
new_log_ident= my_strndup((byte*) buf + ident_offset,
|
new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
|
||||||
(uint) ident_len,
|
|
||||||
MYF(MY_WME));
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,7 +1097,7 @@ bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
|
|||||||
uint new_length= (var ? var->value->str_value.length() : 0);
|
uint new_length= (var ? var->value->str_value.length() : 0);
|
||||||
if (!old_value)
|
if (!old_value)
|
||||||
old_value= (char*) "";
|
old_value= (char*) "";
|
||||||
if (!(res= my_strndup((byte*)old_value, new_length, MYF(0))))
|
if (!(res= my_strndup(old_value, new_length, MYF(0))))
|
||||||
return 1;
|
return 1;
|
||||||
/*
|
/*
|
||||||
Replace the old value in such a way that the any thread using
|
Replace the old value in such a way that the any thread using
|
||||||
@ -2632,7 +2632,7 @@ bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
|
|||||||
old_value= make_default_log_name(buff, log_ext);
|
old_value= make_default_log_name(buff, log_ext);
|
||||||
str_length= strlen(old_value);
|
str_length= strlen(old_value);
|
||||||
}
|
}
|
||||||
if (!(res= my_strndup((byte*)old_value, str_length, MYF(MY_FAE+MY_WME))))
|
if (!(res= my_strndup(old_value, str_length, MYF(MY_FAE+MY_WME))))
|
||||||
{
|
{
|
||||||
result= 1;
|
result= 1;
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -1055,7 +1055,7 @@ public:
|
|||||||
uint name_length_arg, gptr data_arg)
|
uint name_length_arg, gptr data_arg)
|
||||||
:name_length(name_length_arg), data(data_arg)
|
:name_length(name_length_arg), data(data_arg)
|
||||||
{
|
{
|
||||||
name= my_strndup((byte*) name_arg, name_length, MYF(MY_WME));
|
name= my_strndup(name_arg, name_length, MYF(MY_WME));
|
||||||
links->push_back(this);
|
links->push_back(this);
|
||||||
}
|
}
|
||||||
inline bool cmp(const char *name_cmp, uint length)
|
inline bool cmp(const char *name_cmp, uint length)
|
||||||
|
16
sql/slave.cc
16
sql/slave.cc
@ -1347,9 +1347,8 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
|||||||
// save old db in case we are creating in a different database
|
// save old db in case we are creating in a different database
|
||||||
save_db = thd->db;
|
save_db = thd->db;
|
||||||
save_db_length= thd->db_length;
|
save_db_length= thd->db_length;
|
||||||
thd->db = (char*)db;
|
DBUG_ASSERT(db != 0);
|
||||||
DBUG_ASSERT(thd->db != 0);
|
thd->reset_db((char*)db, strlen(db));
|
||||||
thd->db_length= strlen(thd->db);
|
|
||||||
mysql_parse(thd, thd->query, packet_len); // run create table
|
mysql_parse(thd, thd->query, packet_len); // run create table
|
||||||
thd->db = save_db; // leave things the way the were before
|
thd->db = save_db; // leave things the way the were before
|
||||||
thd->db_length= save_db_length;
|
thd->db_length= save_db_length;
|
||||||
@ -3511,8 +3510,9 @@ err:
|
|||||||
sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
|
sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
|
||||||
IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
|
IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
|
||||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||||
thd->query = thd->db = 0; // extra safety
|
thd->query= 0; // extra safety
|
||||||
thd->query_length= thd->db_length= 0;
|
thd->query_length= 0;
|
||||||
|
thd->reset_db(NULL, 0);
|
||||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||||
if (mysql)
|
if (mysql)
|
||||||
{
|
{
|
||||||
@ -3760,8 +3760,10 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
|
|||||||
should already have done these assignments (each event which sets these
|
should already have done these assignments (each event which sets these
|
||||||
variables is supposed to set them to 0 before terminating)).
|
variables is supposed to set them to 0 before terminating)).
|
||||||
*/
|
*/
|
||||||
thd->query= thd->db= thd->catalog= 0;
|
thd->catalog= 0;
|
||||||
thd->query_length= thd->db_length= 0;
|
thd->reset_db(NULL, 0);
|
||||||
|
thd->query= 0;
|
||||||
|
thd->query_length= 0;
|
||||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||||
thd->proc_info = "Waiting for slave mutex on exit";
|
thd->proc_info = "Waiting for slave mutex on exit";
|
||||||
pthread_mutex_lock(&rli->run_lock);
|
pthread_mutex_lock(&rli->run_lock);
|
||||||
|
107
sql/sp.cc
107
sql/sp.cc
@ -406,7 +406,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
|
|||||||
{
|
{
|
||||||
LEX *old_lex= thd->lex, newlex;
|
LEX *old_lex= thd->lex, newlex;
|
||||||
String defstr;
|
String defstr;
|
||||||
char olddb[128];
|
char old_db_buf[NAME_LEN+1];
|
||||||
|
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
|
||||||
bool dbchanged;
|
bool dbchanged;
|
||||||
ulong old_sql_mode= thd->variables.sql_mode;
|
ulong old_sql_mode= thd->variables.sql_mode;
|
||||||
ha_rows old_select_limit= thd->variables.select_limit;
|
ha_rows old_select_limit= thd->variables.select_limit;
|
||||||
@ -450,9 +451,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbchanged= FALSE;
|
if ((ret= sp_use_new_db(thd, name->m_db, &old_db, 1, &dbchanged)))
|
||||||
if ((ret= sp_use_new_db(thd, name->m_db.str, olddb, sizeof(olddb),
|
|
||||||
1, &dbchanged)))
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length());
|
lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length());
|
||||||
@ -462,14 +461,14 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
|
|||||||
{
|
{
|
||||||
sp_head *sp= newlex.sphead;
|
sp_head *sp= newlex.sphead;
|
||||||
|
|
||||||
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
|
if (dbchanged && (ret= mysql_change_db(thd, old_db.str, 1)))
|
||||||
goto end;
|
goto end;
|
||||||
delete sp;
|
delete sp;
|
||||||
ret= SP_PARSE_ERROR;
|
ret= SP_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
|
if (dbchanged && (ret= mysql_change_db(thd, old_db.str, 1)))
|
||||||
goto end;
|
goto end;
|
||||||
*sphp= newlex.sphead;
|
*sphp= newlex.sphead;
|
||||||
(*sphp)->set_definer(&definer_user_name, &definer_host_name);
|
(*sphp)->set_definer(&definer_user_name, &definer_host_name);
|
||||||
@ -507,15 +506,14 @@ db_create_routine(THD *thd, int type, sp_head *sp)
|
|||||||
int ret;
|
int ret;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
char definer[USER_HOST_BUFF_SIZE];
|
char definer[USER_HOST_BUFF_SIZE];
|
||||||
char olddb[128];
|
char old_db_buf[NAME_LEN+1];
|
||||||
|
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
|
||||||
bool dbchanged;
|
bool dbchanged;
|
||||||
DBUG_ENTER("db_create_routine");
|
DBUG_ENTER("db_create_routine");
|
||||||
DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length,
|
DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length,
|
||||||
sp->m_name.str));
|
sp->m_name.str));
|
||||||
|
|
||||||
dbchanged= FALSE;
|
if ((ret= sp_use_new_db(thd, sp->m_db, &old_db, 0, &dbchanged)))
|
||||||
if ((ret= sp_use_new_db(thd, sp->m_db.str, olddb, sizeof(olddb),
|
|
||||||
0, &dbchanged)))
|
|
||||||
{
|
{
|
||||||
ret= SP_NO_DB_ERROR;
|
ret= SP_NO_DB_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
@ -642,7 +640,7 @@ db_create_routine(THD *thd, int type, sp_head *sp)
|
|||||||
done:
|
done:
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
if (dbchanged)
|
if (dbchanged)
|
||||||
(void)mysql_change_db(thd, olddb, 1);
|
(void) mysql_change_db(thd, old_db.str, 1);
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1815,49 +1813,76 @@ create_string(THD *thd, String *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Utilities...
|
/*
|
||||||
//
|
Change the current database if needed.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
sp_use_new_db()
|
||||||
|
thd thread handle
|
||||||
|
|
||||||
|
new_db new database name (a string and its length)
|
||||||
|
|
||||||
|
old_db [IN] str points to a buffer where to store the old
|
||||||
|
database, length contains the size of the buffer
|
||||||
|
[OUT] if old db was not NULL, its name is copied
|
||||||
|
to the buffer pointed at by str and length is updated
|
||||||
|
accordingly. Otherwise str[0] is set to '\0' and length
|
||||||
|
is set to 0. The out parameter should be used only if
|
||||||
|
the database name has been changed (see dbchangedp).
|
||||||
|
|
||||||
|
dbchangedp [OUT] is set to TRUE if the current database is changed,
|
||||||
|
FALSE otherwise. A database is not changed if the old
|
||||||
|
name is the same as the new one, both names are empty,
|
||||||
|
or an error has occurred.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 success
|
||||||
|
1 access denied or out of memory (the error message is
|
||||||
|
set in THD)
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sp_use_new_db(THD *thd, char *newdb, char *olddb, uint olddblen,
|
sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db,
|
||||||
bool no_access_check, bool *dbchangedp)
|
bool no_access_check, bool *dbchangedp)
|
||||||
{
|
{
|
||||||
bool changeit;
|
int ret;
|
||||||
|
static char empty_c_string[1]= {0}; /* used for not defined db */
|
||||||
DBUG_ENTER("sp_use_new_db");
|
DBUG_ENTER("sp_use_new_db");
|
||||||
DBUG_PRINT("enter", ("newdb: %s", newdb));
|
DBUG_PRINT("enter", ("newdb: %s", new_db.str));
|
||||||
|
|
||||||
if (! newdb)
|
/*
|
||||||
newdb= (char *)"";
|
Set new_db to an empty string if it's NULL, because mysql_change_db
|
||||||
if (thd->db && thd->db[0])
|
requires a non-NULL argument.
|
||||||
|
new_db.str can be NULL only if we're restoring the old database after
|
||||||
|
execution of a stored procedure and there were no current database
|
||||||
|
selected. The stored procedure itself must always have its database
|
||||||
|
initialized.
|
||||||
|
*/
|
||||||
|
if (new_db.str == NULL)
|
||||||
|
new_db.str= empty_c_string;
|
||||||
|
|
||||||
|
if (thd->db)
|
||||||
{
|
{
|
||||||
if (my_strcasecmp(system_charset_info, thd->db, newdb) == 0)
|
old_db->length= (strmake(old_db->str, thd->db, old_db->length) -
|
||||||
changeit= 0;
|
old_db->str);
|
||||||
else
|
|
||||||
{
|
|
||||||
changeit= 1;
|
|
||||||
strnmov(olddb, thd->db, olddblen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // thd->db empty
|
{
|
||||||
if (newdb[0])
|
old_db->str[0]= '\0';
|
||||||
changeit= 1;
|
old_db->length= 0;
|
||||||
else
|
|
||||||
changeit= 0;
|
|
||||||
olddb[0] = '\0';
|
|
||||||
}
|
}
|
||||||
if (!changeit)
|
|
||||||
|
/* Don't change the database if the new name is the same as the old one. */
|
||||||
|
if (my_strcasecmp(system_charset_info, old_db->str, new_db.str) == 0)
|
||||||
{
|
{
|
||||||
*dbchangedp= FALSE;
|
*dbchangedp= FALSE;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
int ret= mysql_change_db(thd, newdb, no_access_check);
|
|
||||||
|
|
||||||
if (! ret)
|
ret= mysql_change_db(thd, new_db.str, no_access_check);
|
||||||
*dbchangedp= TRUE;
|
|
||||||
DBUG_RETURN(ret);
|
*dbchangedp= ret == 0;
|
||||||
}
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
sql/sp.h
14
sql/sp.h
@ -104,15 +104,15 @@ extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
|
|||||||
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup);
|
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup);
|
||||||
void close_proc_table(THD *thd, Open_tables_state *backup);
|
void close_proc_table(THD *thd, Open_tables_state *backup);
|
||||||
|
|
||||||
//
|
|
||||||
// Utilities...
|
|
||||||
//
|
|
||||||
|
|
||||||
// Do a "use newdb". The current db is stored at olddb.
|
/*
|
||||||
// If newdb is the same as the current one, nothing is changed.
|
Do a "use new_db". The current db is stored at old_db. If new_db is the
|
||||||
// dbchangedp is set to true if the db was actually changed.
|
same as the current one, nothing is changed. dbchangedp is set to true if
|
||||||
|
the db was actually changed.
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sp_use_new_db(THD *thd, char *newdb, char *olddb, uint olddbmax,
|
sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db,
|
||||||
bool no_access_check, bool *dbchangedp);
|
bool no_access_check, bool *dbchangedp);
|
||||||
|
|
||||||
#endif /* _SP_H_ */
|
#endif /* _SP_H_ */
|
||||||
|
@ -385,24 +385,6 @@ sp_name::init_qname(THD *thd)
|
|||||||
m_name.length, m_name.str);
|
m_name.length, m_name.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
sp_name *
|
|
||||||
sp_name_current_db_new(THD *thd, LEX_STRING name)
|
|
||||||
{
|
|
||||||
sp_name *qname;
|
|
||||||
|
|
||||||
if (! thd->db)
|
|
||||||
qname= new sp_name(name);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LEX_STRING db;
|
|
||||||
|
|
||||||
db.length= strlen(thd->db);
|
|
||||||
db.str= thd->strmake(thd->db, db.length);
|
|
||||||
qname= new sp_name(db, name);
|
|
||||||
}
|
|
||||||
qname->init_qname(thd);
|
|
||||||
return qname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check that the name 'ident' is ok. It's assumed to be an 'ident'
|
Check that the name 'ident' is ok. It's assumed to be an 'ident'
|
||||||
@ -513,27 +495,20 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
|
|||||||
/* During parsing, we must use thd->mem_root */
|
/* During parsing, we must use thd->mem_root */
|
||||||
MEM_ROOT *root= thd->mem_root;
|
MEM_ROOT *root= thd->mem_root;
|
||||||
|
|
||||||
/* We have to copy strings to get them into the right memroot */
|
DBUG_ASSERT(name);
|
||||||
if (name)
|
/* Must be initialized in the parser */
|
||||||
{
|
DBUG_ASSERT(name->m_db.str && name->m_db.length);
|
||||||
m_db.length= name->m_db.length;
|
|
||||||
if (name->m_db.length == 0)
|
|
||||||
m_db.str= NULL;
|
|
||||||
else
|
|
||||||
m_db.str= strmake_root(root, name->m_db.str, name->m_db.length);
|
|
||||||
m_name.length= name->m_name.length;
|
|
||||||
m_name.str= strmake_root(root, name->m_name.str, name->m_name.length);
|
|
||||||
|
|
||||||
if (name->m_qname.length == 0)
|
/* We have to copy strings to get them into the right memroot */
|
||||||
name->init_qname(thd);
|
m_db.length= name->m_db.length;
|
||||||
m_qname.length= name->m_qname.length;
|
m_db.str= strmake_root(root, name->m_db.str, name->m_db.length);
|
||||||
m_qname.str= strmake_root(root, name->m_qname.str, m_qname.length);
|
m_name.length= name->m_name.length;
|
||||||
}
|
m_name.str= strmake_root(root, name->m_name.str, name->m_name.length);
|
||||||
else if (thd->db)
|
|
||||||
{
|
if (name->m_qname.length == 0)
|
||||||
m_db.length= thd->db_length;
|
name->init_qname(thd);
|
||||||
m_db.str= strmake_root(root, thd->db, m_db.length);
|
m_qname.length= name->m_qname.length;
|
||||||
}
|
m_qname.str= strmake_root(root, name->m_qname.str, m_qname.length);
|
||||||
|
|
||||||
if (m_param_begin && m_param_end)
|
if (m_param_begin && m_param_end)
|
||||||
{
|
{
|
||||||
@ -949,7 +924,8 @@ bool
|
|||||||
sp_head::execute(THD *thd)
|
sp_head::execute(THD *thd)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("sp_head::execute");
|
DBUG_ENTER("sp_head::execute");
|
||||||
char olddb[128];
|
char old_db_buf[NAME_LEN+1];
|
||||||
|
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
|
||||||
bool dbchanged;
|
bool dbchanged;
|
||||||
sp_rcontext *ctx;
|
sp_rcontext *ctx;
|
||||||
bool err_status= FALSE;
|
bool err_status= FALSE;
|
||||||
@ -996,10 +972,8 @@ sp_head::execute(THD *thd)
|
|||||||
m_first_instance->m_last_cached_sp == this) ||
|
m_first_instance->m_last_cached_sp == this) ||
|
||||||
(m_recursion_level + 1 == m_next_cached_sp->m_recursion_level));
|
(m_recursion_level + 1 == m_next_cached_sp->m_recursion_level));
|
||||||
|
|
||||||
dbchanged= FALSE;
|
|
||||||
if (m_db.length &&
|
if (m_db.length &&
|
||||||
(err_status= sp_use_new_db(thd, m_db.str, olddb, sizeof(olddb), 0,
|
(err_status= sp_use_new_db(thd, m_db, &old_db, 0, &dbchanged)))
|
||||||
&dbchanged)))
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if ((ctx= thd->spcont))
|
if ((ctx= thd->spcont))
|
||||||
@ -1170,10 +1144,10 @@ sp_head::execute(THD *thd)
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
No access check when changing back to where we came from.
|
No access check when changing back to where we came from.
|
||||||
(It would generate an error from mysql_change_db() when olddb=="")
|
(It would generate an error from mysql_change_db() when old_db=="")
|
||||||
*/
|
*/
|
||||||
if (! thd->killed)
|
if (! thd->killed)
|
||||||
err_status|= mysql_change_db(thd, olddb, 1);
|
err_status|= mysql_change_db(thd, old_db.str, 1);
|
||||||
}
|
}
|
||||||
m_flags&= ~IS_INVOKED;
|
m_flags&= ~IS_INVOKED;
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
@ -1857,9 +1831,6 @@ sp_head::reset_thd_mem_root(THD *thd)
|
|||||||
(ulong) &mem_root, (ulong) &thd->mem_root));
|
(ulong) &mem_root, (ulong) &thd->mem_root));
|
||||||
free_list= thd->free_list; // Keep the old list
|
free_list= thd->free_list; // Keep the old list
|
||||||
thd->free_list= NULL; // Start a new one
|
thd->free_list= NULL; // Start a new one
|
||||||
/* Copy the db, since substatements will point to it */
|
|
||||||
m_thd_db= thd->db;
|
|
||||||
thd->db= thd->strmake(thd->db, thd->db_length);
|
|
||||||
m_thd= thd;
|
m_thd= thd;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
@ -1875,7 +1846,6 @@ sp_head::restore_thd_mem_root(THD *thd)
|
|||||||
DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx",
|
DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx",
|
||||||
(ulong) &mem_root, (ulong) &thd->mem_root));
|
(ulong) &mem_root, (ulong) &thd->mem_root));
|
||||||
thd->free_list= flist; // Restore the old one
|
thd->free_list= flist; // Restore the old one
|
||||||
thd->db= m_thd_db; // Restore the original db pointer
|
|
||||||
thd->mem_root= m_thd_root;
|
thd->mem_root= m_thd_root;
|
||||||
m_thd= NULL;
|
m_thd= NULL;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@ -61,13 +61,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
LEX_STRING m_sroutines_key;
|
LEX_STRING m_sroutines_key;
|
||||||
|
|
||||||
sp_name(LEX_STRING name)
|
|
||||||
: m_name(name)
|
|
||||||
{
|
|
||||||
m_db.str= m_qname.str= m_sroutines_key.str= 0;
|
|
||||||
m_db.length= m_qname.length= m_sroutines_key.length= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp_name(LEX_STRING db, LEX_STRING name)
|
sp_name(LEX_STRING db, LEX_STRING name)
|
||||||
: m_db(db), m_name(name)
|
: m_db(db), m_name(name)
|
||||||
{
|
{
|
||||||
@ -101,8 +94,6 @@ public:
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
sp_name *
|
|
||||||
sp_name_current_db_new(THD *thd, LEX_STRING name);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
check_routine_name(LEX_STRING name);
|
check_routine_name(LEX_STRING name);
|
||||||
@ -356,7 +347,6 @@ private:
|
|||||||
|
|
||||||
MEM_ROOT *m_thd_root; // Temp. store for thd's mem_root
|
MEM_ROOT *m_thd_root; // Temp. store for thd's mem_root
|
||||||
THD *m_thd; // Set if we have reset mem_root
|
THD *m_thd; // Set if we have reset mem_root
|
||||||
char *m_thd_db; // Original thd->db pointer
|
|
||||||
|
|
||||||
sp_pcontext *m_pcont; // Parse context
|
sp_pcontext *m_pcont; // Parse context
|
||||||
List<LEX> m_lex; // Temp. store for the other lex
|
List<LEX> m_lex; // Temp. store for the other lex
|
||||||
|
@ -1135,7 +1135,7 @@ public:
|
|||||||
uint tmp_table, global_read_lock;
|
uint tmp_table, global_read_lock;
|
||||||
uint server_status,open_options;
|
uint server_status,open_options;
|
||||||
enum enum_thread_type system_thread;
|
enum enum_thread_type system_thread;
|
||||||
uint32 db_length;
|
uint db_length;
|
||||||
uint select_number; //number of select (used for EXPLAIN)
|
uint select_number; //number of select (used for EXPLAIN)
|
||||||
/* variables.transaction_isolation is reset to this after each commit */
|
/* variables.transaction_isolation is reset to this after each commit */
|
||||||
enum_tx_isolation session_tx_isolation;
|
enum_tx_isolation session_tx_isolation;
|
||||||
@ -1443,6 +1443,47 @@ public:
|
|||||||
current_stmt_binlog_row_based= FALSE;
|
current_stmt_binlog_row_based= FALSE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize the current database from a NULL-terminated string with length
|
||||||
|
*/
|
||||||
|
void set_db(const char *new_db, uint new_db_len)
|
||||||
|
{
|
||||||
|
if (new_db)
|
||||||
|
{
|
||||||
|
/* Do not reallocate memory if current chunk is big enough. */
|
||||||
|
if (db && db_length >= new_db_len)
|
||||||
|
memcpy(db, new_db, new_db_len+1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
safeFree(db);
|
||||||
|
db= my_strndup(new_db, new_db_len, MYF(MY_WME));
|
||||||
|
}
|
||||||
|
db_length= db ? new_db_len: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void reset_db(char *new_db, uint new_db_len)
|
||||||
|
{
|
||||||
|
db= new_db;
|
||||||
|
db_length= new_db_len;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Copy the current database to the argument. Use the current arena to
|
||||||
|
allocate memory for a deep copy: current database may be freed after
|
||||||
|
a statement is parsed but before it's executed.
|
||||||
|
*/
|
||||||
|
bool copy_db_to(char **p_db, uint *p_db_length)
|
||||||
|
{
|
||||||
|
if (db == NULL)
|
||||||
|
{
|
||||||
|
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
*p_db= strmake(db, db_length);
|
||||||
|
if (p_db_length)
|
||||||
|
*p_db_length= db_length;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1790,7 +1831,7 @@ typedef struct st_sort_buffer {
|
|||||||
|
|
||||||
class Table_ident :public Sql_alloc
|
class Table_ident :public Sql_alloc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LEX_STRING db;
|
LEX_STRING db;
|
||||||
LEX_STRING table;
|
LEX_STRING table;
|
||||||
SELECT_LEX_UNIT *sel;
|
SELECT_LEX_UNIT *sel;
|
||||||
|
@ -930,8 +930,7 @@ exit:
|
|||||||
{
|
{
|
||||||
if (!(thd->slave_thread)) /* a slave thread will free it itself */
|
if (!(thd->slave_thread)) /* a slave thread will free it itself */
|
||||||
x_free(thd->db);
|
x_free(thd->db);
|
||||||
thd->db= 0;
|
thd->reset_db(NULL, 0);
|
||||||
thd->db_length= 0;
|
|
||||||
}
|
}
|
||||||
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
|
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
|
||||||
start_waiting_global_read_lock(thd);
|
start_waiting_global_read_lock(thd);
|
||||||
@ -1345,14 +1344,10 @@ end:
|
|||||||
{
|
{
|
||||||
if (!(thd->slave_thread))
|
if (!(thd->slave_thread))
|
||||||
my_free(dbname, MYF(0));
|
my_free(dbname, MYF(0));
|
||||||
thd->db= NULL;
|
thd->reset_db(NULL, 0);
|
||||||
thd->db_length= 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
thd->reset_db(dbname, db_length); // THD::~THD will free this
|
||||||
thd->db= dbname; // THD::~THD will free this
|
|
||||||
thd->db_length= db_length;
|
|
||||||
}
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
if (!no_access_check)
|
if (!no_access_check)
|
||||||
sctx->db_access= db_access;
|
sctx->db_access= db_access;
|
||||||
|
@ -312,9 +312,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
{
|
{
|
||||||
if (thd->locked_tables)
|
if (thd->locked_tables)
|
||||||
{
|
{
|
||||||
if (find_locked_table(thd,
|
DBUG_ASSERT(table_list->db); /* Must be set in the parser */
|
||||||
table_list->db ? table_list->db : thd->db,
|
if (find_locked_table(thd, table_list->db, table_list->table_name))
|
||||||
table_list->table_name))
|
|
||||||
{
|
{
|
||||||
my_error(ER_DELAYED_INSERT_TABLE_LOCKED, MYF(0),
|
my_error(ER_DELAYED_INSERT_TABLE_LOCKED, MYF(0),
|
||||||
table_list->table_name);
|
table_list->table_name);
|
||||||
@ -1401,8 +1400,8 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
|
|||||||
TABLE *table;
|
TABLE *table;
|
||||||
DBUG_ENTER("delayed_get_table");
|
DBUG_ENTER("delayed_get_table");
|
||||||
|
|
||||||
if (!table_list->db)
|
/* Must be set in the parser */
|
||||||
table_list->db=thd->db;
|
DBUG_ASSERT(table_list->db);
|
||||||
|
|
||||||
/* Find the thread which handles this table. */
|
/* Find the thread which handles this table. */
|
||||||
if (!(tmp=find_handler(thd,table_list)))
|
if (!(tmp=find_handler(thd,table_list)))
|
||||||
@ -1429,15 +1428,15 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
|
|||||||
pthread_mutex_lock(&LOCK_thread_count);
|
pthread_mutex_lock(&LOCK_thread_count);
|
||||||
thread_count++;
|
thread_count++;
|
||||||
pthread_mutex_unlock(&LOCK_thread_count);
|
pthread_mutex_unlock(&LOCK_thread_count);
|
||||||
if (!(tmp->thd.db=my_strdup(table_list->db,MYF(MY_WME))) ||
|
tmp->thd.set_db(table_list->db, strlen(table_list->db));
|
||||||
!(tmp->thd.query=my_strdup(table_list->table_name,MYF(MY_WME))))
|
tmp->thd.query= my_strdup(table_list->table_name,MYF(MY_WME));
|
||||||
|
if (tmp->thd.db == NULL || tmp->thd.query == NULL)
|
||||||
{
|
{
|
||||||
delete tmp;
|
delete tmp;
|
||||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
tmp->table_list= *table_list; // Needed to open table
|
tmp->table_list= *table_list; // Needed to open table
|
||||||
tmp->table_list.db= tmp->thd.db;
|
|
||||||
tmp->table_list.alias= tmp->table_list.table_name= tmp->thd.query;
|
tmp->table_list.alias= tmp->table_list.table_name= tmp->thd.query;
|
||||||
tmp->lock();
|
tmp->lock();
|
||||||
pthread_mutex_lock(&tmp->mutex);
|
pthread_mutex_lock(&tmp->mutex);
|
||||||
|
@ -808,6 +808,11 @@ public:
|
|||||||
*this= *state;
|
*this= *state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Direct addition to the list of query tables.
|
||||||
|
If you are using this function, you must ensure that the table
|
||||||
|
object, in particular table->db member, is initialized.
|
||||||
|
*/
|
||||||
void add_to_query_tables(TABLE_LIST *table)
|
void add_to_query_tables(TABLE_LIST *table)
|
||||||
{
|
{
|
||||||
*(table->prev_global= query_tables_last)= table;
|
*(table->prev_global= query_tables_last)= table;
|
||||||
|
210
sql/sql_parse.cc
210
sql/sql_parse.cc
@ -111,8 +111,6 @@ const char *xa_state_names[]={
|
|||||||
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
|
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
|
||||||
};
|
};
|
||||||
|
|
||||||
static char empty_c_string[1]= {0}; // Used for not defined 'db'
|
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
static void test_signal(int sig_ptr)
|
static void test_signal(int sig_ptr)
|
||||||
{
|
{
|
||||||
@ -315,8 +313,7 @@ int check_user(THD *thd, enum enum_server_command command,
|
|||||||
thd->db is saved in caller and needs to be freed by caller if this
|
thd->db is saved in caller and needs to be freed by caller if this
|
||||||
function returns 0
|
function returns 0
|
||||||
*/
|
*/
|
||||||
thd->db= 0;
|
thd->reset_db(NULL, 0);
|
||||||
thd->db_length= 0;
|
|
||||||
if (mysql_change_db(thd, db, FALSE))
|
if (mysql_change_db(thd, db, FALSE))
|
||||||
{
|
{
|
||||||
/* Send the error to the client */
|
/* Send the error to the client */
|
||||||
@ -356,9 +353,8 @@ int check_user(THD *thd, enum enum_server_command command,
|
|||||||
if connect failed. Also in case of 'CHANGE USER' failure, current
|
if connect failed. Also in case of 'CHANGE USER' failure, current
|
||||||
database will be switched to 'no database selected'.
|
database will be switched to 'no database selected'.
|
||||||
*/
|
*/
|
||||||
thd->db= 0;
|
thd->reset_db(NULL, 0);
|
||||||
thd->db_length= 0;
|
|
||||||
|
|
||||||
USER_RESOURCES ur;
|
USER_RESOURCES ur;
|
||||||
int res= acl_getroot(thd, &ur, passwd, passwd_len);
|
int res= acl_getroot(thd, &ur, passwd, passwd_len);
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
@ -1365,19 +1361,6 @@ end:
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This works because items are allocated with sql_alloc() */
|
|
||||||
|
|
||||||
void free_items(Item *item)
|
|
||||||
{
|
|
||||||
Item *next;
|
|
||||||
DBUG_ENTER("free_items");
|
|
||||||
for (; item ; item=next)
|
|
||||||
{
|
|
||||||
next=item->next;
|
|
||||||
item->delete_self();
|
|
||||||
}
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This works because items are allocated with sql_alloc() */
|
/* This works because items are allocated with sql_alloc() */
|
||||||
|
|
||||||
@ -1389,7 +1372,26 @@ void cleanup_items(Item *item)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
|
/*
|
||||||
|
Handle COM_TABLE_DUMP command
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
mysql_table_dump
|
||||||
|
thd thread handle
|
||||||
|
db database name or an empty string. If empty,
|
||||||
|
the current database of the connection is used
|
||||||
|
tbl_name name of the table to dump
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
This function is written to handle one specific command only.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 success
|
||||||
|
1 error, the error message is set in THD
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
int mysql_table_dump(THD* thd, char* db, char* tbl_name)
|
||||||
{
|
{
|
||||||
TABLE* table;
|
TABLE* table;
|
||||||
TABLE_LIST* table_list;
|
TABLE_LIST* table_list;
|
||||||
@ -1426,7 +1428,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
net_flush(&thd->net);
|
net_flush(&thd->net);
|
||||||
if ((error= table->file->dump(thd,fd)))
|
if ((error= table->file->dump(thd,-1)))
|
||||||
my_error(ER_GET_ERRNO, MYF(0), error);
|
my_error(ER_GET_ERRNO, MYF(0), error);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -1678,7 +1680,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
}
|
}
|
||||||
tbl_name= strmake(db, packet + 1, db_len)+1;
|
tbl_name= strmake(db, packet + 1, db_len)+1;
|
||||||
strmake(tbl_name, packet + db_len + 2, tbl_len);
|
strmake(tbl_name, packet + db_len + 2, tbl_len);
|
||||||
mysql_table_dump(thd, db, tbl_name, -1);
|
mysql_table_dump(thd, db, tbl_name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COM_CHANGE_USER:
|
case COM_CHANGE_USER:
|
||||||
@ -1853,11 +1855,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
|
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
|
||||||
&LOCK_status);
|
&LOCK_status);
|
||||||
bzero((char*) &table_list,sizeof(table_list));
|
bzero((char*) &table_list,sizeof(table_list));
|
||||||
if (!(table_list.db=thd->db))
|
if (thd->copy_db_to(&table_list.db, 0))
|
||||||
{
|
|
||||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
pend= strend(packet);
|
pend= strend(packet);
|
||||||
thd->convert_string(&conv_name, system_charset_info,
|
thd->convert_string(&conv_name, system_charset_info,
|
||||||
packet, (uint) (pend-packet), thd->charset());
|
packet, (uint) (pend-packet), thd->charset());
|
||||||
@ -2205,6 +2204,34 @@ void log_slow_statement(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
prepare_schema_table()
|
||||||
|
thd thread handle
|
||||||
|
lex current lex
|
||||||
|
table_ident table alias if it's used
|
||||||
|
schema_table_idx the type of the INFORMATION_SCHEMA table to be
|
||||||
|
created
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function is used in the parser to convert a SHOW or DESCRIBE
|
||||||
|
table_name command to a SELECT from INFORMATION_SCHEMA.
|
||||||
|
It prepares a SELECT_LEX and a TABLE_LIST object to represent the
|
||||||
|
given command as a SELECT parse tree.
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Due to the way this function works with memory and LEX it cannot
|
||||||
|
be used outside the parser (parse tree transformations outside
|
||||||
|
the parser break PS and SP).
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 success
|
||||||
|
1 out of memory or SHOW commands are not allowed
|
||||||
|
in this version of the server.
|
||||||
|
*/
|
||||||
|
|
||||||
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
||||||
enum enum_schema_tables schema_table_idx)
|
enum enum_schema_tables schema_table_idx)
|
||||||
{
|
{
|
||||||
@ -2233,13 +2260,13 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
char *db= lex->select_lex.db ? lex->select_lex.db : thd->db;
|
char *db;
|
||||||
if (!db)
|
if (lex->select_lex.db == NULL &&
|
||||||
|
thd->copy_db_to(&lex->select_lex.db, 0))
|
||||||
{
|
{
|
||||||
my_message(ER_NO_DB_ERROR,
|
DBUG_RETURN(1);
|
||||||
ER(ER_NO_DB_ERROR), MYF(0)); /* purecov: inspected */
|
|
||||||
DBUG_RETURN(1); /* purecov: inspected */
|
|
||||||
}
|
}
|
||||||
|
db= lex->select_lex.db;
|
||||||
remove_escape(db); // Fix escaped '_'
|
remove_escape(db); // Fix escaped '_'
|
||||||
if (check_db_name(db))
|
if (check_db_name(db))
|
||||||
{
|
{
|
||||||
@ -2256,11 +2283,6 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
|||||||
db);
|
db);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
We need to do a copy to make this prepared statement safe if this
|
|
||||||
was thd->db
|
|
||||||
*/
|
|
||||||
lex->select_lex.db= thd->strdup(db);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2797,8 +2819,8 @@ mysql_execute_command(THD *thd)
|
|||||||
case SQLCOM_LOAD_MASTER_TABLE:
|
case SQLCOM_LOAD_MASTER_TABLE:
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
if (!first_table->db)
|
DBUG_ASSERT(first_table->db); /* Must be set in the parser */
|
||||||
first_table->db= thd->db;
|
|
||||||
if (check_access(thd, CREATE_ACL, first_table->db,
|
if (check_access(thd, CREATE_ACL, first_table->db,
|
||||||
&first_table->grant.privilege, 0, 0,
|
&first_table->grant.privilege, 0, 0,
|
||||||
test(first_table->schema_table)))
|
test(first_table->schema_table)))
|
||||||
@ -3053,25 +3075,8 @@ end_with_restore_list:
|
|||||||
my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name);
|
my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (!select_lex->db)
|
/* Must be set in the parser */
|
||||||
{
|
DBUG_ASSERT(select_lex->db);
|
||||||
/*
|
|
||||||
In the case of ALTER TABLE ... RENAME we should supply the
|
|
||||||
default database if the new name is not explicitly qualified
|
|
||||||
by a database. (Bug #11493)
|
|
||||||
*/
|
|
||||||
if (lex->alter_info.flags & ALTER_RENAME)
|
|
||||||
{
|
|
||||||
if (! thd->db)
|
|
||||||
{
|
|
||||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
select_lex->db= thd->db;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
select_lex->db= first_table->db;
|
|
||||||
}
|
|
||||||
if (check_access(thd, priv_needed, first_table->db,
|
if (check_access(thd, priv_needed, first_table->db,
|
||||||
&first_table->grant.privilege, 0, 0,
|
&first_table->grant.privilege, 0, 0,
|
||||||
test(first_table->schema_table)) ||
|
test(first_table->schema_table)) ||
|
||||||
@ -3824,12 +3829,8 @@ end_with_restore_list:
|
|||||||
}
|
}
|
||||||
case SQLCOM_ALTER_DB:
|
case SQLCOM_ALTER_DB:
|
||||||
{
|
{
|
||||||
char *db= lex->name ? lex->name : thd->db;
|
char *db= lex->name;
|
||||||
if (!db)
|
DBUG_ASSERT(db); /* Must be set in the parser */
|
||||||
{
|
|
||||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strip_sp(db) || check_db_name(db))
|
if (!strip_sp(db) || check_db_name(db))
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_DB_NAME, MYF(0), db);
|
my_error(ER_WRONG_DB_NAME, MYF(0), db);
|
||||||
@ -4364,23 +4365,11 @@ end_with_restore_list:
|
|||||||
case SQLCOM_CREATE_SPFUNCTION:
|
case SQLCOM_CREATE_SPFUNCTION:
|
||||||
{
|
{
|
||||||
uint namelen;
|
uint namelen;
|
||||||
char *name, *db;
|
char *name;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
DBUG_ASSERT(lex->sphead != 0);
|
DBUG_ASSERT(lex->sphead != 0);
|
||||||
|
DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
|
||||||
if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
|
|
||||||
{
|
|
||||||
if (!thd->db)
|
|
||||||
{
|
|
||||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
|
||||||
delete lex->sphead;
|
|
||||||
lex->sphead= 0;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
lex->sphead->m_db.length= strlen(thd->db);
|
|
||||||
lex->sphead->m_db.str= thd->db;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)))
|
||||||
@ -4497,34 +4486,17 @@ end_with_restore_list:
|
|||||||
}
|
}
|
||||||
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||||
|
|
||||||
/*
|
|
||||||
We need to copy name and db in order to use them for
|
|
||||||
check_routine_access which is called after lex->sphead has
|
|
||||||
been deleted.
|
|
||||||
*/
|
|
||||||
name= thd->strdup(name);
|
|
||||||
lex->sphead->m_db.str= db= thd->strmake(lex->sphead->m_db.str,
|
|
||||||
lex->sphead->m_db.length);
|
|
||||||
res= (result= lex->sphead->create(thd));
|
res= (result= lex->sphead->create(thd));
|
||||||
if (result == SP_OK)
|
if (result == SP_OK)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
We must cleanup the unit and the lex here because
|
|
||||||
sp_grant_privileges calls (indirectly) db_find_routine,
|
|
||||||
which in turn may call MYSQLparse with THD::lex.
|
|
||||||
TODO: fix db_find_routine to use a temporary lex.
|
|
||||||
*/
|
|
||||||
lex->unit.cleanup();
|
|
||||||
delete lex->sphead;
|
|
||||||
lex->sphead= 0;
|
|
||||||
#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,
|
||||||
db, name,
|
lex->sphead->m_db.str, name,
|
||||||
lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
|
lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
|
||||||
{
|
{
|
||||||
if (sp_grant_privileges(thd, db, 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,
|
||||||
@ -4532,6 +4504,9 @@ end_with_restore_list:
|
|||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
lex->unit.cleanup();
|
||||||
|
delete lex->sphead;
|
||||||
|
lex->sphead= 0;
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -4948,7 +4923,8 @@ end_with_restore_list:
|
|||||||
view_store_options(thd, first_table, &buff);
|
view_store_options(thd, first_table, &buff);
|
||||||
buff.append(STRING_WITH_LEN("VIEW "));
|
buff.append(STRING_WITH_LEN("VIEW "));
|
||||||
/* Test if user supplied a db (ie: we did not use thd->db) */
|
/* Test if user supplied a db (ie: we did not use thd->db) */
|
||||||
if (first_table->db != thd->db && first_table->db[0])
|
if (first_table->db && first_table->db[0] &&
|
||||||
|
(thd->db == NULL || strcmp(first_table->db, thd->db)))
|
||||||
{
|
{
|
||||||
append_identifier(thd, &buff, first_table->db,
|
append_identifier(thd, &buff, first_table->db,
|
||||||
first_table->db_length);
|
first_table->db_length);
|
||||||
@ -5612,7 +5588,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||||||
(want_access & ~EXTRA_ACL) &&
|
(want_access & ~EXTRA_ACL) &&
|
||||||
thd->db)
|
thd->db)
|
||||||
tables->grant.privilege= want_access;
|
tables->grant.privilege= want_access;
|
||||||
else if (tables->db && tables->db == thd->db)
|
else if (tables->db && thd->db && strcmp(tables->db, thd->db) == 0)
|
||||||
{
|
{
|
||||||
if (found && !grant_option) // db already checked
|
if (found && !grant_option) // db already checked
|
||||||
tables->grant.privilege=found_access;
|
tables->grant.privilege=found_access;
|
||||||
@ -5760,22 +5736,25 @@ bool check_merge_table_access(THD *thd, char *db,
|
|||||||
|
|
||||||
static bool check_db_used(THD *thd,TABLE_LIST *tables)
|
static bool check_db_used(THD *thd,TABLE_LIST *tables)
|
||||||
{
|
{
|
||||||
|
char *current_db= NULL;
|
||||||
for (; tables; tables= tables->next_global)
|
for (; tables; tables= tables->next_global)
|
||||||
{
|
{
|
||||||
if (!tables->db)
|
if (tables->db == NULL)
|
||||||
{
|
{
|
||||||
if (!(tables->db=thd->db))
|
/*
|
||||||
{
|
This code never works and should be removed in 5.1. All tables
|
||||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
|
that are added to the list of tables should already have its
|
||||||
MYF(0)); /* purecov: tested */
|
database field initialized properly (see st_lex::add_table_to_list).
|
||||||
return TRUE; /* purecov: tested */
|
*/
|
||||||
}
|
DBUG_ASSERT(0);
|
||||||
|
if (thd->copy_db_to(¤t_db, 0))
|
||||||
|
return TRUE;
|
||||||
|
tables->db= current_db;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Check stack size; Send error if there isn't enough stack to continue
|
Check stack size; Send error if there isn't enough stack to continue
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -6417,19 +6396,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
ptr->db= table->db.str;
|
ptr->db= table->db.str;
|
||||||
ptr->db_length= table->db.length;
|
ptr->db_length= table->db.length;
|
||||||
}
|
}
|
||||||
else if (thd->db)
|
else if (thd->copy_db_to(&ptr->db, &ptr->db_length))
|
||||||
{
|
DBUG_RETURN(0);
|
||||||
ptr->db= thd->db;
|
|
||||||
ptr->db_length= thd->db_length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The following can't be "" as we may do 'casedn_str()' on it */
|
|
||||||
ptr->db= empty_c_string;
|
|
||||||
ptr->db_length= 0;
|
|
||||||
}
|
|
||||||
if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
|
|
||||||
ptr->db= thd->strdup(ptr->db);
|
|
||||||
|
|
||||||
ptr->alias= alias_str;
|
ptr->alias= alias_str;
|
||||||
if (lower_case_table_names && table->table.length)
|
if (lower_case_table_names && table->table.length)
|
||||||
@ -7646,6 +7614,8 @@ bool insert_precheck(THD *thd, TABLE_LIST *tables)
|
|||||||
my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
|
my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
if (check_db_used(thd, tables))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4406,7 +4406,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||||||
{
|
{
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
src_db= table_ident->db.str ? table_ident->db.str : thd->db;
|
DBUG_ASSERT(table_ident->db.str); /* Must be set in the parser */
|
||||||
|
src_db= table_ident->db.str;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Validate the source table
|
Validate the source table
|
||||||
|
@ -928,8 +928,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
|||||||
|
|
||||||
save_db.str= thd->db;
|
save_db.str= thd->db;
|
||||||
save_db.length= thd->db_length;
|
save_db.length= thd->db_length;
|
||||||
thd->db_length= strlen(db);
|
thd->reset_db((char*) db, strlen(db));
|
||||||
thd->db= (char *) db;
|
|
||||||
while ((trg_create_str= it++))
|
while ((trg_create_str= it++))
|
||||||
{
|
{
|
||||||
trg_sql_mode= itm++;
|
trg_sql_mode= itm++;
|
||||||
@ -1031,8 +1030,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
|||||||
|
|
||||||
lex_end(&lex);
|
lex_end(&lex);
|
||||||
}
|
}
|
||||||
thd->db= save_db.str;
|
thd->reset_db(save_db.str, save_db.length);
|
||||||
thd->db_length= save_db.length;
|
|
||||||
thd->lex= old_lex;
|
thd->lex= old_lex;
|
||||||
thd->spcont= save_spcont;
|
thd->spcont= save_spcont;
|
||||||
thd->variables.sql_mode= save_sql_mode;
|
thd->variables.sql_mode= save_sql_mode;
|
||||||
@ -1045,8 +1043,7 @@ err_with_lex_cleanup:
|
|||||||
thd->lex= old_lex;
|
thd->lex= old_lex;
|
||||||
thd->spcont= save_spcont;
|
thd->spcont= save_spcont;
|
||||||
thd->variables.sql_mode= save_sql_mode;
|
thd->variables.sql_mode= save_sql_mode;
|
||||||
thd->db= save_db.str;
|
thd->reset_db(save_db.str, save_db.length);
|
||||||
thd->db_length= save_db.length;
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,8 @@ void udf_init()
|
|||||||
READ_RECORD read_record_info;
|
READ_RECORD read_record_info;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
int error;
|
int error;
|
||||||
DBUG_ENTER("udf_init");
|
DBUG_ENTER("ufd_init");
|
||||||
|
char db[]= "mysql"; /* A subject to casednstr, can't be constant */
|
||||||
|
|
||||||
if (initialized)
|
if (initialized)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -135,13 +136,12 @@ void udf_init()
|
|||||||
initialized = 1;
|
initialized = 1;
|
||||||
new_thd->thread_stack= (char*) &new_thd;
|
new_thd->thread_stack= (char*) &new_thd;
|
||||||
new_thd->store_globals();
|
new_thd->store_globals();
|
||||||
new_thd->db= my_strdup("mysql", MYF(0));
|
new_thd->set_db(db, sizeof(db)-1);
|
||||||
new_thd->db_length=5;
|
|
||||||
|
|
||||||
bzero((gptr) &tables,sizeof(tables));
|
bzero((gptr) &tables,sizeof(tables));
|
||||||
tables.alias= tables.table_name= (char*) "func";
|
tables.alias= tables.table_name= (char*) "func";
|
||||||
tables.lock_type = TL_READ;
|
tables.lock_type = TL_READ;
|
||||||
tables.db=new_thd->db;
|
tables.db= db;
|
||||||
|
|
||||||
if (simple_open_n_lock_tables(new_thd, &tables))
|
if (simple_open_n_lock_tables(new_thd, &tables))
|
||||||
{
|
{
|
||||||
|
@ -452,15 +452,15 @@ bool mysql_create_view(THD *thd,
|
|||||||
*/
|
*/
|
||||||
for (sl= select_lex; sl; sl= sl->next_select())
|
for (sl= select_lex; sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
char *db= view->db ? view->db : thd->db;
|
DBUG_ASSERT(view->db); /* Must be set in the parser */
|
||||||
List_iterator_fast<Item> it(sl->item_list);
|
List_iterator_fast<Item> it(sl->item_list);
|
||||||
Item *item;
|
Item *item;
|
||||||
fill_effective_table_privileges(thd, &view->grant, db,
|
fill_effective_table_privileges(thd, &view->grant, view->db,
|
||||||
view->table_name);
|
view->table_name);
|
||||||
while ((item= it++))
|
while ((item= it++))
|
||||||
{
|
{
|
||||||
Item_field *fld;
|
Item_field *fld;
|
||||||
uint priv= (get_column_grant(thd, &view->grant, db,
|
uint priv= (get_column_grant(thd, &view->grant, view->db,
|
||||||
view->table_name, item->name) &
|
view->table_name, item->name) &
|
||||||
VIEW_ANY_ACL);
|
VIEW_ANY_ACL);
|
||||||
if ((fld= item->filed_for_view_update()))
|
if ((fld= item->filed_for_view_update()))
|
||||||
@ -643,8 +643,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
|||||||
|
|
||||||
if (!parser->ok() || !is_equal(&view_type, parser->type()))
|
if (!parser->ok() || !is_equal(&view_type, parser->type()))
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_OBJECT, MYF(0),
|
my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
|
||||||
(view->db ? view->db : thd->db), view->table_name, "VIEW");
|
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1594,12 +1594,18 @@ sp_name:
|
|||||||
}
|
}
|
||||||
| ident
|
| ident
|
||||||
{
|
{
|
||||||
|
THD *thd= YYTHD;
|
||||||
|
LEX_STRING db;
|
||||||
if (check_routine_name($1))
|
if (check_routine_name($1))
|
||||||
{
|
{
|
||||||
my_error(ER_SP_WRONG_NAME, MYF(0), $1.str);
|
my_error(ER_SP_WRONG_NAME, MYF(0), $1.str);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
$$= sp_name_current_db_new(YYTHD, $1);
|
if (thd->copy_db_to(&db.str, &db.length))
|
||||||
|
YYABORT;
|
||||||
|
$$= new sp_name(db, $1);
|
||||||
|
if ($$)
|
||||||
|
$$->init_qname(YYTHD);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -3184,14 +3190,26 @@ create2:
|
|||||||
| LIKE table_ident
|
| LIKE table_ident
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
THD *thd= lex->thd;
|
||||||
if (!(lex->like_name= $2))
|
if (!(lex->like_name= $2))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
if ($2->db.str == NULL &&
|
||||||
|
thd->copy_db_to(&($2->db.str), &($2->db.length)))
|
||||||
|
{
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| '(' LIKE table_ident ')'
|
| '(' LIKE table_ident ')'
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
THD *thd= lex->thd;
|
||||||
if (!(lex->like_name= $3))
|
if (!(lex->like_name= $3))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
if ($3->db.str == NULL &&
|
||||||
|
thd->copy_db_to(&($3->db.str), &($3->db.length)))
|
||||||
|
{
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -4640,8 +4658,10 @@ alter:
|
|||||||
lex->key_list.empty();
|
lex->key_list.empty();
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
lex->select_lex.init_order();
|
lex->select_lex.init_order();
|
||||||
lex->select_lex.db=lex->name= 0;
|
lex->name= 0;
|
||||||
lex->like_name= 0;
|
lex->like_name= 0;
|
||||||
|
lex->select_lex.db=
|
||||||
|
((TABLE_LIST*) lex->select_lex.table_list.first)->db;
|
||||||
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
||||||
lex->create_info.db_type= 0;
|
lex->create_info.db_type= 0;
|
||||||
lex->create_info.default_table_charset= NULL;
|
lex->create_info.default_table_charset= NULL;
|
||||||
@ -4660,8 +4680,11 @@ alter:
|
|||||||
opt_create_database_options
|
opt_create_database_options
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
THD *thd= Lex->thd;
|
||||||
lex->sql_command=SQLCOM_ALTER_DB;
|
lex->sql_command=SQLCOM_ALTER_DB;
|
||||||
lex->name= $3;
|
lex->name= $3;
|
||||||
|
if (lex->name == NULL && thd->copy_db_to(&lex->name, NULL))
|
||||||
|
YYABORT;
|
||||||
}
|
}
|
||||||
| ALTER PROCEDURE sp_name
|
| ALTER PROCEDURE sp_name
|
||||||
{
|
{
|
||||||
@ -5096,14 +5119,20 @@ alter_list_item:
|
|||||||
| RENAME opt_to table_ident
|
| RENAME opt_to table_ident
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
THD *thd= lex->thd;
|
||||||
lex->select_lex.db=$3->db.str;
|
lex->select_lex.db=$3->db.str;
|
||||||
lex->name= $3->table.str;
|
if (lex->select_lex.db == NULL &&
|
||||||
|
thd->copy_db_to(&lex->select_lex.db, NULL))
|
||||||
|
{
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
if (check_table_name($3->table.str,$3->table.length) ||
|
if (check_table_name($3->table.str,$3->table.length) ||
|
||||||
$3->db.str && check_db_name($3->db.str))
|
$3->db.str && check_db_name($3->db.str))
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
|
my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
|
lex->name= $3->table.str;
|
||||||
lex->alter_info.flags|= ALTER_RENAME;
|
lex->alter_info.flags|= ALTER_RENAME;
|
||||||
}
|
}
|
||||||
| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
|
| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
|
||||||
@ -6449,7 +6478,13 @@ simple_expr:
|
|||||||
#endif /* HAVE_DLOPEN */
|
#endif /* HAVE_DLOPEN */
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_name *name= sp_name_current_db_new(YYTHD, $1);
|
THD *thd= lex->thd;
|
||||||
|
LEX_STRING db;
|
||||||
|
if (thd->copy_db_to(&db.str, &db.length))
|
||||||
|
YYABORT;
|
||||||
|
sp_name *name= new sp_name(db, $1);
|
||||||
|
if (name)
|
||||||
|
name->init_qname(thd);
|
||||||
|
|
||||||
sp_add_used_routine(lex, YYTHD, name, TYPE_ENUM_FUNCTION);
|
sp_add_used_routine(lex, YYTHD, name, TYPE_ENUM_FUNCTION);
|
||||||
if ($4)
|
if ($4)
|
||||||
@ -10328,7 +10363,9 @@ grant_ident:
|
|||||||
'*'
|
'*'
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->current_select->db= lex->thd->db;
|
THD *thd= lex->thd;
|
||||||
|
if (thd->copy_db_to(&lex->current_select->db, NULL))
|
||||||
|
YYABORT;
|
||||||
if (lex->grant == GLOBAL_ACLS)
|
if (lex->grant == GLOBAL_ACLS)
|
||||||
lex->grant = DB_ACLS & ~GRANT_ACL;
|
lex->grant = DB_ACLS & ~GRANT_ACL;
|
||||||
else if (lex->columns.elements)
|
else if (lex->columns.elements)
|
||||||
|
@ -695,7 +695,8 @@ typedef struct st_table_list
|
|||||||
thr_lock_type lock_type;
|
thr_lock_type lock_type;
|
||||||
uint outer_join; /* Which join type */
|
uint outer_join; /* Which join type */
|
||||||
uint shared; /* Used in multi-upd */
|
uint shared; /* Used in multi-upd */
|
||||||
uint32 db_length, table_name_length;
|
uint db_length;
|
||||||
|
uint32 table_name_length;
|
||||||
bool updatable; /* VIEW/TABLE can be updated now */
|
bool updatable; /* VIEW/TABLE can be updated now */
|
||||||
bool straight; /* optimize with prev table */
|
bool straight; /* optimize with prev table */
|
||||||
bool updating; /* for replicate-do/ignore table */
|
bool updating; /* for replicate-do/ignore table */
|
||||||
|
@ -1560,6 +1560,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
|
|||||||
TABLE *table;
|
TABLE *table;
|
||||||
Tz_names_entry *tmp_tzname;
|
Tz_names_entry *tmp_tzname;
|
||||||
my_bool return_val= 1;
|
my_bool return_val= 1;
|
||||||
|
char db[]= "mysql";
|
||||||
int res;
|
int res;
|
||||||
DBUG_ENTER("my_tz_init");
|
DBUG_ENTER("my_tz_init");
|
||||||
|
|
||||||
@ -1616,13 +1617,12 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
|
|||||||
leap seconds shared by all time zones.
|
leap seconds shared by all time zones.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
thd->db= my_strdup("mysql",MYF(0));
|
thd->set_db(db, sizeof(db)-1);
|
||||||
thd->db_length= 5; // Safety
|
|
||||||
bzero((char*) &tables_buff, sizeof(TABLE_LIST));
|
bzero((char*) &tables_buff, sizeof(TABLE_LIST));
|
||||||
tables_buff[0].alias= tables_buff[0].table_name=
|
tables_buff[0].alias= tables_buff[0].table_name=
|
||||||
(char*)"time_zone_leap_second";
|
(char*)"time_zone_leap_second";
|
||||||
tables_buff[0].lock_type= TL_READ;
|
tables_buff[0].lock_type= TL_READ;
|
||||||
tables_buff[0].db= thd->db;
|
tables_buff[0].db= db;
|
||||||
/*
|
/*
|
||||||
Fill TABLE_LIST for the rest of the time zone describing tables
|
Fill TABLE_LIST for the rest of the time zone describing tables
|
||||||
and link it to first one.
|
and link it to first one.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user