summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <jani@a193-229-222-105.elisa-laajakaista.fi>2006-05-30 16:07:49 +0300
committerunknown <jani@a193-229-222-105.elisa-laajakaista.fi>2006-05-30 16:07:49 +0300
commitae26d2aa5a13c49ce75e6b08d9799a8a799ff307 (patch)
tree2c12e857ee11b7f222060e29da2c84e53eaf050b
parent772758b6ecdec2551910a5c1f0cec5cee99315ec (diff)
parent8a5ca696ec572c7583ab5f73a726ce04fe72c413 (diff)
downloadmariadb-git-ae26d2aa5a13c49ce75e6b08d9799a8a799ff307.tar.gz
Merge a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.0
into a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-new mysql-test/mysql-test-run.pl: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/grant.result: Auto merged mysql-test/r/heap_btree.result: Auto merged mysql-test/r/information_schema_db.result: Auto merged mysql-test/r/lock_multi.result: Auto merged mysql-test/r/sp.result: Auto merged mysql-test/r/subselect.result: Auto merged mysql-test/r/view_grant.result: Auto merged mysql-test/t/lock_multi.test: Auto merged mysql-test/t/sp.test: Auto merged mysql-test/t/view_grant.test: Auto merged mysys/default.c: Auto merged server-tools/instance-manager/guardian.cc: Auto merged sql/field.h: Auto merged sql/item.h: Auto merged sql/item_subselect.cc: Auto merged sql/item_timefunc.cc: Auto merged sql/lock.cc: Auto merged sql/mysql_priv.h: Auto merged sql/sql_acl.cc: Auto merged sql/sql_delete.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_load.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_update.cc: Auto merged sql/table.cc: Auto merged storage/heap/hp_write.c: Auto merged storage/ndb/src/ndbapi/DictCache.cpp: Auto merged storage/ndb/src/ndbapi/DictCache.hpp: Auto merged client/mysqlbinlog.cc: Manual merge from 5.0 client/mysqldump.c: Manual merge from 5.0 configure.in: Manual merge from 5.0 mysql-test/r/mysqldump.result: Manual merge from 5.0 mysql-test/t/mysqldump.test: Manual merge from 5.0 mysql-test/t/rpl_insert_id.test: Manual merge from 5.0 server-tools/instance-manager/manager.cc: Manual merge from 5.0 sql/field.cc: Manual merge from 5.0 sql/ha_ndbcluster.cc: Manual merge from 5.0 sql/mysqld.cc: Manual merge from 5.0 sql/sql_base.cc: Manual merge from 5.0 sql/sql_lex.cc: Manual merge from 5.0 sql/sql_select.cc: Manual merge from 5.0 sql/sql_table.cc: Manual merge from 5.0
-rw-r--r--client/mysqlbinlog.cc17
-rw-r--r--client/mysqldump.c63
-rw-r--r--extra/yassl/include/yassl_error.hpp4
-rw-r--r--extra/yassl/mySTL/stdexcept.hpp2
-rw-r--r--extra/yassl/src/yassl_error.cpp3
-rw-r--r--extra/yassl/src/yassl_int.cpp11
-rw-r--r--extra/yassl/taocrypt/src/integer.cpp5
-rw-r--r--extra/yassl/taocrypt/src/misc.cpp13
-rwxr-xr-xextra/yassl/taocrypt/taocrypt.vcproj24
-rw-r--r--mysql-test/r/flush.result7
-rw-r--r--mysql-test/r/grant.result34
-rw-r--r--mysql-test/r/group_min_max.result41
-rw-r--r--mysql-test/r/heap_btree.result3
-rw-r--r--mysql-test/r/information_schema_db.result57
-rw-r--r--mysql-test/r/innodb_mysql.result76
-rw-r--r--mysql-test/r/lock_multi.result16
-rw-r--r--mysql-test/r/mysqldump.result40
-rw-r--r--mysql-test/r/sp.result30
-rw-r--r--mysql-test/r/subselect.result21
-rw-r--r--mysql-test/r/view_grant.result85
-rw-r--r--mysql-test/std_data/bug15328.cnf2
-rw-r--r--mysql-test/t/flush.test40
-rw-r--r--mysql-test/t/grant.test15
-rw-r--r--mysql-test/t/group_min_max.test54
-rw-r--r--mysql-test/t/heap_btree.test8
-rw-r--r--mysql-test/t/information_schema_db.test60
-rw-r--r--mysql-test/t/innodb_mysql.test94
-rw-r--r--mysql-test/t/lock_multi.test32
-rw-r--r--mysql-test/t/mysqldump.test20
-rw-r--r--mysql-test/t/sp.test46
-rw-r--r--mysql-test/t/subselect.test22
-rw-r--r--mysql-test/t/view_grant.test95
-rw-r--r--mysys/default.c4
-rw-r--r--server-tools/instance-manager/guardian.cc22
-rw-r--r--server-tools/instance-manager/manager.cc45
-rw-r--r--sql/field.cc11
-rw-r--r--sql/field.h6
-rw-r--r--sql/item.h3
-rw-r--r--sql/item_subselect.cc1
-rw-r--r--sql/item_timefunc.cc36
-rw-r--r--sql/lock.cc34
-rw-r--r--sql/mysql_priv.h9
-rw-r--r--sql/mysqld.cc10
-rw-r--r--sql/sql_acl.cc17
-rw-r--r--sql/sql_base.cc73
-rw-r--r--sql/sql_delete.cc18
-rw-r--r--sql/sql_insert.cc18
-rw-r--r--sql/sql_lex.cc108
-rw-r--r--sql/sql_lex.h151
-rw-r--r--sql/sql_load.cc9
-rw-r--r--sql/sql_parse.cc39
-rw-r--r--sql/sql_select.cc59
-rw-r--r--sql/sql_show.cc17
-rw-r--r--sql/sql_table.cc15
-rw-r--r--sql/sql_update.cc17
-rw-r--r--sql/table.cc17
-rw-r--r--storage/heap/hp_write.c2
57 files changed, 1378 insertions, 403 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 4b2527c25ef..81ad74466eb 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -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)
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 58cd2342bd3..e257e3734a1 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -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)
diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp
index 9c12b06e34a..2f35fecb59b 100644
--- a/extra/yassl/include/yassl_error.hpp
+++ b/extra/yassl/include/yassl_error.hpp
@@ -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
diff --git a/extra/yassl/mySTL/stdexcept.hpp b/extra/yassl/mySTL/stdexcept.hpp
index b50dd35edae..33ea43bf0e0 100644
--- a/extra/yassl/mySTL/stdexcept.hpp
+++ b/extra/yassl/mySTL/stdexcept.hpp
@@ -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
};
diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp
index 1973c54d781..72b8e459241 100644
--- a/extra/yassl/src/yassl_error.cpp
+++ b/extra/yassl/src/yassl_error.cpp
@@ -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)
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index a715d32f282..842bcd5fb5d 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -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;
}
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index 885ddfbf630..a296e122985 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -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)
diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp
index 4ef163a7f5d..2869df71c8a 100644
--- a/extra/yassl/taocrypt/src/misc.cpp
+++ b/extra/yassl/taocrypt/src/misc.cpp
@@ -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
diff --git a/extra/yassl/taocrypt/taocrypt.vcproj b/extra/yassl/taocrypt/taocrypt.vcproj
index 603fafd4090..7eef7b82db7 100755
--- a/extra/yassl/taocrypt/taocrypt.vcproj
+++ b/extra/yassl/taocrypt/taocrypt.vcproj
@@ -397,6 +397,27 @@
</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
Name="Debug|Win32">
@@ -572,6 +593,9 @@
RelativePath="include\md2.hpp">
</File>
<File
+ RelativePath="include\md4.hpp">
+ </File>
+ <File
RelativePath="include\md5.hpp">
</File>
<File
diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result
index 16c308e3450..a7f5e5e8fec 100644
--- a/mysql-test/r/flush.result
+++ b/mysql-test/r/flush.result
@@ -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;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index 4815798d807..75afab911b9 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -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;
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index f9b55cc6a7b..d62586dba85 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -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);
diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result
index 7b944558a62..4c7ea0eae7b 100644
--- a/mysql-test/r/heap_btree.result
+++ b/mysql-test/r/heap_btree.result
@@ -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;
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index 37537e257da..5919e0f071d 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -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;
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index bbd9550196f..8dbfa906fe1 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -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;
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
index 1ab51e9fad5..180c8f41b70 100644
--- a/mysql-test/r/lock_multi.result
+++ b/mysql-test/r/lock_multi.result
@@ -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;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 493e79d4136..fabf721466e 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -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 ('','');
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 8330c391715..9bdd1d5645f 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -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;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 71a71a14ad2..e307bb9eafe 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -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;
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index 928e3635ec6..4dfdd65339a 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -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;
diff --git a/mysql-test/std_data/bug15328.cnf b/mysql-test/std_data/bug15328.cnf
new file mode 100644
index 00000000000..e23d33bfa54
--- /dev/null
+++ b/mysql-test/std_data/bug15328.cnf
@@ -0,0 +1,2 @@
+[mysqldump]
+fields-optionally-enclosed-by="
diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test
index f5fd9fcadf2..95ba633fefd 100644
--- a/mysql-test/t/flush.test
+++ b/mysql-test/t/flush.test
@@ -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
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index 97f13381557..3db38d93ee1 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -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
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index d9836ccc8df..874f3cd1a80 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -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
diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test
index f1b9d290885..fb715fccefe 100644
--- a/mysql-test/t/heap_btree.test
+++ b/mysql-test/t/heap_btree.test
@@ -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
diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test
index b65135a621d..2cfa766d799 100644
--- a/mysql-test/t/information_schema_db.test
+++ b/mysql-test/t/information_schema_db.test
@@ -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;
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index 3de55e1c403..c7d2e2c0acd 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -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;
+
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 3d07ec98d69..a24ee8be64e 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -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
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 732a3ce89da..1aef8f6c176 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -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;
@@ -607,6 +607,13 @@ 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
#
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 90d43bf7cc0..8f5fcdc9d52 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -5850,6 +5850,52 @@ 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
#
#--disable_warnings
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 3f48b648f40..8916a5cec6d 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -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;
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 8deff474587..d55323e2c56 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -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;
diff --git a/mysys/default.c b/mysys/default.c
index 3a80d7b37b9..863ebc37dbc 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -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--;
diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc
index 7a9ff3e8367..b58241272f9 100644
--- a/server-tools/instance-manager/guardian.cc
+++ b/server-tools/instance-manager/guardian.cc
@@ -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
{
diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc
index e2bb09cb9fa..599131089ed 100644
--- a/server-tools/instance-manager/manager.cc
+++ b/server-tools/instance-manager/manager.cc
@@ -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.
diff --git a/sql/field.cc b/sql/field.cc
index e1d7aaf6343..19c781388d0 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1218,7 +1218,7 @@ 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),
@@ -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]
}
}
diff --git a/sql/field.h b/sql/field.h
index 602b4ea779d..b473100eaab 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -55,12 +55,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)
*/
diff --git a/sql/item.h b/sql/item.h
index 2f99034130a..c422eee87e8 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -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) {};
/*
@@ -2289,6 +2291,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;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 5280dbf6813..8fa341520f1 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -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
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 9d98e446c84..a2c7af79ef3 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -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));
}
diff --git a/sql/lock.cc b/sql/lock.cc
index 5a6cd58dd56..80861e3beb5 100644
--- a/sql/lock.cc
+++ b/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)))
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index e3db96be2e7..bc99c1dc8f4 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -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;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 91828edec9c..029290d9f39 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -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
@@ -2859,6 +2858,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);
@@ -5021,7 +5021,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,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index d2501d08c4d..76d1567514d 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -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
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 58c04224ac9..85729c314ae 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -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
@@ -5368,6 +5375,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
SYNOPSIS
@@ -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++;
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 44b0fe1a2f1..eb05ad654e4 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -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);
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 84760e93d8e..d8934b54b85 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -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 :
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 02711ed8f48..d45f4369095 100644
--- a/sql/sql_lex.cc
+++ b/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;
@@ -1604,6 +1598,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.
SYNOPSIS
@@ -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);
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 12c7b106c26..77f79ad61f4 100644
--- a/sql/sql_lex.h
+++ b/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;
@@ -989,14 +1053,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
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index bf8a6b8cfbe..5c5e56f9ecc 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -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
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 3206cfa2d52..f11ab437a64 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2212371db92..4918768a03f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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),
&reg_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,
&copy_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(), &copy_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, &copy_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)
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index bdf0724ee96..892b59574d9 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2375,7 +2375,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;
@@ -2394,6 +2393,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");
@@ -2406,6 +2406,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
@@ -2446,8 +2448,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;
}
@@ -2558,9 +2559,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;
}
@@ -2577,11 +2579,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);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 289051c2dd1..634e43569ca 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3896,6 +3896,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;
@@ -3921,6 +3922,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;
@@ -4673,7 +4675,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;
@@ -4708,7 +4711,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);
/*
@@ -4882,7 +4886,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;
@@ -5117,6 +5121,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();
@@ -5452,7 +5458,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);
}
/*
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 75e8db6621f..50afe87e219 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -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))
diff --git a/sql/table.cc b/sql/table.cc
index d0caba7fe9e..235b2a9413a 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2821,7 +2821,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();
@@ -3181,8 +3182,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);
diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c
index a60d32eecb6..bc94e3bfae4 100644
--- a/storage/heap/hp_write.c
+++ b/storage/heap/hp_write.c
@@ -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