summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2013-06-18 02:01:34 +0300
committerMichael Widenius <monty@askmonty.org>2013-06-18 02:01:34 +0300
commit2534521f9a7d66b48cb9ca9402e82a0c58b156d8 (patch)
tree920207a20892d748bd6b04a6699f07a5f3f1fae5
parent0b7f8ed9738546f57d9159b52894e5abc99086fc (diff)
downloadmariadb-git-2534521f9a7d66b48cb9ca9402e82a0c58b156d8.tar.gz
Fixed some merge issues:
- temporary tables now works - mysql-system_tables updated to not use temporary tables - PASSWORD() function fixed - Support for STATS_AUTO_RECALC, STATS_PERSISTENT and STATS_SAMPLE_PAGES table options
-rwxr-xr-xmysql-test/mysql-test-run.pl2
-rw-r--r--scripts/mysql_system_tables.sql7
-rw-r--r--scripts/mysql_system_tables_data.sql8
-rw-r--r--sql/item_strfunc.cc125
-rw-r--r--sql/item_strfunc.h17
-rw-r--r--sql/lex.h3
-rw-r--r--sql/lock.cc1
-rw-r--r--sql/log_event.cc3
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/sp_head.cc3
-rw-r--r--sql/sql_acl.cc20
-rw-r--r--sql/sql_acl.h10
-rw-r--r--sql/sql_admin.cc12
-rw-r--r--sql/sql_base.cc23
-rw-r--r--sql/sql_handler.cc3
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_parse.cc72
-rw-r--r--sql/sql_prepare.cc31
-rw-r--r--sql/sql_show.cc48
-rw-r--r--sql/sql_table.cc35
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_view.cc3
-rw-r--r--sql/sql_yacc.yy102
24 files changed, 473 insertions, 62 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 46f2215ffb8..ea22f9577e9 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -552,7 +552,7 @@ sub main {
}
}
- if ( not defined @$completed ) {
+ if ( not @$completed ) {
mtr_error("Test suite aborted");
}
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index d0535dce584..6ed9e22f748 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -79,10 +79,10 @@ CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NUL
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
--- Create general_log if CSV is enabled.
-- Create general_log if CSV is enabled.
-SET @have_csv = (SELECT support FROM information_schema.engines WHERE engine = 'CSV');
+SET @have_csv = 'NO';
+SET @have_csv = (SELECT @@have_csv);
SET @str = IF (@have_csv = 'YES', 'CREATE TABLE IF NOT EXISTS general_log (event_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, user_host MEDIUMTEXT NOT NULL, thread_id BIGINT(21) UNSIGNED NOT NULL, server_id INTEGER UNSIGNED NOT NULL, command_type VARCHAR(64) NOT NULL, argument MEDIUMTEXT NOT NULL) engine=CSV CHARACTER SET utf8 comment="General log"', 'SET @dummy = 0');
PREPARE stmt FROM @str;
@@ -130,7 +130,8 @@ CREATE TABLE IF NOT EXISTS innodb_index_stats (
SET SESSION sql_mode=@sql_mode_orig;
-set @have_innodb= (select count(engine) from information_schema.engines where engine='INNODB' and support != 'NO');
+SET @have_innodb = 'NO';
+SET @have_innodb = (SELECT @@have_innodb);
SET @cmd="CREATE TABLE IF NOT EXISTS slave_relay_log_info (
Number_of_lines INTEGER UNSIGNED NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql
index 878555e9458..243d4d8d444 100644
--- a/scripts/mysql_system_tables_data.sql
+++ b/scripts/mysql_system_tables_data.sql
@@ -37,10 +37,10 @@ DROP TABLE tmp_db;
-- from local machine if "users" table didn't exist before
CREATE TEMPORARY TABLE tmp_user LIKE user;
set @current_hostname= @@hostname;
-INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','');
-REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','' FROM dual WHERE LOWER( @current_hostname) != 'localhost';
-REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','');
-REPLACE INTO tmp_user VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','');
+INSERT INTO tmp_user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','');
+REPLACE INTO tmp_user SELECT @current_hostname,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','' FROM dual WHERE LOWER( @current_hostname) != 'localhost';
+REPLACE INTO tmp_user VALUES ('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','');
+REPLACE INTO tmp_user VALUES ('::1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','','');
INSERT INTO tmp_user (host,user) VALUES ('localhost','');
INSERT INTO tmp_user (host,user) SELECT @current_hostname,'' FROM dual WHERE LOWER(@current_hostname ) != 'localhost';
INSERT INTO user SELECT * FROM tmp_user WHERE @had_user_table=0;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 9b88e45be0e..a8287d5fe43 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1808,28 +1808,133 @@ void Item_func_trim::print(String *str, enum_query_type query_type)
/* Item_func_password */
+/**
+ Helper function for calculating a new password. Used in
+ Item_func_password::fix_length_and_dec() for const parameters and in
+ Item_func_password::val_str_ascii() for non-const parameters.
+ @param str The plain text password which should be digested
+ @param buffer a pointer to the buffer where the digest will be stored.
+
+ @note The buffer must be of at least CRYPT_MAX_PASSWORD_SIZE size.
+
+ @return Size of the password.
+*/
+
+static int calculate_password(String *str, char *buffer)
+{
+ DBUG_ASSERT(str);
+ if (str->length() == 0) // PASSWORD('') returns ''
+ return 0;
+
+ int buffer_len= 0;
+ THD *thd= current_thd;
+ int old_passwords= 0;
+ if (thd)
+ old_passwords= thd->variables.old_passwords;
+
+#if defined(HAVE_OPENSSL)
+ if (old_passwords == 2)
+ {
+ my_make_scrambled_password(buffer, str->ptr(),
+ str->length());
+ buffer_len= (int) strlen(buffer) + 1;
+ }
+ else
+#endif
+ if (old_passwords == 0)
+ {
+ my_make_scrambled_password_sha1(buffer, str->ptr(),
+ str->length());
+ buffer_len= SCRAMBLED_PASSWORD_CHAR_LENGTH;
+ }
+ else
+ if (old_passwords == 1)
+ {
+ my_make_scrambled_password_323(buffer, str->ptr(),
+ str->length());
+ buffer_len= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
+ }
+ return buffer_len;
+}
+
+/* Item_func_password */
+void Item_func_password::fix_length_and_dec()
+{
+ maybe_null= false; // PASSWORD() never returns NULL
+
+ if (args[0]->const_item())
+ {
+ String str;
+ String *res= args[0]->val_str(&str);
+ if (!args[0]->null_value)
+ {
+ m_hashed_password_buffer_len=
+ calculate_password(res, m_hashed_password_buffer);
+ fix_length_and_charset(m_hashed_password_buffer_len, default_charset());
+ m_recalculate_password= false;
+ return;
+ }
+ }
+
+ m_recalculate_password= true;
+ fix_length_and_charset(CRYPT_MAX_PASSWORD_SIZE, default_charset());
+}
+
String *Item_func_password::val_str_ascii(String *str)
{
DBUG_ASSERT(fixed == 1);
- String *res= args[0]->val_str(str);
- if ((null_value=args[0]->null_value))
- return 0;
- if (res->length() == 0)
+
+ String *res= args[0]->val_str(str);
+
+ if (args[0]->null_value)
+ res= make_empty_result();
+
+ /* we treat NULLs as equal to empty string when calling the plugin */
+ check_password_policy(res);
+
+ null_value= 0;
+ if (args[0]->null_value) // PASSWORD(NULL) returns ''
+ return res;
+
+ if (m_recalculate_password)
+ m_hashed_password_buffer_len= calculate_password(res,
+ m_hashed_password_buffer);
+
+ if (m_hashed_password_buffer_len == 0)
return make_empty_result();
- my_make_scrambled_password(tmp_value, res->ptr(), res->length());
- str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1);
+
+ str->set(m_hashed_password_buffer, m_hashed_password_buffer_len,
+ default_charset());
+
return str;
}
-char *Item_func_password::alloc(THD *thd, const char *password,
- size_t pass_len)
+char *Item_func_password::
+ create_password_hash_buffer(THD *thd, const char *password, size_t pass_len)
{
- char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
- if (buff)
+ String *password_str= new (thd->mem_root)String(password, thd->variables.
+ character_set_client);
+ check_password_policy(password_str);
+
+ char *buff= NULL;
+ if (thd->variables.old_passwords == 0)
+ {
+ /* Allocate memory for the password scramble and one extra byte for \0 */
+ buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH + 1);
+ my_make_scrambled_password_sha1(buff, password, pass_len);
+ }
+#if defined(HAVE_OPENSSL)
+ else
+ {
+ /* Allocate memory for the password scramble and one extra byte for \0 */
+ buff= (char *) thd->alloc(CRYPT_MAX_PASSWORD_SIZE + 1);
my_make_scrambled_password(buff, password, pass_len);
+ }
+#endif
return buff;
}
+
/* Item_func_old_password */
String *Item_func_old_password::val_str_ascii(String *str)
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 44be352bb05..c4fdc453ccc 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -21,6 +21,8 @@
/* This file defines all string functions */
+#include "crypt_genhash_impl.h"
+
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
@@ -311,16 +313,21 @@ public:
class Item_func_password :public Item_str_ascii_func
{
- char tmp_value[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
+ char m_hashed_password_buffer[CRYPT_MAX_PASSWORD_SIZE + 1];
+ unsigned int m_hashed_password_buffer_len;
+ bool m_recalculate_password;
public:
- Item_func_password(Item *a) :Item_str_ascii_func(a) {}
- String *val_str_ascii(String *str);
- void fix_length_and_dec()
+ Item_func_password(Item *a) :Item_str_ascii_func(a)
{
- fix_length_and_charset(SCRAMBLED_PASSWORD_CHAR_LENGTH, default_charset());
+ m_hashed_password_buffer_len= 0;
+ m_recalculate_password= false;
}
+ String *val_str_ascii(String *str);
+ void fix_length_and_dec();
const char *func_name() const { return "password"; }
static char *alloc(THD *thd, const char *password, size_t pass_len);
+ static char *create_password_hash_buffer(THD *thd, const char *password,
+ size_t pass_len);
};
diff --git a/sql/lex.h b/sql/lex.h
index 0f20df71576..06d6012b469 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -557,6 +557,9 @@ static SYMBOL symbols[] = {
{ "START", SYM(START_SYM)},
{ "STARTING", SYM(STARTING)},
{ "STARTS", SYM(STARTS_SYM)},
+ { "STATS_AUTO_RECALC",SYM(STATS_AUTO_RECALC_SYM)},
+ { "STATS_PERSISTENT", SYM(STATS_PERSISTENT_SYM)},
+ { "STATS_SAMPLE_PAGES",SYM(STATS_SAMPLE_PAGES_SYM)},
{ "STATUS", SYM(STATUS_SYM)},
{ "STOP", SYM(STOP_SYM)},
{ "STORAGE", SYM(STORAGE_SYM)},
diff --git a/sql/lock.cc b/sql/lock.cc
index bf53a925424..22ef9b95d29 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -705,7 +705,6 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
{
TABLE *t= table_ptr[i];
-
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE &&
t->s->tmp_table != INTERNAL_TMP_TABLE)
{
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 4983263f589..c270b83fa7e 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -5607,7 +5607,8 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
update it inside mysql_load().
*/
List<Item> tmp_list;
- if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
+ if (open_temporary_tables(thd, &tables) ||
+ mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
handle_dup, ignore, net != 0))
thd->is_slave_error= 1;
if (thd->cuted_fields)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 65cce38e788..260427c1e2b 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3630,7 +3630,9 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
DBUG_PRINT("info", ("memory_used: %lld size: %lld",
(longlong) thd->status_var.memory_used, size));
thd->status_var.memory_used+= size;
+#ifndef ENABLE_BEFORE_END_OF_MERGE
DBUG_ASSERT((longlong) thd->status_var.memory_used >= 0);
+#endif
}
}
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index e54bd796bbb..59363a7a04a 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3094,7 +3094,8 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
Check whenever we have access to tables for this statement
and open and lock them before executing instructions core function.
*/
- if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)
+ if (open_temporary_tables(thd, tables) ||
+ check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, tables, TRUE, 0))
result= -1;
else
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index a33e087fdf4..2771ee25ffd 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -4634,6 +4634,19 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
}
continue;
}
+
+ if (is_temporary_table(tl))
+ {
+ /*
+ If this table list element corresponds to a pre-opened temporary
+ table skip checking of all relevant table-level privileges for it.
+ Note that during creation of temporary table we still need to check
+ if user has CREATE_TMP_ACL.
+ */
+ tl->grant.want_privilege= 0;
+ continue;
+ }
+
GRANT_TABLE *grant_table= table_hash_search(sctx->host, sctx->ip,
tl->get_db_name(),
sctx->priv_user,
@@ -9364,3 +9377,10 @@ maria_declare_plugin(mysql_password)
MariaDB_PLUGIN_MATURITY_BETA /* Maturity */
}
maria_declare_plugin_end;
+
+
+/* called when new user is created or exsisting password is changed */
+int check_password_policy(String *password)
+{
+ return (0);
+}
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 3169746419c..d519279e9c2 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -95,6 +95,14 @@
CREATE_ACL | DROP_ACL | ALTER_ACL | INDEX_ACL | \
TRIGGER_ACL | REFERENCES_ACL | GRANT_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL)
+/**
+ Table-level privileges which are automatically "granted" to everyone on
+ existing temporary tables (CREATE_ACL is necessary for ALTER ... RENAME).
+*/
+#define TMP_TABLE_ACLS \
+(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
+ INDEX_ACL | ALTER_ACL)
+
/*
Defines to change the above bits to how things are stored in tables
This is needed as the 'host' and 'db' table is missing a few privileges
@@ -245,7 +253,7 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
-
+int check_password_policy(String *password);
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define check_grant(A,B,C,D,E,F) 0
#define check_grant_db(A,B) 0
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index be2a4d3df64..214cfdd0bbb 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -44,7 +44,8 @@ static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
thd->mdl_context.release_transactional_locks();
DEBUG_SYNC(thd, "ha_admin_try_alter");
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
- result_code= mysql_recreate_table(thd, table_list);
+ result_code= (open_temporary_tables(thd, table_list) ||
+ mysql_recreate_table(thd, table_list));
reenable_binlog(thd);
/*
mysql_recreate_table() can push OK or ERROR.
@@ -404,7 +405,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
da->push_warning_info(&tmp_wi);
- open_error= open_and_lock_tables(thd, table, TRUE, 0);
+ open_error= (open_temporary_tables(thd, table) ||
+ open_and_lock_tables(thd, table, TRUE, 0));
da->pop_warning_info();
}
@@ -418,7 +420,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
mode. It does make sense for the user to see such errors.
*/
- open_error= open_and_lock_tables(thd, table, TRUE, 0);
+ open_error= (open_temporary_tables(thd, table) ||
+ open_and_lock_tables(thd, table, TRUE, 0));
}
thd->prepare_derived_at_open= FALSE;
@@ -857,7 +860,8 @@ send_result_message:
table->mdl_request.ticket= NULL;
DEBUG_SYNC(thd, "ha_admin_open_ltable");
table->mdl_request.set_type(MDL_SHARED_WRITE);
- if ((table->table= open_ltable(thd, table, lock_type, 0)))
+ if (open_temporary_tables(thd, table) ||
+ (table->table= open_ltable(thd, table, lock_type, 0)))
{
result_code= table->table->file->ha_analyze(thd, check_opt);
if (result_code == HA_ADMIN_ALREADY_DONE)
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 0680c8f1b23..e223b521bfb 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -4534,6 +4534,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
bool safe_to_ignore_table= FALSE;
DBUG_ENTER("open_and_process_table");
DEBUG_SYNC(thd, "open_and_process_table");
+ DBUG_ASSERT(!tables->table);
/*
Ignore placeholders for derived tables. After derived tables
@@ -5172,6 +5173,14 @@ restart:
for (tables= *table_to_open; tables;
table_to_open= &tables->next_global, tables= tables->next_global)
{
+ /* Ignore temporary tables, as these has already been opened */
+ if (tables->table)
+ {
+ DBUG_ASSERT(is_temporary_table(tables));
+ /* We have to increment the counter for lock_tables */
+ (*counter)++;
+ continue;
+ }
error= open_and_process_table(thd, thd->lex, tables, counter,
flags, prelocking_strategy,
has_prelocking_list, &ot_ctx,
@@ -5206,6 +5215,10 @@ restart:
if (ot_ctx.recover_from_failed_open(thd))
goto err;
+ /* Re-open temporary tables after close_tables_for_reopen(). */
+ if (open_temporary_tables(thd, *start))
+ goto err;
+
error= FALSE;
goto restart;
}
@@ -5259,6 +5272,10 @@ restart:
if (ot_ctx.recover_from_failed_open(thd))
goto err;
+ /* Re-open temporary tables after close_tables_for_reopen(). */
+ if (open_temporary_tables(thd, *start))
+ goto err;
+
error= FALSE;
goto restart;
}
@@ -5673,6 +5690,10 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
bool error;
DBUG_ENTER("open_ltable");
+ /* Ignore temporary tables as they have already ben opened*/
+ if (table_list->table)
+ DBUG_RETURN(table_list->table);
+
/* should not be used in a prelocked_mode context, see NOTE above */
DBUG_ASSERT(thd->locked_tables_mode < LTM_PRELOCKED);
@@ -5922,7 +5943,6 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
uint flags)
{
TABLE_LIST *table;
-
DBUG_ENTER("lock_tables");
/*
We can't meet statement requiring prelocking if we already
@@ -6276,6 +6296,7 @@ TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
}
tmp_table->reginfo.lock_type= TL_WRITE; // Simulate locked
+ tmp_table->grant.privilege= TMP_TABLE_ACLS;
share->tmp_table= (tmp_table->file->has_transactions() ?
TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 64b21ea6ab0..03978f3a4ba 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -294,7 +294,8 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
open_ltable() or open_table() because we would like to be able
to open a temporary table.
*/
- error= open_tables(thd, &tables, &counter, 0);
+ error= (open_temporary_tables(thd, tables) ||
+ open_tables(thd, &tables, &counter, 0));
if (error)
goto err;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 9b12b6dcbeb..67fa3301b6c 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -509,6 +509,7 @@ void lex_start(THD *thd)
lex->use_only_table_context= FALSE;
lex->parse_vcol_expr= FALSE;
lex->verbose= 0;
+ lex->contains_plaintext_password= false;
lex->name.str= 0;
lex->name.length= 0;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 964acddfc23..92c78335238 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -2388,6 +2388,8 @@ struct LEX: public Query_tables_list
bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */
bool all_privileges;
bool proxy_priv;
+ bool contains_plaintext_password;
+
sp_pcontext *spcont;
st_sp_chistics sp_chistics;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index e80a221f3c4..e3503c171ac 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -512,7 +512,7 @@ void init_update_queries(void)
DDL statements that should start with closing opened handlers.
We use this flag only for statements for which open HANDLERs
- have to be closed before emporary tables are pre-opened.
+ have to be closed before temporary tables are pre-opened.
*/
sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_HA_CLOSE;
sql_command_flags[SQLCOM_DROP_TABLE]|= CF_HA_CLOSE;
@@ -1411,6 +1411,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->set_query(fields, query_length);
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
+ if (open_temporary_tables(thd, &table_list))
+ break;
+
if (check_table_access(thd, SELECT_ACL, &table_list,
TRUE, UINT_MAX, FALSE))
break;
@@ -2386,6 +2389,30 @@ mysql_execute_command(THD *thd)
goto error;
}
+ /*
+ Close tables open by HANDLERs before executing DDL statement
+ which is going to affect those tables.
+
+ This should happen before temporary tables are pre-opened as
+ otherwise we will get errors about attempt to re-open tables
+ if table to be changed is open through HANDLER.
+
+ Note that even although this is done before any privilege
+ checks there is no security problem here as closing open
+ HANDLER doesn't require any privileges anyway.
+ */
+ if (sql_command_flags[lex->sql_command] & CF_HA_CLOSE)
+ mysql_ha_rm_tables(thd, all_tables);
+
+ /*
+ Pre-open temporary tables to simplify privilege checking
+ for statements which need this.
+ */
+ if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES)
+ {
+ if (open_temporary_tables(thd, all_tables))
+ goto error;
+ }
switch (lex->sql_command) {
case SQLCOM_SHOW_EVENTS:
@@ -2771,7 +2798,10 @@ case SQLCOM_PREPARE:
}
#endif
- /* Close any open handlers for the table. */
+ /*
+ Close any open handlers for the table. We need to this extra call here
+ as there may have been new handlers created since the previous call.
+ */
mysql_ha_rm_tables(thd, create_table);
if (select_lex->item_list.elements) // With select
@@ -3107,6 +3137,13 @@ end_with_restore_list:
else
{
/*
+ Temporary tables should be opened for SHOW CREATE TABLE, but not
+ for SHOW CREATE VIEW.
+ */
+ if (open_temporary_tables(thd, all_tables))
+ goto error;
+
+ /*
The fact that check_some_access() returned FALSE does not mean that
access is granted. We need to check if first_table->grant.privilege
contains any table-specific privilege.
@@ -3284,6 +3321,18 @@ end_with_restore_list:
case SQLCOM_INSERT:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
+
+ /*
+ Since INSERT DELAYED doesn't support temporary tables, we could
+ not pre-open temporary tables for SQLCOM_INSERT / SQLCOM_REPLACE.
+ Open them here instead.
+ */
+ if (first_table->lock_type != TL_WRITE_DELAYED)
+ {
+ if ((res= open_temporary_tables(thd, all_tables)))
+ break;
+ }
+
if ((res= insert_precheck(thd, all_tables)))
break;
@@ -3621,6 +3670,19 @@ end_with_restore_list:
thd->mdl_context.release_transactional_locks();
if (res)
goto error;
+
+ /*
+ Here we have to pre-open temporary tables for LOCK TABLES.
+
+ CF_PREOPEN_TMP_TABLES is not set for this SQL statement simply
+ because LOCK TABLES calls close_thread_tables() as a first thing
+ (it's called from unlock_locked_tables() above). So even if
+ CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened
+ in a usual way, they would have been closed.
+ */
+ if (open_temporary_tables(thd, all_tables))
+ goto error;
+
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
FALSE, UINT_MAX, FALSE))
goto error;
@@ -5438,6 +5500,12 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
DBUG_ASSERT(dst_table);
+ /*
+ Open temporary tables to be able to detect them during privilege check.
+ */
+ if (open_temporary_tables(thd, dst_table))
+ return TRUE;
+
if (check_access(thd, SELECT_ACL, dst_table->db,
&dst_table->grant.privilege,
&dst_table->grant.m_internal,
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 2460f15ab62..4649555a348 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1253,6 +1253,17 @@ static bool mysql_test_insert(Prepared_statement *stmt,
List_item *values;
DBUG_ENTER("mysql_test_insert");
+ /*
+ Since INSERT DELAYED doesn't support temporary tables, we could
+ not pre-open temporary tables for SQLCOM_INSERT / SQLCOM_REPLACE.
+ Open them here instead.
+ */
+ if (table_list->lock_type != TL_WRITE_DELAYED)
+ {
+ if (open_temporary_tables(thd, table_list))
+ goto error;
+ }
+
if (insert_precheck(thd, table_list))
goto error;
@@ -1819,6 +1830,13 @@ static bool mysql_test_create_view(Prepared_statement *stmt)
if (create_view_precheck(thd, tables, view, lex->create_view_mode))
goto err;
+ /*
+ Since we can't pre-open temporary tables for SQLCOM_CREATE_VIEW,
+ (see mysql_create_view) we have to do it here instead.
+ */
+ if (open_temporary_tables(thd, tables))
+ goto err;
+
if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_PREPARE))
goto err;
@@ -2056,6 +2074,19 @@ static bool check_prepared_statement(Prepared_statement *stmt)
if (tables)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
+ if (sql_command_flags[sql_command] & CF_HA_CLOSE)
+ mysql_ha_rm_tables(thd, tables);
+
+ /*
+ Open temporary tables that are known now. Temporary tables added by
+ prelocking will be opened afterwards (during open_tables()).
+ */
+ if (sql_command_flags[sql_command] & CF_PREOPEN_TMP_TABLES)
+ {
+ if (open_temporary_tables(thd, tables))
+ goto error;
+ }
+
switch (sql_command) {
case SQLCOM_REPLACE:
case SQLCOM_INSERT:
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1fc24b61c47..f3cb797226c 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1880,6 +1880,22 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
if (create_info.options & HA_OPTION_NO_PACK_KEYS)
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
+ if (share->db_create_options & HA_OPTION_STATS_PERSISTENT)
+ packet->append(STRING_WITH_LEN(" STATS_PERSISTENT=1"));
+ if (share->db_create_options & HA_OPTION_NO_STATS_PERSISTENT)
+ packet->append(STRING_WITH_LEN(" STATS_PERSISTENT=0"));
+ if (share->stats_auto_recalc == HA_STATS_AUTO_RECALC_ON)
+ packet->append(STRING_WITH_LEN(" STATS_AUTO_RECALC=1"));
+ else if (share->stats_auto_recalc == HA_STATS_AUTO_RECALC_OFF)
+ packet->append(STRING_WITH_LEN(" STATS_AUTO_RECALC=0"));
+ if (share->stats_sample_pages != 0)
+ {
+ char *end;
+ packet->append(STRING_WITH_LEN(" STATS_SAMPLE_PAGES="));
+ end= longlong10_to_str(share->stats_sample_pages, buff, 10);
+ packet->append(buff, (uint) (end - buff));
+ }
+
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
if (create_info.options & HA_OPTION_CHECKSUM)
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
@@ -4059,12 +4075,13 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
'only_view_structure()'.
*/
lex->sql_command= SQLCOM_SHOW_FIELDS;
- result= open_normal_and_derived_tables(thd, table_list,
- (MYSQL_OPEN_IGNORE_FLUSH |
- MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
- (can_deadlock ?
- MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)),
- DT_PREPARE | DT_CREATE);
+ result= (open_temporary_tables(thd, table_list) ||
+ open_normal_and_derived_tables(thd, table_list,
+ (MYSQL_OPEN_IGNORE_FLUSH |
+ MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
+ (can_deadlock ?
+ MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)),
+ DT_PREPARE | DT_CREATE));
/*
Restore old value of sql_command back as it is being looked at in
process_table() function.
@@ -4898,7 +4915,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
}
else
{
- char option_buff[350];
+ char option_buff[512];
String str(option_buff,sizeof(option_buff), system_charset_info);
TABLE *show_table= tables->table;
TABLE_SHARE *share= show_table->s;
@@ -4963,6 +4980,23 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
str.qs_append(STRING_WITH_LEN(" pack_keys=0"));
+ if (share->db_create_options & HA_OPTION_STATS_PERSISTENT)
+ str.qs_append(STRING_WITH_LEN(" stats_persistent=1"));
+
+ if (share->db_create_options & HA_OPTION_NO_STATS_PERSISTENT)
+ str.qs_append(STRING_WITH_LEN(" stats_persistent=0"));
+
+ if (share->stats_auto_recalc == HA_STATS_AUTO_RECALC_ON)
+ str.qs_append(STRING_WITH_LEN(" stats_auto_recalc=1"));
+ else if (share->stats_auto_recalc == HA_STATS_AUTO_RECALC_OFF)
+ str.qs_append(STRING_WITH_LEN(" stats_auto_recalc=0"));
+
+ if (share->stats_sample_pages != 0)
+ {
+ str.qs_append(STRING_WITH_LEN(" stats_sample_pages="));
+ str.qs_append(share->stats_sample_pages);
+ }
+
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
if (share->db_create_options & HA_OPTION_CHECKSUM)
str.qs_append(STRING_WITH_LEN(" checksum=1"));
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 733d5f51071..e5860b1ab9a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -609,9 +609,9 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
DBUG_ENTER("build_tmptable_filename");
char *p= strnmov(buff, mysql_tmpdir, bufflen);
- my_snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
+ my_snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x",
tmp_file_prefix, current_pid,
- thd->thread_id, thd->tmp_table++, reg_ext);
+ thd->thread_id, thd->tmp_table++);
if (lower_case_table_names)
{
@@ -2083,15 +2083,18 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
MYSQL_OPEN_SKIP_TEMPORARY))
DBUG_RETURN(true);
for (table= tables; table; table= table->next_local)
-
+ {
+ if (is_temporary_table(table))
+ continue;
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name,
false);
+ }
}
else
{
for (table= tables; table; table= table->next_local)
- if (table->open_type != OT_BASE_ONLY &&
- find_temporary_table(thd, table))
+ {
+ if (is_temporary_table(table))
{
/*
A temporary table.
@@ -2123,6 +2126,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
DBUG_RETURN(true);
table->mdl_request.ticket= table->table->mdl_ticket;
}
+ }
}
}
@@ -4760,14 +4764,16 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
result= mysql_create_table_no_lock(thd, create_table->db,
create_table->table_name, create_info,
alter_info, &is_trans, create_table_mode);
+ if (result)
+ DBUG_RETURN(result);
/* In RBR we don't need to log CREATE TEMPORARY TABLE */
if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table())
DBUG_RETURN(0);
- if (!result)
- result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(),
- is_trans);
+ result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans);
+ thd->abort_on_warning= false;
+
end:
DBUG_RETURN(result);
}
@@ -6438,8 +6444,16 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
table->file->info(HA_STATUS_AUTO);
create_info->auto_increment_value= table->file->stats.auto_increment_value;
}
+
if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
create_info->key_block_size= table->s->key_block_size;
+
+ if (!(used_fields & HA_CREATE_USED_STATS_SAMPLE_PAGES))
+ create_info->stats_sample_pages= table->s->stats_sample_pages;
+
+ if (!(used_fields & HA_CREATE_USED_STATS_AUTO_RECALC))
+ create_info->stats_auto_recalc= table->s->stats_auto_recalc;
+
if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
create_info->transactional= table->s->transactional;
@@ -6824,6 +6838,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
(used_fields & HA_CREATE_USED_PACK_KEYS))
db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
+ if ((create_info->table_options &
+ (HA_OPTION_STATS_PERSISTENT | HA_OPTION_NO_STATS_PERSISTENT)) ||
+ (used_fields & HA_CREATE_USED_STATS_PERSISTENT))
+ db_create_options&= ~(HA_OPTION_STATS_PERSISTENT | HA_OPTION_NO_STATS_PERSISTENT);
+
if (create_info->table_options &
(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index eab8b3af84c..1dd83fa8865 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -932,7 +932,7 @@ int mysql_update(THD *thd,
char buff[MYSQL_ERRMSG_SIZE];
my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found,
(ulong) updated,
- (ulong) thd->get_stmt_da()->statement_warn_count());
+ (ulong) thd->get_stmt_da()->current_statement_warn_count());
my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
id, buff);
DBUG_PRINT("info",("%ld records updated", (long) updated));
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 38d6b41d92b..036c04bf2f6 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -437,7 +437,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
lex->link_first_table_back(view, link_to_local);
view->open_type= OT_BASE_ONLY;
- if (open_and_lock_tables(thd, lex->query_tables, TRUE, 0))
+ if (open_temporary_tables(thd, lex->query_tables) ||
+ open_and_lock_tables(thd, lex->query_tables, TRUE, 0))
{
view= lex->unlink_first_table(&link_to_local);
res= TRUE;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 8e5ec870ac3..521aed2e04a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1497,6 +1497,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token STARTING
%token STARTS_SYM
%token START_SYM /* SQL-2003-R */
+%token STATS_AUTO_RECALC_SYM
+%token STATS_PERSISTENT_SYM
+%token STATS_SAMPLE_PAGES_SYM
%token STATUS_SYM
%token STDDEV_SAMP_SYM /* SQL-2003-N */
%token STD_SYM
@@ -2135,6 +2138,7 @@ master_def:
| MASTER_PASSWORD_SYM EQ TEXT_STRING_sys
{
Lex->mi.password = $3.str;
+ Lex->contains_plaintext_password= true;
}
| MASTER_PORT_SYM EQ ulong_num
{
@@ -2445,6 +2449,7 @@ server_option:
| PASSWORD TEXT_STRING_sys
{
Lex->server_options.password= $2.str;
+ Lex->contains_plaintext_password= true;
}
| SOCKET_SYM TEXT_STRING_sys
{
@@ -5531,6 +5536,70 @@ create_table_option:
~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
}
+ | STATS_AUTO_RECALC_SYM opt_equal ulong_num
+ {
+ switch($3) {
+ case 0:
+ Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_OFF;
+ break;
+ case 1:
+ Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_ON;
+ break;
+ default:
+ my_parse_error(ER(ER_SYNTAX_ERROR));
+ MYSQL_YYABORT;
+ }
+ Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC;
+ }
+ | STATS_AUTO_RECALC_SYM opt_equal DEFAULT
+ {
+ Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_DEFAULT;
+ Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC;
+ }
+ | STATS_PERSISTENT_SYM opt_equal ulong_num
+ {
+ switch($3) {
+ case 0:
+ Lex->create_info.table_options|= HA_OPTION_NO_STATS_PERSISTENT;
+ break;
+ case 1:
+ Lex->create_info.table_options|= HA_OPTION_STATS_PERSISTENT;
+ break;
+ default:
+ my_parse_error(ER(ER_SYNTAX_ERROR));
+ MYSQL_YYABORT;
+ }
+ Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT;
+ }
+ | STATS_PERSISTENT_SYM opt_equal DEFAULT
+ {
+ Lex->create_info.table_options&=
+ ~(HA_OPTION_STATS_PERSISTENT | HA_OPTION_NO_STATS_PERSISTENT);
+ Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT;
+ }
+ | STATS_SAMPLE_PAGES_SYM opt_equal ulong_num
+ {
+ /* From user point of view STATS_SAMPLE_PAGES can be specified as
+ STATS_SAMPLE_PAGES=N (where 0<N<=65535, it does not make sense to
+ scan 0 pages) or STATS_SAMPLE_PAGES=default. Internally we record
+ =default as 0. See create_frm() in sql/table.cc, we use only two
+ bytes for stats_sample_pages and this is why we do not allow
+ larger values. 65535 pages, 16kb each means to sample 1GB, which
+ is impractical. If at some point this needs to be extended, then
+ we can store the higher bits from stats_sample_pages in .frm too. */
+ if ($3 == 0 || $3 > 0xffff)
+ {
+ my_parse_error(ER(ER_SYNTAX_ERROR));
+ MYSQL_YYABORT;
+ }
+ Lex->create_info.stats_sample_pages=$3;
+ Lex->create_info.used_fields|= HA_CREATE_USED_STATS_SAMPLE_PAGES;
+ }
+ | STATS_SAMPLE_PAGES_SYM opt_equal DEFAULT
+ {
+ Lex->create_info.stats_sample_pages=0;
+ Lex->create_info.used_fields|= HA_CREATE_USED_STATS_SAMPLE_PAGES;
+ }
| CHECKSUM_SYM opt_equal ulong_num
{
Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM;
@@ -9531,6 +9600,7 @@ function_call_conflict:
| OLD_PASSWORD '(' expr ')'
{
$$= new (YYTHD->mem_root) Item_func_old_password($3);
+ Lex->contains_plaintext_password= true;
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -9538,7 +9608,8 @@ function_call_conflict:
{
THD *thd= YYTHD;
Item* i1;
- if (thd->variables.old_passwords)
+ Lex->contains_plaintext_password= true;
+ if (thd->variables.old_passwords == 1)
i1= new (thd->mem_root) Item_func_old_password($3);
else
i1= new (thd->mem_root) Item_func_password($3);
@@ -14432,24 +14503,33 @@ text_or_password:
TEXT_STRING { $$=$1.str;}
| PASSWORD '(' TEXT_STRING ')'
{
- $$= $3.length ? YYTHD->variables.old_passwords ?
- Item_func_old_password::alloc(YYTHD, $3.str, $3.length) :
- Item_func_password::alloc(YYTHD, $3.str, $3.length) :
- $3.str;
+ if ($3.length == 0)
+ $$= $3.str;
+ else
+ switch (YYTHD->variables.old_passwords) {
+ case 1: $$= Item_func_old_password::
+ alloc(YYTHD, $3.str, $3.length);
+ break;
+ case 0:
+ case 2: $$= Item_func_password::
+ create_password_hash_buffer(YYTHD, $3.str, $3.length);
+ break;
+ }
if ($$ == NULL)
MYSQL_YYABORT;
+ Lex->contains_plaintext_password= true;
}
| OLD_PASSWORD '(' TEXT_STRING ')'
{
- $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str,
- $3.length) :
+ $$= $3.length ? Item_func_old_password::
+ alloc(YYTHD, $3.str, $3.length) :
$3.str;
if ($$ == NULL)
MYSQL_YYABORT;
+ Lex->contains_plaintext_password= true;
}
;
-
set_expr_or_default:
expr { $$=$1; }
| DEFAULT { $$=0; }
@@ -14930,9 +15010,11 @@ grant_user:
user IDENTIFIED_SYM BY TEXT_STRING
{
$$=$1; $1->password=$4;
+ if (Lex->sql_command == SQLCOM_REVOKE)
+ MYSQL_YYABORT;
if ($4.length)
{
- if (YYTHD->variables.old_passwords)
+ if (YYTHD->variables.old_passwords == 1)
{
char *buff=
(char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
@@ -14948,7 +15030,7 @@ grant_user:
(char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
if (buff == NULL)
MYSQL_YYABORT;
- my_make_scrambled_password(buff, $4.str, $4.length);
+ my_make_scrambled_password_sha1(buff, $4.str, $4.length);
$1->password.str= buff;
$1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
}