mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
Merge emurphy@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into mysql.com:/home/emurphy/src/bk-clean/mysql-5.1-new
This commit is contained in:
commit
a9ca1339d5
62 changed files with 1401 additions and 415 deletions
|
@ -72,6 +72,7 @@ static int port= 0;
|
|||
static const char* sock= 0;
|
||||
static const char* user = 0;
|
||||
static char* pass = 0;
|
||||
static char *charset= 0;
|
||||
|
||||
static ulonglong start_position, stop_position;
|
||||
#define start_position_mot ((my_off_t)start_position)
|
||||
|
@ -733,6 +734,9 @@ static struct my_option my_long_options[] =
|
|||
"Extract only binlog entries created by the server having the given id.",
|
||||
(gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"set-charset", OPT_SET_CHARSET,
|
||||
"Add 'SET NAMES character_set' to the output.", (gptr*) &charset,
|
||||
(gptr*) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"short-form", 's', "Just show the queries, no extra info.",
|
||||
(gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
|
||||
0, 0},
|
||||
|
@ -1457,6 +1461,13 @@ int main(int argc, char** argv)
|
|||
"/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,"
|
||||
"COMPLETION_TYPE=0*/;\n");
|
||||
|
||||
if (charset)
|
||||
fprintf(result_file,
|
||||
"\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
|
||||
"\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
|
||||
"\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
|
||||
"\n/*!40101 SET NAMES %s */;\n", charset);
|
||||
|
||||
for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ;
|
||||
(--argc >= 0) && !stop_passed ; )
|
||||
{
|
||||
|
@ -1481,6 +1492,12 @@ int main(int argc, char** argv)
|
|||
if (disable_log_bin)
|
||||
fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n");
|
||||
|
||||
if (charset)
|
||||
fprintf(result_file,
|
||||
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
|
||||
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
|
||||
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
|
||||
|
||||
if (tmpdir.list)
|
||||
free_tmpdir(&tmpdir);
|
||||
if (result_file != stdout)
|
||||
|
|
|
@ -3063,14 +3063,13 @@ static my_bool dump_all_views_in_db(char *database)
|
|||
different case (e.g. T1 vs t1)
|
||||
|
||||
RETURN
|
||||
int - 0 if a tablename was retrieved. 1 if not
|
||||
pointer to the table name
|
||||
0 if error
|
||||
*/
|
||||
|
||||
static int get_actual_table_name(const char *old_table_name,
|
||||
char *new_table_name,
|
||||
int buf_size)
|
||||
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
|
||||
{
|
||||
int retval;
|
||||
char *name= 0;
|
||||
MYSQL_RES *table_res;
|
||||
MYSQL_ROW row;
|
||||
char query[50 + 2*NAME_LEN];
|
||||
|
@ -3087,66 +3086,55 @@ static int get_actual_table_name(const char *old_table_name,
|
|||
safe_exit(EX_MYSQLERR);
|
||||
}
|
||||
|
||||
retval = 1;
|
||||
|
||||
if ((table_res= mysql_store_result(sock)))
|
||||
{
|
||||
my_ulonglong num_rows= mysql_num_rows(table_res);
|
||||
if (num_rows > 0)
|
||||
{
|
||||
ulong *lengths;
|
||||
/*
|
||||
Return first row
|
||||
TODO: Return all matching rows
|
||||
*/
|
||||
row= mysql_fetch_row(table_res);
|
||||
strmake(new_table_name, row[0], buf_size-1);
|
||||
retval= 0;
|
||||
lengths= mysql_fetch_lengths(table_res);
|
||||
name= strmake_root(root, row[0], lengths[0]);
|
||||
}
|
||||
mysql_free_result(table_res);
|
||||
}
|
||||
DBUG_RETURN(retval);
|
||||
DBUG_PRINT("exit", ("new_table_name: %s", name));
|
||||
DBUG_RETURN(name);
|
||||
}
|
||||
|
||||
|
||||
static int dump_selected_tables(char *db, char **table_names, int tables)
|
||||
{
|
||||
uint i;
|
||||
char table_buff[NAME_LEN*+3];
|
||||
char new_table_name[NAME_LEN];
|
||||
DYNAMIC_STRING lock_tables_query;
|
||||
HASH dump_tables;
|
||||
char *table_name;
|
||||
MEM_ROOT root;
|
||||
char **dump_tables, **pos, **end;
|
||||
DBUG_ENTER("dump_selected_tables");
|
||||
|
||||
if (init_dumping(db))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/* Init hash table for storing the actual name of tables to dump */
|
||||
if (hash_init(&dump_tables, charset_info, 16, 0, 0,
|
||||
(hash_get_key) get_table_key, (hash_free_key) free_table_ent,
|
||||
0))
|
||||
init_alloc_root(&root, 8192, 0);
|
||||
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
|
||||
exit(EX_EOM);
|
||||
|
||||
init_dynamic_string(&lock_tables_query, "LOCK TABLES ", 256, 1024);
|
||||
for (; tables > 0 ; tables-- , table_names++)
|
||||
{
|
||||
/* the table name passed on commandline may be wrong case */
|
||||
if (!get_actual_table_name(*table_names,
|
||||
new_table_name, sizeof(new_table_name)))
|
||||
if ((*pos= get_actual_table_name(*table_names, &root)))
|
||||
{
|
||||
/* Add found table name to lock_tables_query */
|
||||
if (lock_tables)
|
||||
{
|
||||
dynstr_append(&lock_tables_query,
|
||||
quote_name(new_table_name, table_buff, 1));
|
||||
dynstr_append(&lock_tables_query, quote_name(*pos, table_buff, 1));
|
||||
dynstr_append(&lock_tables_query, " READ /*!32311 LOCAL */,");
|
||||
}
|
||||
|
||||
/* Add found table name to dump_tables list */
|
||||
if (my_hash_insert(&dump_tables,
|
||||
(byte*)my_strdup(new_table_name, MYF(0))))
|
||||
exit(EX_EOM);
|
||||
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3156,6 +3144,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
|
|||
/* We shall countinue here, if --force was given */
|
||||
}
|
||||
}
|
||||
end= pos;
|
||||
|
||||
if (lock_tables)
|
||||
{
|
||||
|
@ -3175,24 +3164,20 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
|
|||
print_xml_tag1(md_result_file, "", "database name=", db, "\n");
|
||||
|
||||
/* Dump each selected table */
|
||||
for (i= 0; i < dump_tables.records; i++)
|
||||
for (pos= dump_tables; pos < end; pos++)
|
||||
{
|
||||
table_name= hash_element(&dump_tables, i);
|
||||
DBUG_PRINT("info",("Dumping table %s", table_name));
|
||||
dump_table(table_name,db);
|
||||
DBUG_PRINT("info",("Dumping table %s", *pos));
|
||||
dump_table(*pos, db);
|
||||
if (opt_dump_triggers &&
|
||||
mysql_get_server_version(sock) >= 50009)
|
||||
dump_triggers_for_table(table_name, db);
|
||||
dump_triggers_for_table(*pos, db);
|
||||
}
|
||||
|
||||
/* Dump each selected view */
|
||||
if (was_views)
|
||||
{
|
||||
for(i=0; i < dump_tables.records; i++)
|
||||
{
|
||||
table_name= hash_element(&dump_tables, i);
|
||||
get_view_structure(table_name, db);
|
||||
}
|
||||
for (pos= dump_tables; pos < end; pos++)
|
||||
get_view_structure(*pos, db);
|
||||
}
|
||||
if (opt_events && !opt_xml &&
|
||||
mysql_get_server_version(sock) >= 50106)
|
||||
|
@ -3207,7 +3192,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
|
|||
DBUG_PRINT("info", ("Dumping routines for database %s", db));
|
||||
dump_routines_for_db(db);
|
||||
}
|
||||
hash_free(&dump_tables);
|
||||
free_root(&root, MYF(0));
|
||||
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
|
||||
order_by= 0;
|
||||
if (opt_xml)
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#ifndef yaSSL_ERROR_HPP
|
||||
#define yaSSL_ERROR_HPP
|
||||
|
||||
#include "stdexcept.hpp"
|
||||
|
||||
|
||||
namespace yaSSL {
|
||||
|
@ -63,7 +62,7 @@ enum { MAX_ERROR_SZ = 80 };
|
|||
|
||||
void SetErrorString(YasslError, char*);
|
||||
|
||||
|
||||
/* remove for now, if go back to exceptions use this wrapper
|
||||
// Base class for all yaSSL exceptions
|
||||
class Error : public mySTL::runtime_error {
|
||||
YasslError error_;
|
||||
|
@ -75,6 +74,7 @@ public:
|
|||
YasslError get_number() const;
|
||||
Library get_lib() const;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
} // naemspace
|
||||
|
|
|
@ -46,10 +46,8 @@ public:
|
|||
// for compiler generated call, never used
|
||||
static void operator delete(void*) { assert(0); }
|
||||
private:
|
||||
#if defined(__hpux)
|
||||
// don't allow dynamic creation of exceptions
|
||||
static void* operator new(size_t);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
#include "yassl_error.hpp"
|
||||
#include "error.hpp" // TaoCrypt error numbers
|
||||
#include "openssl/ssl.h" // SSL_ERROR_WANT_READ
|
||||
#include <string.h> // strncpy
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
|
||||
/* may bring back in future
|
||||
Error::Error(const char* s, YasslError e, Library l)
|
||||
: mySTL::runtime_error(s), error_(e), lib_(l)
|
||||
{
|
||||
|
@ -48,6 +50,7 @@ Library Error::get_lib() const
|
|||
|
||||
return lib_;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void SetErrorString(YasslError error, char* buffer)
|
||||
|
|
|
@ -2106,9 +2106,14 @@ ASN1_STRING* StringHolder::GetString()
|
|||
extern "C" void yaSSL_CleanUp()
|
||||
{
|
||||
TaoCrypt::CleanUp();
|
||||
ysDelete(yaSSL::cryptProviderInstance);
|
||||
ysDelete(yaSSL::sslFactoryInstance);
|
||||
ysDelete(yaSSL::sessionsInstance);
|
||||
yaSSL::ysDelete(yaSSL::cryptProviderInstance);
|
||||
yaSSL::ysDelete(yaSSL::sslFactoryInstance);
|
||||
yaSSL::ysDelete(yaSSL::sessionsInstance);
|
||||
|
||||
// In case user calls more than once, prevent seg fault
|
||||
yaSSL::cryptProviderInstance = 0;
|
||||
yaSSL::sslFactoryInstance = 0;
|
||||
yaSSL::sessionsInstance = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2735,8 +2735,11 @@ void CleanUp()
|
|||
{
|
||||
tcDelete(one);
|
||||
tcDelete(zero);
|
||||
}
|
||||
|
||||
// In case user calls more than once, prevent seg fault
|
||||
one = 0;
|
||||
zero = 0;
|
||||
}
|
||||
|
||||
Integer::Integer(RandomNumberGenerator& rng, const Integer& min,
|
||||
const Integer& max)
|
||||
|
|
|
@ -81,6 +81,19 @@ extern "C" {
|
|||
|
||||
}
|
||||
|
||||
#if defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
|
||||
extern "C" {
|
||||
|
||||
int __cxa_pure_virtual() {
|
||||
assert("Pure virtual method called." == "Aborted");
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif
|
||||
|
||||
#endif // YASSL_PURE_C
|
||||
|
||||
|
||||
|
|
|
@ -396,6 +396,27 @@
|
|||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\md4.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
BasicRuntimeChecks="3"
|
||||
BrowseInformation="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\md5.cpp">
|
||||
<FileConfiguration
|
||||
|
@ -571,6 +592,9 @@
|
|||
<File
|
||||
RelativePath="include\md2.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="include\md4.hpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="include\md5.hpp">
|
||||
</File>
|
||||
|
|
|
@ -156,3 +156,5 @@ drop function bug15728_insert;
|
|||
drop table t1, t2;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
||||
sync_slave_with_master;
|
||||
|
|
|
@ -48,3 +48,10 @@ lock table t1 read, t2 read, t3 read;
|
|||
flush tables with read lock;
|
||||
unlock tables;
|
||||
drop table t1, t2, t3;
|
||||
create table t1 (c1 int);
|
||||
create table t2 (c1 int);
|
||||
lock table t1 write;
|
||||
flush tables with read lock;
|
||||
insert into t2 values(1);
|
||||
unlock tables;
|
||||
drop table t1, t2;
|
||||
|
|
|
@ -357,12 +357,12 @@ show grants for grant_user@localhost;
|
|||
Grants for grant_user@localhost
|
||||
GRANT USAGE ON *.* TO 'grant_user'@'localhost'
|
||||
GRANT INSERT (a, d, c, b) ON `test`.`t1` TO 'grant_user'@'localhost'
|
||||
select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv;
|
||||
select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv order by Column_name;
|
||||
Host Db User Table_name Column_name Column_priv
|
||||
localhost test grant_user t1 b Insert
|
||||
localhost test grant_user t1 d Insert
|
||||
localhost test grant_user t1 a Insert
|
||||
localhost test grant_user t1 b Insert
|
||||
localhost test grant_user t1 c Insert
|
||||
localhost test grant_user t1 d Insert
|
||||
revoke ALL PRIVILEGES on t1 from grant_user@localhost;
|
||||
show grants for grant_user@localhost;
|
||||
Grants for grant_user@localhost
|
||||
|
@ -381,13 +381,27 @@ grant update (a) on mysqltest_1.t1 to mysqltest_3@localhost;
|
|||
grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost;
|
||||
grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost;
|
||||
grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost;
|
||||
show grants for mysqltest_3@localhost;
|
||||
Grants for mysqltest_3@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost'
|
||||
GRANT SELECT (b) ON `mysqltest_1`.`t2` TO 'mysqltest_3'@'localhost'
|
||||
GRANT UPDATE (a) ON `mysqltest_1`.`t1` TO 'mysqltest_3'@'localhost'
|
||||
GRANT UPDATE (d) ON `mysqltest_2`.`t2` TO 'mysqltest_3'@'localhost'
|
||||
GRANT SELECT (c) ON `mysqltest_2`.`t1` TO 'mysqltest_3'@'localhost'
|
||||
SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES
|
||||
WHERE GRANTEE = '''mysqltest_3''@''localhost'''
|
||||
ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE;
|
||||
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE
|
||||
'mysqltest_3'@'localhost' NULL mysqltest_1 t1 a UPDATE NO
|
||||
'mysqltest_3'@'localhost' NULL mysqltest_2 t1 c SELECT NO
|
||||
'mysqltest_3'@'localhost' NULL mysqltest_1 t2 b SELECT NO
|
||||
'mysqltest_3'@'localhost' NULL mysqltest_2 t2 d UPDATE NO
|
||||
SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES
|
||||
WHERE GRANTEE = '''mysqltest_3''@''localhost'''
|
||||
ORDER BY TABLE_NAME,PRIVILEGE_TYPE;
|
||||
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
|
||||
SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES
|
||||
WHERE GRANTEE = '''mysqltest_3''@''localhost'''
|
||||
ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE;
|
||||
GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
|
||||
SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES
|
||||
WHERE GRANTEE = '''mysqltest_3''@''localhost'''
|
||||
ORDER BY TABLE_CATALOG,PRIVILEGE_TYPE;
|
||||
GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE
|
||||
'mysqltest_3'@'localhost' NULL USAGE NO
|
||||
update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1;
|
||||
ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for column 'q' in table 't1'
|
||||
update mysqltest_1.t2, mysqltest_2.t2 set d=20 where d=1;
|
||||
|
|
|
@ -1981,46 +1981,7 @@ a
|
|||
b
|
||||
c
|
||||
d
|
||||
create table t4 (
|
||||
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
|
||||
) engine=innodb;
|
||||
insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
|
||||
create index idx12672_0 on t4 (a1);
|
||||
create index idx12672_1 on t4 (a1,a2,b,c);
|
||||
create index idx12672_2 on t4 (a1,a2,b);
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Table is already up to date
|
||||
select distinct a1 from t4 where pk_col not in (1,2,3,4);
|
||||
a1
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
drop table t1,t2,t3,t4;
|
||||
create table t1 (
|
||||
a varchar(30), b varchar(30), primary key(a), key(b)
|
||||
) engine=innodb;
|
||||
select distinct a from t1;
|
||||
a
|
||||
drop table t1;
|
||||
create table t1(a int, key(a)) engine=innodb;
|
||||
insert into t1 values(1);
|
||||
select a, count(a) from t1 group by a with rollup;
|
||||
a count(a)
|
||||
1 1
|
||||
NULL 1
|
||||
drop table t1;
|
||||
create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb;
|
||||
insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d");
|
||||
alter table t1 drop primary key, add primary key (f2, f1);
|
||||
explain select distinct f1 a, f1 b from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary
|
||||
explain select distinct f1, f2 from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary
|
||||
drop table t1;
|
||||
drop table t1,t2,t3;
|
||||
create table t1 (c1 int not null,c2 int not null, primary key(c1,c2));
|
||||
insert into t1 (c1,c2) values
|
||||
(10,1),(10,2),(10,3),(20,4),(20,5),(20,6),(30,7),(30,8),(30,9);
|
||||
|
|
|
@ -256,3 +256,6 @@ SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE()
|
|||
INDEX_LENGTH
|
||||
21
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY;
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
drop table if exists t1,t2;
|
||||
drop view if exists v1,v2;
|
||||
drop function if exists f1;
|
||||
drop function if exists f2;
|
||||
use INFORMATION_SCHEMA;
|
||||
show tables;
|
||||
Tables_in_information_schema
|
||||
|
@ -31,10 +35,12 @@ TABLE_CONSTRAINTS
|
|||
TABLE_PRIVILEGES
|
||||
TRIGGERS
|
||||
create database `inf%`;
|
||||
create database mbase;
|
||||
use `inf%`;
|
||||
show tables;
|
||||
Tables_in_inf%
|
||||
grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost';
|
||||
grant all privileges on `mbase`.* to 'mysqltest_1'@'localhost';
|
||||
create table t1 (f1 int);
|
||||
create function func1(curr_int int) returns int
|
||||
begin
|
||||
|
@ -43,9 +49,58 @@ select max(f1) from t1 into ret_val;
|
|||
return ret_val;
|
||||
end|
|
||||
create view v1 as select f1 from t1 where f1 = func1(f1);
|
||||
create function func2() returns int return 1;
|
||||
use mbase;
|
||||
create procedure p1 ()
|
||||
begin
|
||||
select table_name from information_schema.key_column_usage
|
||||
order by table_name;
|
||||
end|
|
||||
create table t1
|
||||
(f1 int(10) unsigned not null,
|
||||
f2 varchar(100) not null,
|
||||
primary key (f1), unique key (f2));
|
||||
select * from information_schema.tables;
|
||||
call mbase.p1();
|
||||
call mbase.p1();
|
||||
call mbase.p1();
|
||||
use `inf%`;
|
||||
drop user mysqltest_1@localhost;
|
||||
drop table t1;
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='inf%' and func2();
|
||||
table_name table_type table_comment
|
||||
v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='inf%' and func2();
|
||||
table_name table_type table_comment
|
||||
v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define
|
||||
drop view v1;
|
||||
drop function func1;
|
||||
drop table t1;
|
||||
drop function func2;
|
||||
drop database `inf%`;
|
||||
drop procedure mbase.p1;
|
||||
drop database mbase;
|
||||
use test;
|
||||
create table t1 (i int);
|
||||
create function f1 () returns int return (select max(i) from t1);
|
||||
create view v1 as select f1();
|
||||
create table t2 (id int);
|
||||
create function f2 () returns int return (select max(i) from t2);
|
||||
create view v2 as select f2();
|
||||
drop table t2;
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='test';
|
||||
table_name table_type table_comment
|
||||
t1 BASE TABLE
|
||||
v1 VIEW VIEW
|
||||
v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
|
||||
drop table t1;
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='test';
|
||||
table_name table_type table_comment
|
||||
v1 VIEW View 'test.v1' references invalid table(s) or column(s) or function(s) or define
|
||||
v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop view v1, v2;
|
||||
|
|
|
@ -192,3 +192,79 @@ select count(*), min(7), max(7) from t2m, t1i;
|
|||
count(*) min(7) max(7)
|
||||
0 NULL NULL
|
||||
drop table t1m, t1i, t2m, t2i;
|
||||
create table t1 (
|
||||
a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
|
||||
);
|
||||
insert into t1 (a1, a2, b, c, d) values
|
||||
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
|
||||
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
|
||||
('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
|
||||
('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
|
||||
('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
|
||||
('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
|
||||
('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
|
||||
('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
|
||||
('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
|
||||
('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
|
||||
('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
|
||||
('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
|
||||
('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
|
||||
('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
|
||||
('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
|
||||
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
|
||||
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
|
||||
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
|
||||
('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
|
||||
('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
|
||||
('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
|
||||
('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
|
||||
('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
|
||||
('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
|
||||
('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
|
||||
('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
|
||||
('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
|
||||
('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
|
||||
('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
|
||||
('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
|
||||
('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
|
||||
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
|
||||
create table t4 (
|
||||
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
|
||||
) engine=innodb;
|
||||
insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
|
||||
create index idx12672_0 on t4 (a1);
|
||||
create index idx12672_1 on t4 (a1,a2,b,c);
|
||||
create index idx12672_2 on t4 (a1,a2,b);
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
select distinct a1 from t4 where pk_col not in (1,2,3,4);
|
||||
a1
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
drop table t1,t4;
|
||||
create table t1 (
|
||||
a varchar(30), b varchar(30), primary key(a), key(b)
|
||||
) engine=innodb;
|
||||
select distinct a from t1;
|
||||
a
|
||||
drop table t1;
|
||||
create table t1(a int, key(a)) engine=innodb;
|
||||
insert into t1 values(1);
|
||||
select a, count(a) from t1 group by a with rollup;
|
||||
a count(a)
|
||||
1 1
|
||||
NULL 1
|
||||
drop table t1;
|
||||
create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb;
|
||||
insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d");
|
||||
alter table t1 drop primary key, add primary key (f2, f1);
|
||||
explain select distinct f1 a, f1 b from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary
|
||||
explain select distinct f1, f2 from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary
|
||||
drop table t1;
|
||||
|
|
|
@ -50,3 +50,19 @@ Field Type Null Key Default Extra
|
|||
a int(11) YES NULL
|
||||
unlock tables;
|
||||
drop table t1;
|
||||
use mysql;
|
||||
LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
|
||||
FLUSH TABLES;
|
||||
use mysql;
|
||||
SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
|
||||
OPTIMIZE TABLES columns_priv, db, host, user;
|
||||
Table Op Msg_type Msg_text
|
||||
mysql.columns_priv optimize status OK
|
||||
mysql.db optimize status OK
|
||||
mysql.host optimize status OK
|
||||
mysql.user optimize status OK
|
||||
UNLOCK TABLES;
|
||||
Select_priv
|
||||
N
|
||||
use test;
|
||||
use test;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa;
|
||||
DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa, t3;
|
||||
drop database if exists mysqldump_test_db;
|
||||
drop database if exists db1;
|
||||
drop database if exists db2;
|
||||
|
@ -1509,6 +1509,7 @@ a b
|
|||
12 meg
|
||||
drop table t1, t2;
|
||||
drop database db1;
|
||||
--fields-optionally-enclosed-by="
|
||||
CREATE DATABASE mysqldump_test_db;
|
||||
USE mysqldump_test_db;
|
||||
CREATE TABLE t1 ( a INT );
|
||||
|
@ -1738,6 +1739,43 @@ t1 CREATE TABLE `t1` (
|
|||
KEY `t1_name` (`t1_name`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1
|
||||
drop table `t1`;
|
||||
create table t1(a int);
|
||||
create table t2(a int);
|
||||
create table t3(a int);
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
DROP TABLE IF EXISTS `t3`;
|
||||
CREATE TABLE `t3` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
DROP TABLE IF EXISTS `t1`;
|
||||
CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
DROP TABLE IF EXISTS `t2`;
|
||||
CREATE TABLE `t2` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
drop table t1, t2, t3;
|
||||
End of 4.1 tests
|
||||
create table t1 (a binary(1), b blob);
|
||||
insert into t1 values ('','');
|
||||
|
|
|
@ -4970,4 +4970,34 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|||
DROP FUNCTION bug18589_f1|
|
||||
DROP PROCEDURE bug18589_p1|
|
||||
DROP PROCEDURE bug18589_p2|
|
||||
DROP FUNCTION IF EXISTS bug18037_f1|
|
||||
DROP PROCEDURE IF EXISTS bug18037_p1|
|
||||
DROP PROCEDURE IF EXISTS bug18037_p2|
|
||||
CREATE FUNCTION bug18037_f1() RETURNS INT
|
||||
BEGIN
|
||||
RETURN @@server_id;
|
||||
END|
|
||||
CREATE PROCEDURE bug18037_p1()
|
||||
BEGIN
|
||||
DECLARE v INT DEFAULT @@server_id;
|
||||
END|
|
||||
CREATE PROCEDURE bug18037_p2()
|
||||
BEGIN
|
||||
CASE @@server_id
|
||||
WHEN -1 THEN
|
||||
SELECT 0;
|
||||
ELSE
|
||||
SELECT 1;
|
||||
END CASE;
|
||||
END|
|
||||
SELECT bug18037_f1()|
|
||||
bug18037_f1()
|
||||
1
|
||||
CALL bug18037_p1()|
|
||||
CALL bug18037_p2()|
|
||||
1
|
||||
1
|
||||
DROP FUNCTION bug18037_f1|
|
||||
DROP PROCEDURE bug18037_p1|
|
||||
DROP PROCEDURE bug18037_p2|
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -3183,3 +3183,24 @@ select * from (select min(i) from t1 where j=(select * from (select min(j) from
|
|||
min(i)
|
||||
1
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (i BIGINT UNSIGNED);
|
||||
INSERT INTO t1 VALUES (10000000000000000000);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE TABLE t2 (i BIGINT UNSIGNED);
|
||||
INSERT INTO t2 VALUES (10000000000000000000);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
/* simple test */
|
||||
SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
|
||||
i
|
||||
10000000000000000000
|
||||
1
|
||||
/* subquery test */
|
||||
SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
|
||||
i
|
||||
10000000000000000000
|
||||
/* subquery test with cast*/
|
||||
SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
|
||||
i
|
||||
10000000000000000000
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
|
|
@ -535,3 +535,88 @@ View Create View
|
|||
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v2` AS select 1 AS `1`
|
||||
drop view v1;
|
||||
drop view v2;
|
||||
CREATE DATABASE mysqltest1;
|
||||
CREATE USER readonly@localhost;
|
||||
CREATE TABLE mysqltest1.t1 (x INT);
|
||||
INSERT INTO mysqltest1.t1 VALUES (1), (2);
|
||||
CREATE SQL SECURITY INVOKER VIEW mysqltest1.v_t1 AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ts AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ti AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tu AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tus AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_td AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tds AS SELECT * FROM mysqltest1.t1;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly;
|
||||
GRANT SELECT ON mysqltest1.v_ts TO readonly;
|
||||
GRANT INSERT ON mysqltest1.v_ti TO readonly;
|
||||
GRANT UPDATE ON mysqltest1.v_tu TO readonly;
|
||||
GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly;
|
||||
GRANT DELETE ON mysqltest1.v_td TO readonly;
|
||||
GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly;
|
||||
SELECT * FROM mysqltest1.v_t1;
|
||||
ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
INSERT INTO mysqltest1.v_t1 VALUES(4);
|
||||
ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
DELETE FROM mysqltest1.v_t1 WHERE x = 1;
|
||||
ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
UPDATE mysqltest1.v_t1 SET x = 3 WHERE x = 2;
|
||||
ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
UPDATE mysqltest1.v_t1 SET x = 3;
|
||||
ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
DELETE FROM mysqltest1.v_t1;
|
||||
ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SELECT 1 FROM mysqltest1.v_t1;
|
||||
ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
SELECT * FROM mysqltest1.t1;
|
||||
ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 't1'
|
||||
SELECT * FROM mysqltest1.v_ts;
|
||||
x
|
||||
1
|
||||
2
|
||||
SELECT * FROM mysqltest1.v_ts, mysqltest1.t1 WHERE mysqltest1.t1.x = mysqltest1.v_ts.x;
|
||||
ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 't1'
|
||||
SELECT * FROM mysqltest1.v_ti;
|
||||
ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for table 'v_ti'
|
||||
INSERT INTO mysqltest1.v_ts VALUES (100);
|
||||
ERROR 42000: INSERT command denied to user 'readonly'@'localhost' for table 'v_ts'
|
||||
INSERT INTO mysqltest1.v_ti VALUES (100);
|
||||
UPDATE mysqltest1.v_ts SET x= 200 WHERE x = 100;
|
||||
ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'v_ts'
|
||||
UPDATE mysqltest1.v_ts SET x= 200;
|
||||
ERROR 42000: UPDATE command denied to user 'readonly'@'localhost' for table 'v_ts'
|
||||
UPDATE mysqltest1.v_tu SET x= 200 WHERE x = 100;
|
||||
UPDATE mysqltest1.v_tus SET x= 200 WHERE x = 100;
|
||||
UPDATE mysqltest1.v_tu SET x= 200;
|
||||
DELETE FROM mysqltest1.v_ts WHERE x= 200;
|
||||
ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'v_ts'
|
||||
DELETE FROM mysqltest1.v_ts;
|
||||
ERROR 42000: DELETE command denied to user 'readonly'@'localhost' for table 'v_ts'
|
||||
DELETE FROM mysqltest1.v_td WHERE x= 200;
|
||||
ERROR 42000: SELECT command denied to user 'readonly'@'localhost' for column 'x' in table 'v_td'
|
||||
DELETE FROM mysqltest1.v_tds WHERE x= 200;
|
||||
DELETE FROM mysqltest1.v_td;
|
||||
DROP VIEW mysqltest1.v_tds;
|
||||
DROP VIEW mysqltest1.v_td;
|
||||
DROP VIEW mysqltest1.v_tus;
|
||||
DROP VIEW mysqltest1.v_tu;
|
||||
DROP VIEW mysqltest1.v_ti;
|
||||
DROP VIEW mysqltest1.v_ts;
|
||||
DROP VIEW mysqltest1.v_t1;
|
||||
DROP TABLE mysqltest1.t1;
|
||||
DROP USER readonly@localhost;
|
||||
DROP DATABASE mysqltest1;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
CREATE DEFINER = 'no-such-user'@localhost VIEW v AS SELECT a from t1;
|
||||
Warnings:
|
||||
Note 1449 There is no 'no-such-user'@'localhost' registered
|
||||
SHOW CREATE VIEW v;
|
||||
View Create View
|
||||
v CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `t1`.`a` AS `a` from `t1`
|
||||
Warnings:
|
||||
Note 1449 There is no 'no-such-user'@'localhost' registered
|
||||
SELECT * FROM v;
|
||||
ERROR HY000: There is no 'no-such-user'@'localhost' registered
|
||||
DROP VIEW v;
|
||||
DROP TABLE t1;
|
||||
USE test;
|
||||
|
|
2
mysql-test/std_data/bug15328.cnf
Normal file
2
mysql-test/std_data/bug15328.cnf
Normal file
|
@ -0,0 +1,2 @@
|
|||
[mysqldump]
|
||||
fields-optionally-enclosed-by="
|
|
@ -102,3 +102,43 @@ unlock tables;
|
|||
drop table t1, t2, t3;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# Test of deadlock problem when doing FLUSH TABLE with read lock
|
||||
# (Bug was in NTPL threads in Linux when using different mutex while
|
||||
# waiting for a condtion variable)
|
||||
|
||||
create table t1 (c1 int);
|
||||
create table t2 (c1 int);
|
||||
|
||||
connect (con1,localhost,root,,);
|
||||
connect (con3,localhost,root,,);
|
||||
|
||||
connection con1;
|
||||
lock table t1 write;
|
||||
|
||||
connection con2;
|
||||
send flush tables with read lock;
|
||||
--sleep 1
|
||||
|
||||
connection con3;
|
||||
send insert into t2 values(1);
|
||||
--sleep 1
|
||||
|
||||
connection con1;
|
||||
unlock tables;
|
||||
disconnect con1;
|
||||
|
||||
connection con2;
|
||||
reap;
|
||||
disconnect con2;
|
||||
|
||||
connection con3;
|
||||
# It hangs here (insert into t2 does not end).
|
||||
reap;
|
||||
disconnect con3;
|
||||
|
||||
connection default;
|
||||
drop table t1, t2;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
|
|
@ -302,7 +302,7 @@ DROP DATABASE testdb10;
|
|||
create table t1(a int, b int, c int, d int);
|
||||
grant insert(b), insert(c), insert(d), insert(a) on t1 to grant_user@localhost;
|
||||
show grants for grant_user@localhost;
|
||||
select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv;
|
||||
select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv order by Column_name;
|
||||
revoke ALL PRIVILEGES on t1 from grant_user@localhost;
|
||||
show grants for grant_user@localhost;
|
||||
select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv;
|
||||
|
@ -326,7 +326,18 @@ grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost;
|
|||
grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost;
|
||||
connect (conn1,localhost,mysqltest_3,,);
|
||||
connection conn1;
|
||||
show grants for mysqltest_3@localhost;
|
||||
SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES
|
||||
WHERE GRANTEE = '''mysqltest_3''@''localhost'''
|
||||
ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE;
|
||||
SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES
|
||||
WHERE GRANTEE = '''mysqltest_3''@''localhost'''
|
||||
ORDER BY TABLE_NAME,PRIVILEGE_TYPE;
|
||||
SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES
|
||||
WHERE GRANTEE = '''mysqltest_3''@''localhost'''
|
||||
ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE;
|
||||
SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES
|
||||
WHERE GRANTEE = '''mysqltest_3''@''localhost'''
|
||||
ORDER BY TABLE_CATALOG,PRIVILEGE_TYPE;
|
||||
--error 1143
|
||||
update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1;
|
||||
--error 1143
|
||||
|
|
|
@ -659,59 +659,7 @@ select a1 from t1 where a2 = 'b' group by a1;
|
|||
explain select distinct a1 from t1 where a2 = 'b';
|
||||
select distinct a1 from t1 where a2 = 'b';
|
||||
|
||||
#
|
||||
# Bug #12672: primary key implcitly included in every innodb index
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
create table t4 (
|
||||
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
|
||||
) engine=innodb;
|
||||
--enable_warnings
|
||||
insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
|
||||
|
||||
create index idx12672_0 on t4 (a1);
|
||||
create index idx12672_1 on t4 (a1,a2,b,c);
|
||||
create index idx12672_2 on t4 (a1,a2,b);
|
||||
analyze table t1;
|
||||
|
||||
select distinct a1 from t4 where pk_col not in (1,2,3,4);
|
||||
|
||||
drop table t1,t2,t3,t4;
|
||||
|
||||
#
|
||||
# Bug #6142: a problem with the empty innodb table
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
create table t1 (
|
||||
a varchar(30), b varchar(30), primary key(a), key(b)
|
||||
) engine=innodb;
|
||||
--enable_warnings
|
||||
select distinct a from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #9798: group by with rollup
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
create table t1(a int, key(a)) engine=innodb;
|
||||
--enable_warnings
|
||||
insert into t1 values(1);
|
||||
select a, count(a) from t1 group by a with rollup;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #13293 Wrongly used index results in endless loop.
|
||||
#
|
||||
create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb;
|
||||
insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d");
|
||||
alter table t1 drop primary key, add primary key (f2, f1);
|
||||
explain select distinct f1 a, f1 b from t1;
|
||||
explain select distinct f1, f2 from t1;
|
||||
drop table t1;
|
||||
|
||||
drop table t1,t2,t3;
|
||||
#
|
||||
# Bug #14920 Ordering aggregated result sets with composite primary keys
|
||||
# corrupts resultset
|
||||
|
|
|
@ -176,4 +176,12 @@ UPDATE t1 SET val=1;
|
|||
SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1';
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# BUG#12873 - BTREE index on MEMORY table with multiple NULL values doesn't
|
||||
# work properly
|
||||
#
|
||||
CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY;
|
||||
INSERT INTO t1 VALUES(NULL),(NULL);
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
-- source include/testdb_only.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2;
|
||||
drop view if exists v1,v2;
|
||||
drop function if exists f1;
|
||||
drop function if exists f2;
|
||||
--enable_warnings
|
||||
|
||||
use INFORMATION_SCHEMA;
|
||||
--replace_result Tables_in_INFORMATION_SCHEMA Tables_in_information_schema
|
||||
show tables;
|
||||
--replace_result 'Tables_in_INFORMATION_SCHEMA (T%)' 'Tables_in_information_schema (T%)'
|
||||
show tables from INFORMATION_SCHEMA like 'T%';
|
||||
create database `inf%`;
|
||||
create database mbase;
|
||||
use `inf%`;
|
||||
show tables;
|
||||
|
||||
#
|
||||
# Bug#18113 SELECT * FROM information_schema.xxx crashes server
|
||||
# Bug#17204 second CALL to procedure crashes Server
|
||||
# Crash happened when one selected data from one of INFORMATION_SCHEMA
|
||||
# tables and in order to build its contents server had to open view which
|
||||
# used stored function and table or view on which one had not global or
|
||||
|
@ -18,6 +27,7 @@ show tables;
|
|||
# privileges at all).
|
||||
#
|
||||
grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost';
|
||||
grant all privileges on `mbase`.* to 'mysqltest_1'@'localhost';
|
||||
create table t1 (f1 int);
|
||||
delimiter |;
|
||||
create function func1(curr_int int) returns int
|
||||
|
@ -28,15 +38,63 @@ begin
|
|||
end|
|
||||
delimiter ;|
|
||||
create view v1 as select f1 from t1 where f1 = func1(f1);
|
||||
create function func2() returns int return 1;
|
||||
|
||||
use mbase;
|
||||
delimiter |;
|
||||
create procedure p1 ()
|
||||
begin
|
||||
select table_name from information_schema.key_column_usage
|
||||
order by table_name;
|
||||
end|
|
||||
delimiter ;|
|
||||
|
||||
create table t1
|
||||
(f1 int(10) unsigned not null,
|
||||
f2 varchar(100) not null,
|
||||
primary key (f1), unique key (f2));
|
||||
|
||||
connect (user1,localhost,mysqltest_1,,);
|
||||
connection user1;
|
||||
--disable_result_log
|
||||
select * from information_schema.tables;
|
||||
call mbase.p1();
|
||||
call mbase.p1();
|
||||
call mbase.p1();
|
||||
--enable_result_log
|
||||
|
||||
connection default;
|
||||
use `inf%`;
|
||||
drop user mysqltest_1@localhost;
|
||||
drop table t1;
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='inf%' and func2();
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='inf%' and func2();
|
||||
drop view v1;
|
||||
drop function func1;
|
||||
drop table t1;
|
||||
drop function func2;
|
||||
|
||||
drop database `inf%`;
|
||||
drop procedure mbase.p1;
|
||||
drop database mbase;
|
||||
|
||||
#
|
||||
# Bug#18282 INFORMATION_SCHEMA.TABLES provides inconsistent info about invalid views
|
||||
#
|
||||
use test;
|
||||
create table t1 (i int);
|
||||
create function f1 () returns int return (select max(i) from t1);
|
||||
create view v1 as select f1();
|
||||
create table t2 (id int);
|
||||
create function f2 () returns int return (select max(i) from t2);
|
||||
create view v2 as select f2();
|
||||
drop table t2;
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='test';
|
||||
drop table t1;
|
||||
select table_name, table_type, table_comment from information_schema.tables
|
||||
where table_schema='test';
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop view v1, v2;
|
||||
|
|
|
@ -129,3 +129,97 @@ select count(*), min(7), max(7) from t2m, t1i;
|
|||
|
||||
drop table t1m, t1i, t2m, t2i;
|
||||
|
||||
#
|
||||
# Bug #12672: primary key implcitly included in every innodb index
|
||||
# (was part of group_min_max.test)
|
||||
#
|
||||
|
||||
create table t1 (
|
||||
a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
|
||||
);
|
||||
|
||||
insert into t1 (a1, a2, b, c, d) values
|
||||
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
|
||||
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
|
||||
('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
|
||||
('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
|
||||
('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
|
||||
('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
|
||||
('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
|
||||
('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
|
||||
('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
|
||||
('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
|
||||
('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
|
||||
('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
|
||||
('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
|
||||
('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
|
||||
('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
|
||||
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
|
||||
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
|
||||
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
|
||||
('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
|
||||
('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
|
||||
('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
|
||||
('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
|
||||
('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
|
||||
('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
|
||||
('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
|
||||
('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
|
||||
('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
|
||||
('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
|
||||
('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
|
||||
('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
|
||||
('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
|
||||
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
|
||||
--disable_warnings
|
||||
create table t4 (
|
||||
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
|
||||
) engine=innodb;
|
||||
--enable_warnings
|
||||
insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
|
||||
|
||||
create index idx12672_0 on t4 (a1);
|
||||
create index idx12672_1 on t4 (a1,a2,b,c);
|
||||
create index idx12672_2 on t4 (a1,a2,b);
|
||||
analyze table t1;
|
||||
|
||||
select distinct a1 from t4 where pk_col not in (1,2,3,4);
|
||||
|
||||
drop table t1,t4;
|
||||
|
||||
#
|
||||
# Bug #6142: a problem with the empty innodb table
|
||||
# (was part of group_min_max.test)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
create table t1 (
|
||||
a varchar(30), b varchar(30), primary key(a), key(b)
|
||||
) engine=innodb;
|
||||
--enable_warnings
|
||||
select distinct a from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #9798: group by with rollup
|
||||
# (was part of group_min_max.test)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
create table t1(a int, key(a)) engine=innodb;
|
||||
--enable_warnings
|
||||
insert into t1 values(1);
|
||||
select a, count(a) from t1 group by a with rollup;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #13293 Wrongly used index results in endless loop.
|
||||
# (was part of group_min_max.test)
|
||||
#
|
||||
create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb;
|
||||
insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d");
|
||||
alter table t1 drop primary key, add primary key (f2, f1);
|
||||
explain select distinct f1 a, f1 b from t1;
|
||||
explain select distinct f1, f2 from t1;
|
||||
drop table t1;
|
||||
|
||||
|
|
|
@ -126,3 +126,35 @@ show columns from t1;
|
|||
connection locker;
|
||||
unlock tables;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#16986 - Deadlock condition with MyISAM tables
|
||||
#
|
||||
connection locker;
|
||||
use mysql;
|
||||
LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE;
|
||||
FLUSH TABLES;
|
||||
--sleep 1
|
||||
#
|
||||
connection reader;
|
||||
use mysql;
|
||||
#NOTE: This must be a multi-table select, otherwise the deadlock will not occur
|
||||
send SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
|
||||
--sleep 1
|
||||
#
|
||||
connection locker;
|
||||
# Make test case independent from earlier grants.
|
||||
--replace_result "Table is already up to date" "OK"
|
||||
OPTIMIZE TABLES columns_priv, db, host, user;
|
||||
UNLOCK TABLES;
|
||||
#
|
||||
connection reader;
|
||||
reap;
|
||||
use test;
|
||||
#
|
||||
connection locker;
|
||||
use test;
|
||||
#
|
||||
connection default;
|
||||
|
||||
# End of 5.0 tests
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
--source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa;
|
||||
DROP TABLE IF EXISTS t1, `"t"1`, t1aa, t2, t2aa, t3;
|
||||
drop database if exists mysqldump_test_db;
|
||||
drop database if exists db1;
|
||||
drop database if exists db2;
|
||||
|
@ -606,6 +606,13 @@ select * from t2 order by a;
|
|||
drop table t1, t2;
|
||||
drop database db1;
|
||||
|
||||
#
|
||||
# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence
|
||||
#
|
||||
|
||||
--exec $MYSQL_MY_PRINT_DEFAULTS --defaults-extra-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump
|
||||
|
||||
|
||||
#
|
||||
# Bug #9558 mysqldump --no-data db t1 t2 format still dumps data
|
||||
#
|
||||
|
@ -741,6 +748,17 @@ show create table `t1`;
|
|||
|
||||
drop table `t1`;
|
||||
|
||||
#
|
||||
# Bug #18536: wrong table order
|
||||
#
|
||||
|
||||
create table t1(a int);
|
||||
create table t2(a int);
|
||||
create table t3(a int);
|
||||
--error 6
|
||||
--exec $MYSQL_DUMP --skip-comments --force --no-data test t3 t1 non_existing t2
|
||||
drop table t1, t2, t3;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
# Bug #13318: Bad result with empty field and --hex-blob
|
||||
#
|
||||
|
|
|
@ -5849,6 +5849,52 @@ DROP PROCEDURE bug18589_p1|
|
|||
DROP PROCEDURE bug18589_p2|
|
||||
|
||||
|
||||
#
|
||||
# BUG#18037: Server crash when returning system variable in stored procedures
|
||||
# BUG#19633: Stack corruption in fix_fields()/THD::rollback_item_tree_changes()
|
||||
#
|
||||
|
||||
# Prepare.
|
||||
|
||||
--disable_warnings
|
||||
DROP FUNCTION IF EXISTS bug18037_f1|
|
||||
DROP PROCEDURE IF EXISTS bug18037_p1|
|
||||
DROP PROCEDURE IF EXISTS bug18037_p2|
|
||||
--enable_warnings
|
||||
|
||||
# Test case.
|
||||
|
||||
CREATE FUNCTION bug18037_f1() RETURNS INT
|
||||
BEGIN
|
||||
RETURN @@server_id;
|
||||
END|
|
||||
|
||||
CREATE PROCEDURE bug18037_p1()
|
||||
BEGIN
|
||||
DECLARE v INT DEFAULT @@server_id;
|
||||
END|
|
||||
|
||||
CREATE PROCEDURE bug18037_p2()
|
||||
BEGIN
|
||||
CASE @@server_id
|
||||
WHEN -1 THEN
|
||||
SELECT 0;
|
||||
ELSE
|
||||
SELECT 1;
|
||||
END CASE;
|
||||
END|
|
||||
|
||||
SELECT bug18037_f1()|
|
||||
CALL bug18037_p1()|
|
||||
CALL bug18037_p2()|
|
||||
|
||||
# Cleanup.
|
||||
|
||||
DROP FUNCTION bug18037_f1|
|
||||
DROP PROCEDURE bug18037_p1|
|
||||
DROP PROCEDURE bug18037_p2|
|
||||
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
|
|
@ -2109,3 +2109,25 @@ insert into t1 values (1, 2), (2, 2), (3, 2);
|
|||
select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#19700: subselect returning BIGINT always returned it as SIGNED
|
||||
#
|
||||
CREATE TABLE t1 (i BIGINT UNSIGNED);
|
||||
INSERT INTO t1 VALUES (10000000000000000000); -- > MAX SIGNED BIGINT 9323372036854775807
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
CREATE TABLE t2 (i BIGINT UNSIGNED);
|
||||
INSERT INTO t2 VALUES (10000000000000000000); -- same as first table
|
||||
INSERT INTO t2 VALUES (1);
|
||||
|
||||
/* simple test */
|
||||
SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
|
||||
|
||||
/* subquery test */
|
||||
SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
|
||||
|
||||
/* subquery test with cast*/
|
||||
SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
|
|
@ -718,3 +718,98 @@ show create view v1;
|
|||
show create view v2;
|
||||
drop view v1;
|
||||
drop view v2;
|
||||
|
||||
#
|
||||
# Bug#18681: View privileges are broken
|
||||
#
|
||||
CREATE DATABASE mysqltest1;
|
||||
CREATE USER readonly@localhost;
|
||||
CREATE TABLE mysqltest1.t1 (x INT);
|
||||
INSERT INTO mysqltest1.t1 VALUES (1), (2);
|
||||
CREATE SQL SECURITY INVOKER VIEW mysqltest1.v_t1 AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ts AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_ti AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tu AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tus AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_td AS SELECT * FROM mysqltest1.t1;
|
||||
CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tds AS SELECT * FROM mysqltest1.t1;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly;
|
||||
GRANT SELECT ON mysqltest1.v_ts TO readonly;
|
||||
GRANT INSERT ON mysqltest1.v_ti TO readonly;
|
||||
GRANT UPDATE ON mysqltest1.v_tu TO readonly;
|
||||
GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly;
|
||||
GRANT DELETE ON mysqltest1.v_td TO readonly;
|
||||
GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly;
|
||||
|
||||
CONNECT (n1,localhost,readonly,,);
|
||||
CONNECTION n1;
|
||||
|
||||
--error 1356
|
||||
SELECT * FROM mysqltest1.v_t1;
|
||||
--error 1356
|
||||
INSERT INTO mysqltest1.v_t1 VALUES(4);
|
||||
--error 1356
|
||||
DELETE FROM mysqltest1.v_t1 WHERE x = 1;
|
||||
--error 1356
|
||||
UPDATE mysqltest1.v_t1 SET x = 3 WHERE x = 2;
|
||||
--error 1356
|
||||
UPDATE mysqltest1.v_t1 SET x = 3;
|
||||
--error 1356
|
||||
DELETE FROM mysqltest1.v_t1;
|
||||
--error 1356
|
||||
SELECT 1 FROM mysqltest1.v_t1;
|
||||
--error 1142
|
||||
SELECT * FROM mysqltest1.t1;
|
||||
|
||||
SELECT * FROM mysqltest1.v_ts;
|
||||
--error 1142
|
||||
SELECT * FROM mysqltest1.v_ts, mysqltest1.t1 WHERE mysqltest1.t1.x = mysqltest1.v_ts.x;
|
||||
--error 1142
|
||||
SELECT * FROM mysqltest1.v_ti;
|
||||
|
||||
--error 1142
|
||||
INSERT INTO mysqltest1.v_ts VALUES (100);
|
||||
INSERT INTO mysqltest1.v_ti VALUES (100);
|
||||
|
||||
--error 1142
|
||||
UPDATE mysqltest1.v_ts SET x= 200 WHERE x = 100;
|
||||
--error 1142
|
||||
UPDATE mysqltest1.v_ts SET x= 200;
|
||||
UPDATE mysqltest1.v_tu SET x= 200 WHERE x = 100;
|
||||
UPDATE mysqltest1.v_tus SET x= 200 WHERE x = 100;
|
||||
UPDATE mysqltest1.v_tu SET x= 200;
|
||||
|
||||
--error 1142
|
||||
DELETE FROM mysqltest1.v_ts WHERE x= 200;
|
||||
--error 1142
|
||||
DELETE FROM mysqltest1.v_ts;
|
||||
--error 1143
|
||||
DELETE FROM mysqltest1.v_td WHERE x= 200;
|
||||
DELETE FROM mysqltest1.v_tds WHERE x= 200;
|
||||
DELETE FROM mysqltest1.v_td;
|
||||
|
||||
CONNECTION default;
|
||||
DROP VIEW mysqltest1.v_tds;
|
||||
DROP VIEW mysqltest1.v_td;
|
||||
DROP VIEW mysqltest1.v_tus;
|
||||
DROP VIEW mysqltest1.v_tu;
|
||||
DROP VIEW mysqltest1.v_ti;
|
||||
DROP VIEW mysqltest1.v_ts;
|
||||
DROP VIEW mysqltest1.v_t1;
|
||||
DROP TABLE mysqltest1.t1;
|
||||
DROP USER readonly@localhost;
|
||||
DROP DATABASE mysqltest1;
|
||||
|
||||
#
|
||||
# BUG#14875: Bad view DEFINER makes SHOW CREATE VIEW fail
|
||||
#
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
CREATE DEFINER = 'no-such-user'@localhost VIEW v AS SELECT a from t1;
|
||||
--warning 1448
|
||||
SHOW CREATE VIEW v;
|
||||
--error 1449
|
||||
SELECT * FROM v;
|
||||
DROP VIEW v;
|
||||
DROP TABLE t1;
|
||||
USE test;
|
||||
|
|
|
@ -763,7 +763,9 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
|
|||
value_end=value;
|
||||
|
||||
/* remove quotes around argument */
|
||||
if ((*value == '\"' || *value == '\'') && *value == value_end[-1])
|
||||
if ((*value == '\"' || *value == '\'') && /* First char is quote */
|
||||
(value + 1 < value_end ) && /* String is longer than 1 */
|
||||
*value == value_end[-1] ) /* First char is equal to last char */
|
||||
{
|
||||
value++;
|
||||
value_end--;
|
||||
|
|
|
@ -827,7 +827,7 @@ then
|
|||
c_ev="$c_ev 'HIGH_NOT_PRECEDENCE'"
|
||||
c_ev="$c_ev ) DEFAULT '' NOT NULL,"
|
||||
c_ev="$c_ev comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',"
|
||||
c_ev="$c_ev PRIMARY KEY (definer, db, name)"
|
||||
c_ev="$c_ev PRIMARY KEY (db, name)"
|
||||
c_ev="$c_ev ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';"
|
||||
fi
|
||||
|
||||
|
|
|
@ -175,9 +175,12 @@ void Guardian_thread::process_instance(Instance *instance,
|
|||
case JUST_CRASHED:
|
||||
if (current_time - current_node->crash_moment <= 2)
|
||||
{
|
||||
instance->start();
|
||||
log_info("guardian: starting instance %s",
|
||||
instance->options.instance_name);
|
||||
if (instance->is_crashed())
|
||||
{
|
||||
instance->start();
|
||||
log_info("guardian: starting instance %s",
|
||||
instance->options.instance_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
current_node->state= CRASHED;
|
||||
|
@ -188,11 +191,14 @@ void Guardian_thread::process_instance(Instance *instance,
|
|||
{
|
||||
if ((current_node->restart_counter < restart_retry))
|
||||
{
|
||||
instance->start();
|
||||
current_node->last_checked= current_time;
|
||||
current_node->restart_counter++;
|
||||
log_info("guardian: restarting instance %s",
|
||||
instance->options.instance_name);
|
||||
if (instance->is_crashed())
|
||||
{
|
||||
instance->start();
|
||||
current_node->last_checked= current_time;
|
||||
current_node->restart_counter++;
|
||||
log_info("guardian: restarting instance %s",
|
||||
instance->options.instance_name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -198,28 +198,6 @@ void manager()
|
|||
if (create_pid_file(Options::Main::pid_file_name, manager_pid))
|
||||
return; /* necessary logging has been already done. */
|
||||
|
||||
sigset_t mask;
|
||||
set_signals(&mask);
|
||||
|
||||
/* create the listener */
|
||||
{
|
||||
pthread_t listener_thd_id;
|
||||
pthread_attr_t listener_thd_attr;
|
||||
int rc;
|
||||
|
||||
pthread_attr_init(&listener_thd_attr);
|
||||
pthread_attr_setdetachstate(&listener_thd_attr, PTHREAD_CREATE_DETACHED);
|
||||
rc= set_stacksize_n_create_thread(&listener_thd_id, &listener_thd_attr,
|
||||
listener, &listener_args);
|
||||
pthread_attr_destroy(&listener_thd_attr);
|
||||
if (rc)
|
||||
{
|
||||
log_error("manager(): set_stacksize_n_create_thread(listener) failed");
|
||||
goto err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* create guardian thread */
|
||||
{
|
||||
pthread_t guardian_thd_id;
|
||||
|
@ -268,6 +246,29 @@ void manager()
|
|||
}
|
||||
}
|
||||
|
||||
/* Initialize signals and alarm-infrastructure. */
|
||||
|
||||
sigset_t mask;
|
||||
set_signals(&mask);
|
||||
|
||||
/* create the listener */
|
||||
{
|
||||
pthread_t listener_thd_id;
|
||||
pthread_attr_t listener_thd_attr;
|
||||
int rc;
|
||||
|
||||
pthread_attr_init(&listener_thd_attr);
|
||||
pthread_attr_setdetachstate(&listener_thd_attr, PTHREAD_CREATE_DETACHED);
|
||||
rc= set_stacksize_n_create_thread(&listener_thd_id, &listener_thd_attr,
|
||||
listener, &listener_args);
|
||||
pthread_attr_destroy(&listener_thd_attr);
|
||||
if (rc)
|
||||
{
|
||||
log_error("manager(): set_stacksize_n_create_thread(listener) failed");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
After the list of guarded instances have been initialized,
|
||||
Guardian should start them.
|
||||
|
|
13
sql/field.cc
13
sql/field.cc
|
@ -1218,12 +1218,12 @@ String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val)
|
|||
Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
|
||||
uchar null_bit_arg,
|
||||
utype unireg_check_arg, const char *field_name_arg)
|
||||
:ptr(ptr_arg),null_ptr(null_ptr_arg),
|
||||
:ptr(ptr_arg), null_ptr(null_ptr_arg),
|
||||
table(0), orig_table(0), table_name(0),
|
||||
field_name(field_name_arg),
|
||||
query_id(0), key_start(0), part_of_key(0), part_of_sortkey(0),
|
||||
unireg_check(unireg_check_arg),
|
||||
field_length(length_arg), null_bit(null_bit_arg), dflt_field(0)
|
||||
field_length(length_arg), null_bit(null_bit_arg)
|
||||
{
|
||||
flags=null_ptr ? 0: NOT_NULL_FLAG;
|
||||
comment.str= (char*) "";
|
||||
|
@ -9059,14 +9059,15 @@ create_field::create_field(Field *old_field,Field *orig_field)
|
|||
diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
|
||||
orig_field->table->record[0]);
|
||||
orig_field->move_field_offset(diff); // Points now at default_values
|
||||
is_null= orig_field->is_real_null();
|
||||
res= orig_field->val_str(&tmp);
|
||||
orig_field->move_field_offset(-diff); // Back to record[0]
|
||||
if (!is_null)
|
||||
if (!orig_field->is_real_null())
|
||||
{
|
||||
char buff[MAX_FIELD_WIDTH], *pos;
|
||||
String tmp(buff, sizeof(buff), charset), *res;
|
||||
res= orig_field->val_str(&tmp);
|
||||
pos= (char*) sql_strmake(res->ptr(), res->length());
|
||||
def= new Item_string(pos, res->length(), charset);
|
||||
}
|
||||
orig_field->move_field_offset(-diff); // Back to record[0]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,12 +54,6 @@ public:
|
|||
|
||||
char *ptr; // Position to field in record
|
||||
uchar *null_ptr; // Byte where null_bit is
|
||||
/*
|
||||
dflt_field is used only for the fields of temporary tables.
|
||||
It points to the default value of the field in another table
|
||||
from which this field has been created.
|
||||
*/
|
||||
Field *dflt_field; // Field to copy default value from
|
||||
/*
|
||||
Note that you can use table->in_use as replacement for current_thd member
|
||||
only inside of val_*() and store() members (e.g. you can't use it in cons)
|
||||
|
|
|
@ -417,6 +417,8 @@ public:
|
|||
required, otherwise we only reading it and SELECT
|
||||
privilege might be required.
|
||||
*/
|
||||
Settable_routine_parameter() {}
|
||||
virtual ~Settable_routine_parameter() {}
|
||||
virtual void set_required_privilege(bool rw) {};
|
||||
|
||||
/*
|
||||
|
@ -2330,6 +2332,7 @@ public:
|
|||
max_length= item->max_length;
|
||||
decimals= item->decimals;
|
||||
collation.set(item->collation);
|
||||
unsigned_flag= item->unsigned_flag;
|
||||
return 0;
|
||||
};
|
||||
virtual void store(Item *)= 0;
|
||||
|
|
|
@ -407,6 +407,7 @@ void Item_singlerow_subselect::fix_length_and_dec()
|
|||
engine->fix_length_and_dec(row);
|
||||
value= *row;
|
||||
}
|
||||
unsigned_flag= value->unsigned_flag;
|
||||
/*
|
||||
If there are not tables in subquery then ability to have NULL value
|
||||
depends on SELECT list (if single row subquery have tables then it
|
||||
|
|
|
@ -2010,39 +2010,11 @@ longlong Item_date_add_interval::val_int()
|
|||
|
||||
bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
|
||||
{
|
||||
INTERVAL interval, other_interval;
|
||||
String val= value; // Because of const
|
||||
|
||||
if (this == item)
|
||||
return TRUE;
|
||||
|
||||
if ((item->type() != FUNC_ITEM) ||
|
||||
(arg_count != ((Item_func*) item)->arg_count) ||
|
||||
(func_name() != ((Item_func*) item)->func_name()))
|
||||
return FALSE;
|
||||
|
||||
Item_date_add_interval *other= (Item_date_add_interval*) item;
|
||||
|
||||
if ((int_type != other->int_type) ||
|
||||
(!args[0]->eq(other->args[0], binary_cmp)))
|
||||
return FALSE;
|
||||
|
||||
if (!args[1]->const_item() || !other->args[1]->const_item())
|
||||
return (args[1]->eq(other->args[1], binary_cmp));
|
||||
|
||||
if (get_interval_value(args[1], int_type, &val, &interval))
|
||||
return FALSE;
|
||||
|
||||
val= other->value;
|
||||
|
||||
if ((get_interval_value(other->args[1], other->int_type, &val,
|
||||
&other_interval)) ||
|
||||
((date_sub_interval ^ interval.neg) ^
|
||||
(other->date_sub_interval ^ other_interval.neg)))
|
||||
return FALSE;
|
||||
|
||||
// Assume comparing same types here due to earlier check
|
||||
return memcmp(&interval, &other_interval, sizeof(INTERVAL)) == 0;
|
||||
if (!Item_func::eq(item, binary_cmp))
|
||||
return 0;
|
||||
return ((int_type == other->int_type) &&
|
||||
(date_sub_interval == other->date_sub_interval));
|
||||
}
|
||||
|
||||
|
||||
|
|
34
sql/lock.cc
34
sql/lock.cc
|
@ -1174,16 +1174,17 @@ bool lock_global_read_lock(THD *thd)
|
|||
|
||||
if (!thd->global_read_lock)
|
||||
{
|
||||
const char *old_message;
|
||||
(void) pthread_mutex_lock(&LOCK_global_read_lock);
|
||||
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
|
||||
"Waiting to get readlock");
|
||||
old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
|
||||
"Waiting to get readlock");
|
||||
DBUG_PRINT("info",
|
||||
("waiting_for: %d protect_against: %d",
|
||||
waiting_for_read_lock, protect_against_global_read_lock));
|
||||
|
||||
waiting_for_read_lock++;
|
||||
while (protect_against_global_read_lock && !thd->killed)
|
||||
pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
|
||||
pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
|
||||
waiting_for_read_lock--;
|
||||
if (thd->killed)
|
||||
{
|
||||
|
@ -1205,9 +1206,15 @@ bool lock_global_read_lock(THD *thd)
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void unlock_global_read_lock(THD *thd)
|
||||
{
|
||||
uint tmp;
|
||||
DBUG_ENTER("unlock_global_read_lock");
|
||||
DBUG_PRINT("info",
|
||||
("global_read_lock: %u global_read_lock_blocks_commit: %u",
|
||||
global_read_lock, global_read_lock_blocks_commit));
|
||||
|
||||
pthread_mutex_lock(&LOCK_global_read_lock);
|
||||
tmp= --global_read_lock;
|
||||
if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
|
||||
|
@ -1215,8 +1222,13 @@ void unlock_global_read_lock(THD *thd)
|
|||
pthread_mutex_unlock(&LOCK_global_read_lock);
|
||||
/* Send the signal outside the mutex to avoid a context switch */
|
||||
if (!tmp)
|
||||
pthread_cond_broadcast(&COND_refresh);
|
||||
{
|
||||
DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock"));
|
||||
pthread_cond_broadcast(&COND_global_read_lock);
|
||||
}
|
||||
thd->global_read_lock= 0;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
#define must_wait (global_read_lock && \
|
||||
|
@ -1254,11 +1266,15 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
|
|||
*/
|
||||
DBUG_RETURN(is_not_commit);
|
||||
}
|
||||
old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
|
||||
old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
|
||||
"Waiting for release of readlock");
|
||||
while (must_wait && ! thd->killed &&
|
||||
(!abort_on_refresh || thd->version == refresh_version))
|
||||
(void) pthread_cond_wait(&COND_refresh,&LOCK_global_read_lock);
|
||||
{
|
||||
DBUG_PRINT("signal", ("Waiting for COND_global_read_lock"));
|
||||
(void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
|
||||
DBUG_PRINT("signal", ("Got COND_global_read_lock"));
|
||||
}
|
||||
if (thd->killed)
|
||||
result=1;
|
||||
}
|
||||
|
@ -1287,7 +1303,7 @@ void start_waiting_global_read_lock(THD *thd)
|
|||
(waiting_for_read_lock || global_read_lock_blocks_commit));
|
||||
(void) pthread_mutex_unlock(&LOCK_global_read_lock);
|
||||
if (tmp)
|
||||
pthread_cond_broadcast(&COND_refresh);
|
||||
pthread_cond_broadcast(&COND_global_read_lock);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -1309,10 +1325,10 @@ bool make_global_read_lock_block_commit(THD *thd)
|
|||
/* For testing we set up some blocking, to see if we can be killed */
|
||||
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
|
||||
protect_against_global_read_lock++;);
|
||||
old_message= thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
|
||||
old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
|
||||
"Waiting for all running commits to finish");
|
||||
while (protect_against_global_read_lock && !thd->killed)
|
||||
pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
|
||||
pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
|
||||
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
|
||||
protect_against_global_read_lock--;);
|
||||
if ((error= test(thd->killed)))
|
||||
|
|
|
@ -849,6 +849,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t);
|
|||
bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
|
||||
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||
Item ***copy_func, Field **from_field,
|
||||
Field **def_field,
|
||||
bool group, bool modify_item,
|
||||
bool table_cant_handle_bit_fields,
|
||||
bool make_copy_field,
|
||||
|
@ -1106,6 +1107,13 @@ bool insert_fields(THD *thd, Name_resolution_context *context,
|
|||
bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
|
||||
Item **conds, TABLE_LIST **leaves, bool select_insert);
|
||||
bool setup_tables_and_check_access (THD *thd,
|
||||
Name_resolution_context *context,
|
||||
List<TABLE_LIST> *from_clause,
|
||||
TABLE_LIST *tables, Item **conds,
|
||||
TABLE_LIST **leaves,
|
||||
bool select_insert,
|
||||
ulong want_access);
|
||||
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||
List<Item> *sum_func_list, uint wild_num);
|
||||
bool setup_fields(THD *thd, Item** ref_pointer_array,
|
||||
|
@ -1549,6 +1557,7 @@ extern pthread_cond_t COND_server_started;
|
|||
extern int mysqld_server_started;
|
||||
extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
|
||||
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
|
||||
extern pthread_cond_t COND_global_read_lock;
|
||||
extern pthread_attr_t connection_attrib;
|
||||
extern I_List<THD> threads;
|
||||
extern I_List<NAMED_LIST> key_caches;
|
||||
|
|
|
@ -605,7 +605,7 @@ pthread_mutex_t LOCK_prepared_stmt_count;
|
|||
pthread_mutex_t LOCK_des_key_file;
|
||||
#endif
|
||||
rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
|
||||
pthread_cond_t COND_refresh,COND_thread_count;
|
||||
pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
|
||||
pthread_t signal_thread;
|
||||
pthread_attr_t connection_attrib;
|
||||
pthread_mutex_t LOCK_server_started;
|
||||
|
@ -1335,6 +1335,7 @@ static void clean_up_mutexes()
|
|||
(void) pthread_mutex_destroy(&LOCK_prepared_stmt_count);
|
||||
(void) pthread_cond_destroy(&COND_thread_count);
|
||||
(void) pthread_cond_destroy(&COND_refresh);
|
||||
(void) pthread_cond_destroy(&COND_global_read_lock);
|
||||
(void) pthread_cond_destroy(&COND_thread_cache);
|
||||
(void) pthread_cond_destroy(&COND_flush_thread_cache);
|
||||
(void) pthread_cond_destroy(&COND_manager);
|
||||
|
@ -1757,13 +1758,11 @@ void end_thread(THD *thd, bool put_in_cache)
|
|||
}
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("sending a broadcast"));
|
||||
|
||||
/* Tell main we are ready */
|
||||
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
||||
/* It's safe to broadcast outside a lock (COND... is not deleted here) */
|
||||
DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
|
||||
(void) pthread_cond_broadcast(&COND_thread_count);
|
||||
DBUG_PRINT("info", ("unlocked thread_count mutex"));
|
||||
#ifdef ONE_THREAD
|
||||
if (!(test_flags & TEST_NO_THREADS)) // For debugging under Linux
|
||||
#endif
|
||||
|
@ -2853,6 +2852,7 @@ static int init_thread_environment()
|
|||
(void) my_rwlock_init(&LOCK_grant, NULL);
|
||||
(void) pthread_cond_init(&COND_thread_count,NULL);
|
||||
(void) pthread_cond_init(&COND_refresh,NULL);
|
||||
(void) pthread_cond_init(&COND_global_read_lock,NULL);
|
||||
(void) pthread_cond_init(&COND_thread_cache,NULL);
|
||||
(void) pthread_cond_init(&COND_flush_thread_cache,NULL);
|
||||
(void) pthread_cond_init(&COND_manager,NULL);
|
||||
|
@ -5026,7 +5026,7 @@ Disable with --skip-bdb (will save memory).",
|
|||
REQUIRED_ARG, 2/*default*/, 0/*min-value*/, 2/*max-value*/, 0, 0, 0},
|
||||
{"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0,
|
||||
GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running.",
|
||||
{"external-locking", OPT_USE_LOCKING, "Use system (external) locking (disabled by default). With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running. Disable with --skip-external-locking.",
|
||||
(gptr*) &opt_external_locking, (gptr*) &opt_external_locking,
|
||||
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
|
||||
|
|
|
@ -1088,6 +1088,8 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
|
|||
|
||||
sctx->master_access= 0;
|
||||
sctx->db_access= 0;
|
||||
sctx->priv_user= (char *) "";
|
||||
*sctx->priv_host= 0;
|
||||
|
||||
/*
|
||||
Find acl entry in user database.
|
||||
|
@ -3692,6 +3694,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
|||
TABLE_LIST *table, *first_not_own_table= thd->lex->first_not_own_table();
|
||||
Security_context *sctx= thd->security_ctx;
|
||||
uint i;
|
||||
ulong orig_want_access= want_access;
|
||||
DBUG_ENTER("check_grant");
|
||||
DBUG_ASSERT(number > 0);
|
||||
|
||||
|
@ -3713,18 +3716,22 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
|||
table->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
|
||||
}
|
||||
|
||||
want_access&= ~sctx->master_access;
|
||||
if (!want_access)
|
||||
DBUG_RETURN(0); // ok
|
||||
|
||||
rw_rdlock(&LOCK_grant);
|
||||
for (table= tables;
|
||||
table && number-- && table != first_not_own_table;
|
||||
table= table->next_global)
|
||||
{
|
||||
GRANT_TABLE *grant_table;
|
||||
sctx = test(table->security_ctx) ?
|
||||
table->security_ctx : thd->security_ctx;
|
||||
|
||||
want_access= orig_want_access;
|
||||
want_access&= ~sctx->master_access;
|
||||
if (!want_access)
|
||||
continue; // ok
|
||||
|
||||
if (!(~table->grant.privilege & want_access) ||
|
||||
table->derived || table->schema_table || table->belong_to_view)
|
||||
table->derived || table->schema_table)
|
||||
{
|
||||
/*
|
||||
It is subquery in the FROM clause. VIEW set table->derived after
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <m_ctype.h>
|
||||
#include <my_dir.h>
|
||||
#include <hash.h>
|
||||
#ifdef __WIN__
|
||||
#ifdef __WIN__
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
|
@ -879,7 +879,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
|
|||
bool found=1;
|
||||
/* Wait until all threads has closed all the tables we had locked */
|
||||
DBUG_PRINT("info",
|
||||
("Waiting for others threads to close their open tables"));
|
||||
("Waiting for other threads to close their open tables"));
|
||||
while (found && ! thd->killed)
|
||||
{
|
||||
found=0;
|
||||
|
@ -890,6 +890,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
|
|||
((table->s->version) < refresh_version && table->db_stat))
|
||||
{
|
||||
found=1;
|
||||
DBUG_PRINT("signal", ("Waiting for COND_refresh"));
|
||||
pthread_cond_wait(&COND_refresh,&LOCK_open);
|
||||
break;
|
||||
}
|
||||
|
@ -1684,6 +1685,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
|
|||
thd->mysys_var->current_cond= cond;
|
||||
proc_info=thd->proc_info;
|
||||
thd->proc_info="Waiting for table";
|
||||
DBUG_ENTER("wait_for_condition");
|
||||
if (!thd->killed)
|
||||
(void) pthread_cond_wait(cond, mutex);
|
||||
|
||||
|
@ -1704,6 +1706,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
|
|||
thd->mysys_var->current_cond= 0;
|
||||
thd->proc_info= proc_info;
|
||||
pthread_mutex_unlock(&thd->mysys_var->mutex);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1982,6 +1985,10 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
{
|
||||
if (table->s->version != refresh_version)
|
||||
{
|
||||
DBUG_PRINT("note",
|
||||
("Found table '%s.%s' with different refresh version",
|
||||
table_list->db, table_list->table_name));
|
||||
|
||||
/*
|
||||
Don't close tables if we are working with a log table or were
|
||||
asked not to close the table explicitly
|
||||
|
@ -5367,6 +5374,58 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
prepare tables and check access for the view tables
|
||||
|
||||
SYNOPSIS
|
||||
setup_tables_and_check_view_access()
|
||||
thd Thread handler
|
||||
context name resolution contest to setup table list there
|
||||
from_clause Top-level list of table references in the FROM clause
|
||||
tables Table list (select_lex->table_list)
|
||||
conds Condition of current SELECT (can be changed by VIEW)
|
||||
leaves List of join table leaves list (select_lex->leaf_tables)
|
||||
refresh It is onle refresh for subquery
|
||||
select_insert It is SELECT ... INSERT command
|
||||
want_access what access is needed
|
||||
|
||||
NOTE
|
||||
a wrapper for check_tables that will also check the resulting
|
||||
table leaves list for access to all the tables that belong to a view
|
||||
|
||||
RETURN
|
||||
FALSE ok; In this case *map will include the chosen index
|
||||
TRUE error
|
||||
*/
|
||||
bool setup_tables_and_check_access(THD *thd,
|
||||
Name_resolution_context *context,
|
||||
List<TABLE_LIST> *from_clause,
|
||||
TABLE_LIST *tables,
|
||||
Item **conds, TABLE_LIST **leaves,
|
||||
bool select_insert,
|
||||
ulong want_access)
|
||||
{
|
||||
TABLE_LIST *leaves_tmp = NULL;
|
||||
|
||||
if (setup_tables (thd, context, from_clause, tables, conds,
|
||||
&leaves_tmp, select_insert))
|
||||
return TRUE;
|
||||
|
||||
if (leaves)
|
||||
*leaves = leaves_tmp;
|
||||
|
||||
for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf)
|
||||
if (leaves_tmp->belong_to_view &&
|
||||
check_one_table_access(thd, want_access, leaves_tmp))
|
||||
{
|
||||
tables->hide_view_error(thd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a key_map from a list of index names
|
||||
|
||||
|
@ -6003,6 +6062,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
|
|||
TABLE_SHARE *share;
|
||||
bool result= 0, signalled= 0;
|
||||
DBUG_ENTER("remove_table_from_cache");
|
||||
DBUG_PRINT("enter", ("Table: '%s.%s' flags: %u", db, table_name, flags));
|
||||
|
||||
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
|
||||
for (;;)
|
||||
|
@ -6029,7 +6089,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
|
|||
DBUG_PRINT("info", ("Table was in use by other thread"));
|
||||
in_use->some_tables_deleted=1;
|
||||
if (table->db_stat)
|
||||
{
|
||||
DBUG_PRINT("info", ("Found another active instance of the table"));
|
||||
result=1;
|
||||
}
|
||||
/* Kill delayed insert threads */
|
||||
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
|
||||
! in_use->killed)
|
||||
|
@ -6084,6 +6147,12 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
|
|||
|
||||
if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
|
||||
{
|
||||
/*
|
||||
Signal any thread waiting for tables to be freed to
|
||||
reopen their tables
|
||||
*/
|
||||
(void) pthread_cond_broadcast(&COND_refresh);
|
||||
DBUG_PRINT("info", ("Waiting for refresh signal"));
|
||||
if (!(flags & RTFC_CHECK_KILLED_FLAG) || !thd->killed)
|
||||
{
|
||||
dropping_tables++;
|
||||
|
|
|
@ -394,10 +394,11 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
|
|||
DBUG_ENTER("mysql_prepare_delete");
|
||||
|
||||
thd->lex->allow_sum_func= 0;
|
||||
if (setup_tables(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
table_list, conds, &select_lex->leaf_tables,
|
||||
FALSE) ||
|
||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
table_list, conds,
|
||||
&select_lex->leaf_tables, FALSE,
|
||||
DELETE_ACL) ||
|
||||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||
setup_ftfuncs(select_lex))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
@ -456,10 +457,11 @@ bool mysql_multi_delete_prepare(THD *thd)
|
|||
|
||||
lex->query_tables also point on local list of DELETE SELECT_LEX
|
||||
*/
|
||||
if (setup_tables(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
lex->query_tables, &lex->select_lex.where,
|
||||
&lex->select_lex.leaf_tables, FALSE))
|
||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
lex->query_tables, &lex->select_lex.where,
|
||||
&lex->select_lex.leaf_tables, FALSE,
|
||||
DELETE_ACL))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
|
||||
|
|
|
@ -759,10 +759,11 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
|
|||
bool insert_into_view= (table_list->view != 0);
|
||||
DBUG_ENTER("mysql_prepare_insert_check_table");
|
||||
|
||||
if (setup_tables(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
table_list, where, &thd->lex->select_lex.leaf_tables,
|
||||
select_insert))
|
||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
table_list, where,
|
||||
&thd->lex->select_lex.leaf_tables,
|
||||
select_insert, INSERT_ACL))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (insert_into_view && !fields.elements)
|
||||
|
@ -2588,12 +2589,13 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||
while ((item=it++))
|
||||
{
|
||||
create_field *cr_field;
|
||||
Field *field;
|
||||
Field *field, *def_field;
|
||||
if (item->type() == Item::FUNC_ITEM)
|
||||
field=item->tmp_table_field(&tmp_table);
|
||||
field= item->tmp_table_field(&tmp_table);
|
||||
else
|
||||
field=create_tmp_field(thd, &tmp_table, item, item->type(),
|
||||
(Item ***) 0, &tmp_field, 0, 0, 0, 0, 0);
|
||||
field= create_tmp_field(thd, &tmp_table, item, item->type(),
|
||||
(Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
|
||||
0);
|
||||
if (!field ||
|
||||
!(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
|
||||
((Item_field *)item)->field :
|
||||
|
|
108
sql/sql_lex.cc
108
sql/sql_lex.cc
|
@ -152,8 +152,7 @@ void lex_start(THD *thd, const uchar *buf, uint length)
|
|||
lex->found_semicolon= 0;
|
||||
lex->safe_to_cache_query= 1;
|
||||
lex->time_zone_tables_used= 0;
|
||||
lex->leaf_tables_insert= lex->query_tables= 0;
|
||||
lex->query_tables_last= &lex->query_tables;
|
||||
lex->leaf_tables_insert= 0;
|
||||
lex->variables_used= 0;
|
||||
lex->empty_field_list_on_rset= 0;
|
||||
lex->select_lex.select_number= 1;
|
||||
|
@ -175,17 +174,12 @@ void lex_start(THD *thd, const uchar *buf, uint length)
|
|||
lex->sphead= NULL;
|
||||
lex->spcont= NULL;
|
||||
lex->proc_list.first= 0;
|
||||
lex->query_tables_own_last= 0;
|
||||
lex->escape_used= lex->et_compile_phase= FALSE;
|
||||
lex->reset_query_tables_list(FALSE);
|
||||
|
||||
lex->name= 0;
|
||||
lex->et= NULL;
|
||||
|
||||
if (lex->sroutines.records)
|
||||
my_hash_reset(&lex->sroutines);
|
||||
lex->sroutines_list.empty();
|
||||
lex->sroutines_list_own_last= lex->sroutines_list.next;
|
||||
lex->sroutines_list_own_elements= 0;
|
||||
lex->nest_level=0 ;
|
||||
lex->allow_sum_func= 0;
|
||||
lex->in_sum_func= NULL;
|
||||
|
@ -1603,6 +1597,52 @@ void st_select_lex::print_limit(THD *thd, String *str)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialize (or reset) Query_tables_list object.
|
||||
|
||||
SYNOPSIS
|
||||
reset_query_tables_list()
|
||||
init TRUE - we should perform full initialization of object with
|
||||
allocating needed memory
|
||||
FALSE - object is already initialized so we should only reset
|
||||
its state so it can be used for parsing/processing
|
||||
of new statement
|
||||
|
||||
DESCRIPTION
|
||||
This method initializes Query_tables_list so it can be used as part
|
||||
of LEX object for parsing/processing of statement. One can also use
|
||||
this method to reset state of already initialized Query_tables_list
|
||||
so it can be used for processing of new statement.
|
||||
*/
|
||||
|
||||
void Query_tables_list::reset_query_tables_list(bool init)
|
||||
{
|
||||
query_tables= 0;
|
||||
query_tables_last= &query_tables;
|
||||
query_tables_own_last= 0;
|
||||
if (init)
|
||||
hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
|
||||
else if (sroutines.records)
|
||||
my_hash_reset(&sroutines);
|
||||
sroutines_list.empty();
|
||||
sroutines_list_own_last= sroutines_list.next;
|
||||
sroutines_list_own_elements= 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Destroy Query_tables_list object with freeing all resources used by it.
|
||||
|
||||
SYNOPSIS
|
||||
destroy_query_tables_list()
|
||||
*/
|
||||
|
||||
void Query_tables_list::destroy_query_tables_list()
|
||||
{
|
||||
hash_free(&sroutines);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialize LEX object.
|
||||
|
||||
|
@ -1619,12 +1659,9 @@ void st_select_lex::print_limit(THD *thd, String *str)
|
|||
|
||||
st_lex::st_lex()
|
||||
:result(0), yacc_yyss(0), yacc_yyvs(0),
|
||||
sql_command(SQLCOM_END), query_tables_own_last(0)
|
||||
sql_command(SQLCOM_END)
|
||||
{
|
||||
hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
|
||||
sroutines_list.empty();
|
||||
sroutines_list_own_last= sroutines_list.next;
|
||||
sroutines_list_own_elements= 0;
|
||||
reset_query_tables_list(TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2008,6 +2045,11 @@ void st_lex::link_first_table_back(TABLE_LIST *first,
|
|||
|
||||
SYNOPSIS
|
||||
st_lex::cleanup_after_one_table_open()
|
||||
|
||||
NOTE
|
||||
This method is mostly responsible for cleaning up of selects lists and
|
||||
derived tables state. To rollback changes in Query_tables_list one has
|
||||
to call Query_tables_list::reset_query_tables_list(FALSE).
|
||||
*/
|
||||
|
||||
void st_lex::cleanup_after_one_table_open()
|
||||
|
@ -2034,11 +2076,41 @@ void st_lex::cleanup_after_one_table_open()
|
|||
select_lex.cut_subtree();
|
||||
}
|
||||
time_zone_tables_used= 0;
|
||||
if (sroutines.records)
|
||||
my_hash_reset(&sroutines);
|
||||
sroutines_list.empty();
|
||||
sroutines_list_own_last= sroutines_list.next;
|
||||
sroutines_list_own_elements= 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Save current state of Query_tables_list for this LEX, and prepare it
|
||||
for processing of new statemnt.
|
||||
|
||||
SYNOPSIS
|
||||
reset_n_backup_query_tables_list()
|
||||
backup Pointer to Query_tables_list instance to be used for backup
|
||||
*/
|
||||
|
||||
void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup)
|
||||
{
|
||||
backup->set_query_tables_list(this);
|
||||
/*
|
||||
We have to perform full initialization here since otherwise we
|
||||
will damage backed up state.
|
||||
*/
|
||||
this->reset_query_tables_list(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Restore state of Query_tables_list for this LEX from backup.
|
||||
|
||||
SYNOPSIS
|
||||
restore_backup_query_tables_list()
|
||||
backup Pointer to Query_tables_list instance used for backup
|
||||
*/
|
||||
|
||||
void st_lex::restore_backup_query_tables_list(Query_tables_list *backup)
|
||||
{
|
||||
this->destroy_query_tables_list();
|
||||
this->set_query_tables_list(backup);
|
||||
}
|
||||
|
||||
|
||||
|
|
151
sql/sql_lex.h
151
sql/sql_lex.h
|
@ -752,9 +752,95 @@ extern sys_var *trg_new_row_fake_var;
|
|||
enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE,
|
||||
XA_SUSPEND, XA_FOR_MIGRATE};
|
||||
|
||||
|
||||
/*
|
||||
Class representing list of all tables used by statement.
|
||||
It also contains information about stored functions used by statement
|
||||
since during its execution we may have to add all tables used by its
|
||||
stored functions/triggers to this list in order to pre-open and lock
|
||||
them.
|
||||
|
||||
Also used by st_lex::reset_n_backup/restore_backup_query_tables_list()
|
||||
methods to save and restore this information.
|
||||
*/
|
||||
|
||||
class Query_tables_list
|
||||
{
|
||||
public:
|
||||
/* Global list of all tables used by this statement */
|
||||
TABLE_LIST *query_tables;
|
||||
/* Pointer to next_global member of last element in the previous list. */
|
||||
TABLE_LIST **query_tables_last;
|
||||
/*
|
||||
If non-0 then indicates that query requires prelocking and points to
|
||||
next_global member of last own element in query table list (i.e. last
|
||||
table which was not added to it as part of preparation to prelocking).
|
||||
0 - indicates that this query does not need prelocking.
|
||||
*/
|
||||
TABLE_LIST **query_tables_own_last;
|
||||
/* Set of stored routines called by statement. */
|
||||
HASH sroutines;
|
||||
/*
|
||||
List linking elements of 'sroutines' set. Allows you to add new elements
|
||||
to this set as you iterate through the list of existing elements.
|
||||
'sroutines_list_own_last' is pointer to ::next member of last element of
|
||||
this list which represents routine which is explicitly used by query.
|
||||
'sroutines_list_own_elements' number of explicitly used routines.
|
||||
We use these two members for restoring of 'sroutines_list' to the state
|
||||
in which it was right after query parsing.
|
||||
*/
|
||||
SQL_LIST sroutines_list;
|
||||
byte **sroutines_list_own_last;
|
||||
uint sroutines_list_own_elements;
|
||||
|
||||
/*
|
||||
These constructor and destructor serve for creation/destruction
|
||||
of Query_tables_list instances which are used as backup storage.
|
||||
*/
|
||||
Query_tables_list() {}
|
||||
~Query_tables_list() {}
|
||||
|
||||
/* Initializes (or resets) Query_tables_list object for "real" use. */
|
||||
void reset_query_tables_list(bool init);
|
||||
void destroy_query_tables_list();
|
||||
void set_query_tables_list(Query_tables_list *state)
|
||||
{
|
||||
*this= *state;
|
||||
}
|
||||
|
||||
void add_to_query_tables(TABLE_LIST *table)
|
||||
{
|
||||
*(table->prev_global= query_tables_last)= table;
|
||||
query_tables_last= &table->next_global;
|
||||
}
|
||||
bool requires_prelocking()
|
||||
{
|
||||
return test(query_tables_own_last);
|
||||
}
|
||||
void mark_as_requiring_prelocking(TABLE_LIST **tables_own_last)
|
||||
{
|
||||
query_tables_own_last= tables_own_last;
|
||||
}
|
||||
/* Return pointer to first not-own table in query-tables or 0 */
|
||||
TABLE_LIST* first_not_own_table()
|
||||
{
|
||||
return ( query_tables_own_last ? *query_tables_own_last : 0);
|
||||
}
|
||||
void chop_off_not_own_tables()
|
||||
{
|
||||
if (query_tables_own_last)
|
||||
{
|
||||
*query_tables_own_last= 0;
|
||||
query_tables_last= query_tables_own_last;
|
||||
query_tables_own_last= 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* The state of the lex parsing. This is saved in the THD struct */
|
||||
|
||||
typedef struct st_lex
|
||||
typedef struct st_lex : public Query_tables_list
|
||||
{
|
||||
uint yylineno,yytoklen; /* Simulate lex */
|
||||
LEX_YYSTYPE yylval;
|
||||
|
@ -787,14 +873,6 @@ typedef struct st_lex
|
|||
gptr yacc_yyss,yacc_yyvs;
|
||||
THD *thd;
|
||||
CHARSET_INFO *charset;
|
||||
TABLE_LIST *query_tables; /* global list of all tables in this query */
|
||||
/*
|
||||
last element next_global of previous list (used only for list building
|
||||
during parsing and VIEW processing. This pointer could be invalid during
|
||||
processing of information schema tables(see get_schema_tables_result
|
||||
function)
|
||||
*/
|
||||
TABLE_LIST **query_tables_last;
|
||||
/* store original leaf_tables for INSERT SELECT and PS/SP */
|
||||
TABLE_LIST *leaf_tables_insert;
|
||||
/* Position (first character index) of SELECT of CREATE VIEW statement */
|
||||
|
@ -935,20 +1013,6 @@ typedef struct st_lex
|
|||
bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */
|
||||
bool all_privileges;
|
||||
sp_pcontext *spcont;
|
||||
/* Set of stored routines called by statement. */
|
||||
HASH sroutines;
|
||||
/*
|
||||
List linking elements of 'sroutines' set. Allows you to add new elements
|
||||
to this set as you iterate through the list of existing elements.
|
||||
'sroutines_list_own_last' is pointer to ::next member of last element of
|
||||
this list which represents routine which is explicitly used by query.
|
||||
'sroutines_list_own_elements' number of explicitly used routines.
|
||||
We use these two members for restoring of 'sroutines_list' to the state
|
||||
in which it was right after query parsing.
|
||||
*/
|
||||
SQL_LIST sroutines_list;
|
||||
byte **sroutines_list_own_last;
|
||||
uint sroutines_list_own_elements;
|
||||
|
||||
st_sp_chistics sp_chistics;
|
||||
|
||||
|
@ -988,14 +1052,6 @@ typedef struct st_lex
|
|||
*/
|
||||
const char *stmt_definition_begin;
|
||||
|
||||
/*
|
||||
If non-0 then indicates that query requires prelocking and points to
|
||||
next_global member of last own element in query table list (i.e. last
|
||||
table which was not added to it as part of preparation to prelocking).
|
||||
0 - indicates that this query does not need prelocking.
|
||||
*/
|
||||
TABLE_LIST **query_tables_own_last;
|
||||
|
||||
/*
|
||||
Pointers to part of LOAD DATA statement that should be rewritten
|
||||
during replication ("LOCAL 'filename' REPLACE INTO" part).
|
||||
|
@ -1014,7 +1070,7 @@ typedef struct st_lex
|
|||
|
||||
virtual ~st_lex()
|
||||
{
|
||||
hash_free(&sroutines);
|
||||
destroy_query_tables_list();
|
||||
}
|
||||
|
||||
inline void uncacheable(uint8 cause)
|
||||
|
@ -1039,11 +1095,6 @@ typedef struct st_lex
|
|||
TABLE_LIST *unlink_first_table(bool *link_to_local);
|
||||
void link_first_table_back(TABLE_LIST *first, bool link_to_local);
|
||||
void first_lists_tables_same();
|
||||
inline void add_to_query_tables(TABLE_LIST *table)
|
||||
{
|
||||
*(table->prev_global= query_tables_last)= table;
|
||||
query_tables_last= &table->next_global;
|
||||
}
|
||||
bool add_time_zone_tables_to_query_tables(THD *thd);
|
||||
|
||||
bool can_be_merged();
|
||||
|
@ -1075,28 +1126,7 @@ typedef struct st_lex
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
inline bool requires_prelocking()
|
||||
{
|
||||
return test(query_tables_own_last);
|
||||
}
|
||||
inline void mark_as_requiring_prelocking(TABLE_LIST **tables_own_last)
|
||||
{
|
||||
query_tables_own_last= tables_own_last;
|
||||
}
|
||||
/* Return pointer to first not-own table in query-tables or 0 */
|
||||
TABLE_LIST* first_not_own_table()
|
||||
{
|
||||
return ( query_tables_own_last ? *query_tables_own_last : 0);
|
||||
}
|
||||
void chop_off_not_own_tables()
|
||||
{
|
||||
if (query_tables_own_last)
|
||||
{
|
||||
*query_tables_own_last= 0;
|
||||
query_tables_last= query_tables_own_last;
|
||||
query_tables_own_last= 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup_after_one_table_open();
|
||||
|
||||
bool push_context(Name_resolution_context *context)
|
||||
|
@ -1113,6 +1143,9 @@ typedef struct st_lex
|
|||
{
|
||||
return context_stack.head();
|
||||
}
|
||||
|
||||
void reset_n_backup_query_tables_list(Query_tables_list *backup);
|
||||
void restore_backup_query_tables_list(Query_tables_list *backup);
|
||||
} LEX;
|
||||
|
||||
struct st_lex_local: public st_lex
|
||||
|
|
|
@ -153,10 +153,11 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||
ha_enable_transaction(thd, FALSE);
|
||||
if (open_and_lock_tables(thd, table_list))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (setup_tables(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
table_list, &unused_conds,
|
||||
&thd->lex->select_lex.leaf_tables, FALSE))
|
||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
table_list, &unused_conds,
|
||||
&thd->lex->select_lex.leaf_tables, FALSE,
|
||||
INSERT_ACL | UPDATE_ACL))
|
||||
DBUG_RETURN(-1);
|
||||
if (!table_list->table || // do not suport join view
|
||||
!table_list->updatable || // and derived tables
|
||||
|
|
|
@ -5188,23 +5188,35 @@ error:
|
|||
|
||||
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
|
||||
{
|
||||
Security_context * backup_ctx= thd->security_ctx;
|
||||
|
||||
/* we need to switch to the saved context (if any) */
|
||||
if (all_tables->security_ctx)
|
||||
thd->security_ctx= all_tables->security_ctx;
|
||||
|
||||
if (check_access(thd, privilege, all_tables->db,
|
||||
&all_tables->grant.privilege, 0, 0,
|
||||
test(all_tables->schema_table)))
|
||||
return 1;
|
||||
goto deny;
|
||||
|
||||
/* Show only 1 table for check_grant */
|
||||
if (grant_option && check_grant(thd, privilege, all_tables, 0, 1, 0))
|
||||
return 1;
|
||||
goto deny;
|
||||
|
||||
thd->security_ctx= backup_ctx;
|
||||
|
||||
/* Check rights on tables of subselects and implictly opened tables */
|
||||
TABLE_LIST *subselects_tables;
|
||||
if ((subselects_tables= all_tables->next_global))
|
||||
{
|
||||
if ((check_table_access(thd, SELECT_ACL, subselects_tables, 0)))
|
||||
return 1;
|
||||
goto deny;
|
||||
}
|
||||
return 0;
|
||||
|
||||
deny:
|
||||
thd->security_ctx= backup_ctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5385,6 +5397,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||
ulong found_access=0;
|
||||
TABLE_LIST *org_tables= tables;
|
||||
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
|
||||
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
|
||||
/*
|
||||
The check that first_not_own_table is not reached is for the case when
|
||||
the given table list refers to the list for prelocking (contains tables
|
||||
|
@ -5392,12 +5405,17 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||
*/
|
||||
for (; tables != first_not_own_table; tables= tables->next_global)
|
||||
{
|
||||
if (tables->security_ctx)
|
||||
sctx= tables->security_ctx;
|
||||
else
|
||||
sctx= backup_ctx;
|
||||
|
||||
if (tables->schema_table &&
|
||||
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
|
||||
{
|
||||
if (!no_errors)
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
thd->security_ctx->priv_user, thd->security_ctx->priv_host,
|
||||
sctx->priv_user, sctx->priv_host,
|
||||
information_schema_name.str);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -5406,12 +5424,13 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||
Remove SHOW_VIEW_ACL, because it will be checked during making view
|
||||
*/
|
||||
tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
|
||||
if (tables->derived || tables->schema_table || tables->belong_to_view ||
|
||||
if (tables->derived || tables->schema_table ||
|
||||
(tables->table && (int)tables->table->s->tmp_table) ||
|
||||
my_tz_check_n_skip_implicit_tables(&tables,
|
||||
thd->lex->time_zone_tables_used))
|
||||
continue;
|
||||
if ((thd->security_ctx->master_access & want_access) ==
|
||||
thd->security_ctx= sctx;
|
||||
if ((sctx->master_access & want_access) ==
|
||||
(want_access & ~EXTRA_ACL) &&
|
||||
thd->db)
|
||||
tables->grant.privilege= want_access;
|
||||
|
@ -5423,19 +5442,23 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||
{
|
||||
if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
|
||||
0, no_errors, test(tables->schema_table)))
|
||||
return TRUE; // Access denied
|
||||
goto deny; // Access denied
|
||||
found_access=tables->grant.privilege;
|
||||
found=1;
|
||||
}
|
||||
}
|
||||
else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
|
||||
0, no_errors, test(tables->schema_table)))
|
||||
return TRUE;
|
||||
goto deny;
|
||||
}
|
||||
thd->security_ctx= backup_ctx;
|
||||
if (grant_option)
|
||||
return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
|
||||
test(want_access & EXTRA_ACL), UINT_MAX, no_errors);
|
||||
return FALSE;
|
||||
deny:
|
||||
thd->security_ctx= backup_ctx;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -337,9 +337,10 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||
/* Check that all tables, fields, conds and order are ok */
|
||||
|
||||
if ((!(select_options & OPTION_SETUP_TABLES_DONE) &&
|
||||
setup_tables(thd, &select_lex->context, join_list,
|
||||
tables_list, &conds, &select_lex->leaf_tables,
|
||||
FALSE)) ||
|
||||
setup_tables_and_check_access(thd, &select_lex->context, join_list,
|
||||
tables_list, &conds,
|
||||
&select_lex->leaf_tables, FALSE,
|
||||
SELECT_ACL)) ||
|
||||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
|
||||
select_lex->setup_ref_array(thd, og_num) ||
|
||||
setup_fields(thd, (*rref_pointer_array), fields_list, 1,
|
||||
|
@ -8175,6 +8176,7 @@ Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
|
|||
in this array
|
||||
from_field if field will be created using other field as example,
|
||||
pointer example field will be written here
|
||||
default_field If field has a default value field, store it here
|
||||
group 1 if we are going to do a relative group by on result
|
||||
modify_item 1 if item->result_field should point to new item.
|
||||
This is relevent for how fill_record() is going to
|
||||
|
@ -8193,6 +8195,7 @@ Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
|
|||
|
||||
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||
Item ***copy_func, Field **from_field,
|
||||
Field **default_field,
|
||||
bool group, bool modify_item,
|
||||
bool table_cant_handle_bit_fields,
|
||||
bool make_copy_field,
|
||||
|
@ -8260,7 +8263,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||
if (orig_type == Item::REF_ITEM && orig_modify)
|
||||
((Item_ref*)orig_item)->set_result_field(result);
|
||||
if (field->field->eq_def(result))
|
||||
result->dflt_field= field->field;
|
||||
*default_field= field->field;
|
||||
return result;
|
||||
}
|
||||
/* Fall through */
|
||||
|
@ -8349,7 +8352,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
char *tmpname,path[FN_REFLEN];
|
||||
byte *pos,*group_buff;
|
||||
uchar *null_flags;
|
||||
Field **reg_field, **from_field;
|
||||
Field **reg_field, **from_field, **default_field;
|
||||
uint *blob_field;
|
||||
Copy_field *copy=0;
|
||||
KEY *keyinfo;
|
||||
|
@ -8419,6 +8422,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
&table, sizeof(*table),
|
||||
&share, sizeof(*share),
|
||||
®_field, sizeof(Field*) * (field_count+1),
|
||||
&default_field, sizeof(Field*) * (field_count),
|
||||
&blob_field, sizeof(uint)*(field_count+1),
|
||||
&from_field, sizeof(Field*)*field_count,
|
||||
©_func, sizeof(*copy_func)*(copy_func_count+1),
|
||||
|
@ -8448,6 +8452,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
|
||||
bzero((char*) table,sizeof(*table));
|
||||
bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
|
||||
bzero((char*) default_field, sizeof(Field*) * (field_count));
|
||||
bzero((char*) from_field,sizeof(Field*)*field_count);
|
||||
|
||||
table->mem_root= own_root;
|
||||
|
@ -8514,9 +8519,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
Item *arg= *argp;
|
||||
if (!arg->const_item())
|
||||
{
|
||||
uint field_index= (uint) (reg_field - table->field);
|
||||
Field *new_field=
|
||||
create_tmp_field(thd, table, arg, arg->type(), ©_func,
|
||||
tmp_from_field, group != 0,not_all_columns,
|
||||
tmp_from_field, &default_field[field_index],
|
||||
group != 0,not_all_columns,
|
||||
distinct, 0,
|
||||
param->convert_blob_length);
|
||||
if (!new_field)
|
||||
|
@ -8525,12 +8532,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
reclength+=new_field->pack_length();
|
||||
if (new_field->flags & BLOB_FLAG)
|
||||
{
|
||||
*blob_field++= (uint) (reg_field - table->field);
|
||||
*blob_field++= field_index;
|
||||
blob_count++;
|
||||
}
|
||||
if (new_field->type() == FIELD_TYPE_BIT)
|
||||
total_uneven_bit_length+= new_field->field_length & 7;
|
||||
new_field->field_index= (uint) (reg_field - table->field);
|
||||
new_field->field_index= field_index;
|
||||
*(reg_field++)= new_field;
|
||||
if (new_field->real_type() == MYSQL_TYPE_STRING ||
|
||||
new_field->real_type() == MYSQL_TYPE_VARCHAR)
|
||||
|
@ -8557,6 +8564,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
}
|
||||
else
|
||||
{
|
||||
uint field_index= (uint) (reg_field - table->field);
|
||||
/*
|
||||
The last parameter to create_tmp_field() is a bit tricky:
|
||||
|
||||
|
@ -8573,7 +8581,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
Field *new_field= (param->schema_table) ?
|
||||
create_tmp_field_for_schema(thd, item, table) :
|
||||
create_tmp_field(thd, table, item, type, ©_func,
|
||||
tmp_from_field, group != 0,
|
||||
tmp_from_field, &default_field[field_index],
|
||||
group != 0,
|
||||
!force_copy_fields &&
|
||||
(not_all_columns || group !=0),
|
||||
item->marker == 4, force_copy_fields,
|
||||
|
@ -8595,7 +8604,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
total_uneven_bit_length+= new_field->field_length & 7;
|
||||
if (new_field->flags & BLOB_FLAG)
|
||||
{
|
||||
*blob_field++= (uint) (reg_field - table->field);
|
||||
*blob_field++= field_index;
|
||||
blob_count++;
|
||||
}
|
||||
if (item->marker == 4 && item->maybe_null)
|
||||
|
@ -8605,7 +8614,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
}
|
||||
new_field->query_id= thd->query_id;
|
||||
new_field->fieldnr= ++fieldnr;
|
||||
new_field->field_index= (uint) (reg_field - table->field);
|
||||
new_field->field_index= field_index;
|
||||
*(reg_field++) =new_field;
|
||||
}
|
||||
if (!--hidden_field_count)
|
||||
|
@ -8625,6 +8634,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
}
|
||||
DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
|
||||
field_count= (uint) (reg_field - table->field);
|
||||
*reg_field= 0;
|
||||
*blob_field= 0; // End marker
|
||||
share->fields= field_count;
|
||||
|
||||
|
@ -8742,30 +8752,31 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
}
|
||||
field->reset();
|
||||
|
||||
if (field->dflt_field && field->dflt_field->ptr)
|
||||
/*
|
||||
Test if there is a default field value. The test for ->ptr is to skip
|
||||
'offset' fields generated by initalize_tables
|
||||
*/
|
||||
if (default_field[i] && default_field[i]->ptr)
|
||||
{
|
||||
/*
|
||||
field->dflt_field is set only in the cases when 'field' can
|
||||
inherit the default value that is defined for the field referred
|
||||
by the Item_field object from which 'field' has been created.
|
||||
For a field created not from a Item_field item dflt_field == 0.
|
||||
default_field[i] is set only in the cases when 'field' can
|
||||
inherit the default value that is defined for the field referred
|
||||
by the Item_field object from which 'field' has been created.
|
||||
*/
|
||||
my_ptrdiff_t diff;
|
||||
Field *orig_field= field->dflt_field;
|
||||
Field *orig_field= default_field[i];
|
||||
/* Get the value from default_values */
|
||||
diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
|
||||
orig_field->table->record[0]);
|
||||
orig_field->move_field_offset(diff); // Points now at default_values
|
||||
bool is_null= orig_field->is_real_null();
|
||||
char *from= orig_field->ptr;
|
||||
orig_field->move_field_offset(-diff); // Back to record[0]
|
||||
if (is_null)
|
||||
if (orig_field->is_real_null())
|
||||
field->set_null();
|
||||
else
|
||||
{
|
||||
field->set_notnull();
|
||||
memcpy(field->ptr, from, field->pack_length());
|
||||
memcpy(field->ptr, orig_field->ptr, field->pack_length());
|
||||
}
|
||||
orig_field->move_field_offset(-diff); // Back to record[0]
|
||||
}
|
||||
|
||||
if (from_field[i])
|
||||
|
@ -12309,6 +12320,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||
Item::Type order_item_type;
|
||||
Item **select_item; /* The corresponding item from the SELECT clause. */
|
||||
Field *from_field; /* The corresponding field from the FROM clause. */
|
||||
uint counter;
|
||||
bool unaliased;
|
||||
|
||||
/*
|
||||
Local SP variables may be int but are expressions, not positions.
|
||||
|
@ -12330,8 +12343,6 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
|
|||
return FALSE;
|
||||
}
|
||||
/* Lookup the current GROUP/ORDER field in the SELECT clause. */
|
||||
uint counter;
|
||||
bool unaliased;
|
||||
select_item= find_item_in_list(order_item, fields, &counter,
|
||||
REPORT_EXCEPT_NOT_FOUND, &unaliased);
|
||||
if (!select_item)
|
||||
|
|
|
@ -2376,7 +2376,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
TABLE *table= tables->table;
|
||||
SELECT_LEX *select_lex= &lex->select_lex;
|
||||
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
|
||||
TABLE_LIST **save_query_tables_last= lex->query_tables_last;
|
||||
enum_sql_command save_sql_command= lex->sql_command;
|
||||
SELECT_LEX *lsel= tables->schema_select_lex;
|
||||
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
|
||||
|
@ -2395,6 +2394,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
enum legacy_db_type not_used;
|
||||
Open_tables_state open_tables_state_backup;
|
||||
bool save_view_prepare_mode= lex->view_prepare_mode;
|
||||
Query_tables_list query_tables_list_backup;
|
||||
lex->view_prepare_mode= TRUE;
|
||||
DBUG_ENTER("get_all_tables");
|
||||
|
||||
|
@ -2407,6 +2407,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
*/
|
||||
lex->sql_command= SQLCOM_SHOW_FIELDS;
|
||||
|
||||
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
|
||||
|
||||
/*
|
||||
We should not introduce deadlocks even if we already have some
|
||||
tables open and locked, since we won't lock tables which we will
|
||||
|
@ -2447,8 +2449,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
show_table_list->db),
|
||||
show_table_list->alias));
|
||||
thd->temporary_tables= 0;
|
||||
close_thread_tables(thd);
|
||||
show_table_list->table= 0;
|
||||
close_tables_for_reopen(thd, &show_table_list);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -2559,9 +2560,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
in this case.
|
||||
*/
|
||||
res= schema_table->process_table(thd, show_table_list, table,
|
||||
res, base_name,
|
||||
show_table_list->alias);
|
||||
close_thread_tables(thd);
|
||||
res, base_name,
|
||||
show_table_list->alias);
|
||||
close_tables_for_reopen(thd, &show_table_list);
|
||||
DBUG_ASSERT(!lex->query_tables_own_last);
|
||||
if (res)
|
||||
goto err;
|
||||
}
|
||||
|
@ -2578,11 +2580,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
error= 0;
|
||||
err:
|
||||
thd->restore_backup_open_tables_state(&open_tables_state_backup);
|
||||
lex->restore_backup_query_tables_list(&query_tables_list_backup);
|
||||
lex->derived_tables= derived_tables;
|
||||
lex->all_selects_list= old_all_select_lex;
|
||||
lex->query_tables_last= save_query_tables_last;
|
||||
lex->view_prepare_mode= save_view_prepare_mode;
|
||||
*save_query_tables_last= 0;
|
||||
lex->sql_command= save_sql_command;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
|
|
@ -3897,6 +3897,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
*/
|
||||
ha_autocommit_or_rollback(thd, 1);
|
||||
close_thread_tables(thd);
|
||||
lex->reset_query_tables_list(FALSE);
|
||||
if (protocol->write())
|
||||
goto err;
|
||||
continue;
|
||||
|
@ -3922,6 +3923,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
protocol->store(buff, length, system_charset_info);
|
||||
ha_autocommit_or_rollback(thd, 0);
|
||||
close_thread_tables(thd);
|
||||
lex->reset_query_tables_list(FALSE);
|
||||
table->table=0; // For query cache
|
||||
if (protocol->write())
|
||||
goto err;
|
||||
|
@ -4674,7 +4676,8 @@ static uint compare_tables(TABLE *table, List<create_field> *create_list,
|
|||
HA_CREATE_INFO *create_info,
|
||||
ALTER_INFO *alter_info, uint order_num,
|
||||
uint *index_drop_buffer, uint *index_drop_count,
|
||||
uint *index_add_buffer, uint *index_add_count)
|
||||
uint *index_add_buffer, uint *index_add_count,
|
||||
bool varchar)
|
||||
{
|
||||
Field **f_ptr, *field;
|
||||
uint changes= 0, tmp;
|
||||
|
@ -4709,7 +4712,8 @@ static uint compare_tables(TABLE *table, List<create_field> *create_list,
|
|||
create_info->used_fields & HA_CREATE_USED_CHARSET ||
|
||||
create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
|
||||
(alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
|
||||
order_num)
|
||||
order_num ||
|
||||
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
|
||||
DBUG_RETURN(ALTER_TABLE_DATA_CHANGED);
|
||||
|
||||
/*
|
||||
|
@ -4883,7 +4887,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
uint db_create_options, used_fields;
|
||||
handlerton *old_db_type, *new_db_type;
|
||||
uint need_copy_table= 0;
|
||||
bool no_table_reopen= FALSE;
|
||||
bool no_table_reopen= FALSE, varchar= FALSE;
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
uint fast_alter_partition= 0;
|
||||
bool partition_changed= FALSE;
|
||||
|
@ -5118,6 +5122,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
Field **f_ptr,*field;
|
||||
for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
|
||||
{
|
||||
if (field->type() == MYSQL_TYPE_STRING)
|
||||
varchar= TRUE;
|
||||
/* Check if field should be dropped */
|
||||
Alter_drop *drop;
|
||||
drop_it.rewind();
|
||||
|
@ -5453,7 +5459,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
key_info_buffer, key_count,
|
||||
create_info, alter_info, order_num,
|
||||
index_drop_buffer, &index_drop_count,
|
||||
index_add_buffer, &index_add_count);
|
||||
index_add_buffer, &index_add_count,
|
||||
varchar);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -748,9 +748,11 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
|||
tables.alias= table_list->alias;
|
||||
thd->lex->allow_sum_func= 0;
|
||||
|
||||
if (setup_tables(thd, &select_lex->context, &select_lex->top_join_list,
|
||||
table_list, conds, &select_lex->leaf_tables,
|
||||
FALSE) ||
|
||||
if (setup_tables_and_check_access(thd, &select_lex->context,
|
||||
&select_lex->top_join_list,
|
||||
table_list, conds,
|
||||
&select_lex->leaf_tables,
|
||||
FALSE, UPDATE_ACL) ||
|
||||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||
select_lex->setup_ref_array(thd, order_num) ||
|
||||
setup_order(thd, select_lex->ref_pointer_array,
|
||||
|
@ -841,10 +843,11 @@ reopen_tables:
|
|||
call in setup_tables()).
|
||||
*/
|
||||
|
||||
if (setup_tables(thd, &lex->select_lex.context,
|
||||
&lex->select_lex.top_join_list,
|
||||
table_list, &lex->select_lex.where,
|
||||
&lex->select_lex.leaf_tables, FALSE))
|
||||
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
|
||||
&lex->select_lex.top_join_list,
|
||||
table_list, &lex->select_lex.where,
|
||||
&lex->select_lex.leaf_tables, FALSE,
|
||||
UPDATE_ACL))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (setup_fields_with_no_wrap(thd, 0, *fields, 2, 0, 0))
|
||||
|
|
|
@ -1191,9 +1191,11 @@ ok:
|
|||
ok2:
|
||||
if (!old_lex->time_zone_tables_used && thd->lex->time_zone_tables_used)
|
||||
old_lex->time_zone_tables_used= thd->lex->time_zone_tables_used;
|
||||
DBUG_ASSERT(lex == thd->lex);
|
||||
thd->lex= old_lex; // Needed for prepare_security
|
||||
result= !table->prelocking_placeholder && table->prepare_security(thd);
|
||||
|
||||
lex_end(thd->lex);
|
||||
lex_end(lex);
|
||||
end:
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
|
|
17
sql/table.cc
17
sql/table.cc
|
@ -2832,7 +2832,8 @@ void st_table_list::hide_view_error(THD *thd)
|
|||
if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
|
||||
thd->net.last_errno == ER_SP_DOES_NOT_EXIST ||
|
||||
thd->net.last_errno == ER_PROCACCESS_DENIED_ERROR ||
|
||||
thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR)
|
||||
thd->net.last_errno == ER_COLUMNACCESS_DENIED_ERROR ||
|
||||
thd->net.last_errno == ER_TABLEACCESS_DENIED_ERROR)
|
||||
{
|
||||
TABLE_LIST *top= top_table();
|
||||
thd->clear_error();
|
||||
|
@ -3192,8 +3193,18 @@ bool st_table_list::prepare_view_securety_context(THD *thd)
|
|||
definer.host.str,
|
||||
thd->db))
|
||||
{
|
||||
my_error(ER_NO_SUCH_USER, MYF(0), definer.user.str, definer.host.str);
|
||||
DBUG_RETURN(TRUE);
|
||||
if (thd->lex->sql_command == SQLCOM_SHOW_CREATE)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_NO_SUCH_USER,
|
||||
ER(ER_NO_SUCH_USER),
|
||||
definer.user.str, definer.host.str);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_error(ER_NO_SUCH_USER, MYF(0), definer.user.str, definer.host.str);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
|
|
|
@ -105,7 +105,7 @@ int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *record,
|
|||
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
|
||||
if (keyinfo->flag & HA_NOSAME)
|
||||
{
|
||||
custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME | SEARCH_UPDATE;
|
||||
custom_arg.search_flag= SEARCH_FIND | SEARCH_UPDATE;
|
||||
keyinfo->rb_tree.flag= TREE_NO_DUPS;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
SUBDIRS = mytap . mysys examples
|
||||
|
||||
noinst_SCRIPTS = unit
|
||||
#EXTRA_DIST = unit.pl
|
||||
EXTRA_DIST = unit.pl
|
||||
|
||||
unittests = mytap mysys
|
||||
|
||||
|
|
|
@ -33,7 +33,8 @@ int vio_read(Vio * vio, gptr buf, int size)
|
|||
{
|
||||
int r;
|
||||
DBUG_ENTER("vio_read");
|
||||
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
|
||||
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %d", vio->sd, (long) buf,
|
||||
size));
|
||||
|
||||
/* Ensure nobody uses vio_read_buff and vio_read simultaneously */
|
||||
DBUG_ASSERT(vio->read_end == vio->read_pos);
|
||||
|
@ -64,7 +65,8 @@ int vio_read_buff(Vio *vio, gptr buf, int size)
|
|||
int rc;
|
||||
#define VIO_UNBUFFERED_READ_MIN_SIZE 2048
|
||||
DBUG_ENTER("vio_read_buff");
|
||||
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
|
||||
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %d", vio->sd, (long) buf,
|
||||
size));
|
||||
|
||||
if (vio->read_pos < vio->read_end)
|
||||
{
|
||||
|
@ -102,7 +104,8 @@ int vio_write(Vio * vio, const gptr buf, int size)
|
|||
{
|
||||
int r;
|
||||
DBUG_ENTER("vio_write");
|
||||
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
|
||||
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %d", vio->sd, (long) buf,
|
||||
size));
|
||||
#ifdef __WIN__
|
||||
r = send(vio->sd, buf, size,0);
|
||||
#else
|
||||
|
@ -223,7 +226,7 @@ int vio_keepalive(Vio* vio, my_bool set_keep_alive)
|
|||
int r=0;
|
||||
uint opt = 0;
|
||||
DBUG_ENTER("vio_keepalive");
|
||||
DBUG_PRINT("enter", ("sd: %d, set_keep_alive: %d", vio->sd, (int)
|
||||
DBUG_PRINT("enter", ("sd: %d set_keep_alive: %d", vio->sd, (int)
|
||||
set_keep_alive));
|
||||
if (vio->type != VIO_TYPE_NAMEDPIPE)
|
||||
{
|
||||
|
@ -393,7 +396,8 @@ int vio_read_pipe(Vio * vio, gptr buf, int size)
|
|||
{
|
||||
DWORD length;
|
||||
DBUG_ENTER("vio_read_pipe");
|
||||
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
|
||||
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %d", vio->sd, (long) buf,
|
||||
size));
|
||||
|
||||
if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
|
||||
DBUG_RETURN(-1);
|
||||
|
@ -407,7 +411,8 @@ int vio_write_pipe(Vio * vio, const gptr buf, int size)
|
|||
{
|
||||
DWORD length;
|
||||
DBUG_ENTER("vio_write_pipe");
|
||||
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
|
||||
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %d", vio->sd, (long) buf,
|
||||
size));
|
||||
|
||||
if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
|
||||
DBUG_RETURN(-1);
|
||||
|
@ -452,7 +457,8 @@ int vio_read_shared_memory(Vio * vio, gptr buf, int size)
|
|||
char *current_postion;
|
||||
|
||||
DBUG_ENTER("vio_read_shared_memory");
|
||||
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
|
||||
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %d", vio->sd, (long) buf,
|
||||
size));
|
||||
|
||||
remain_local = size;
|
||||
current_postion=buf;
|
||||
|
@ -513,7 +519,8 @@ int vio_write_shared_memory(Vio * vio, const gptr buf, int size)
|
|||
char *current_postion;
|
||||
|
||||
DBUG_ENTER("vio_write_shared_memory");
|
||||
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
|
||||
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %d", vio->sd, (long) buf,
|
||||
size));
|
||||
|
||||
remain = size;
|
||||
current_postion = buf;
|
||||
|
|
Loading…
Reference in a new issue