mirror of
https://github.com/MariaDB/server.git
synced 2025-03-23 23:48:41 +01:00
Merge 10.3 into 10.4
This commit is contained in:
commit
533a13af06
96 changed files with 3159 additions and 820 deletions
client
cmake/Internal/CPack
extra/mariabackup
include
libmariadblibmysqld
man
mysql-test
include
main
blackhole.resultblackhole.testbootstrap_innodb.resultbootstrap_innodb.testfunc_group.resultkill.resultkill.testlock_view.resultlock_view.testmysqldump-system,win.rdiffmysqldump-system.resultmysqldump-system.testmysqldump.resultorder_by.resultorder_by.testplugin_innodb.testpool_of_threads.resultpool_of_threads.testprecedence.resultprocesslist_notembedded.resultprocesslist_notembedded.testset_statement_notembedded.resultset_statement_notembedded.testsubselect4.resulttype_newdecimal.resulttype_ranges.result
suite
galera_3nodes
maria
mariabackup
rpl/t
sys_vars
r
t
vcol/r
mysys
plugin
sql
field.ccfield.hfilesort.cchandler.hitem_cmpfunc.ccitem_func.ccitem_sum.cclex_string.hmf_iocache_encr.ccmy_decimal.hopt_range.ccopt_split.ccopt_sum.ccsql_base.ccsql_class.ccsql_class.hsql_join_cache.ccsql_lex.ccsql_parse.ccsql_prepare.ccsql_select.ccsql_string.ccsql_type.hsys_vars.ictable.hunireg.ccunireg.h
storage
blackhole
connect
maria
myisam
perfschema
tokudb/mysql-test/tokudb/r
strings
tests
|
@ -205,7 +205,8 @@ Bucket *find_longest_match(HashTable *ht, char *str, uint length,
|
|||
void completion_hash_clean(HashTable *ht)
|
||||
{
|
||||
free_root(&ht->mem_root,MYF(0));
|
||||
bzero((char*) ht->arBuckets,ht->nTableSize*sizeof(Bucket *));
|
||||
if (size_t s= ht->nTableSize)
|
||||
bzero((char*) ht->arBuckets, s * sizeof(Bucket *));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "client_priv.h"
|
||||
#include <sslopt-vars.h>
|
||||
#include "../scripts/mysql_fix_privilege_tables_sql.c"
|
||||
#include <../scripts/mysql_fix_privilege_tables_sql.c>
|
||||
|
||||
#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
|
||||
*/
|
||||
|
||||
#define DUMP_VERSION "10.18"
|
||||
/* on merge conflict, bump to a higher version again */
|
||||
#define DUMP_VERSION "10.19"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
|
@ -117,6 +118,21 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m
|
|||
opt_events= 0, opt_comments_used= 0,
|
||||
opt_alltspcs=0, opt_notspcs= 0, opt_logging,
|
||||
opt_drop_trigger= 0 ;
|
||||
#define OPT_SYSTEM_ALL 1
|
||||
#define OPT_SYSTEM_USERS 2
|
||||
#define OPT_SYSTEM_PLUGINS 4
|
||||
#define OPT_SYSTEM_UDFS 8
|
||||
#define OPT_SYSTEM_SERVERS 16
|
||||
#define OPT_SYSTEM_STATS 32
|
||||
#define OPT_SYSTEM_TIMEZONES 64
|
||||
static const char *opt_system_type_values[]=
|
||||
{"all", "users", "plugins", "udfs", "servers", "stats", "timezones"};
|
||||
static TYPELIB opt_system_types=
|
||||
{
|
||||
array_elements(opt_system_type_values), "system dump options",
|
||||
opt_system_type_values, NULL
|
||||
};
|
||||
static ulonglong opt_system= 0ULL;
|
||||
static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0,
|
||||
select_field_names_inited= 0;
|
||||
static ulong opt_max_allowed_packet, opt_net_buffer_length;
|
||||
|
@ -526,6 +542,8 @@ static struct my_option my_long_options[] =
|
|||
&opt_mysql_unix_port, &opt_mysql_unix_port, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#include <sslopt-longopts.h>
|
||||
{"system", 256, "Dump system tables as portable SQL",
|
||||
&opt_system, &opt_system, &opt_system_types, GET_SET, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"tab",'T',
|
||||
"Create tab-separated textfile for each table to given path. (Create .sql "
|
||||
"and .txt files.) NOTE: This only works if mysqldump is run on the same "
|
||||
|
@ -569,7 +587,7 @@ static const char *load_default_groups[]=
|
|||
static void maybe_exit(int error);
|
||||
static void die(int error, const char* reason, ...);
|
||||
static void maybe_die(int error, const char* reason, ...);
|
||||
static void write_header(FILE *sql_file, char *db_name);
|
||||
static void write_header(FILE *sql_file, const char *db_name);
|
||||
static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
|
||||
const char *prefix,const char *name,
|
||||
int string_value);
|
||||
|
@ -580,6 +598,12 @@ static int init_dumping_tables(char *);
|
|||
static int init_dumping(char *, int init_func(char*));
|
||||
static int dump_databases(char **);
|
||||
static int dump_all_databases();
|
||||
static int dump_all_users_roles_and_grants();
|
||||
static int dump_all_plugins();
|
||||
static int dump_all_udfs();
|
||||
static int dump_all_servers();
|
||||
static int dump_all_stats();
|
||||
static int dump_all_timezones();
|
||||
static char *quote_name(const char *name, char *buff, my_bool force);
|
||||
char check_if_ignore_table(const char *table_name, char *table_type);
|
||||
static char *primary_key_fields(const char *table_name);
|
||||
|
@ -641,9 +665,10 @@ static void print_version(void)
|
|||
static void short_usage_sub(FILE *f)
|
||||
{
|
||||
fprintf(f, "Usage: %s [OPTIONS] database [tables]\n", my_progname_short);
|
||||
fprintf(f, "OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
|
||||
fprintf(f, "OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
|
||||
my_progname_short);
|
||||
fprintf(f, "OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname_short);
|
||||
fprintf(f, "OR %s [OPTIONS] --all-databases\n", my_progname_short);
|
||||
fprintf(f, "OR %s [OPTIONS] --system=[SYSTEMOPTIONS]]\n", my_progname_short);
|
||||
}
|
||||
|
||||
|
||||
|
@ -691,7 +716,7 @@ static const char *fix_for_comment(const char *ident)
|
|||
}
|
||||
|
||||
|
||||
static void write_header(FILE *sql_file, char *db_name)
|
||||
static void write_header(FILE *sql_file, const char *db_name)
|
||||
{
|
||||
if (opt_xml)
|
||||
{
|
||||
|
@ -1038,6 +1063,76 @@ static int get_options(int *argc, char ***argv)
|
|||
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
|
||||
return(ho_error);
|
||||
|
||||
if (opt_system & OPT_SYSTEM_ALL)
|
||||
opt_system|= ~0;
|
||||
|
||||
if (opt_system & OPT_SYSTEM_USERS &&
|
||||
(my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.db", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.global_priv", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.tables_priv", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.columns_priv", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.procs_priv", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.user", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.host", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.proxies_priv", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.roles_mapping", MYF(MY_WME))) ||
|
||||
/* and MySQL-8.0 role tables (role_edges and default_roles) as well */
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.role_edges", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.default_roles", MYF(MY_WME)))))
|
||||
return(EX_EOM);
|
||||
|
||||
if (opt_system & OPT_SYSTEM_PLUGINS &&
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.plugin", MYF(MY_WME))))
|
||||
return(EX_EOM);
|
||||
|
||||
if (opt_system & OPT_SYSTEM_UDFS &&
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.func", MYF(MY_WME))))
|
||||
return(EX_EOM);
|
||||
|
||||
if (opt_system & OPT_SYSTEM_SERVERS &&
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.servers", MYF(MY_WME))))
|
||||
return(EX_EOM);
|
||||
|
||||
if (opt_system & OPT_SYSTEM_STATS &&
|
||||
(my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.column_stats", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.index_stats", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.table_stats", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.innodb_table_stats", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.innodb_index_stats", MYF(MY_WME)))))
|
||||
return(EX_EOM);
|
||||
|
||||
if (opt_system & OPT_SYSTEM_TIMEZONES &&
|
||||
(my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.time_zone", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.time_zone_leap_second", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.time_zone_name", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.time_zone_transition", MYF(MY_WME))) ||
|
||||
my_hash_insert(&ignore_table,
|
||||
(uchar*) my_strdup("mysql.time_zone_transition_type", MYF(MY_WME)))))
|
||||
return(EX_EOM);
|
||||
|
||||
*mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
|
||||
*mysql_params->p_net_buffer_length= opt_net_buffer_length;
|
||||
if (debug_info_flag)
|
||||
|
@ -1102,7 +1197,7 @@ static int get_options(int *argc, char ***argv)
|
|||
!(charset_info= get_charset_by_csname(default_charset,
|
||||
MY_CS_PRIMARY, MYF(MY_WME))))
|
||||
exit(1);
|
||||
if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
|
||||
if ((*argc < 1 && (!opt_alldbs && !opt_system)) || (*argc > 0 && opt_alldbs))
|
||||
{
|
||||
short_usage(stderr);
|
||||
return EX_USAGE;
|
||||
|
@ -1226,7 +1321,6 @@ static int fetch_db_collation(const char *db_name,
|
|||
my_bool err_status= FALSE;
|
||||
MYSQL_RES *db_cl_res;
|
||||
MYSQL_ROW db_cl_row;
|
||||
|
||||
if (mysql_select_db(mysql, db_name))
|
||||
{
|
||||
DB_error(mysql, "when selecting the database");
|
||||
|
@ -2806,7 +2900,7 @@ static void get_sequence_structure(const char *seq, const char *db)
|
|||
number of fields in table, 0 if error
|
||||
*/
|
||||
|
||||
static uint get_table_structure(char *table, char *db, char *table_type,
|
||||
static uint get_table_structure(const char *table, const char *db, char *table_type,
|
||||
char *ignore_flag)
|
||||
{
|
||||
my_bool init=0, delayed, write_data, complete_insert;
|
||||
|
@ -3755,7 +3849,7 @@ static char *alloc_query_str(size_t size)
|
|||
*/
|
||||
|
||||
|
||||
static void dump_table(char *table, char *db, const uchar *hash_key, size_t len)
|
||||
static void dump_table(const char *table, const char *db, const uchar *hash_key, size_t len)
|
||||
{
|
||||
char ignore_flag;
|
||||
char buf[200], table_buff[NAME_LEN+3];
|
||||
|
@ -4287,6 +4381,442 @@ static char *getTableName(int reset)
|
|||
} /* getTableName */
|
||||
|
||||
|
||||
/*
|
||||
dump user/role grants
|
||||
ARGS
|
||||
user_role: is either a user, or a role
|
||||
*/
|
||||
|
||||
static int dump_grants(const char *user_role)
|
||||
{
|
||||
DYNAMIC_STRING sqlbuf;
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *tableres;
|
||||
|
||||
init_dynamic_string_checked(&sqlbuf, "SHOW GRANTS FOR ", 256, 1024);
|
||||
dynstr_append_checked(&sqlbuf, user_role);
|
||||
|
||||
if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str))
|
||||
{
|
||||
dynstr_free(&sqlbuf);
|
||||
return 1;
|
||||
}
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
if (strncmp(row[0], "SET DEFAULT ROLE", sizeof("SET DEFAULT ROLE") - 1) == 0)
|
||||
continue;
|
||||
fprintf(md_result_file, "%s;\n", row[0]);
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
dynstr_free(&sqlbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dump create user
|
||||
*/
|
||||
|
||||
static int dump_create_user(const char *user)
|
||||
{
|
||||
DYNAMIC_STRING sqlbuf;
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *tableres;
|
||||
|
||||
init_dynamic_string_checked(&sqlbuf, "SHOW CREATE USER ", 256, 1024);
|
||||
dynstr_append_checked(&sqlbuf, user);
|
||||
|
||||
if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str))
|
||||
{
|
||||
dynstr_free(&sqlbuf);
|
||||
return 1;
|
||||
}
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
fprintf(md_result_file, "CREATE %sUSER %s%s;\n", opt_replace_into ? "/*M!100103 OR REPLACE */ ": "",
|
||||
opt_ignore ? "IF NOT EXISTS " : "",
|
||||
row[0] + sizeof("CREATE USER"));
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
dynstr_free(&sqlbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dump all users, roles and their grants
|
||||
*/
|
||||
|
||||
static int dump_all_users_roles_and_grants()
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *tableres;
|
||||
int result= 0;
|
||||
/* Roles added in MariaDB-10.0.5 or MySQL-8.0 */
|
||||
my_bool maria_roles_exist= (mysql_get_server_version(mysql) >= 100005);
|
||||
my_bool mysql_roles_exist= (mysql_get_server_version(mysql) >= 80001) && !maria_roles_exist;
|
||||
|
||||
if (mysql_query_with_error_report(mysql, &tableres,
|
||||
"SELECT CONCAT(QUOTE(u.user), '@', QUOTE(u.Host)) AS u "
|
||||
"FROM mysql.user u "
|
||||
" /*!80001 LEFT JOIN mysql.role_edges e "
|
||||
" ON u.user=e.from_user "
|
||||
" AND u.host=e.from_host "
|
||||
" WHERE e.from_user IS NULL */"
|
||||
" /*M!100005 WHERE is_role='N' */"))
|
||||
return 1;
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
if (opt_replace_into)
|
||||
/* Protection against removing the current import user */
|
||||
/* MySQL-8.0 export capability */
|
||||
fprintf(md_result_file,
|
||||
"DELIMITER |\n"
|
||||
"/*M!100101 IF current_user()=\"%s\" THEN\n"
|
||||
" SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=30001,"
|
||||
" MESSAGE_TEXT=\"Don't remove current user %s'\";\n"
|
||||
"END IF */|\n"
|
||||
"DELIMITER ;\n"
|
||||
"/*!50701 DROP USER IF EXISTS %s */;\n", row[0], row[0], row[0]);
|
||||
if (dump_create_user(row[0]))
|
||||
result= 1;
|
||||
/* if roles exist, defer dumping grants until after roles created */
|
||||
if (maria_roles_exist || mysql_roles_exist)
|
||||
continue;
|
||||
if (dump_grants(row[0]))
|
||||
result= 1;
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
|
||||
if (!(maria_roles_exist || mysql_roles_exist))
|
||||
goto exit;
|
||||
|
||||
/*
|
||||
Preserve current role active role, in case this dump is imported
|
||||
in the same connection that assumes the active role at the beginning
|
||||
is the same as at the end of the connection. This is so:
|
||||
|
||||
#!/bin/sh
|
||||
(
|
||||
echo "set role special_role; ";
|
||||
cat mysqldump.sql;
|
||||
echo "$dosomethingspecial"
|
||||
) | mysql -h $host
|
||||
|
||||
doesn't end up with a suprise that the $dosomethingspecial cannot
|
||||
be done because `special_role` isn't active.
|
||||
|
||||
We create a new role for importing that becomes the default admin for new
|
||||
roles. This is because without being a admin on new roles we don't
|
||||
have the necessary privileges to grant users to a created role or to
|
||||
create new admins for the created role.
|
||||
|
||||
At the end of the import the mariadb_dump_import_role is be dropped,
|
||||
which implictly drops all its admin aspects of the dropped role.
|
||||
This is significiantly easlier than revoking the ADMIN of each role
|
||||
from the current user.
|
||||
*/
|
||||
fputs("SELECT COALESCE(CURRENT_ROLE(),'NONE') into @current_role;\n"
|
||||
"CREATE ROLE IF NOT EXISTS mariadb_dump_import_role;\n"
|
||||
"GRANT mariadb_dump_import_role TO CURRENT_USER();\n"
|
||||
"SET ROLE mariadb_dump_import_role;\n"
|
||||
, md_result_file);
|
||||
/* No show create role yet, MDEV-22311 */
|
||||
/* Roles, with user admins first, then roles they administer, and recurse on that */
|
||||
if (maria_roles_exist && mysql_query_with_error_report(mysql, &tableres,
|
||||
"WITH RECURSIVE create_role_order AS"
|
||||
" (SELECT 1 as n, roles_mapping.*"
|
||||
" FROM mysql.roles_mapping"
|
||||
" JOIN mysql.user USING (user,host)"
|
||||
" WHERE is_role='N'"
|
||||
" AND Admin_option='Y'"
|
||||
" UNION SELECT c.n+1, r.*"
|
||||
" FROM create_role_order c"
|
||||
" JOIN mysql.roles_mapping r ON c.role=r.user"
|
||||
" AND r.host=''"
|
||||
" AND r.Admin_option='Y') "
|
||||
"SELECT QUOTE(ROLE) AS r,"
|
||||
" CONCAT(QUOTE(user),"
|
||||
" IF(HOST='', '', CONCAT('@', QUOTE(HOST)))) AS c,"
|
||||
" Admin_option "
|
||||
"FROM create_role_order ORDER BY n, r, user"))
|
||||
return 1;
|
||||
/*
|
||||
TODO Mysql - misses roles that have no admin or role members.
|
||||
MySQL roles don't require an admin.
|
||||
*/
|
||||
if (mysql_roles_exist && mysql_query_with_error_report(mysql, &tableres,
|
||||
"WITH RECURSIVE create_role_order AS"
|
||||
" (SELECT 1 AS n,"
|
||||
" re.*"
|
||||
" FROM mysql.role_edges re"
|
||||
" JOIN mysql.user u ON re.TO_HOST=u.HOST"
|
||||
" AND re.TO_USER = u.USER"
|
||||
" LEFT JOIN mysql.role_edges re2 ON re.TO_USER=re2.FROM_USER"
|
||||
" AND re2.TO_HOST=re2.FROM_HOST"
|
||||
" WHERE re2.FROM_USER IS NULL"
|
||||
" UNION SELECT c.n+1,"
|
||||
" re.*"
|
||||
" FROM create_role_order c"
|
||||
" JOIN mysql.role_edges re ON c.FROM_USER=re.TO_USER"
|
||||
" AND c.FROM_HOST=re.TO_HOST) "
|
||||
"SELECT CONCAT(QUOTE(FROM_USER), '/*!80001 @', QUOTE(FROM_HOST), '*/') AS r,"
|
||||
" CONCAT(QUOTE(TO_USER), IF(n=1, CONCAT('@', QUOTE(TO_HOST)),"
|
||||
" CONCAT('/*!80001 @', QUOTE(TO_HOST), ' */'))) AS u,"
|
||||
" WITH_ADMIN_OPTION "
|
||||
"FROM create_role_order "
|
||||
"ORDER BY n,"
|
||||
" FROM_USER,"
|
||||
" FROM_HOST,"
|
||||
" TO_USER,"
|
||||
" TO_HOST,"
|
||||
" WITH_ADMIN_OPTION"))
|
||||
return 1;
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
/* MySQL-8.0 export capability */
|
||||
if (opt_replace_into)
|
||||
fprintf(md_result_file,
|
||||
"/*!80001 DROP ROLE IF EXISTS %s */;\n", row[0]);
|
||||
fprintf(md_result_file,
|
||||
"/*!80001 CREATE ROLE %s%s */;\n", opt_ignore ? "IF NOT EXISTS " : "", row[0]);
|
||||
/* By default created with current role */
|
||||
fprintf(md_result_file,
|
||||
"%sROLE %s%s WITH ADMIN mariadb_dump_import_role */;\n",
|
||||
opt_replace_into ? "/*M!100103 CREATE OR REPLACE ": "/*M!100005 CREATE ",
|
||||
opt_ignore ? "IF NOT EXISTS " : "", row[0]);
|
||||
fprintf(md_result_file, "/*M!100005 GRANT %s TO %s%s*/;\n",
|
||||
row[0], row[1], (row[2][0] == 'Y') ? " WITH ADMIN OPTION " : "");
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
|
||||
/* users and their default role */
|
||||
if (maria_roles_exist && mysql_query_with_error_report(mysql, &tableres,
|
||||
"select IF(default_role='', 'NONE', QUOTE(default_role)) as r,"
|
||||
"concat(QUOTE(User), '@', QUOTE(Host)) as u FROM mysql.user "
|
||||
"/*M!100005 WHERE is_role='N' */"))
|
||||
return 1;
|
||||
if (mysql_roles_exist && mysql_query_with_error_report(mysql, &tableres,
|
||||
"SELECT IF(DEFAULT_ROLE_HOST IS NULL, 'NONE', CONCAT(QUOTE(DEFAULT_ROLE_USER),"
|
||||
" '@', QUOTE(DEFAULT_ROLE_HOST))) as r,"
|
||||
" CONCAT(QUOTE(mu.USER),'@',QUOTE(mu.HOST)) as u "
|
||||
"FROM mysql.user mu LEFT JOIN mysql.default_roles using (USER, HOST)"))
|
||||
return 1;
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
if (dump_grants(row[1]))
|
||||
result= 1;
|
||||
fprintf(md_result_file, "/*M!100005 SET DEFAULT ROLE %s FOR %s */;\n", row[0], row[1]);
|
||||
fprintf(md_result_file, "/*!80001 ALTER USER %s DEFAULT ROLE %s */;\n", row[1], row[0]);
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
|
||||
if (maria_roles_exist && mysql_query_with_error_report(mysql, &tableres,
|
||||
"SELECT DISTINCT QUOTE(m.role) AS r "
|
||||
" FROM mysql.roles_mapping m"
|
||||
" JOIN mysql.user u ON u.user = m.role"
|
||||
" WHERE is_role='Y'"
|
||||
" AND Admin_option='Y'"
|
||||
" ORDER BY m.role"))
|
||||
return 1;
|
||||
if (mysql_roles_exist && mysql_query_with_error_report(mysql, &tableres,
|
||||
"SELECT DISTINCT CONCAT(QUOTE(FROM_USER),'@', QUOTE(FROM_HOST)) AS r "
|
||||
"FROM mysql.role_edges"))
|
||||
return 1;
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
if (dump_grants(row[0]))
|
||||
result= 1;
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
/* switch back */
|
||||
fputs("SET ROLE NONE;\n"
|
||||
"DROP ROLE mariadb_dump_import_role;\n"
|
||||
"/*M!100203 EXECUTE IMMEDIATE CONCAT('SET ROLE ', @current_role) */;\n",
|
||||
md_result_file);
|
||||
exit:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dump all plugins
|
||||
*/
|
||||
|
||||
static int dump_all_plugins()
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *tableres;
|
||||
|
||||
if (mysql_query_with_error_report(mysql, &tableres, "SHOW PLUGINS"))
|
||||
return 1;
|
||||
/* Name, Status, Type, Library, License */
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
if (strcmp("ACTIVE", row[1]) != 0)
|
||||
continue;
|
||||
/* Should we be skipping builtins? */
|
||||
if (row[3] == NULL)
|
||||
continue;
|
||||
if (opt_replace_into)
|
||||
{
|
||||
fprintf(md_result_file, "/*M!100401 UNINSTALL PLUGIN IF EXIST %s */;\n",
|
||||
row[0]);
|
||||
}
|
||||
fprintf(md_result_file,
|
||||
"INSTALL PLUGIN %s %s SONAME '%s';\n", row[0],
|
||||
opt_ignore ? "/*M!100401 IF NOT EXISTS */" : "", row[3]);
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dump all udfs
|
||||
*/
|
||||
|
||||
static int dump_all_udfs()
|
||||
{
|
||||
/* we don't support all these types yet, but get prepared if we do */
|
||||
static const char *udf_types[] = {"STRING", "REAL", "INT", "ROW", "DECIMAL", "TIME" };
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *tableres;
|
||||
int retresult, result= 0;
|
||||
|
||||
if (mysql_query_with_error_report(mysql, &tableres, "SELECT * FROM mysql.func"))
|
||||
return 1;
|
||||
/* Name, ret, dl, type*/
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
retresult= atoi(row[1]);
|
||||
if (retresult < 0 || array_elements(udf_types) <= (size_t) retresult)
|
||||
{
|
||||
fprintf(stderr, "%s: Error: invalid return type on udf function '%s'\n",
|
||||
my_progname_short, row[0]);
|
||||
result= 1;
|
||||
continue;
|
||||
}
|
||||
if (opt_replace_into)
|
||||
{
|
||||
fprintf(md_result_file, "/*!50701 DROP FUNCTION IF EXISTS %s */;\n",
|
||||
row[0]);
|
||||
}
|
||||
fprintf(md_result_file,
|
||||
"CREATE %s%sFUNCTION %s%s RETURNS %s SONAME '%s';\n",
|
||||
opt_replace_into ? "/*M!100103 OR REPLACE */ ": "",
|
||||
(strcmp("AGGREGATE", row[2])==0 ? "AGGREGATE " : ""),
|
||||
opt_ignore ? "IF NOT EXISTS " : "", row[0], udf_types[retresult], row[2]);
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dump all servers
|
||||
*/
|
||||
|
||||
static int dump_all_servers()
|
||||
{
|
||||
/* No create server yet - MDEV-15696 */
|
||||
MYSQL_ROW row;
|
||||
MYSQL_RES *tableres;
|
||||
MYSQL_FIELD *f;
|
||||
unsigned int num_fields, i;
|
||||
my_bool comma_prepend= 0;
|
||||
const char *qstring;
|
||||
|
||||
if (mysql_query_with_error_report(mysql, &tableres, "SELECT * FROM mysql.servers"))
|
||||
return 1;
|
||||
num_fields= mysql_num_fields(tableres);
|
||||
while ((row= mysql_fetch_row(tableres)))
|
||||
{
|
||||
fprintf(md_result_file,"CREATE %sSERVER %s%s FOREIGN DATA WRAPPER %s OPTIONS (",
|
||||
opt_replace_into ? "/*M!100103 OR REPLACE */ ": "",
|
||||
opt_ignore ? "/*M!100103 IF NOT EXISTS */ " : "", row[0], row[7]);
|
||||
for (i= 1; i < num_fields; i++)
|
||||
{
|
||||
if (i == 7 || row[i][0] == '\0') /* Wrapper or empty string */
|
||||
continue;
|
||||
f= &tableres->fields[i];
|
||||
qstring= (f->type == MYSQL_TYPE_STRING || f->type == MYSQL_TYPE_VAR_STRING) ? "'" : "";
|
||||
fprintf(md_result_file, "%s%s %s%s%s",
|
||||
(comma_prepend ? ", " : ""), f->name, qstring, row[i], qstring);
|
||||
comma_prepend= 1;
|
||||
}
|
||||
fputs(");\n", md_result_file);
|
||||
}
|
||||
mysql_free_result(tableres);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dump all system statistical tables
|
||||
*/
|
||||
|
||||
static int dump_all_stats()
|
||||
{
|
||||
my_bool prev_no_create_info;
|
||||
|
||||
if (mysql_select_db(mysql, "mysql"))
|
||||
{
|
||||
DB_error(mysql, "when selecting the database");
|
||||
return 1; /* If --force */
|
||||
}
|
||||
fprintf(md_result_file,"\nUSE mysql;\n");
|
||||
prev_no_create_info= opt_no_create_info;
|
||||
opt_no_create_info= 1; /* don't overwrite recreate tables */
|
||||
/* EITS added in 10.0.1 */
|
||||
if (mysql_get_server_version(mysql) >= 100001)
|
||||
{
|
||||
dump_table("column_stats", "mysql", NULL, 0);
|
||||
dump_table("index_stats", "mysql", NULL, 0);
|
||||
dump_table("table_stats", "mysql", NULL, 0);
|
||||
}
|
||||
/* Innodb may be disabled */
|
||||
if (!mysql_query(mysql, "show fields from innodb_index_stats"))
|
||||
{
|
||||
MYSQL_RES *tableres= mysql_store_result(mysql);
|
||||
mysql_free_result(tableres);
|
||||
dump_table("innodb_index_stats", "mysql", NULL, 0);
|
||||
dump_table("innodb_table_stats", "mysql", NULL, 0);
|
||||
}
|
||||
opt_no_create_info= prev_no_create_info;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dump all system timezones
|
||||
*/
|
||||
|
||||
static int dump_all_timezones()
|
||||
{
|
||||
my_bool opt_prev_no_create_info;
|
||||
if (mysql_select_db(mysql, "mysql"))
|
||||
{
|
||||
DB_error(mysql, "when selecting the database");
|
||||
return 1; /* If --force */
|
||||
}
|
||||
opt_prev_no_create_info= opt_no_create_info;
|
||||
opt_no_create_info= 1;
|
||||
fprintf(md_result_file,"\nUSE mysql;\n");
|
||||
dump_table("time_zone", "mysql", NULL, 0);
|
||||
dump_table("time_zone_name", "mysql", NULL, 0);
|
||||
dump_table("time_zone_leap_second", "mysql", NULL, 0);
|
||||
dump_table("time_zone_transition", "mysql", NULL, 0);
|
||||
dump_table("time_zone_transition_type", "mysql", NULL, 0);
|
||||
opt_no_create_info= opt_prev_no_create_info;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
dump all logfile groups and tablespaces
|
||||
*/
|
||||
|
@ -6319,7 +6849,7 @@ int main(int argc, char **argv)
|
|||
dump_tablespaces_for_tables(*argv, (argv + 1), (argc - 1));
|
||||
dump_selected_tables(*argv, (argv + 1), (argc - 1));
|
||||
}
|
||||
else
|
||||
else if (argc > 0)
|
||||
{
|
||||
/* One or more databases, all tables */
|
||||
if (!opt_alltspcs && !opt_notspcs)
|
||||
|
@ -6328,6 +6858,25 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (opt_system & OPT_SYSTEM_PLUGINS)
|
||||
dump_all_plugins();
|
||||
|
||||
if (opt_system & OPT_SYSTEM_USERS)
|
||||
dump_all_users_roles_and_grants();
|
||||
|
||||
if (opt_system & OPT_SYSTEM_UDFS)
|
||||
dump_all_udfs();
|
||||
|
||||
if (opt_system & OPT_SYSTEM_SERVERS)
|
||||
dump_all_servers();
|
||||
|
||||
/* These must be last as they explictly change the current database to mysql */
|
||||
if (opt_system & OPT_SYSTEM_STATS)
|
||||
dump_all_stats();
|
||||
|
||||
if (opt_system & OPT_SYSTEM_TIMEZONES)
|
||||
dump_all_timezones();
|
||||
|
||||
/* add 'START SLAVE' to end of dump */
|
||||
if (opt_slave_apply && add_slave_statements())
|
||||
goto err;
|
||||
|
|
|
@ -26,26 +26,28 @@ set_from_component(VENDOR)
|
|||
# the scriptlet, if present, is appended (together with the %posttrans tag)
|
||||
# to the pre-uninstall scriptlet
|
||||
#
|
||||
set(base_time "PRE")
|
||||
set(base_type "UNINSTALL")
|
||||
set(base_var CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_${base_time}_${base_type}_SCRIPT_FILE)
|
||||
set(acc)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.18)
|
||||
set(base_time "PRE")
|
||||
set(base_type "UNINSTALL")
|
||||
set(base_var CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_${base_time}_${base_type}_SCRIPT_FILE)
|
||||
set(acc)
|
||||
|
||||
macro(read_one_file time_ type_ tag_)
|
||||
set(var CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_${time_}_${type_}_SCRIPT_FILE)
|
||||
if (${var})
|
||||
file(READ ${${var}} content)
|
||||
set(acc "${tag_}\n${content}\n\n${acc}")
|
||||
macro(read_one_file time_ type_ tag_)
|
||||
set(var CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_${time_}_${type_}_SCRIPT_FILE)
|
||||
if (${var})
|
||||
file(READ ${${var}} content)
|
||||
set(acc "${tag_}\n${content}\n\n${acc}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
read_one_file("POST" "TRANS" "%posttrans")
|
||||
if (acc)
|
||||
set(orig_${base_var} ${${base_var}})
|
||||
read_one_file(${base_time} ${base_type} "")
|
||||
set(${base_var} ${CPACK_TOPLEVEL_DIRECTORY}/SPECS/${CPACK_RPM_PACKAGE_COMPONENT}_${base_time}_${base_type}.scriptlet)
|
||||
file(WRITE ${${base_var}} "${acc}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
read_one_file("POST" "TRANS" "%posttrans")
|
||||
if (acc)
|
||||
set(orig_${base_var} ${${base_var}})
|
||||
read_one_file(${base_time} ${base_type} "")
|
||||
set(${base_var} ${CPACK_TOPLEVEL_DIRECTORY}/SPECS/${CPACK_RPM_PACKAGE_COMPONENT}_${base_time}_${base_type}.scriptlet)
|
||||
file(WRITE ${${base_var}} "${acc}")
|
||||
endif()
|
||||
endif(CMAKE_VERSION VERSION_LESS 3.18)
|
||||
|
||||
# load the original CPackRPM.cmake
|
||||
set(orig_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
|
||||
|
@ -59,7 +61,9 @@ set(CMAKE_MODULE_PATH ${orig_CMAKE_MODULE_PATH})
|
|||
|
||||
restore(LICENSE)
|
||||
restore(VENDOR)
|
||||
set(${base_var} ${orig_${base_var}})
|
||||
if(${orig_${base_var}})
|
||||
set(${base_var} ${orig_${base_var}})
|
||||
endif()
|
||||
|
||||
# per-component cleanup
|
||||
foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV)
|
||||
|
|
|
@ -1444,7 +1444,7 @@ out:
|
|||
|
||||
void backup_fix_ddl(void);
|
||||
|
||||
static lsn_t get_current_lsn(MYSQL *connection)
|
||||
lsn_t get_current_lsn(MYSQL *connection)
|
||||
{
|
||||
static const char lsn_prefix[] = "\nLog sequence number ";
|
||||
lsn_t lsn = 0;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#define XTRABACKUP_BACKUP_COPY_H
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql.h>
|
||||
#include "datasink.h"
|
||||
|
||||
/* special files */
|
||||
|
@ -48,4 +49,7 @@ is_path_separator(char);
|
|||
bool
|
||||
directory_exists(const char *dir, bool create);
|
||||
|
||||
lsn_t
|
||||
get_current_lsn(MYSQL *connection);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2570,6 +2570,8 @@ static my_bool xtrabackup_copy_datafile(fil_node_t *node, uint thread_n,
|
|||
return(FALSE);
|
||||
}
|
||||
|
||||
memset(&write_filt_ctxt, 0, sizeof(xb_write_filt_ctxt_t));
|
||||
|
||||
bool was_dropped;
|
||||
pthread_mutex_lock(&backup_mutex);
|
||||
was_dropped = (ddl_tracker.drops.find(node->space->id) != ddl_tracker.drops.end());
|
||||
|
@ -2601,7 +2603,6 @@ static my_bool xtrabackup_copy_datafile(fil_node_t *node, uint thread_n,
|
|||
sizeof dst_name - 1);
|
||||
dst_name[sizeof dst_name - 1] = '\0';
|
||||
|
||||
memset(&write_filt_ctxt, 0, sizeof(xb_write_filt_ctxt_t));
|
||||
ut_a(write_filter.process != NULL);
|
||||
|
||||
if (write_filter.init != NULL &&
|
||||
|
@ -2941,8 +2942,14 @@ static void dbug_mariabackup_event(const char *event,const char *key)
|
|||
|
||||
}
|
||||
#define DBUG_MARIABACKUP_EVENT(A, B) DBUG_EXECUTE_IF("mariabackup_events", dbug_mariabackup_event(A,B););
|
||||
#define DBUG_MB_INJECT_CODE(EVENT, KEY, CODE) \
|
||||
DBUG_EXECUTE_IF("mariabackup_inject_code", {\
|
||||
char *env = getenv(EVENT); \
|
||||
if (env && !strcmp(env, KEY)) { CODE } \
|
||||
})
|
||||
#else
|
||||
#define DBUG_MARIABACKUP_EVENT(A,B)
|
||||
#define DBUG_MB_INJECT_CODE(EVENT, KEY, CODE)
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -2967,6 +2974,8 @@ DECLARE_THREAD(data_copy_thread_func)(
|
|||
|
||||
while ((node = datafiles_iter_next(ctxt->it)) != NULL) {
|
||||
DBUG_MARIABACKUP_EVENT("before_copy", node->space->name);
|
||||
DBUG_MB_INJECT_CODE("wait_innodb_redo_before_copy", node->space->name,
|
||||
backup_wait_for_lsn(get_current_lsn(mysql_connection)););
|
||||
/* copy the datafile */
|
||||
if (xtrabackup_copy_datafile(node, num, NULL,
|
||||
xtrabackup_incremental ? wf_incremental : wf_write_through))
|
||||
|
|
|
@ -538,8 +538,11 @@ static inline int my_b_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
|
|||
MEM_CHECK_DEFINED(Buffer, Count);
|
||||
if (info->write_pos + Count <= info->write_end)
|
||||
{
|
||||
memcpy(info->write_pos, Buffer, Count);
|
||||
info->write_pos+= Count;
|
||||
if (Count)
|
||||
{
|
||||
memcpy(info->write_pos, Buffer, Count);
|
||||
info->write_pos+= Count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return _my_b_write(info, Buffer, Count);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 62427520a5ba20e42fe51f5045062a7a9cadb466
|
||||
Subproject commit e38244220646a7e95c9be22576460aa7a4eb715f
|
|
@ -333,7 +333,7 @@ static my_bool emb_read_query_result(MYSQL *mysql)
|
|||
static int emb_stmt_execute(MYSQL_STMT *stmt)
|
||||
{
|
||||
DBUG_ENTER("emb_stmt_execute");
|
||||
uchar header[5];
|
||||
uchar header[9];
|
||||
THD *thd;
|
||||
my_bool res;
|
||||
|
||||
|
@ -345,6 +345,7 @@ static int emb_stmt_execute(MYSQL_STMT *stmt)
|
|||
|
||||
int4store(header, stmt->stmt_id);
|
||||
header[4]= (uchar) stmt->flags;
|
||||
header[5]= header[6]= header[7]= header[8]= 0; // safety
|
||||
thd= (THD*)stmt->mysql->thd;
|
||||
thd->client_param_count= stmt->param_count;
|
||||
thd->client_params= stmt->params;
|
||||
|
|
117
man/mysqldump.1
117
man/mysqldump.1
|
@ -1,6 +1,6 @@
|
|||
'\" t
|
||||
.\"
|
||||
.TH "\FBMYSQLDUMP\FR" "1" "28 March 2019" "MariaDB 10\&.4" "MariaDB Database System"
|
||||
.TH "\FBMYSQLDUMP\FR" "1" "24 October 2020" "MariaDB 10\&.4" "MariaDB Database System"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * set default formatting
|
||||
.\" -----------------------------------------------------------------
|
||||
|
@ -36,7 +36,7 @@ tables, consider using the
|
|||
instead because it can accomplish faster backups and faster restores\&. See
|
||||
\fBmysqlhotcopy\fR(1)\&.
|
||||
.PP
|
||||
There are three general ways to invoke
|
||||
There are four general ways to invoke
|
||||
\fBmysqldump\fR:
|
||||
.sp
|
||||
.if n \{\
|
||||
|
@ -46,6 +46,7 @@ There are three general ways to invoke
|
|||
shell> \fBmysqldump [\fR\fB\fIoptions\fR\fR\fB] \fR\fB\fIdb_name\fR\fR\fB [\fR\fB\fItbl_name\fR\fR\fB \&.\&.\&.]\fR
|
||||
shell> \fBmysqldump [\fR\fB\fIoptions\fR\fR\fB] \-\-databases \fR\fB\fIdb_name\fR\fR\fB \&.\&.\&.\fR
|
||||
shell> \fBmysqldump [\fR\fB\fIoptions\fR\fR\fB] \-\-all\-databases\fR
|
||||
shell> \fBmysqldump [\fR\fB\fIoptions\fR\fR\fB] \-\-system={options}\fR
|
||||
.fi
|
||||
.if n \{\
|
||||
.RE
|
||||
|
@ -2192,6 +2193,110 @@ Verify server's "Common Name" in its cert against hostname used when connecting.
|
|||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
.\" mysqladmin: Dump system tables option
|
||||
.\" Dump system tables option: mysqladmin
|
||||
\fB\-\-system=\fR\fB\fI{all, users, plugins, udfs, servers, stats, timezones}\fR\fR
|
||||
.sp
|
||||
Dump the system tables in the mysql database in a logical form\&. This option is an empty set by default\&.
|
||||
.sp
|
||||
One or more options can be listed in comma separated list\&.
|
||||
.sp
|
||||
The options here are:
|
||||
.sp
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
all \- an alias to enabling all of the below options\&.
|
||||
.RE
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
users \- the users, roles and their grants outputed as \fBCREATE USER\fB, \fBCREATE ROLE\fR, \fBGRANT\fR, and \fBSET DEFAULT ROLE\fR (\fBALTER USER\fR for MySQL-8.0+)\&.
|
||||
.RE
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
plugins \- active plugins of the server outputed as \fBINSTALL PLUGIN\fR\&.
|
||||
.RE
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
udfs \- user define functions outputed as \fBCREATE FUNCTION\fR\&.
|
||||
.RE
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
servers \- remote (federated) servers as \fBCREATE SERVER\fR\&.
|
||||
.RE
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
stats \- statistics tables, InnoDB and Engine Independent Table Statistics (EITS), are dumped as \fBINSERT\fR/\fBREPLACE INFO\fR statements without (re)creating tables\&.
|
||||
.RE
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
timezones \- timezone related system tables dumped as \fBINSERT\fR/\fBREPLACE INTO\fR statements without (re)creating tables\&.
|
||||
.RE
|
||||
.sp
|
||||
The format of the output is affected by \fB\-\-replace\fR and \fB\-\-insert\-into\fR\&. The \fB\-\-replace\fR option will output \fBCREATE OR REPLACE\fR
|
||||
forms of SQL, and also \fBDROP IF EXISTS\fR prior to \fBCREATE\fR, if a \fBCREATE OR REPLACE\fR option isn't available.
|
||||
.sp
|
||||
With \fB\-\-system=user\fR (or \fBall\fR), and \fB\-\-replace\fR, SQL is generated to generate an error if attempting to import the dump with a connection user that is being replaced within the dump\&.
|
||||
.sp
|
||||
The \fB\-\-insert\-into\fR option will cause \fBCREATE IF NOT EXIST\fR forms of SQL to generated if available.
|
||||
.sp
|
||||
For stats, and timezones, \fB\-\-replace\fR and \fB\-\-insert\-info\fR have the usual effects.
|
||||
.sp
|
||||
Enabling specific options here will cause the relevant tables in the mysql database to be ignored when dumping the mysql database or \fB\-\-all\-databases\fR\&.
|
||||
.sp
|
||||
Experimentally this option is designed to be able to dump system information from MySQL-5\&.7 and 8\&.0 servers\&. SQL generated is also
|
||||
experimentally compatible with MySQL-5\&.7/8\&.0\&. Mappings of implemenation specific grants/plugins isn't always one-to-one however\&.
|
||||
.sp
|
||||
.RE
|
||||
.RS 4
|
||||
.ie n \{\
|
||||
\h'-04'\(bu\h'+03'\c
|
||||
.\}
|
||||
.el \{\
|
||||
.sp -1
|
||||
.IP \(bu 2.3
|
||||
.\}
|
||||
.\" mysqldump: tab option
|
||||
.\" tab option: mysqldump
|
||||
\fB\-\-tab=\fR\fB\fIpath\fR\fR,
|
||||
|
@ -2673,7 +2778,7 @@ If you encounter problems backing up views, please read the section that covers
|
|||
.SH "COPYRIGHT"
|
||||
.br
|
||||
.PP
|
||||
Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2015 MariaDB Foundation
|
||||
Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2020 MariaDB Foundation
|
||||
.PP
|
||||
This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
|
||||
.PP
|
||||
|
@ -2681,12 +2786,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU
|
|||
.PP
|
||||
You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/.
|
||||
.sp
|
||||
.SH "NOTES"
|
||||
.IP " 1." 4
|
||||
Bug#30123
|
||||
.RS 4
|
||||
\%http://bugs.mysql.com/bug.php?id=30123
|
||||
.RE
|
||||
.SH "SEE ALSO"
|
||||
For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/
|
||||
.SH AUTHOR
|
||||
|
|
7
mysql-test/include/have_static_innodb.inc
Normal file
7
mysql-test/include/have_static_innodb.inc
Normal file
|
@ -0,0 +1,7 @@
|
|||
source include/have_innodb.inc;
|
||||
|
||||
if (!`select count(*) from information_schema.plugins
|
||||
where plugin_name = 'innodb' and plugin_status = 'active' and
|
||||
plugin_library is null`) {
|
||||
skip Need compiled-in InnoDB;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
TRUE
|
||||
NULL
|
|
@ -24,3 +24,9 @@ SELECT 0 FROM t1 FORCE INDEX FOR GROUP BY(a) WHERE a = 0 OR b = 0 AND c = 0;
|
|||
0
|
||||
DROP TABLE t1;
|
||||
End of 5.6 tests
|
||||
CREATE TABLE `t` (
|
||||
`a` varchar(3000) NOT NULL default '',
|
||||
PRIMARY KEY (`a`)
|
||||
) ENGINE=BLACKHOLE;
|
||||
DROP TABLE `t`;
|
||||
End of 10.1 tests
|
||||
|
|
|
@ -38,3 +38,19 @@ SELECT 0 FROM t1 FORCE INDEX FOR GROUP BY(a) WHERE a = 0 OR b = 0 AND c = 0;
|
|||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.6 tests
|
||||
|
||||
#
|
||||
# MDEV-24017 / bug 53588 test case.
|
||||
#
|
||||
# Create long enough index (between 1000 and 3500). 1000 is the old value,
|
||||
# 3500 is innodb value (see ha_innobase::max_supported_key_length()). Without
|
||||
# the fix the test will fail with "Specified key was too long" error.
|
||||
#
|
||||
CREATE TABLE `t` (
|
||||
`a` varchar(3000) NOT NULL default '',
|
||||
PRIMARY KEY (`a`)
|
||||
) ENGINE=BLACKHOLE;
|
||||
|
||||
DROP TABLE `t`;
|
||||
|
||||
--echo End of 10.1 tests
|
||||
|
|
8
mysql-test/main/bootstrap_innodb.result
Normal file
8
mysql-test/main/bootstrap_innodb.result
Normal file
|
@ -0,0 +1,8 @@
|
|||
create table t1(a int) engine=innodb;
|
||||
# restart
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
5
|
||||
drop table t1;
|
27
mysql-test/main/bootstrap_innodb.test
Normal file
27
mysql-test/main/bootstrap_innodb.test
Normal file
|
@ -0,0 +1,27 @@
|
|||
source include/have_static_innodb.inc;
|
||||
source include/not_embedded.inc;
|
||||
|
||||
let $datadir= `select @@datadir`;
|
||||
|
||||
create table t1(a int) engine=innodb;
|
||||
source include/shutdown_mysqld.inc;
|
||||
|
||||
write_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql;
|
||||
use test;
|
||||
insert t1 values (1);
|
||||
start transaction;
|
||||
insert t1 values (2);
|
||||
savepoint s1;
|
||||
insert t1 values (3);
|
||||
savepoint s2;
|
||||
insert t1 values (4);
|
||||
rollback to savepoint s1;
|
||||
insert t1 values (5);
|
||||
commit;
|
||||
EOF
|
||||
exec $MYSQLD_BOOTSTRAP_CMD --datadir=$datadir --innodb < $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1;
|
||||
remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql;
|
||||
|
||||
source include/start_mysqld.inc;
|
||||
select * from t1;
|
||||
drop table t1;
|
|
@ -1186,13 +1186,13 @@ i count(*) std(e1/e2)
|
|||
3 4 0.00000000
|
||||
select std(s1/s2) from bug22555;
|
||||
std(s1/s2)
|
||||
0.21328517
|
||||
0.21325764
|
||||
select std(o1/o2) from bug22555;
|
||||
std(o1/o2)
|
||||
0.2132576358664934
|
||||
select std(e1/e2) from bug22555;
|
||||
std(e1/e2)
|
||||
0.21328517
|
||||
0.21325764
|
||||
set @saved_div_precision_increment=@@div_precision_increment;
|
||||
set div_precision_increment=19;
|
||||
select i, count(*), std(s1/s2) from bug22555 group by i order by i;
|
||||
|
|
|
@ -375,8 +375,7 @@ SELECT SLEEP(1000);
|
|||
connection con1;
|
||||
KILL QUERY ID @id;
|
||||
connection default;
|
||||
SLEEP(1000)
|
||||
1
|
||||
ERROR 70100: Query execution was interrupted
|
||||
KILL QUERY ID 0;
|
||||
ERROR HY000: Unknown query id: 0
|
||||
#
|
||||
|
@ -392,8 +391,7 @@ ERROR HY000: You are not owner of query ID
|
|||
connection con1;
|
||||
KILL QUERY ID @id;
|
||||
connection default;
|
||||
SLEEP(1000)
|
||||
1
|
||||
ERROR 70100: Query execution was interrupted
|
||||
disconnect con5;
|
||||
DROP USER u1@localhost;
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
|
|
|
@ -607,6 +607,7 @@ let $wait_condition= SELECT @id:=QUERY_ID FROM INFORMATION_SCHEMA.PROCESSLIST WH
|
|||
source include/wait_condition.inc;
|
||||
KILL QUERY ID @id;
|
||||
connection default;
|
||||
--error ER_QUERY_INTERRUPTED
|
||||
reap;
|
||||
|
||||
--error ER_NO_SUCH_QUERY
|
||||
|
@ -633,6 +634,7 @@ connection con1;
|
|||
KILL QUERY ID @id;
|
||||
|
||||
connection default;
|
||||
--error ER_QUERY_INTERRUPTED
|
||||
reap;
|
||||
disconnect con5;
|
||||
DROP USER u1@localhost;
|
||||
|
|
231
mysql-test/main/lock_view.result
Normal file
231
mysql-test/main/lock_view.result
Normal file
|
@ -0,0 +1,231 @@
|
|||
create database mysqltest1;
|
||||
create database mysqltest2;
|
||||
create database mysqltest3;
|
||||
create user invoker@localhost;
|
||||
create user definer@localhost;
|
||||
grant select,show view on mysqltest1.* to invoker@localhost;
|
||||
grant select,show view on mysqltest1.* to definer@localhost;
|
||||
grant select,show view on mysqltest2.* to invoker@localhost;
|
||||
grant select,show view on mysqltest2.* to definer@localhost;
|
||||
grant select,show view on mysqltest3.* to invoker@localhost;
|
||||
grant select on performance_schema.* to definer@localhost;
|
||||
create table mysqltest1.t1 (a int);
|
||||
create definer=definer@localhost view mysqltest2.v2 as select * from mysqltest1.t1;
|
||||
create definer=definer@localhost view mysqltest3.v3 as select * from mysqltest2.v2;
|
||||
create definer=definer@localhost view mysqltest3.v3is as select schema_name from information_schema.schemata order by schema_name;
|
||||
create definer=definer@localhost view mysqltest3.v3ps as select user from performance_schema.users where current_connections>0 order by user;
|
||||
create definer=definer@localhost view mysqltest3.v3nt as select 1;
|
||||
create definer=definer@localhost sql security invoker view mysqltest3.v3i as select * from mysqltest1.t1;
|
||||
|
||||
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest1` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||
|
||||
USE `mysqltest1`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest2` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||
|
||||
USE `mysqltest2`;
|
||||
SET @saved_cs_client = @@character_set_client;
|
||||
SET character_set_client = utf8;
|
||||
/*!50001 CREATE TABLE `v2` (
|
||||
`a` tinyint NOT NULL
|
||||
) ENGINE=MyISAM */;
|
||||
SET character_set_client = @saved_cs_client;
|
||||
|
||||
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqltest3` /*!40100 DEFAULT CHARACTER SET latin1 */;
|
||||
|
||||
USE `mysqltest3`;
|
||||
SET @saved_cs_client = @@character_set_client;
|
||||
SET character_set_client = utf8;
|
||||
/*!50001 CREATE TABLE `v3` (
|
||||
`a` tinyint NOT NULL
|
||||
) ENGINE=MyISAM */;
|
||||
SET character_set_client = @saved_cs_client;
|
||||
SET @saved_cs_client = @@character_set_client;
|
||||
SET character_set_client = utf8;
|
||||
/*!50001 CREATE TABLE `v3i` (
|
||||
`a` tinyint NOT NULL
|
||||
) ENGINE=MyISAM */;
|
||||
SET character_set_client = @saved_cs_client;
|
||||
SET @saved_cs_client = @@character_set_client;
|
||||
SET character_set_client = utf8;
|
||||
/*!50001 CREATE TABLE `v3is` (
|
||||
`schema_name` tinyint NOT NULL
|
||||
) ENGINE=MyISAM */;
|
||||
SET character_set_client = @saved_cs_client;
|
||||
SET @saved_cs_client = @@character_set_client;
|
||||
SET character_set_client = utf8;
|
||||
/*!50001 CREATE TABLE `v3nt` (
|
||||
`1` tinyint NOT NULL
|
||||
) ENGINE=MyISAM */;
|
||||
SET character_set_client = @saved_cs_client;
|
||||
SET @saved_cs_client = @@character_set_client;
|
||||
SET character_set_client = utf8;
|
||||
/*!50001 CREATE TABLE `v3ps` (
|
||||
`user` tinyint NOT NULL
|
||||
) ENGINE=MyISAM */;
|
||||
SET character_set_client = @saved_cs_client;
|
||||
|
||||
USE `mysqltest1`;
|
||||
|
||||
USE `mysqltest2`;
|
||||
/*!50001 DROP TABLE IF EXISTS `v2`*/;
|
||||
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||
/*!50001 SET character_set_client = latin1 */;
|
||||
/*!50001 SET character_set_results = latin1 */;
|
||||
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||
/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
|
||||
/*!50001 VIEW `v2` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` */;
|
||||
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||
|
||||
USE `mysqltest3`;
|
||||
/*!50001 DROP TABLE IF EXISTS `v3`*/;
|
||||
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||
/*!50001 SET character_set_client = latin1 */;
|
||||
/*!50001 SET character_set_results = latin1 */;
|
||||
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||
/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
|
||||
/*!50001 VIEW `v3` AS select `v2`.`a` AS `a` from `mysqltest2`.`v2` */;
|
||||
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||
/*!50001 DROP TABLE IF EXISTS `v3i`*/;
|
||||
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||
/*!50001 SET character_set_client = latin1 */;
|
||||
/*!50001 SET character_set_results = latin1 */;
|
||||
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||
/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY INVOKER */
|
||||
/*!50001 VIEW `v3i` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` */;
|
||||
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||
/*!50001 DROP TABLE IF EXISTS `v3is`*/;
|
||||
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||
/*!50001 SET character_set_client = latin1 */;
|
||||
/*!50001 SET character_set_results = latin1 */;
|
||||
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||
/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
|
||||
/*!50001 VIEW `v3is` AS select `information_schema`.`schemata`.`SCHEMA_NAME` AS `schema_name` from `information_schema`.`schemata` order by `information_schema`.`schemata`.`SCHEMA_NAME` */;
|
||||
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||
/*!50001 DROP TABLE IF EXISTS `v3nt`*/;
|
||||
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||
/*!50001 SET character_set_client = latin1 */;
|
||||
/*!50001 SET character_set_results = latin1 */;
|
||||
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||
/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
|
||||
/*!50001 VIEW `v3nt` AS select 1 AS `1` */;
|
||||
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||
/*!50001 DROP TABLE IF EXISTS `v3ps`*/;
|
||||
/*!50001 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50001 SET @saved_cs_results = @@character_set_results */;
|
||||
/*!50001 SET @saved_col_connection = @@collation_connection */;
|
||||
/*!50001 SET character_set_client = latin1 */;
|
||||
/*!50001 SET character_set_results = latin1 */;
|
||||
/*!50001 SET collation_connection = latin1_swedish_ci */;
|
||||
/*!50001 CREATE ALGORITHM=UNDEFINED */
|
||||
/*!50013 DEFINER=`definer`@`localhost` SQL SECURITY DEFINER */
|
||||
/*!50001 VIEW `v3ps` AS select `performance_schema`.`users`.`USER` AS `user` from `performance_schema`.`users` where `performance_schema`.`users`.`CURRENT_CONNECTIONS` > 0 order by `performance_schema`.`users`.`USER` */;
|
||||
/*!50001 SET character_set_client = @saved_cs_client */;
|
||||
/*!50001 SET character_set_results = @saved_cs_results */;
|
||||
/*!50001 SET collation_connection = @saved_col_connection */;
|
||||
connect inv,localhost,invoker;
|
||||
lock table mysqltest3.v3 write;
|
||||
ERROR 42000: Access denied for user 'invoker'@'localhost' to database 'mysqltest3'
|
||||
disconnect inv;
|
||||
connection default;
|
||||
grant lock tables on mysqltest3.* to invoker@localhost;
|
||||
connect inv,localhost,invoker;
|
||||
show create view mysqltest3.v3;
|
||||
View Create View character_set_client collation_connection
|
||||
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest3`.`v3` AS select `v2`.`a` AS `a` from `mysqltest2`.`v2` latin1 latin1_swedish_ci
|
||||
show create view mysqltest3.v3is;
|
||||
View Create View character_set_client collation_connection
|
||||
v3is CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest3`.`v3is` AS select `information_schema`.`schemata`.`SCHEMA_NAME` AS `schema_name` from `information_schema`.`schemata` order by `information_schema`.`schemata`.`SCHEMA_NAME` latin1 latin1_swedish_ci
|
||||
show create view mysqltest3.v3ps;
|
||||
View Create View character_set_client collation_connection
|
||||
v3ps CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest3`.`v3ps` AS select `performance_schema`.`users`.`USER` AS `user` from `performance_schema`.`users` where `performance_schema`.`users`.`CURRENT_CONNECTIONS` > 0 order by `performance_schema`.`users`.`USER` latin1 latin1_swedish_ci
|
||||
show create view mysqltest3.v3nt;
|
||||
View Create View character_set_client collation_connection
|
||||
v3nt CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest3`.`v3nt` AS select 1 AS `1` latin1 latin1_swedish_ci
|
||||
show create view mysqltest3.v3i;
|
||||
View Create View character_set_client collation_connection
|
||||
v3i CREATE ALGORITHM=UNDEFINED DEFINER=`definer`@`localhost` SQL SECURITY INVOKER VIEW `mysqltest3`.`v3i` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
|
||||
lock table mysqltest3.v3 write;
|
||||
ERROR HY000: View 'mysqltest3.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
lock table mysqltest3.v3i write;
|
||||
ERROR HY000: View 'mysqltest3.v3i' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
lock table mysqltest3.v3is write;
|
||||
select * from mysqltest3.v3is;
|
||||
schema_name
|
||||
information_schema
|
||||
mysqltest1
|
||||
mysqltest2
|
||||
performance_schema
|
||||
test
|
||||
lock table mysqltest3.v3ps write;
|
||||
select * from mysqltest3.v3ps;
|
||||
user
|
||||
NULL
|
||||
invoker
|
||||
root
|
||||
lock table mysqltest3.v3nt write;
|
||||
select * from mysqltest3.v3nt;
|
||||
1
|
||||
1
|
||||
disconnect inv;
|
||||
connection default;
|
||||
grant lock tables on mysqltest2.* to invoker@localhost;
|
||||
connect inv,localhost,invoker;
|
||||
lock table mysqltest3.v3 write;
|
||||
ERROR HY000: View 'mysqltest3.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
lock table mysqltest3.v3i write;
|
||||
ERROR HY000: View 'mysqltest3.v3i' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
disconnect inv;
|
||||
connection default;
|
||||
grant lock tables on mysqltest1.* to definer@localhost;
|
||||
connect inv,localhost,invoker;
|
||||
lock table mysqltest3.v3 write;
|
||||
select * from mysqltest3.v3;
|
||||
a
|
||||
lock table mysqltest3.v3i write;
|
||||
ERROR HY000: View 'mysqltest3.v3i' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
disconnect inv;
|
||||
connection default;
|
||||
grant lock tables on mysqltest1.* to invoker@localhost;
|
||||
connect inv,localhost,invoker;
|
||||
lock table mysqltest3.v3i write;
|
||||
select * from mysqltest3.v3i;
|
||||
a
|
||||
disconnect inv;
|
||||
connection default;
|
||||
drop user invoker@localhost;
|
||||
drop user definer@localhost;
|
||||
drop database mysqltest1;
|
||||
drop database mysqltest2;
|
||||
drop database mysqltest3;
|
76
mysql-test/main/lock_view.test
Normal file
76
mysql-test/main/lock_view.test
Normal file
|
@ -0,0 +1,76 @@
|
|||
source include/not_embedded.inc;
|
||||
#
|
||||
# LOCK TABLES and privileges on views
|
||||
#
|
||||
create database mysqltest1;
|
||||
create database mysqltest2;
|
||||
create database mysqltest3;
|
||||
create user invoker@localhost;
|
||||
create user definer@localhost;
|
||||
grant select,show view on mysqltest1.* to invoker@localhost;
|
||||
grant select,show view on mysqltest1.* to definer@localhost;
|
||||
grant select,show view on mysqltest2.* to invoker@localhost;
|
||||
grant select,show view on mysqltest2.* to definer@localhost;
|
||||
grant select,show view on mysqltest3.* to invoker@localhost;
|
||||
grant select on performance_schema.* to definer@localhost;
|
||||
create table mysqltest1.t1 (a int);
|
||||
create definer=definer@localhost view mysqltest2.v2 as select * from mysqltest1.t1;
|
||||
create definer=definer@localhost view mysqltest3.v3 as select * from mysqltest2.v2;
|
||||
create definer=definer@localhost view mysqltest3.v3is as select schema_name from information_schema.schemata order by schema_name;
|
||||
create definer=definer@localhost view mysqltest3.v3ps as select user from performance_schema.users where current_connections>0 order by user;
|
||||
create definer=definer@localhost view mysqltest3.v3nt as select 1;
|
||||
create definer=definer@localhost sql security invoker view mysqltest3.v3i as select * from mysqltest1.t1;
|
||||
|
||||
exec $MYSQL_DUMP --compact -B mysqltest1 mysqltest2 mysqltest3;
|
||||
|
||||
connect inv,localhost,invoker;
|
||||
error ER_DBACCESS_DENIED_ERROR;
|
||||
lock table mysqltest3.v3 write;
|
||||
disconnect inv;
|
||||
connection default;
|
||||
|
||||
grant lock tables on mysqltest3.* to invoker@localhost;
|
||||
connect inv,localhost,invoker;
|
||||
show create view mysqltest3.v3;
|
||||
show create view mysqltest3.v3is;
|
||||
show create view mysqltest3.v3ps;
|
||||
show create view mysqltest3.v3nt;
|
||||
show create view mysqltest3.v3i;
|
||||
error ER_VIEW_INVALID;
|
||||
lock table mysqltest3.v3 write;
|
||||
error ER_VIEW_INVALID;
|
||||
lock table mysqltest3.v3i write;
|
||||
lock table mysqltest3.v3is write; select * from mysqltest3.v3is;
|
||||
lock table mysqltest3.v3ps write; select * from mysqltest3.v3ps;
|
||||
lock table mysqltest3.v3nt write; select * from mysqltest3.v3nt;
|
||||
disconnect inv;
|
||||
connection default;
|
||||
|
||||
grant lock tables on mysqltest2.* to invoker@localhost;
|
||||
connect inv,localhost,invoker;
|
||||
error ER_VIEW_INVALID;
|
||||
lock table mysqltest3.v3 write;
|
||||
error ER_VIEW_INVALID;
|
||||
lock table mysqltest3.v3i write;
|
||||
disconnect inv;
|
||||
connection default;
|
||||
|
||||
grant lock tables on mysqltest1.* to definer@localhost;
|
||||
connect inv,localhost,invoker;
|
||||
lock table mysqltest3.v3 write; select * from mysqltest3.v3;
|
||||
error ER_VIEW_INVALID;
|
||||
lock table mysqltest3.v3i write;
|
||||
disconnect inv;
|
||||
connection default;
|
||||
|
||||
grant lock tables on mysqltest1.* to invoker@localhost;
|
||||
connect inv,localhost,invoker;
|
||||
lock table mysqltest3.v3i write; select * from mysqltest3.v3i;
|
||||
disconnect inv;
|
||||
connection default;
|
||||
|
||||
drop user invoker@localhost;
|
||||
drop user definer@localhost;
|
||||
drop database mysqltest1;
|
||||
drop database mysqltest2;
|
||||
drop database mysqltest3;
|
21
mysql-test/main/mysqldump-system,win.rdiff
Normal file
21
mysql-test/main/mysqldump-system,win.rdiff
Normal file
|
@ -0,0 +1,21 @@
|
|||
--- mysqldump-system.result
|
||||
+++ mysqldump-system,win.result
|
||||
@@ -442,7 +442,7 @@
|
||||
mysql.time_zone_transition 3895294076
|
||||
mysql.plugin 0
|
||||
mysql.servers 2783974349
|
||||
-mysql.func 3241572444
|
||||
+mysql.func 310494789
|
||||
mysql.innodb_table_stats 347867921
|
||||
mysql.table_stats 664320059
|
||||
# Opps....
|
||||
@@ -477,7 +477,7 @@
|
||||
mysql.time_zone_transition 3895294076
|
||||
mysql.plugin 0
|
||||
mysql.servers 2783974349
|
||||
-mysql.func 3241572444
|
||||
+mysql.func 310494789
|
||||
mysql.innodb_table_stats 347867921
|
||||
mysql.table_stats 664320059
|
||||
DROP FUNCTION IF EXISTS metaphon;
|
||||
|
497
mysql-test/main/mysqldump-system.result
Normal file
497
mysql-test/main/mysqldump-system.result
Normal file
File diff suppressed because one or more lines are too long
155
mysql-test/main/mysqldump-system.test
Normal file
155
mysql-test/main/mysqldump-system.test
Normal file
|
@ -0,0 +1,155 @@
|
|||
--source include/not_embedded.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_udf.inc
|
||||
--source include/platform.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-23630: mysqldump to logically dump system tables
|
||||
--echo #
|
||||
--echo #
|
||||
|
||||
create table backup_users like mysql.global_priv;
|
||||
create table tables_priv like mysql.tables_priv;
|
||||
insert into backup_users select * from mysql.global_priv;
|
||||
insert into tables_priv select * from mysql.tables_priv;
|
||||
delete from mysql.global_priv where host not in ('localhost');
|
||||
flush privileges;
|
||||
|
||||
# mariadb.sys because of MDEV-24098
|
||||
alter user 'mariadb.sys'@'localhost' ACCOUNT UNLOCK;
|
||||
create user USER;
|
||||
|
||||
# time zone data already loaded
|
||||
|
||||
CREATE ROLE role_1;
|
||||
CREATE ROLE role_2 WITH ADMIN role_1;
|
||||
|
||||
GRANT SHOW DATABASES ON *.* TO role_1;
|
||||
GRANT role_1 TO USER;
|
||||
GRANT role_2 TO USER;
|
||||
SET DEFAULT ROLE role_2 FOR USER;
|
||||
|
||||
ALTER TABLE mysql.roles_mapping ORDER BY Host, User, Role;
|
||||
|
||||
# innodb and EITS tables statistics
|
||||
#
|
||||
set @save_innodb_stats_persistent= @@innodb_stats_persistent;
|
||||
create table mysql.tz like mysql.time_zone_transition;
|
||||
alter table mysql.tz engine=innodb;
|
||||
insert into mysql.tz select * from mysql.time_zone_transition;
|
||||
set global innodb_stats_persistent=1;
|
||||
ANALYZE TABLE mysql.tz PERSISTENT FOR ALL;
|
||||
# for predictable output in tests
|
||||
delete from mysql.index_stats where prefix_arity!=1;
|
||||
delete from mysql.column_stats where column_name!='Time_zone_id';
|
||||
set time_zone="+03:00";
|
||||
update mysql.innodb_index_stats set last_update="2020-01-01" where database_name="mysql" and table_name="tz";
|
||||
update mysql.innodb_table_stats set last_update="2020-01-01" where database_name="mysql" and table_name="tz";
|
||||
set global innodb_stats_persistent= @save_innodb_stats_persistent;
|
||||
alter table mysql.time_zone_name ORDER BY Name;
|
||||
|
||||
CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS(Host 'localhost');
|
||||
|
||||
--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO";
|
||||
|
||||
|
||||
#
|
||||
# Lets actually do some tests.
|
||||
#
|
||||
|
||||
--echo #
|
||||
--echo # mysqldump of system tables with --system=all
|
||||
--echo #
|
||||
|
||||
--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
|
||||
--exec $MYSQL_DUMP --skip-comments --system=all
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # mysqldump of system tables with --system=all --replace
|
||||
--echo #
|
||||
|
||||
--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
|
||||
--exec $MYSQL_DUMP --skip-comments --system=all --replace
|
||||
|
||||
|
||||
# save this for restore
|
||||
--exec $MYSQL_DUMP --system=users,servers,stats,timezones,udfs --replace > $MYSQLTEST_VARDIR/tmp/dump1.sql
|
||||
|
||||
--echo #
|
||||
--echo # mysqldump of system tables with --system=all --insert-ignore
|
||||
--echo #
|
||||
|
||||
--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
|
||||
--exec $MYSQL_DUMP --skip-comments --system=all --insert-ignore
|
||||
|
||||
|
||||
# global_priv checksum not restored because:
|
||||
# mariadb.sys - different Priv on restore
|
||||
# password_last_changed date isn't saved/restored
|
||||
# root user's Priv $.access lower number on restore
|
||||
|
||||
--replace_regex /"password_last_changed":[0-9]+/"password_last_changed":NOW/
|
||||
SELECT * FROM mysql.global_priv ORDER BY User,Host;
|
||||
|
||||
CHECKSUM TABLE mysql.roles_mapping, mysql.time_zone_transition, mysql.plugin,
|
||||
mysql.servers, mysql.func, mysql.innodb_table_stats, mysql.table_stats;
|
||||
|
||||
--echo # Opps....
|
||||
|
||||
CREATE USER mariadb_test_restore IDENTIFIED BY 'getitback';
|
||||
GRANT ALL ON *.* TO mariadb_test_restore WITH GRANT OPTION;
|
||||
GRANT PROXY ON ''@'%' TO mariadb_test_restore WITH GRANT OPTION;
|
||||
GRANT SUPER, CREATE USER /*M!100502 ,FEDERATED ADMIN */ ON *.* TO mariadb_test_restore WITH GRANT OPTION;
|
||||
|
||||
drop user USER;
|
||||
delete from mysql.table_stats;
|
||||
delete from mysql.innodb_table_stats;
|
||||
delete from mysql.time_zone_transition;
|
||||
delete from mysql.time_zone_transition_type;
|
||||
delete from mysql.time_zone;
|
||||
delete from mysql.time_zone_name;
|
||||
delete from mysql.time_zone_leap_second;
|
||||
DROP FUNCTION IF EXISTS metaphon;
|
||||
DROP SERVER s1;
|
||||
set time_zone= @@global.time_zone;
|
||||
|
||||
--echo # Restore from mysqldump
|
||||
--exec $MYSQL --user mariadb_test_restore --password=getitback --show-warnings < $MYSQLTEST_VARDIR/tmp/dump1.sql
|
||||
|
||||
DROP USER mariadb_test_restore;
|
||||
|
||||
# successful restore?
|
||||
|
||||
--replace_regex /"password_last_changed":[0-9]+/"password_last_changed":NOW/
|
||||
SELECT * FROM mysql.global_priv ORDER BY User,Host;
|
||||
|
||||
CHECKSUM TABLE mysql.roles_mapping, mysql.time_zone_transition, mysql.plugin,
|
||||
mysql.servers, mysql.func, mysql.innodb_table_stats, mysql.table_stats;
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
|
||||
DROP FUNCTION IF EXISTS metaphon;
|
||||
|
||||
DROP SERVER s1;
|
||||
|
||||
# EITS && innodb stats
|
||||
DELETE FROM mysql.column_stats WHERE db_name='mysql' and table_name in ('tz', 'gtid_slave_pos');
|
||||
DELETE FROM mysql.index_stats WHERE db_name='mysql' and table_name in ('tz', 'gtid_slave_pos');
|
||||
DELETE FROM mysql.table_stats WHERE db_name='mysql' and table_name in ('tz', 'gtid_slave_pos');
|
||||
DELETE FROM mysql.innodb_index_stats WHERE database_name='mysql' and table_name in ('tz','gtid_slave_pos');
|
||||
DELETE FROM mysql.innodb_table_stats WHERE database_name='mysql' and table_name in ('tz','gtid_slave_pos');
|
||||
drop table mysql.tz;
|
||||
|
||||
DROP ROLE role_2;
|
||||
DROP ROLE role_1;
|
||||
|
||||
drop user USER;
|
||||
|
||||
replace into mysql.global_priv select * from backup_users;
|
||||
replace into mysql.tables_priv select * from tables_priv;
|
||||
flush privileges;
|
||||
drop table backup_users, tables_priv;
|
|
@ -5422,8 +5422,9 @@ proc
|
|||
one
|
||||
DROP DATABASE bug25717383;
|
||||
Usage: mysqldump [OPTIONS] database [tables]
|
||||
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
|
||||
OR mysqldump [OPTIONS] --all-databases [OPTIONS]
|
||||
OR mysqldump [OPTIONS] --databases DB1 [DB2 DB3...]
|
||||
OR mysqldump [OPTIONS] --all-databases
|
||||
OR mysqldump [OPTIONS] --system=[SYSTEMOPTIONS]]
|
||||
For more options, use mysqldump --help
|
||||
#
|
||||
# MDEV-9001 - [PATCH] Fix DB name quoting in mysqldump --routine
|
||||
|
|
|
@ -3508,6 +3508,26 @@ NULLIF(GROUP_CONCAT(v1), null)
|
|||
C
|
||||
B
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-24033: SIGSEGV in __memcmp_avx2_movbe from queue_insert | SIGSEGV in __memcmp_avx2_movbe from native_compare
|
||||
#
|
||||
SET @save_max_length_for_sort_data=@@max_length_for_sort_data;
|
||||
SET @save_max_sort_length= @@max_sort_length;
|
||||
SET @save_sql_select_limit= @@sql_select_limit;
|
||||
CREATE TABLE t1 (a DECIMAL(64,0), b INT);
|
||||
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
|
||||
SET max_length_for_sort_data= 30;
|
||||
SET sql_select_limit = 3;
|
||||
SET max_sort_length=8;
|
||||
SELECT * FROM t1 ORDER BY a+1;
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
SET max_length_for_sort_data=@save_max_length_for_sort_data;
|
||||
SET max_sort_length= @save_max_sort_length;
|
||||
SET sql_select_limit= @save_sql_select_limit;
|
||||
DROP TABLE t1;
|
||||
# End of 10.2 tests
|
||||
#
|
||||
# MDEV-16214: Incorrect plan taken by the optimizer , uses INDEX instead of ref access with ORDER BY
|
||||
|
|
|
@ -2273,6 +2273,27 @@ ORDER BY id+1 DESC;
|
|||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-24033: SIGSEGV in __memcmp_avx2_movbe from queue_insert | SIGSEGV in __memcmp_avx2_movbe from native_compare
|
||||
--echo #
|
||||
|
||||
SET @save_max_length_for_sort_data=@@max_length_for_sort_data;
|
||||
SET @save_max_sort_length= @@max_sort_length;
|
||||
SET @save_sql_select_limit= @@sql_select_limit;
|
||||
|
||||
CREATE TABLE t1 (a DECIMAL(64,0), b INT);
|
||||
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
|
||||
|
||||
SET max_length_for_sort_data= 30;
|
||||
SET sql_select_limit = 3;
|
||||
SET max_sort_length=8;
|
||||
SELECT * FROM t1 ORDER BY a+1;
|
||||
|
||||
SET max_length_for_sort_data=@save_max_length_for_sort_data;
|
||||
SET max_sort_length= @save_max_sort_length;
|
||||
SET sql_select_limit= @save_sql_select_limit;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # End of 10.2 tests
|
||||
|
||||
--echo #
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
--source include/not_embedded.inc
|
||||
--source include/have_example_plugin.inc
|
||||
--source include/have_innodb.inc
|
||||
|
||||
if (!`select count(*) from information_schema.plugins
|
||||
where plugin_name = 'innodb' and plugin_status = 'active' and
|
||||
plugin_library is null`) {
|
||||
skip Need compiled-in InnoDB;
|
||||
}
|
||||
|
||||
--source include/have_static_innodb.inc
|
||||
|
||||
--replace_regex /\.dll/.so/
|
||||
eval install plugin example soname '$HA_EXAMPLE_SO';
|
||||
|
|
|
@ -2180,11 +2180,9 @@ connection extracon2;
|
|||
KILL QUERY <default_connection_ID>;
|
||||
KILL QUERY <con2_connection_ID>;
|
||||
connection default;
|
||||
sleep(50)
|
||||
1
|
||||
ERROR 70100: Query execution was interrupted
|
||||
connection con2;
|
||||
sleep(50)
|
||||
1
|
||||
ERROR 70100: Query execution was interrupted
|
||||
connection extracon;
|
||||
sleep(5.5)
|
||||
0
|
||||
|
|
|
@ -86,8 +86,10 @@ eval KILL QUERY $con1_id;
|
|||
eval KILL QUERY $con2_id;
|
||||
|
||||
connection default;
|
||||
--error ER_QUERY_INTERRUPTED
|
||||
--reap
|
||||
connection con2;
|
||||
--error ER_QUERY_INTERRUPTED
|
||||
--reap
|
||||
|
||||
connection extracon;
|
||||
|
|
|
@ -5919,14 +5919,14 @@ view_definition
|
|||
select 2 / 3 * 3 AS `2 / 3 * 3`,2 / (3 * 3) AS `2 / (3 * 3)`,2 / 3 * 3 AS `(2 / 3) * 3`
|
||||
select 2 / 3 * 3, 2 / (3 * 3), (2 / 3) * 3 union select * from v1;
|
||||
2 / 3 * 3 2 / (3 * 3) (2 / 3) * 3
|
||||
2.0001 0.2222 2.0001
|
||||
2.0000 0.2222 2.0000
|
||||
create or replace view v1 as select 2 / 3 / 3, 2 / (3 / 3), (2 / 3) / 3;
|
||||
Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
|
||||
view_definition
|
||||
select 2 / 3 / 3 AS `2 / 3 / 3`,2 / (3 / 3) AS `2 / (3 / 3)`,2 / 3 / 3 AS `(2 / 3) / 3`
|
||||
select 2 / 3 / 3, 2 / (3 / 3), (2 / 3) / 3 union select * from v1;
|
||||
2 / 3 / 3 2 / (3 / 3) (2 / 3) / 3
|
||||
0.22223333 2.0000 0.22223333
|
||||
0.22222222 2.0000 0.22222222
|
||||
create or replace view v1 as select 2 / 3 DIV 3, 2 / (3 DIV 3), (2 / 3) DIV 3;
|
||||
Select view_definition from information_schema.views where table_schema='test' and table_name='v1';
|
||||
view_definition
|
||||
|
|
|
@ -14,3 +14,16 @@ disconnect con1;
|
|||
connection default;
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
End of 5.5 tests
|
||||
#
|
||||
# MDEV-23752: SHOW EXPLAIN FOR thd waits for sleep
|
||||
#
|
||||
connect con1,localhost,root,,;
|
||||
select sleep(100000);;
|
||||
connection default;
|
||||
SHOW EXPLAIN FOR con_id;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 select sleep(100000)
|
||||
KILL QUERY con_id;
|
||||
# End of 10.2 tests
|
||||
|
|
|
@ -40,3 +40,21 @@ SET DEBUG_SYNC = 'RESET';
|
|||
source include/wait_until_count_sessions.inc;
|
||||
|
||||
--echo End of 5.5 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-23752: SHOW EXPLAIN FOR thd waits for sleep
|
||||
--echo #
|
||||
|
||||
--connect (con1,localhost,root,,)
|
||||
--let $con_id = `SELECT CONNECTION_ID()`
|
||||
--send select sleep(100000);
|
||||
|
||||
--connection default
|
||||
|
||||
--replace_result $con_id con_id
|
||||
eval SHOW EXPLAIN FOR $con_id;
|
||||
|
||||
--replace_result $con_id con_id
|
||||
eval KILL QUERY $con_id;
|
||||
|
||||
--echo # End of 10.2 tests
|
||||
|
|
|
@ -7,9 +7,8 @@ SLEEP(1)
|
|||
SHOW STATUS LIKE "max_statement_time_exceeded";
|
||||
Variable_name Value
|
||||
Max_statement_time_exceeded 0
|
||||
SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(3);
|
||||
SLEEP(3)
|
||||
1
|
||||
SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(10);
|
||||
ERROR 70100: Query execution was interrupted (max_statement_time exceeded)
|
||||
SHOW STATUS LIKE "max_statement_time_exceeded";
|
||||
Variable_name Value
|
||||
Max_statement_time_exceeded 1
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
SELECT @@MAX_STATEMENT_TIME;
|
||||
SET STATEMENT MAX_STATEMENT_TIME=3 FOR SELECT SLEEP(1);
|
||||
SHOW STATUS LIKE "max_statement_time_exceeded";
|
||||
SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(3);
|
||||
--error ER_STATEMENT_TIMEOUT
|
||||
SET STATEMENT MAX_STATEMENT_TIME=1 FOR SELECT SLEEP(10);
|
||||
SHOW STATUS LIKE "max_statement_time_exceeded";
|
||||
SELECT @@MAX_STATEMENT_TIME;
|
||||
|
||||
|
|
|
@ -2596,7 +2596,7 @@ SELECT
|
|||
population, area, population/area,
|
||||
cast(population/area as DECIMAL(20,9)) FROM t1 LIMIT 1;
|
||||
population area population/area cast(population/area as DECIMAL(20,9))
|
||||
11797 91 129.6374 129.637400000
|
||||
11797 91 129.6374 129.637362637
|
||||
SELECT * FROM t1 A
|
||||
WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = B.region);
|
||||
region area population
|
||||
|
|
|
@ -1532,8 +1532,11 @@ select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
|
|||
1.01500000 * 1.01500000 * 0.99500000)
|
||||
0.81298807395367312459230693948000000000
|
||||
create table t1 as select 5.05 / 0.014;
|
||||
Warnings:
|
||||
Note 1265 Data truncated for column '5.05 / 0.014' at row 1
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Note 1265 Data truncated for column '5.05 / 0.014' at row 1
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
|
@ -1648,6 +1651,8 @@ my_col
|
|||
0.12345678912345678912345678912345678912
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||
Warnings:
|
||||
Note 1265 Data truncated for column 'my_col' at row 1
|
||||
DESCRIBE t1;
|
||||
Field Type Null Key Default Extra
|
||||
my_col decimal(65,4) YES NULL
|
||||
|
|
|
@ -91,6 +91,8 @@ DROP INDEX test ON t1;
|
|||
insert into t1 values (10, 1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
|
||||
insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,NULL,2,2,'two','two,one');
|
||||
insert ignore into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303101010','','','','3',3,3);
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'string' at row 1
|
||||
insert ignore into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'utiny' at row 1
|
||||
|
@ -128,7 +130,7 @@ select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,ut
|
|||
auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col
|
||||
10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1
|
||||
11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2
|
||||
12 0.3333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
|
||||
12 0.33333333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
|
||||
13 -1 -1 -1 -1 -1 -1 -1.0 -1.0000 0 00000 0 0 0 0 1997-08-07 08:07:06 1997-04-03 09:08:07 -1 -1 -1 -1
|
||||
14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 0 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295
|
||||
15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295
|
||||
|
@ -180,7 +182,7 @@ Warning 1265 Data truncated for column 'new_field' at row 7
|
|||
select * from t2;
|
||||
auto string mediumblob_col new_field
|
||||
1 2 2 ne
|
||||
2 0.3333 ne
|
||||
2 0.33333333 ne
|
||||
3 -1 -1 ne
|
||||
4 -429496729 -4294967295 ne
|
||||
5 4294967295 4294967295 ne
|
||||
|
|
|
@ -9,10 +9,16 @@ UPDATE t1 SET f1 = f1 + 10;;
|
|||
connection node_2;
|
||||
UPDATE t1 SET f1 = f1 + 100;;
|
||||
connection node_1;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
1
|
||||
connection node_2;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
1
|
||||
connection node_3;
|
||||
SELECT f1 = 111 FROM t1;
|
||||
f1 = 111
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
1
|
||||
SELECT COUNT(*) IN (1, 2) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%committed%';
|
||||
COUNT(*) IN (1, 2)
|
||||
|
|
|
@ -24,13 +24,25 @@ SET GLOBAL wsrep_slave_threads = 2;
|
|||
--send UPDATE t1 SET f1 = f1 + 100;
|
||||
|
||||
--connection node_1
|
||||
#
|
||||
# Note that test is not deterministic. We have following cases possible
|
||||
# (1) Both updates are certified locally and then executed by the applier
|
||||
# (2) Certification of update in node_1 fails because applier has started
|
||||
# update from node_2
|
||||
# (3) Certification of update in node_2 fails because applier has started
|
||||
# update from node_1
|
||||
#
|
||||
--error 0,ER_LOCK_DEADLOCK
|
||||
--reap
|
||||
SELECT COUNT(*) FROM t1;
|
||||
|
||||
--connection node_2
|
||||
--error 0,ER_LOCK_DEADLOCK
|
||||
--reap
|
||||
SELECT COUNT(*) FROM t1;
|
||||
|
||||
--connection node_3
|
||||
SELECT f1 = 111 FROM t1;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
SELECT COUNT(*) IN (1, 2) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%committed%';
|
||||
|
||||
--eval SET GLOBAL wsrep_slave_threads = $wsrep_slave_threads_orig;
|
||||
|
|
|
@ -31,3 +31,47 @@ select * from t2;
|
|||
f1 f2
|
||||
3 qux
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# MDEV-23159 Assertion `table_share->tmp_table != NO_TMP_TABLE ||
|
||||
# m_lock_type != 2' + SIGSEGV in trnman_can_read_from
|
||||
# (on optimized builds)
|
||||
#
|
||||
SET @org_sql_mode=@@SQL_MODE;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Aria ROW_FORMAT=COMPRESSED;
|
||||
INSERT INTO t1 VALUES(1);
|
||||
CREATE TEMPORARY TABLE t2(b INT);
|
||||
EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT MAX(a) FROM t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 system NULL NULL NULL NULL 1 Using index
|
||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
DROP TABLE t1,t2;
|
||||
SET SQL_MODE='';
|
||||
CREATE TABLE t1 (c INT PRIMARY KEY) ENGINE=Aria;
|
||||
CREATE TABLE t2 (d INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
SELECT c FROM t1 WHERE (c) IN (SELECT MIN(c) FROM t2);
|
||||
c
|
||||
DROP TABLE t1,t2;
|
||||
USE test;
|
||||
SET SQL_MODE='ONLY_FULL_GROUP_BY';
|
||||
CREATE TABLE t3 (c1 DECIMAL(1,1) PRIMARY KEY,c2 DATE,c3 NUMERIC(10) UNSIGNED) ENGINE=Aria;
|
||||
CREATE TABLE t2 (f1 INTEGER ) ENGINE=Aria;
|
||||
INSERT INTO t3 VALUES (0,0,0);
|
||||
SELECT c1 FROM t3 WHERE (c1) IN (SELECT MIN(DISTINCT c1) FROM t2);
|
||||
c1
|
||||
DROP TABLE t2,t3;
|
||||
SET @@SQL_MODE=@org_sql_mode;
|
||||
#
|
||||
# MDEV-23222 SIGSEGV in maria_status | Assertion `(longlong)
|
||||
# thd->status_var.local_memory_used >= 0
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = 'MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;;
|
||||
flush tables;
|
||||
CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = 'MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;;
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of 10.3 tests
|
||||
#
|
||||
|
|
|
@ -40,3 +40,58 @@ INSERT IGNORE INTO t1 VALUES (1),(2);
|
|||
CREATE OR REPLACE TABLE t2 ENGINE=Aria AS SELECT SUM(a) AS f1, IFNULL( 'qux', ExtractValue( 'foo', 'bar' ) ) AS f2 FROM t1;
|
||||
select * from t2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-23159 Assertion `table_share->tmp_table != NO_TMP_TABLE ||
|
||||
--echo # m_lock_type != 2' + SIGSEGV in trnman_can_read_from
|
||||
--echo # (on optimized builds)
|
||||
--echo #
|
||||
|
||||
SET @org_sql_mode=@@SQL_MODE;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=Aria ROW_FORMAT=COMPRESSED;
|
||||
INSERT INTO t1 VALUES(1);
|
||||
CREATE TEMPORARY TABLE t2(b INT);
|
||||
EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT MAX(a) FROM t2);
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
SET SQL_MODE='';
|
||||
CREATE TABLE t1 (c INT PRIMARY KEY) ENGINE=Aria;
|
||||
CREATE TABLE t2 (d INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
SELECT c FROM t1 WHERE (c) IN (SELECT MIN(c) FROM t2);
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
USE test;
|
||||
SET SQL_MODE='ONLY_FULL_GROUP_BY';
|
||||
CREATE TABLE t3 (c1 DECIMAL(1,1) PRIMARY KEY,c2 DATE,c3 NUMERIC(10) UNSIGNED) ENGINE=Aria;
|
||||
CREATE TABLE t2 (f1 INTEGER ) ENGINE=Aria;
|
||||
INSERT INTO t3 VALUES (0,0,0);
|
||||
SELECT c1 FROM t3 WHERE (c1) IN (SELECT MIN(DISTINCT c1) FROM t2);
|
||||
DROP TABLE t2,t3;
|
||||
SET @@SQL_MODE=@org_sql_mode;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-23222 SIGSEGV in maria_status | Assertion `(longlong)
|
||||
--echo # thd->status_var.local_memory_used >= 0
|
||||
--echo #
|
||||
|
||||
let $mysqld_datadir= `select @@datadir`;
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
--eval CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = '$MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;
|
||||
flush tables;
|
||||
--remove_file $mysqld_datadir/test/MDEV_23222.frm
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
--error 1,ER_TABLE_EXISTS_ERROR
|
||||
--eval CREATE TABLE MDEV_23222 (i INT) DATA DIRECTORY = '$MYSQL_TMP_DIR', ENGINE=Aria TRANSACTIONAL=1;
|
||||
DROP TABLE t1;
|
||||
--disable_warnings
|
||||
--remove_file $mysqld_datadir/test/MDEV_23222.MAD
|
||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||
--remove_file $MYSQL_TMP_DIR/MDEV_23222.MAD
|
||||
--enable_warnings
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.3 tests
|
||||
--echo #
|
||||
|
|
|
@ -2,6 +2,7 @@ call mtr.add_suppression("InnoDB: New log files created");
|
|||
CREATE TABLE t1(i INT PRIMARY KEY) ENGINE INNODB;
|
||||
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
|
||||
CREATE TABLE t3(i INT) ENGINE INNODB;
|
||||
CREATE TABLE t10(i INT PRIMARY KEY) ENGINE INNODB;
|
||||
# Create full backup , modify table, then create incremental/differential backup
|
||||
INSERT into t1 values(1);
|
||||
# Prepare full backup, apply incremental one
|
||||
|
|
|
@ -8,6 +8,7 @@ let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1;
|
|||
CREATE TABLE t1(i INT PRIMARY KEY) ENGINE INNODB;
|
||||
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
|
||||
CREATE TABLE t3(i INT) ENGINE INNODB;
|
||||
CREATE TABLE t10(i INT PRIMARY KEY) ENGINE INNODB;
|
||||
|
||||
echo # Create full backup , modify table, then create incremental/differential backup;
|
||||
--disable_result_log
|
||||
|
@ -20,8 +21,11 @@ INSERT into t1 values(1);
|
|||
--let after_copy_test_t1=RENAME TABLE test.t1 TO test.t1_renamed
|
||||
--let after_copy_test_t2=DROP TABLE test.t2
|
||||
--let after_copy_test_t3=CREATE INDEX a_i ON test.t3(i);
|
||||
--let before_copy_test_t10=DROP TABLE test.t10
|
||||
--let wait_innodb_redo_before_copy=test/t10
|
||||
|
||||
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir --dbug=+d,mariabackup_events;
|
||||
# mariabackup should crash with assertion if MDEV-24026 is not fixed
|
||||
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir --dbug=+d,mariabackup_events,mariabackup_inject_code;
|
||||
--let after_load_tablespaces=
|
||||
--disable_result_log
|
||||
echo # Prepare full backup, apply incremental one;
|
||||
|
|
|
@ -102,8 +102,7 @@ ALTER TABLE t1 ADD PRIMARY KEY (a);
|
|||
ALTER TABLE t2 ADD PRIMARY KEY (a);
|
||||
ALTER TABLE t3 ADD PRIMARY KEY (a);
|
||||
|
||||
#--sync_slave_with_master
|
||||
--connection slave
|
||||
--sync_slave_with_master
|
||||
RENAME TABLE t3 TO t3_bak;
|
||||
|
||||
--connection master
|
||||
|
|
|
@ -51,9 +51,9 @@ INSERT into t1(name, salary, income_tax) values('Record_2', 501, 501*2.5/1000);
|
|||
INSERT into t1(name, salary, income_tax) values('Record_3', 210, 210*2.5/1000);
|
||||
SELECT * from t1;
|
||||
id name salary income_tax
|
||||
1 Record_1 100011 250.03
|
||||
2 Record_2 501 1.25
|
||||
3 Record_3 210 0.53
|
||||
1 Record_1 100011 250.027
|
||||
2 Record_2 501 1.2525
|
||||
3 Record_3 210 0.525
|
||||
connect test_con2, localhost, root,,;
|
||||
connection test_con2;
|
||||
## Verifying session & global value of variable ##
|
||||
|
@ -69,11 +69,11 @@ INSERT into t1(name, salary, income_tax) values('Record_5', 501, 501*2.5/1000);
|
|||
INSERT into t1(name, salary, income_tax) values('Record_6', 210, 210*2.5/1000);
|
||||
SELECT * from t1;
|
||||
id name salary income_tax
|
||||
1 Record_1 100011 250.03
|
||||
2 Record_2 501 1.25
|
||||
3 Record_3 210 0.53
|
||||
4 Record_4 100011 250.028
|
||||
5 Record_5 501 1.253
|
||||
1 Record_1 100011 250.027
|
||||
2 Record_2 501 1.2525
|
||||
3 Record_3 210 0.525
|
||||
4 Record_4 100011 250.027
|
||||
5 Record_5 501 1.2525
|
||||
6 Record_6 210 0.525
|
||||
## Dropping table t1 ##
|
||||
drop table t1;
|
||||
|
|
|
@ -37,5 +37,9 @@ SET @@GLOBAL.replicate_do_db=null;
|
|||
SELECT @@GLOBAL.replicate_do_db;
|
||||
@@GLOBAL.replicate_do_db
|
||||
|
||||
SET @@GLOBAL.replicate_do_db=DEFAULT;
|
||||
SELECT @@GLOBAL.replicate_do_db;
|
||||
@@GLOBAL.replicate_do_db
|
||||
|
||||
# Cleanup.
|
||||
SET @@GLOBAL.replicate_do_db = @save_replicate_do_db;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
include/master-slave.inc
|
||||
[connection master]
|
||||
connection slave;
|
||||
include/sync_slave_sql_with_master.inc
|
||||
SET @start_max_connections= @@global.max_connections;
|
||||
SET @start_init_slave= @@global.init_slave;
|
||||
SET NAMES utf8;
|
||||
|
@ -19,18 +19,12 @@ SELECT @@global.init_slave = 'SET @@global.max_connections = @@global.max_connec
|
|||
1
|
||||
Expect 1
|
||||
include/assert.inc [@@global.max_connections = @start_max_connections]
|
||||
STOP SLAVE;
|
||||
RESET MASTER;
|
||||
RESET SLAVE;
|
||||
START SLAVE;
|
||||
include/wait_for_slave_to_start.inc
|
||||
include/restart_slave.inc
|
||||
connection master;
|
||||
include/sync_slave_sql_with_master.inc
|
||||
include/assert.inc [@@global.max_connections = @start_max_connections + 1]
|
||||
SET @@global.init_slave = "SET @a=5";
|
||||
STOP SLAVE;
|
||||
RESET MASTER;
|
||||
RESET SLAVE;
|
||||
START SLAVE;
|
||||
include/wait_for_slave_to_start.inc
|
||||
include/restart_slave.inc
|
||||
SHOW VARIABLES LIKE 'init_slave';
|
||||
Variable_name Value
|
||||
init_slave SET @a=5
|
||||
|
|
|
@ -38,5 +38,8 @@ SELECT @@GLOBAL.replicate_do_db;
|
|||
SET @@GLOBAL.replicate_do_db=null;
|
||||
SELECT @@GLOBAL.replicate_do_db;
|
||||
|
||||
SET @@GLOBAL.replicate_do_db=DEFAULT;
|
||||
SELECT @@GLOBAL.replicate_do_db;
|
||||
|
||||
--echo # Cleanup.
|
||||
SET @@GLOBAL.replicate_do_db = @save_replicate_do_db;
|
||||
|
|
|
@ -29,7 +29,13 @@
|
|||
###############################################################################
|
||||
|
||||
source include/master-slave.inc;
|
||||
connection slave;
|
||||
|
||||
# Since a part of slave SQL thread initialisation happens after Slave_SQL_Running
|
||||
# has been set to Yes, there is a race condition between initialisation above and
|
||||
# init_slave setting given below. Synchronise slave applier with master to ensure
|
||||
# init_slave is complete and applier had processed few events like FD.
|
||||
--source include/sync_slave_sql_with_master.inc
|
||||
|
||||
--disable_query_log
|
||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
||||
--enable_query_log
|
||||
|
@ -66,14 +72,15 @@ let $wait_condition= SELECT @@global.max_connections = @start_max_connections;
|
|||
--let $assert_text= @@global.max_connections = @start_max_connections
|
||||
--let $assert_cond= @@global.max_connections = @start_max_connections
|
||||
--source include/assert.inc
|
||||
#
|
||||
# reset of the server
|
||||
STOP SLAVE;
|
||||
--wait_for_slave_to_stop
|
||||
RESET MASTER;
|
||||
RESET SLAVE;
|
||||
START SLAVE;
|
||||
source include/wait_for_slave_to_start.inc;
|
||||
|
||||
--source include/restart_slave_sql.inc
|
||||
|
||||
# Upon slave start, sync the applier with master, to ensure slave has
|
||||
# completed init_slave command execution and processed FD event from the
|
||||
# master.
|
||||
--connection master
|
||||
--source include/sync_slave_sql_with_master.inc
|
||||
|
||||
#
|
||||
# wait for the slave threads have set the global variable.
|
||||
let $wait_timeout= 90;
|
||||
|
@ -87,12 +94,7 @@ let $wait_condition= SELECT @@global.max_connections = @start_max_connections +
|
|||
# Setting a variable(which is local to a session) and must not be visible
|
||||
SET @@global.init_slave = "SET @a=5";
|
||||
#
|
||||
STOP SLAVE;
|
||||
--wait_for_slave_to_stop
|
||||
RESET MASTER;
|
||||
RESET SLAVE;
|
||||
START SLAVE;
|
||||
source include/wait_for_slave_to_start.inc;
|
||||
--source include/restart_slave_sql.inc
|
||||
#
|
||||
SHOW VARIABLES LIKE 'init_slave';
|
||||
# expect NULL
|
||||
|
|
|
@ -29,7 +29,7 @@ set time_zone='+1:00';
|
|||
flush tables;
|
||||
select * from t1;
|
||||
a b v
|
||||
1 2 0.3333000000000000000
|
||||
1 2 0.3333333330000000000
|
||||
select * from t8;
|
||||
a b v
|
||||
1234567890 2 2009-02-14 00:31:30
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -138,8 +138,9 @@ void *alloc_dynamic(DYNAMIC_ARRAY *array)
|
|||
array->size_of_element,
|
||||
MYF(array->malloc_flags | MY_WME))))
|
||||
DBUG_RETURN(0);
|
||||
memcpy(new_ptr, array->buffer,
|
||||
array->elements * array->size_of_element);
|
||||
if (array->elements)
|
||||
memcpy(new_ptr, array->buffer,
|
||||
array->elements * array->size_of_element);
|
||||
array->malloc_flags&= ~MY_INIT_BUFFER_USED;
|
||||
}
|
||||
else if (!(new_ptr=(char*)
|
||||
|
|
|
@ -159,10 +159,18 @@ err:
|
|||
#include <ctype.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#if defined(HAVE_POLL_H)
|
||||
#include <poll.h>
|
||||
#elif defined(HAVE_SYS_POLL_H)
|
||||
#include <sys/poll.h>
|
||||
#endif /* defined(HAVE_POLL_H) */
|
||||
|
||||
static int in[2], out[2];
|
||||
static pid_t pid;
|
||||
static char addr2line_binary[1024];
|
||||
static char output[1024];
|
||||
static struct pollfd poll_fds;
|
||||
Dl_info info;
|
||||
|
||||
int start_addr2line_fork(const char *binary_path)
|
||||
{
|
||||
|
@ -212,15 +220,16 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
|||
ssize_t extra_bytes_read = 0;
|
||||
ssize_t parsed = 0;
|
||||
|
||||
fd_set set;
|
||||
struct timeval timeout;
|
||||
int ret;
|
||||
|
||||
int filename_start = -1;
|
||||
int line_number_start = -1;
|
||||
|
||||
Dl_info info;
|
||||
void *offset;
|
||||
|
||||
poll_fds.fd = out[0];
|
||||
poll_fds.events = POLLIN | POLLRDBAND;
|
||||
|
||||
if (!dladdr(ptr, &info))
|
||||
return 1;
|
||||
|
||||
|
@ -242,16 +251,16 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
|
|||
if (write(in[1], input, len) <= 0)
|
||||
return 3;
|
||||
|
||||
FD_ZERO(&set);
|
||||
FD_SET(out[0], &set);
|
||||
|
||||
/* 100 ms should be plenty of time for addr2line to issue a response. */
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000;
|
||||
/* 500 ms should be plenty of time for addr2line to issue a response. */
|
||||
/* Read in a loop till all the output from addr2line is complete. */
|
||||
while (parsed == total_bytes_read &&
|
||||
select(out[0] + 1, &set, NULL, NULL, &timeout) > 0)
|
||||
(ret= poll(&poll_fds, 1, 500)))
|
||||
{
|
||||
/* error during poll */
|
||||
if (ret < 0)
|
||||
return 1;
|
||||
|
||||
extra_bytes_read= read(out[0], output + total_bytes_read,
|
||||
sizeof(output) - total_bytes_read);
|
||||
if (extra_bytes_read < 0)
|
||||
|
|
|
@ -491,7 +491,7 @@ char *strmake_root(MEM_ROOT *root, const char *str, size_t len)
|
|||
void *memdup_root(MEM_ROOT *root, const void *str, size_t len)
|
||||
{
|
||||
char *pos;
|
||||
if ((pos=alloc_root(root,len)))
|
||||
if ((pos=alloc_root(root,len)) && len)
|
||||
memcpy(pos,str,len);
|
||||
return pos;
|
||||
}
|
||||
|
|
|
@ -112,9 +112,6 @@ void my_error(uint nr, myf MyFlags, ...)
|
|||
char ebuff[ERRMSGSIZE];
|
||||
DBUG_ENTER("my_error");
|
||||
DBUG_PRINT("my", ("nr: %d MyFlags: %lu errno: %d", nr, MyFlags, errno));
|
||||
|
||||
if (errno == 1213)
|
||||
DBUG_ASSERT(0);
|
||||
|
||||
if (!(format = my_get_err_msg(nr)))
|
||||
(void) my_snprintf(ebuff, sizeof(ebuff), "Unknown error %d", nr);
|
||||
|
|
|
@ -14,8 +14,8 @@ CHECK_C_SOURCE_COMPILES(
|
|||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
int main() {
|
||||
char *arg_1;
|
||||
gid_t arg_2, arg_3;
|
||||
char *arg_1= 0;
|
||||
gid_t arg_2=0, arg_3;
|
||||
int arg_4;
|
||||
(void)getgrouplist(arg_1,arg_2,&arg_3,&arg_4);
|
||||
return 0;
|
||||
|
|
|
@ -709,6 +709,8 @@ static char *coll_search(struct user_coll *c, const char *n, size_t len)
|
|||
{
|
||||
struct user_name un;
|
||||
struct user_name *found;
|
||||
if (!c->n_users)
|
||||
return 0;
|
||||
un.name_len= len;
|
||||
un.name= (char *) n;
|
||||
found= (struct user_name*) bsearch(&un, c->users, c->n_users,
|
||||
|
@ -739,7 +741,8 @@ static int coll_insert(struct user_coll *c, char *n, size_t len)
|
|||
|
||||
static void coll_sort(struct user_coll *c)
|
||||
{
|
||||
qsort(c->users, c->n_users, sizeof(c->users[0]), cmp_users);
|
||||
if (c->n_users)
|
||||
qsort(c->users, c->n_users, sizeof(c->users[0]), cmp_users);
|
||||
}
|
||||
|
||||
|
||||
|
@ -970,7 +973,8 @@ static void get_str_n(char *dest, int *dest_len, size_t dest_size,
|
|||
if (src_len >= dest_size)
|
||||
src_len= dest_size - 1;
|
||||
|
||||
memcpy(dest, src, src_len);
|
||||
if (src_len)
|
||||
memcpy(dest, src, src_len);
|
||||
dest[src_len]= 0;
|
||||
*dest_len= (int)src_len;
|
||||
}
|
||||
|
|
|
@ -8674,7 +8674,10 @@ int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
|
|||
b_length=get_length(b_ptr);
|
||||
if (b_length > max_length)
|
||||
b_length=max_length;
|
||||
diff=memcmp(a,b,MY_MIN(a_length,b_length));
|
||||
if (uint32 len= MY_MIN(a_length,b_length))
|
||||
diff= memcmp(a,b,len);
|
||||
else
|
||||
diff= 0;
|
||||
return diff ? diff : (int) (a_length - b_length);
|
||||
}
|
||||
|
||||
|
@ -8731,7 +8734,8 @@ uint Field_blob::get_key_image(uchar *buff,uint length, imagetype type_arg)
|
|||
length=(uint) blob_length;
|
||||
}
|
||||
int2store(buff,length);
|
||||
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
|
||||
if (length)
|
||||
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
|
||||
return HA_KEY_BLOB_LENGTH+length;
|
||||
}
|
||||
|
||||
|
|
|
@ -1394,6 +1394,8 @@ public:
|
|||
virtual uint max_packed_col_length(uint max_length)
|
||||
{ return max_length;}
|
||||
|
||||
virtual bool is_packable() const { return false; }
|
||||
|
||||
uint offset(const uchar *record) const
|
||||
{
|
||||
return (uint) (ptr - record);
|
||||
|
@ -1986,6 +1988,7 @@ public:
|
|||
bool can_optimize_range(const Item_bool_func *cond,
|
||||
const Item *item,
|
||||
bool is_eq_func) const;
|
||||
bool is_packable() const { return true; }
|
||||
};
|
||||
|
||||
/* base class for float and double and decimal (old one) */
|
||||
|
|
|
@ -1978,7 +1978,14 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
|
|||
if (sortorder->field)
|
||||
{
|
||||
CHARSET_INFO *cs= sortorder->field->sort_charset();
|
||||
sortorder->type= sortorder->field->is_packable() ?
|
||||
SORT_FIELD_ATTR::VARIABLE_SIZE :
|
||||
SORT_FIELD_ATTR::FIXED_SIZE;
|
||||
|
||||
sortorder->length= sortorder->field->sort_length();
|
||||
if (sortorder->is_variable_sized())
|
||||
set_if_smaller(sortorder->length, thd->variables.max_sort_length);
|
||||
|
||||
if (use_strnxfrm((cs=sortorder->field->sort_charset())))
|
||||
{
|
||||
*multi_byte_charset= true;
|
||||
|
@ -1989,6 +1996,10 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
|
|||
}
|
||||
else
|
||||
{
|
||||
sortorder->type= sortorder->item->type_handler()->is_packable() ?
|
||||
SORT_FIELD_ATTR::VARIABLE_SIZE :
|
||||
SORT_FIELD_ATTR::FIXED_SIZE;
|
||||
|
||||
sortorder->item->type_handler()->sortlength(thd, sortorder->item,
|
||||
sortorder);
|
||||
if (use_strnxfrm(sortorder->item->collation.collation))
|
||||
|
@ -1998,7 +2009,8 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
|
|||
if (sortorder->item->maybe_null)
|
||||
length++; // Place for NULL marker
|
||||
}
|
||||
set_if_smaller(sortorder->length, thd->variables.max_sort_length);
|
||||
if (sortorder->is_variable_sized())
|
||||
set_if_smaller(sortorder->length, thd->variables.max_sort_length);
|
||||
length+=sortorder->length;
|
||||
}
|
||||
sortorder->field= (Field*) 0; // end marker
|
||||
|
|
|
@ -841,8 +841,10 @@ struct xid_t {
|
|||
void set(long f, const char *g, long gl, const char *b, long bl)
|
||||
{
|
||||
formatID= f;
|
||||
memcpy(data, g, gtrid_length= gl);
|
||||
memcpy(data+gl, b, bqual_length= bl);
|
||||
if ((gtrid_length= gl))
|
||||
memcpy(data, g, gl);
|
||||
if ((bqual_length= bl))
|
||||
memcpy(data+gl, b, bl);
|
||||
}
|
||||
void set(ulonglong xid)
|
||||
{
|
||||
|
|
|
@ -866,6 +866,8 @@ int Arg_comparator::compare_decimal()
|
|||
{
|
||||
if (set_null)
|
||||
owner->null_value= 0;
|
||||
val1.round_self_if_needed((*a)->decimals, HALF_UP);
|
||||
val2.round_self_if_needed((*b)->decimals, HALF_UP);
|
||||
return val1.cmp(val2);
|
||||
}
|
||||
}
|
||||
|
@ -888,6 +890,8 @@ int Arg_comparator::compare_e_decimal()
|
|||
VDec val1(*a), val2(*b);
|
||||
if (val1.is_null() || val2.is_null())
|
||||
return MY_TEST(val1.is_null() && val2.is_null());
|
||||
val1.round_self_if_needed((*a)->decimals, HALF_UP);
|
||||
val2.round_self_if_needed((*b)->decimals, HALF_UP);
|
||||
return MY_TEST(val1.cmp(val2) == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1481,14 +1481,13 @@ double Item_func_div::real_op()
|
|||
my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
int err;
|
||||
my_decimal tmp;
|
||||
VDec2_lazy val(args[0], args[1]);
|
||||
if ((null_value= val.has_null()))
|
||||
return 0;
|
||||
if ((err= check_decimal_overflow(my_decimal_div(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW &
|
||||
~E_DEC_DIV_ZERO,
|
||||
&tmp,
|
||||
decimal_value,
|
||||
val.m_a.ptr(), val.m_b.ptr(),
|
||||
prec_increment))) > 3)
|
||||
{
|
||||
|
@ -1497,7 +1496,6 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
|
|||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
tmp.round_to(decimal_value, decimals, HALF_UP);
|
||||
return decimal_value;
|
||||
}
|
||||
|
||||
|
@ -3928,6 +3926,8 @@ int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex)
|
|||
timeout= m_abs_timeout;
|
||||
|
||||
error= mysql_cond_timedwait(cond, mutex, &timeout);
|
||||
if (m_thd->check_killed())
|
||||
break;
|
||||
if (error == ETIMEDOUT || error == ETIME)
|
||||
{
|
||||
/* Return error if timed out or connection is broken. */
|
||||
|
@ -4774,7 +4774,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, size_t length,
|
|||
length--; // Fix length change above
|
||||
entry->value[length]= 0; // Store end \0
|
||||
}
|
||||
memmove(entry->value, ptr, length);
|
||||
if (length)
|
||||
memmove(entry->value, ptr, length);
|
||||
if (type == DECIMAL_RESULT)
|
||||
((my_decimal*)entry->value)->fix_buffer_pointer();
|
||||
entry->length= length;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2015, MariaDB
|
||||
Copyright (c) 2008, 2020, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -472,7 +472,8 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
|
|||
if (!(orig_args= (Item**) thd->alloc(sizeof(Item*)*arg_count)))
|
||||
return;
|
||||
}
|
||||
memcpy(orig_args, item->orig_args, sizeof(Item*)*arg_count);
|
||||
if (arg_count)
|
||||
memcpy(orig_args, item->orig_args, sizeof(Item*)*arg_count);
|
||||
init_aggregator();
|
||||
with_distinct= item->with_distinct;
|
||||
if (item->aggr)
|
||||
|
@ -1131,7 +1132,8 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
|
|||
check_sum_func(thd, ref))
|
||||
return TRUE;
|
||||
|
||||
memcpy (orig_args, args, sizeof (Item *) * arg_count);
|
||||
if (arg_count)
|
||||
memcpy (orig_args, args, sizeof (Item *) * arg_count);
|
||||
fixed= 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1363,7 +1365,8 @@ Item_sum_sp::fix_fields(THD *thd, Item **ref)
|
|||
if (check_sum_func(thd, ref))
|
||||
return TRUE;
|
||||
|
||||
memcpy(orig_args, args, sizeof(Item *) * arg_count);
|
||||
if (arg_count)
|
||||
memcpy(orig_args, args, sizeof(Item *) * arg_count);
|
||||
fixed= 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -3779,7 +3782,8 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
|
|||
|
||||
/* orig_args is only used for print() */
|
||||
orig_args= (Item**) (order + arg_count_order);
|
||||
memcpy(orig_args, args, sizeof(Item*) * arg_count);
|
||||
if (arg_count)
|
||||
memcpy(orig_args, args, sizeof(Item*) * arg_count);
|
||||
if (limit_clause)
|
||||
{
|
||||
row_limit= row_limit_arg;
|
||||
|
|
|
@ -34,12 +34,12 @@ static inline bool lex_string_cmp(CHARSET_INFO *charset, const LEX_CSTRING *a,
|
|||
|
||||
static inline bool cmp(const LEX_CSTRING *a, const LEX_CSTRING *b)
|
||||
{
|
||||
return (a->length != b->length ||
|
||||
memcmp(a->str, b->str, a->length));
|
||||
return a->length != b->length ||
|
||||
(a->length && memcmp(a->str, b->str, a->length));
|
||||
}
|
||||
static inline bool cmp(const LEX_CSTRING a, const LEX_CSTRING b)
|
||||
{
|
||||
return a.length != b.length || memcmp(a.str, b.str, a.length);
|
||||
return a.length != b.length || (a.length && memcmp(a.str, b.str, a.length));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2015, MariaDB
|
||||
Copyright (c) 2015, 2020, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -85,7 +85,6 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
|
|||
|
||||
do
|
||||
{
|
||||
size_t copied;
|
||||
uint elength, wlength, length;
|
||||
uchar iv[MY_AES_BLOCK_SIZE]= {0};
|
||||
|
||||
|
@ -116,11 +115,13 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
|
|||
|
||||
DBUG_ASSERT(length <= info->buffer_length);
|
||||
|
||||
copied= MY_MIN(Count, (size_t)(length - pos_offset));
|
||||
|
||||
memcpy(Buffer, info->buffer + pos_offset, copied);
|
||||
Count-= copied;
|
||||
Buffer+= copied;
|
||||
size_t copied= MY_MIN(Count, (size_t)(length - pos_offset));
|
||||
if (copied)
|
||||
{
|
||||
memcpy(Buffer, info->buffer + pos_offset, copied);
|
||||
Count-= copied;
|
||||
Buffer+= copied;
|
||||
}
|
||||
|
||||
info->read_pos= info->buffer + pos_offset + copied;
|
||||
info->read_end= info->buffer + length;
|
||||
|
|
|
@ -207,15 +207,15 @@ public:
|
|||
{
|
||||
return to_string(to, 0, 0, 0);
|
||||
}
|
||||
String *to_string_round(String *to, uint scale, my_decimal *round_buff) const
|
||||
String *to_string_round(String *to, int scale, my_decimal *round_buff) const
|
||||
{
|
||||
(void) round_to(round_buff, scale, HALF_UP); // QQ: check result?
|
||||
return round_buff->to_string(to);
|
||||
}
|
||||
int round_to(my_decimal *to, uint scale, decimal_round_mode mode,
|
||||
int round_to(my_decimal *to, int scale, decimal_round_mode mode,
|
||||
int mask= E_DEC_FATAL_ERROR) const
|
||||
{
|
||||
return check_result(mask, decimal_round(this, to, (int) scale, mode));
|
||||
return check_result(mask, decimal_round(this, to, scale, mode));
|
||||
}
|
||||
int to_binary(uchar *bin, int prec, int scale,
|
||||
uint mask= E_DEC_FATAL_ERROR) const;
|
||||
|
|
107
sql/opt_range.cc
107
sql/opt_range.cc
|
@ -15628,6 +15628,113 @@ static void print_ror_scans_arr(TABLE *table, const char *msg,
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
static String dbug_print_sel_arg_buf;
|
||||
|
||||
static void
|
||||
print_sel_arg_key(Field *field, const uchar *key, String *out)
|
||||
{
|
||||
TABLE *table= field->table;
|
||||
my_bitmap_map *old_sets[2];
|
||||
dbug_tmp_use_all_columns(table, old_sets, table->read_set, table->write_set);
|
||||
|
||||
if (field->real_maybe_null())
|
||||
{
|
||||
if (*key)
|
||||
{
|
||||
out->append("NULL");
|
||||
goto end;
|
||||
}
|
||||
key++; // Skip null byte
|
||||
}
|
||||
|
||||
field->set_key_image(key, field->pack_length());
|
||||
|
||||
if (field->type() == MYSQL_TYPE_BIT)
|
||||
(void) field->val_int_as_str(out, 1);
|
||||
else
|
||||
field->val_str(out);
|
||||
|
||||
end:
|
||||
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_sets);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@brief
|
||||
Produce a string representation of an individual SEL_ARG and return pointer
|
||||
to it
|
||||
|
||||
@detail
|
||||
Intended usage:
|
||||
|
||||
(gdb) p dbug_print_sel_arg(ptr)
|
||||
*/
|
||||
|
||||
const char *dbug_print_sel_arg(SEL_ARG *sel_arg)
|
||||
{
|
||||
StringBuffer<64> buf;
|
||||
String &out= dbug_print_sel_arg_buf;
|
||||
out.length(0);
|
||||
|
||||
if (!sel_arg)
|
||||
{
|
||||
out.append("NULL");
|
||||
goto end;
|
||||
}
|
||||
|
||||
out.append("SEL_ARG(");
|
||||
|
||||
const char *stype;
|
||||
switch(sel_arg->type) {
|
||||
case SEL_ARG::IMPOSSIBLE:
|
||||
stype="IMPOSSIBLE";
|
||||
break;
|
||||
case SEL_ARG::MAYBE:
|
||||
stype="MAYBE";
|
||||
break;
|
||||
case SEL_ARG::MAYBE_KEY:
|
||||
stype="MAYBE_KEY";
|
||||
break;
|
||||
case SEL_ARG::KEY_RANGE:
|
||||
default:
|
||||
stype= NULL;
|
||||
}
|
||||
|
||||
if (stype)
|
||||
{
|
||||
out.append("type=");
|
||||
out.append(stype);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sel_arg->min_flag & NO_MIN_RANGE)
|
||||
out.append("-inf");
|
||||
else
|
||||
{
|
||||
print_sel_arg_key(sel_arg->field, sel_arg->min_value, &buf);
|
||||
out.append(buf);
|
||||
}
|
||||
|
||||
out.append((sel_arg->min_flag & NEAR_MIN)? "<" : "<=");
|
||||
|
||||
out.append(sel_arg->field->field_name);
|
||||
|
||||
out.append((sel_arg->max_flag & NEAR_MAX)? "<" : "<=");
|
||||
|
||||
if (sel_arg->max_flag & NO_MAX_RANGE)
|
||||
out.append("+inf");
|
||||
else
|
||||
{
|
||||
print_sel_arg_key(sel_arg->field, sel_arg->max_value, &buf);
|
||||
out.append(buf);
|
||||
}
|
||||
|
||||
out.append(")");
|
||||
|
||||
end:
|
||||
return dbug_print_sel_arg_buf.c_ptr_safe();
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Print a quick range for debugging
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2017 MariaDB
|
||||
Copyright (c) 2017, 2020, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -751,13 +751,13 @@ void JOIN::add_keyuses_for_splitting()
|
|||
added_keyuse_count))
|
||||
goto err;
|
||||
|
||||
memcpy(keyuse.buffer,
|
||||
save_qep->keyuse.buffer,
|
||||
(size_t) save_qep->keyuse.elements * keyuse.size_of_element);
|
||||
keyuse.elements= save_qep->keyuse.elements;
|
||||
idx= keyuse.elements= save_qep->keyuse.elements;
|
||||
if (keyuse.elements)
|
||||
memcpy(keyuse.buffer,
|
||||
save_qep->keyuse.buffer,
|
||||
(size_t) keyuse.elements * keyuse.size_of_element);
|
||||
|
||||
keyuse_ext= &ext_keyuses_for_splitting->at(0);
|
||||
idx= save_qep->keyuse.elements;
|
||||
for (i=0; i < added_keyuse_count; i++, keyuse_ext++, idx++)
|
||||
{
|
||||
set_dynamic(&keyuse, (KEYUSE *) keyuse_ext, idx);
|
||||
|
|
|
@ -399,20 +399,28 @@ int opt_sum_query(THD *thd,
|
|||
break;
|
||||
}
|
||||
longlong info_limit= 1;
|
||||
table->file->info_push(INFO_KIND_FORCE_LIMIT_BEGIN, &info_limit);
|
||||
if (likely(!(error= table->file->ha_index_init((uint) ref.key, 1))))
|
||||
error= (is_max ?
|
||||
get_index_max_value(table, &ref, range_fl) :
|
||||
get_index_min_value(table, &ref, item_field, range_fl,
|
||||
prefix_len));
|
||||
error= 0;
|
||||
|
||||
table->file->info_push(INFO_KIND_FORCE_LIMIT_BEGIN, &info_limit);
|
||||
if (!table->const_table)
|
||||
{
|
||||
if (likely(!(error= table->file->ha_index_init((uint) ref.key,
|
||||
1))))
|
||||
error= (is_max ?
|
||||
get_index_max_value(table, &ref, range_fl) :
|
||||
get_index_min_value(table, &ref, item_field, range_fl,
|
||||
prefix_len));
|
||||
}
|
||||
/* Verify that the read tuple indeed matches the search key */
|
||||
if (!error &&
|
||||
reckey_in_range(is_max, &ref, item_field->field,
|
||||
conds, range_fl, prefix_len))
|
||||
error= HA_ERR_KEY_NOT_FOUND;
|
||||
table->file->ha_end_keyread();
|
||||
table->file->ha_index_end();
|
||||
if (!table->const_table)
|
||||
{
|
||||
table->file->ha_end_keyread();
|
||||
table->file->ha_index_end();
|
||||
}
|
||||
table->file->info_push(INFO_KIND_FORCE_LIMIT_END, NULL);
|
||||
if (error)
|
||||
{
|
||||
|
|
|
@ -2020,7 +2020,7 @@ retry_share:
|
|||
|
||||
#ifdef WITH_WSREP
|
||||
if (!((flags & MYSQL_OPEN_IGNORE_FLUSH) ||
|
||||
(wsrep_on(thd) && thd->wsrep_applier)))
|
||||
(thd->wsrep_applier)))
|
||||
#else
|
||||
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
|
||||
#endif
|
||||
|
|
|
@ -4887,7 +4887,8 @@ extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen)
|
|||
if (!mysql_mutex_trylock(&thd->LOCK_thd_data))
|
||||
{
|
||||
len= MY_MIN(buflen - 1, thd->query_length());
|
||||
memcpy(buf, thd->query(), len);
|
||||
if (len)
|
||||
memcpy(buf, thd->query(), len);
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
}
|
||||
buf[len]= '\0';
|
||||
|
|
|
@ -6088,6 +6088,8 @@ struct SORT_FIELD_ATTR
|
|||
{
|
||||
uint length; /* Length of sort field */
|
||||
uint suffix_length; /* Length suffix (0-4) */
|
||||
enum Type { FIXED_SIZE, VARIABLE_SIZE } type;
|
||||
bool is_variable_sized() { return type == VARIABLE_SIZE; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1396,7 +1396,8 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||
blob_field->get_image(cp, copy->length,
|
||||
blob_field->charset());
|
||||
DBUG_ASSERT(cp + copy->length + copy->blob_length <= buff + buff_size);
|
||||
memcpy(cp+copy->length, copy->str, copy->blob_length);
|
||||
if (copy->blob_length)
|
||||
memcpy(cp+copy->length, copy->str, copy->blob_length);
|
||||
cp+= copy->length+copy->blob_length;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -9553,7 +9553,8 @@ bool LEX::new_sp_instr_stmt(THD *thd,
|
|||
qbuff.length= prefix.length + suffix.length;
|
||||
if (!(qbuff.str= (char*) alloc_root(thd->mem_root, qbuff.length + 1)))
|
||||
return true;
|
||||
memcpy(qbuff.str, prefix.str, prefix.length);
|
||||
if (prefix.length)
|
||||
memcpy(qbuff.str, prefix.str, prefix.length);
|
||||
strmake(qbuff.str + prefix.length, suffix.str, suffix.length);
|
||||
i->m_query= qbuff;
|
||||
return sphead->add_instr(i);
|
||||
|
|
|
@ -104,6 +104,8 @@
|
|||
|
||||
#include "my_json_writer.h"
|
||||
|
||||
#define PRIV_LOCK_TABLES (SELECT_ACL | LOCK_TABLES_ACL)
|
||||
|
||||
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
|
||||
|
||||
#ifdef WITH_ARIA_STORAGE_ENGINE
|
||||
|
@ -1101,7 +1103,6 @@ int bootstrap(MYSQL_FILE *file)
|
|||
|
||||
thd->reset_kill_query(); /* Ensure that killed_errmsg is released */
|
||||
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
|
||||
free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
|
||||
thd->lex->restore_set_statement_var();
|
||||
}
|
||||
delete thd;
|
||||
|
@ -2939,6 +2940,36 @@ retry:
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Check privileges of view tables here, after views were opened.
|
||||
Either definer or invoker has to have PRIV_LOCK_TABLES to be able
|
||||
to lock view and its tables. For mysqldump (that locks views
|
||||
before dumping their structures) compatibility we allow locking
|
||||
views that select from I_S or P_S tables, but downrade the lock
|
||||
to TL_READ
|
||||
*/
|
||||
if (table->belong_to_view &&
|
||||
check_single_table_access(thd, PRIV_LOCK_TABLES, table, 1))
|
||||
{
|
||||
if (table->grant.m_internal.m_schema_access)
|
||||
table->lock_type= TL_READ;
|
||||
else
|
||||
{
|
||||
bool error= true;
|
||||
if (Security_context *sctx= table->security_ctx)
|
||||
{
|
||||
table->security_ctx= 0;
|
||||
error= check_single_table_access(thd, PRIV_LOCK_TABLES, table, 1);
|
||||
table->security_ctx= sctx;
|
||||
}
|
||||
if (error)
|
||||
{
|
||||
my_error(ER_VIEW_INVALID, MYF(0), table->belong_to_view->view_db.str,
|
||||
table->belong_to_view->view_name.str);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lock_tables(thd, tables, counter, 0) ||
|
||||
|
@ -5415,7 +5446,7 @@ mysql_execute_command(THD *thd)
|
|||
if (first_table && lex->type & (REFRESH_READ_LOCK|REFRESH_FOR_EXPORT))
|
||||
{
|
||||
/* Check table-level privileges. */
|
||||
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
|
||||
if (check_table_access(thd, PRIV_LOCK_TABLES, all_tables,
|
||||
FALSE, UINT_MAX, FALSE))
|
||||
goto error;
|
||||
|
||||
|
@ -6755,7 +6786,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
|
|||
|
||||
@param thd Thread handler
|
||||
@param privilege requested privilege
|
||||
@param all_tables global table list of query
|
||||
@param tables global table list of query
|
||||
@param no_errors FALSE/TRUE - report/don't report error to
|
||||
the client (using my_error() call).
|
||||
|
||||
|
@ -6765,28 +6796,25 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
|
|||
1 access denied, error is sent to client
|
||||
*/
|
||||
|
||||
bool check_single_table_access(THD *thd, ulong privilege,
|
||||
TABLE_LIST *all_tables, bool no_errors)
|
||||
bool check_single_table_access(THD *thd, ulong privilege, TABLE_LIST *tables,
|
||||
bool no_errors)
|
||||
{
|
||||
Switch_to_definer_security_ctx backup_sctx(thd, all_tables);
|
||||
Switch_to_definer_security_ctx backup_sctx(thd, tables);
|
||||
|
||||
const char *db_name;
|
||||
if ((all_tables->view || all_tables->field_translation) &&
|
||||
!all_tables->schema_table)
|
||||
db_name= all_tables->view_db.str;
|
||||
if ((tables->view || tables->field_translation) && !tables->schema_table)
|
||||
db_name= tables->view_db.str;
|
||||
else
|
||||
db_name= all_tables->db.str;
|
||||
db_name= tables->db.str;
|
||||
|
||||
if (check_access(thd, privilege, db_name,
|
||||
&all_tables->grant.privilege,
|
||||
&all_tables->grant.m_internal,
|
||||
0, no_errors))
|
||||
if (check_access(thd, privilege, db_name, &tables->grant.privilege,
|
||||
&tables->grant.m_internal, 0, no_errors))
|
||||
return 1;
|
||||
|
||||
/* Show only 1 table for check_grant */
|
||||
if (!(all_tables->belong_to_view &&
|
||||
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
|
||||
check_grant(thd, privilege, all_tables, FALSE, 1, no_errors))
|
||||
if (!(tables->belong_to_view &&
|
||||
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
|
||||
check_grant(thd, privilege, tables, FALSE, 1, no_errors))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
@ -9870,7 +9898,7 @@ static bool lock_tables_precheck(THD *thd, TABLE_LIST *tables)
|
|||
if (is_temporary_table(table))
|
||||
continue;
|
||||
|
||||
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, table,
|
||||
if (check_table_access(thd, PRIV_LOCK_TABLES, table,
|
||||
FALSE, 1, FALSE))
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -127,6 +127,9 @@ When one supplies long data for a placeholder:
|
|||
#include "wsrep_trans_observer.h"
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/* Constants defining bits in parameter type flags. Flags are read from high byte of short value */
|
||||
static const uint PARAMETER_FLAG_UNSIGNED = 128U << 8;
|
||||
|
||||
/**
|
||||
A result class used to send cursor rows using the binary protocol.
|
||||
*/
|
||||
|
@ -953,11 +956,73 @@ static bool insert_bulk_params(Prepared_statement *stmt,
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
static bool set_conversion_functions(Prepared_statement *stmt,
|
||||
uchar **data, uchar *data_end)
|
||||
|
||||
/**
|
||||
Checking if parameter type and flags are valid
|
||||
|
||||
@param typecode ushort value with type in low byte, and flags in high byte
|
||||
|
||||
@retval true this parameter is wrong
|
||||
@retval false this parameter is OK
|
||||
*/
|
||||
|
||||
static bool
|
||||
parameter_type_sanity_check(ushort typecode)
|
||||
{
|
||||
/* Checking if type in lower byte is valid */
|
||||
switch (typecode & 0xff) {
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
case MYSQL_TYPE_TINY:
|
||||
case MYSQL_TYPE_SHORT:
|
||||
case MYSQL_TYPE_LONG:
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_YEAR:
|
||||
case MYSQL_TYPE_BIT:
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
case MYSQL_TYPE_NULL:
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:
|
||||
case MYSQL_TYPE_ENUM:
|
||||
case MYSQL_TYPE_SET:
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_TIME:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_NEWDATE:
|
||||
break;
|
||||
/*
|
||||
This types normally cannot be sent by client, so maybe it'd be
|
||||
better to treat them like an error here.
|
||||
*/
|
||||
case MYSQL_TYPE_TIMESTAMP2:
|
||||
case MYSQL_TYPE_TIME2:
|
||||
case MYSQL_TYPE_DATETIME2:
|
||||
default:
|
||||
return true;
|
||||
};
|
||||
|
||||
// In Flags in high byte only unsigned bit may be set
|
||||
if (typecode & ((~PARAMETER_FLAG_UNSIGNED) & 0x0000ff00))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_conversion_functions(Prepared_statement *stmt, uchar **data)
|
||||
{
|
||||
uchar *read_pos= *data;
|
||||
const uint signed_bit= 1 << 15;
|
||||
|
||||
DBUG_ENTER("set_conversion_functions");
|
||||
/*
|
||||
First execute or types altered by the client, setup the
|
||||
|
@ -970,12 +1035,17 @@ static bool set_conversion_functions(Prepared_statement *stmt,
|
|||
{
|
||||
ushort typecode;
|
||||
|
||||
if (read_pos >= data_end)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/*
|
||||
stmt_execute_packet_sanity_check has already verified, that there
|
||||
are enough data in the packet for data types
|
||||
*/
|
||||
typecode= sint2korr(read_pos);
|
||||
read_pos+= 2;
|
||||
(**it).unsigned_flag= MY_TEST(typecode & signed_bit);
|
||||
if (parameter_type_sanity_check(typecode))
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
(**it).unsigned_flag= MY_TEST(typecode & PARAMETER_FLAG_UNSIGNED);
|
||||
(*it)->setup_conversion(thd, (uchar) (typecode & 0xff));
|
||||
(*it)->sync_clones();
|
||||
}
|
||||
|
@ -985,7 +1055,7 @@ static bool set_conversion_functions(Prepared_statement *stmt,
|
|||
|
||||
|
||||
static bool setup_conversion_functions(Prepared_statement *stmt,
|
||||
uchar **data, uchar *data_end,
|
||||
uchar **data,
|
||||
bool bulk_protocol= 0)
|
||||
{
|
||||
/* skip null bits */
|
||||
|
@ -998,7 +1068,7 @@ static bool setup_conversion_functions(Prepared_statement *stmt,
|
|||
if (*read_pos++) //types supplied / first execute
|
||||
{
|
||||
*data= read_pos;
|
||||
bool res= set_conversion_functions(stmt, data, data_end);
|
||||
bool res= set_conversion_functions(stmt, data);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
*data= read_pos;
|
||||
|
@ -3149,11 +3219,19 @@ static void mysql_stmt_execute_common(THD *thd,
|
|||
|
||||
void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||
{
|
||||
const uint packet_min_lenght= 9;
|
||||
uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround
|
||||
|
||||
DBUG_ENTER("mysqld_stmt_execute");
|
||||
|
||||
if (packet_length < packet_min_lenght)
|
||||
{
|
||||
my_error(ER_MALFORMED_PACKET, MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
ulong stmt_id= uint4korr(packet);
|
||||
ulong flags= (ulong) packet[4];
|
||||
uchar *packet_end= packet + packet_length;
|
||||
DBUG_ENTER("mysqld_stmt_execute");
|
||||
|
||||
packet+= 9; /* stmt_id + 5 bytes of flags */
|
||||
|
||||
|
@ -3209,6 +3287,84 @@ void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Additional packet checks for direct execution
|
||||
|
||||
@param thd THD handle
|
||||
@param stmt prepared statement being directly executed
|
||||
@param paket packet with parameters to bind
|
||||
@param packet_end pointer to the byte after parameters end
|
||||
@param bulk_op is it bulk operation
|
||||
@param direct_exec is it direct execution
|
||||
@param read_bytes need to read types (only with bulk_op)
|
||||
|
||||
@retval true this parameter is wrong
|
||||
@retval false this parameter is OK
|
||||
*/
|
||||
|
||||
static bool
|
||||
stmt_execute_packet_sanity_check(Prepared_statement *stmt,
|
||||
uchar *packet, uchar *packet_end,
|
||||
bool bulk_op, bool direct_exec,
|
||||
bool read_types)
|
||||
{
|
||||
|
||||
DBUG_ASSERT((!read_types) || (read_types && bulk_op));
|
||||
if (stmt->param_count > 0)
|
||||
{
|
||||
uint packet_length= static_cast<uint>(packet_end - packet);
|
||||
uint null_bitmap_bytes= (bulk_op ? 0 : (stmt->param_count + 7)/8);
|
||||
uint min_len_for_param_count = null_bitmap_bytes
|
||||
+ (bulk_op ? 0 : 1); /* sent types byte */
|
||||
|
||||
if (!bulk_op && packet_length >= min_len_for_param_count)
|
||||
{
|
||||
if ((read_types= packet[null_bitmap_bytes]))
|
||||
{
|
||||
/*
|
||||
Should be 0 or 1. If the byte is not 1, that could mean,
|
||||
e.g. that we read incorrect byte due to incorrect number
|
||||
of sent parameters for direct execution (i.e. null bitmap
|
||||
is shorter or longer, than it should be)
|
||||
*/
|
||||
if (packet[null_bitmap_bytes] != '\1')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (read_types)
|
||||
{
|
||||
/* 2 bytes per parameter of the type and flags */
|
||||
min_len_for_param_count+= 2*stmt->param_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
If types are not sent, there is nothing to do here.
|
||||
But for direct execution types should always be sent
|
||||
*/
|
||||
return direct_exec;
|
||||
}
|
||||
|
||||
/*
|
||||
If true, the packet is guaranteed too short for the number of
|
||||
parameters in the PS
|
||||
*/
|
||||
return (packet_length < min_len_for_param_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
If there is no parameters, this should be normally already end
|
||||
of the packet. If it's not - then error
|
||||
*/
|
||||
return (packet_end > packet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Common part of prepared statement execution
|
||||
|
@ -3248,6 +3404,22 @@ static void mysql_stmt_execute_common(THD *thd,
|
|||
llstr(stmt_id, llbuf), "mysqld_stmt_execute");
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
In case of direct execution application decides how many parameters
|
||||
to send.
|
||||
|
||||
Thus extra checks are required to prevent crashes caused by incorrect
|
||||
interpretation of the packet data. Plus there can be always a broken
|
||||
evil client.
|
||||
*/
|
||||
if (stmt_execute_packet_sanity_check(stmt, packet, packet_end, bulk_op,
|
||||
stmt_id == LAST_STMT_ID, read_types))
|
||||
{
|
||||
my_error(ER_MALFORMED_PACKET, MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
stmt->read_types= read_types;
|
||||
|
||||
#if defined(ENABLED_PROFILING)
|
||||
|
@ -4160,7 +4332,7 @@ Prepared_statement::set_parameters(String *expanded_query,
|
|||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
uchar *null_array= packet;
|
||||
res= (setup_conversion_functions(this, &packet, packet_end) ||
|
||||
res= (setup_conversion_functions(this, &packet) ||
|
||||
set_params(this, null_array, packet, packet_end, expanded_query));
|
||||
#else
|
||||
/*
|
||||
|
@ -4360,7 +4532,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
|
|||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (read_types &&
|
||||
set_conversion_functions(this, &packet, packet_end))
|
||||
set_conversion_functions(this, &packet))
|
||||
#else
|
||||
// bulk parameters are not supported for embedded, so it will an error
|
||||
#endif
|
||||
|
|
|
@ -27798,10 +27798,10 @@ JOIN::reoptimize(Item *added_where, table_map join_tables,
|
|||
if (save_to)
|
||||
{
|
||||
DBUG_ASSERT(!keyuse.elements);
|
||||
memcpy(keyuse.buffer,
|
||||
save_to->keyuse.buffer,
|
||||
(size_t) save_to->keyuse.elements * keyuse.size_of_element);
|
||||
keyuse.elements= save_to->keyuse.elements;
|
||||
if (size_t e= keyuse.elements)
|
||||
memcpy(keyuse.buffer,
|
||||
save_to->keyuse.buffer, e * keyuse.size_of_element);
|
||||
}
|
||||
|
||||
/* Add the new access methods to the keyuse array. */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
|
||||
Copyright (c) 2016, MariaDB
|
||||
Copyright (c) 2016, 2020, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -237,8 +237,8 @@ bool Binary_string::copy(const Binary_string &str)
|
|||
{
|
||||
if (alloc(str.str_length))
|
||||
return TRUE;
|
||||
str_length=str.str_length;
|
||||
bmove(Ptr,str.Ptr,str_length); // May be overlapping
|
||||
if ((str_length=str.str_length))
|
||||
bmove(Ptr,str.Ptr,str_length); // May be overlapping
|
||||
Ptr[str_length]=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -574,8 +574,11 @@ bool Binary_string::append_ulonglong(ulonglong val)
|
|||
|
||||
bool String::append(const char *s, size_t arg_length, CHARSET_INFO *cs)
|
||||
{
|
||||
if (!arg_length)
|
||||
return false;
|
||||
|
||||
uint32 offset;
|
||||
|
||||
|
||||
if (needs_conversion((uint32)arg_length, cs, charset(), &offset))
|
||||
{
|
||||
size_t add_length;
|
||||
|
|
|
@ -230,7 +230,7 @@ class Dec_ptr_and_buffer: public Dec_ptr
|
|||
protected:
|
||||
my_decimal m_buffer;
|
||||
public:
|
||||
int round_to(my_decimal *to, uint scale, decimal_round_mode mode)
|
||||
int round_to(my_decimal *to, int scale, decimal_round_mode mode)
|
||||
{
|
||||
DBUG_ASSERT(m_ptr);
|
||||
return m_ptr->round_to(to, scale, mode);
|
||||
|
@ -239,6 +239,14 @@ public:
|
|||
{
|
||||
return round_to(&m_buffer, scale, mode);
|
||||
}
|
||||
int round_self_if_needed(int scale, decimal_round_mode mode)
|
||||
{
|
||||
if (scale >= m_ptr->frac)
|
||||
return E_DEC_OK;
|
||||
int res= m_ptr->round_to(&m_buffer, scale, mode);
|
||||
m_ptr= &m_buffer;
|
||||
return res;
|
||||
}
|
||||
String *to_string_round(String *to, uint dec)
|
||||
{
|
||||
/*
|
||||
|
@ -3647,6 +3655,8 @@ public:
|
|||
const Type_std_attributes *item,
|
||||
SORT_FIELD_ATTR *attr) const= 0;
|
||||
|
||||
virtual bool is_packable() const { return false; }
|
||||
|
||||
virtual uint32 max_display_length(const Item *item) const= 0;
|
||||
virtual uint32 Item_decimal_notation_int_digits(const Item *item) const { return 0; }
|
||||
virtual uint32 calc_pack_length(uint32 length) const= 0;
|
||||
|
@ -4788,7 +4798,11 @@ public:
|
|||
void sortlength(THD *thd,
|
||||
const Type_std_attributes *item,
|
||||
SORT_FIELD_ATTR *attr) const;
|
||||
|
||||
bool is_packable()const { return true; }
|
||||
|
||||
bool union_element_finalize(const Item * item) const;
|
||||
|
||||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
|
|
|
@ -726,7 +726,11 @@ public:
|
|||
{ DBUG_ASSERT(FALSE); }
|
||||
|
||||
void global_save_default(THD *thd, set_var *var)
|
||||
{ DBUG_ASSERT(FALSE); }
|
||||
{
|
||||
char *ptr= (char*)(intptr)option.def_value;
|
||||
var->save_result.string_value.str= ptr;
|
||||
var->save_result.string_value.length= ptr ? strlen(ptr) : 0;
|
||||
}
|
||||
|
||||
bool session_update(THD *thd, set_var *var)
|
||||
{
|
||||
|
|
|
@ -3237,7 +3237,8 @@ inline void mark_as_null_row(TABLE *table)
|
|||
{
|
||||
table->null_row=1;
|
||||
table->status|=STATUS_NULL_ROW;
|
||||
bfill(table->null_flags,table->s->null_bytes,255);
|
||||
if (table->s->null_bytes)
|
||||
bfill(table->null_flags,table->s->null_bytes,255);
|
||||
}
|
||||
|
||||
bool is_simple_order(ORDER *order);
|
||||
|
|
|
@ -981,8 +981,11 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields,
|
|||
it.rewind();
|
||||
while ((field=it++))
|
||||
{
|
||||
memcpy(buff, field->comment.str, field->comment.length);
|
||||
buff+= field->comment.length;
|
||||
if (size_t l= field->comment.length)
|
||||
{
|
||||
memcpy(buff, field->comment.str, l);
|
||||
buff+= l;
|
||||
}
|
||||
}
|
||||
}
|
||||
*buff_arg= buff;
|
||||
|
|
|
@ -76,7 +76,8 @@
|
|||
#define cmp_record(A,B) memcmp((A)->record[0],(A)->B,(size_t) (A)->s->reclength)
|
||||
#define empty_record(A) { \
|
||||
restore_record((A),s->default_values); \
|
||||
bfill((A)->null_flags,(A)->s->null_bytes,255);\
|
||||
if ((A)->s->null_bytes) \
|
||||
bfill((A)->null_flags,(A)->s->null_bytes,255); \
|
||||
}
|
||||
|
||||
/* Defines for use with openfrm, openprt and openfrd */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "thr_lock.h" /* THR_LOCK */
|
||||
#include "handler.h" /* handler */
|
||||
#include "table.h" /* TABLE_SHARE */
|
||||
#include "sql_const.h" /* MAX_KEY */
|
||||
|
||||
/*
|
||||
Shared structure for correct LOCK operation
|
||||
|
@ -65,9 +66,9 @@ public:
|
|||
HA_READ_ORDER | HA_KEYREAD_ONLY);
|
||||
}
|
||||
/* The following defines can be increased if necessary */
|
||||
#define BLACKHOLE_MAX_KEY 64 /* Max allowed keys */
|
||||
#define BLACKHOLE_MAX_KEY MAX_KEY /* Max allowed keys */
|
||||
#define BLACKHOLE_MAX_KEY_SEG 16 /* Max segments for key */
|
||||
#define BLACKHOLE_MAX_KEY_LENGTH 1000
|
||||
#define BLACKHOLE_MAX_KEY_LENGTH 3500 /* Like in InnoDB */
|
||||
uint max_supported_keys() const { return BLACKHOLE_MAX_KEY; }
|
||||
uint max_supported_key_length() const { return BLACKHOLE_MAX_KEY_LENGTH; }
|
||||
uint max_supported_key_part_length() const { return BLACKHOLE_MAX_KEY_LENGTH; }
|
||||
|
|
|
@ -4532,14 +4532,13 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, const char *dbn, bool
|
|||
case TAB_DIR:
|
||||
case TAB_ZIP:
|
||||
case TAB_OEM:
|
||||
if (table && table->pos_in_table_list) // if SELECT
|
||||
{
|
||||
if (table && table->pos_in_table_list) { // if SELECT
|
||||
#if MYSQL_VERSION_ID > 100200
|
||||
Switch_to_definer_security_ctx backup_ctx(thd, table->pos_in_table_list);
|
||||
#endif // VERSION_ID > 100200
|
||||
|
||||
return check_global_access(thd, FILE_ACL);
|
||||
}
|
||||
else
|
||||
} else
|
||||
return check_global_access(thd, FILE_ACL);
|
||||
case TAB_ODBC:
|
||||
case TAB_JDBC:
|
||||
|
@ -4555,7 +4554,7 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, const char *dbn, bool
|
|||
case TAB_VIR:
|
||||
// This is temporary until a solution is found
|
||||
return false;
|
||||
} // endswitch type
|
||||
} // endswitch type
|
||||
|
||||
my_printf_error(ER_UNKNOWN_ERROR, "check_privileges failed", MYF(0));
|
||||
return true;
|
||||
|
|
|
@ -1168,6 +1168,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
FALSE, TRUE))
|
||||
goto err;
|
||||
my_free(log_data);
|
||||
log_data= 0;
|
||||
}
|
||||
|
||||
if (!(flags & HA_DONT_TOUCH_DATA))
|
||||
|
|
|
@ -144,8 +144,11 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
|||
set_if_smaller(length,tmp_length);
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
store_key_length_inc(key,char_length);
|
||||
memcpy(key, pos, char_length);
|
||||
key+= char_length;
|
||||
if (char_length)
|
||||
{
|
||||
memcpy(key, pos, char_length);
|
||||
key+= char_length;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (keyseg->flag & HA_SWAP_KEY)
|
||||
|
|
|
@ -144,12 +144,18 @@ static void set_setup_object_key(PFS_setup_object_key *key,
|
|||
char *ptr= &key->m_hash_key[0];
|
||||
ptr[0]= (char) object_type;
|
||||
ptr++;
|
||||
memcpy(ptr, schema, schema_length);
|
||||
ptr+= schema_length;
|
||||
if (schema_length)
|
||||
{
|
||||
memcpy(ptr, schema, schema_length);
|
||||
ptr+= schema_length;
|
||||
}
|
||||
ptr[0]= 0;
|
||||
ptr++;
|
||||
memcpy(ptr, object, object_length);
|
||||
ptr+= object_length;
|
||||
if (object_length)
|
||||
{
|
||||
memcpy(ptr, object, object_length);
|
||||
ptr+= object_length;
|
||||
}
|
||||
ptr[0]= 0;
|
||||
ptr++;
|
||||
key->m_key_length= (uint)(ptr - &key->m_hash_key[0]);
|
||||
|
|
|
@ -1533,8 +1533,11 @@ select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
|
|||
1.01500000 * 1.01500000 * 0.99500000)
|
||||
0.81298807395367312459230693948000000000
|
||||
create table t1 as select 5.05 / 0.014;
|
||||
Warnings:
|
||||
Note 1265 Data truncated for column '5.05 / 0.014' at row 1
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Note 1265 Data truncated for column '5.05 / 0.014' at row 1
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
|
@ -1649,6 +1652,8 @@ my_col
|
|||
0.12345678912345678912345678912345678912
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
|
||||
Warnings:
|
||||
Note 1265 Data truncated for column 'my_col' at row 1
|
||||
DESCRIBE t1;
|
||||
Field Type Null Key Default Extra
|
||||
my_col decimal(65,4) YES NULL
|
||||
|
|
|
@ -92,6 +92,8 @@ DROP INDEX test ON t1;
|
|||
insert into t1 values (10, 1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
|
||||
insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,NULL,2,2,'two','two,one');
|
||||
insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303101010','','','','3',3,3);
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'string' at row 1
|
||||
insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'utiny' at row 1
|
||||
|
@ -129,7 +131,7 @@ select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,ut
|
|||
auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col
|
||||
10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1
|
||||
11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2
|
||||
12 0.3333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
|
||||
12 0.33333333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
|
||||
13 -1 -1 -1 -1 -1 -1 -1.0 -1.0000 0 00000 0 0 0 0 1997-08-07 08:07:06 1997-04-03 09:08:07 -1 -1 -1 -1
|
||||
14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 0 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295
|
||||
15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295
|
||||
|
@ -181,7 +183,7 @@ Warning 1265 Data truncated for column 'new_field' at row 7
|
|||
select * from t2;
|
||||
auto string mediumblob_col new_field
|
||||
1 2 2 ne
|
||||
2 0.3333 ne
|
||||
2 0.33333333 ne
|
||||
3 -1 -1 ne
|
||||
4 -429496729 -4294967295 ne
|
||||
5 4294967295 4294967295 ne
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (c) 2002-2007 MySQL AB & tommy@valley.ne.jp
|
||||
Copyright (c) 2002, 2014, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2014, SkySQL Ab.
|
||||
Copyright (c) 2009, 2020, MariaDB Corporation.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
|
@ -399,7 +399,7 @@ my_strnxfrm_8bit_bin(CHARSET_INFO *cs,
|
|||
{
|
||||
set_if_smaller(srclen, dstlen);
|
||||
set_if_smaller(srclen, nweights);
|
||||
if (dst != src)
|
||||
if (srclen && dst != src)
|
||||
memcpy(dst, src, srclen);
|
||||
return my_strxfrm_pad_desc_and_reverse(cs, dst, dst + srclen, dst + dstlen,
|
||||
(uint)(nweights - srclen), flags, 0);
|
||||
|
|
|
@ -553,9 +553,11 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)),
|
|||
alloced= a= (uchar*) my_malloc(a_length+b_length+2, MYF(MY_FAE));
|
||||
|
||||
b= a + a_length+1;
|
||||
memcpy((char*) a, (char*) a0, a_length);
|
||||
if (a_length)
|
||||
memcpy((char*) a, (char*) a0, a_length);
|
||||
a[a_length]= 0; /* if length(a0)> len1, need to put 'end of string' */
|
||||
memcpy((char *)b, (char *)b0, b_length);
|
||||
if (b_length)
|
||||
memcpy((char *)b, (char *)b0, b_length);
|
||||
b[b_length]= 0; /* put end of string */
|
||||
a_length= thai2sortable(a, a_length);
|
||||
b_length= thai2sortable(b, b_length);
|
||||
|
|
|
@ -20941,6 +20941,153 @@ static void test_explain_meta()
|
|||
}
|
||||
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
#define MDEV19838_MAX_PARAM_COUNT 32
|
||||
#define MDEV19838_FIELDS_COUNT 17
|
||||
static void test_mdev19838()
|
||||
{
|
||||
int rc;
|
||||
MYSQL_BIND bind[MDEV19838_MAX_PARAM_COUNT];
|
||||
unsigned int i, paramCount = 1;
|
||||
char charvalue[] = "012345678901234567890123456789012345";
|
||||
MYSQL_STMT *stmt;
|
||||
|
||||
myheader("test_mdev19838");
|
||||
|
||||
rc = mysql_query(mysql, "CREATE TABLE mdev19838("
|
||||
"f1 char(36),"
|
||||
"f2 char(36),"
|
||||
"f3 char(36),"
|
||||
"f4 char(36),"
|
||||
"f5 char(36),"
|
||||
"f6 char(36),"
|
||||
"f7 char(36),"
|
||||
"f8 char(36),"
|
||||
"f9 char(36),"
|
||||
"f10 char(36),"
|
||||
"f11 char(36),"
|
||||
"f12 char(36),"
|
||||
"f13 char(36),"
|
||||
"f14 char(36),"
|
||||
"f15 char(36),"
|
||||
"f16 char(36),"
|
||||
"f17 char(36)"
|
||||
")");
|
||||
myquery(rc);
|
||||
|
||||
stmt = mysql_stmt_init(mysql);
|
||||
check_stmt(stmt);
|
||||
|
||||
memset(bind, 0, sizeof(bind));
|
||||
|
||||
for (i = 0; i < MDEV19838_MAX_PARAM_COUNT; ++i)
|
||||
{
|
||||
bind[i].buffer = charvalue;
|
||||
bind[i].buffer_type = MYSQL_TYPE_STRING;
|
||||
bind[i].buffer_length = strlen(charvalue) + 1;
|
||||
bind[i].length = &bind[i].length_value;
|
||||
bind[i].length_value = bind[i].buffer_length - 1;
|
||||
}
|
||||
|
||||
for (paramCount = 1; paramCount < MDEV19838_FIELDS_COUNT; ++paramCount)
|
||||
{
|
||||
mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, ¶mCount);
|
||||
|
||||
rc = mysql_stmt_bind_param(stmt, bind);
|
||||
check_execute(stmt, rc);
|
||||
|
||||
rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
|
||||
"(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
|
||||
" VALUES "
|
||||
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
|
||||
|
||||
/* Expecting an error */
|
||||
DIE_UNLESS(rc != 0);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
stmt = mysql_stmt_init(mysql);
|
||||
check_stmt(stmt);
|
||||
}
|
||||
|
||||
paramCount = 0;
|
||||
mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, ¶mCount);
|
||||
rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838(f1)"
|
||||
" VALUES (?)", -1);
|
||||
/* Expecting an error */
|
||||
DIE_UNLESS(rc != 0);
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
stmt = mysql_stmt_init(mysql);
|
||||
check_stmt(stmt);
|
||||
/* Correct number of parameters */
|
||||
paramCount = MDEV19838_FIELDS_COUNT;
|
||||
mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, ¶mCount);
|
||||
mysql_stmt_bind_param(stmt, bind);
|
||||
|
||||
rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
|
||||
"(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
|
||||
" VALUES "
|
||||
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
|
||||
check_execute(stmt, rc);
|
||||
|
||||
/* MYSQL_TYPE_TINY = 1. This parameter byte can be read as "parameters send" flag byte.
|
||||
Checking that wrong packet is still detected */
|
||||
bind[0].buffer_type = MYSQL_TYPE_TINY;
|
||||
bind[0].length_value = 1;
|
||||
bind[0].buffer_length = 1;
|
||||
|
||||
for (paramCount = 8; paramCount > 0; --paramCount)
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
stmt = mysql_stmt_init(mysql);
|
||||
check_stmt(stmt);
|
||||
|
||||
mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, ¶mCount);
|
||||
|
||||
rc = mysql_stmt_bind_param(stmt, bind);
|
||||
check_execute(stmt, rc);
|
||||
|
||||
rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
|
||||
"(f1, f2, f3, f4, f5, f6, f7, f8, f9)"
|
||||
" VALUES "
|
||||
"(?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
|
||||
|
||||
/* Expecting an error */
|
||||
DIE_UNLESS(rc != 0);
|
||||
}
|
||||
|
||||
/* Test of query w/out parameters, with parameter sent and not sent */
|
||||
for (paramCount = MDEV19838_MAX_PARAM_COUNT; paramCount != (unsigned int)-1; --paramCount)
|
||||
{
|
||||
mysql_stmt_close(stmt);
|
||||
stmt = mysql_stmt_init(mysql);
|
||||
check_stmt(stmt);
|
||||
|
||||
mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, ¶mCount);
|
||||
|
||||
if (paramCount > 0)
|
||||
{
|
||||
rc = mysql_stmt_bind_param(stmt, bind);
|
||||
check_execute(stmt, rc);
|
||||
}
|
||||
|
||||
rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
|
||||
"(f1)"
|
||||
" VALUES "
|
||||
"(0x1111111111111111)", -1);
|
||||
|
||||
/* Expecting an error if parameters are sent */
|
||||
DIE_UNLESS(rc != 0 || paramCount == 0);
|
||||
}
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
|
||||
rc = mysql_query(mysql, "drop table mdev19838");
|
||||
myquery(rc);
|
||||
}
|
||||
#endif // EMBEDDED_LIBRARY
|
||||
|
||||
|
||||
/*
|
||||
MDEV-20261 NULL passed to String::eq, SEGV, server crash, regression in 10.4
|
||||
*/
|
||||
|
@ -21280,6 +21427,9 @@ static struct my_tests_st my_tests[]= {
|
|||
#endif
|
||||
{ "test_ps_params_in_ctes", test_ps_params_in_ctes },
|
||||
{ "test_explain_meta", test_explain_meta },
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
{ "test_mdev19838", test_mdev19838 },
|
||||
#endif
|
||||
{ "test_mdev18408", test_mdev18408 },
|
||||
{ "test_mdev20261", test_mdev20261 },
|
||||
{ 0, 0 }
|
||||
|
|
Loading…
Add table
Reference in a new issue