diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 278fc8fdb7f..5df64e1b26c 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.5-next-mr-bugfixing" +tree_name = "mysql-5.6-next-mr-bugfixing" diff --git a/.bzrignore b/.bzrignore index 3b216cf1cea..351417a4353 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3066,4 +3066,7 @@ sql/share/swedish sql/share/ukrainian libmysqld/examples/mysqltest.cc libmysqld/sql_signal.cc +libmysqld/rpl_handler.cc libmysqld/debug_sync.cc +libmysqld/rpl_handler.cc +dbug/tests diff --git a/BUILD/build_mccge.sh b/BUILD/build_mccge.sh index 379ca1b2c68..3345ac3dcb5 100755 --- a/BUILD/build_mccge.sh +++ b/BUILD/build_mccge.sh @@ -1274,7 +1274,7 @@ set_bsd_configs() if test "x$fast_flag" != "xno" ; then compiler_flags="$compiler_flags -O3" else - compiler_flags="$compiler_flags -O" + compiler_flags="$compiler_flags -O0" fi set_cc_and_cxx_for_gcc } @@ -1305,7 +1305,7 @@ set_linux_configs() if test "x$fast_flag" != "xno" ; then compiler_flags="$compiler_flags -O2" else - compiler_flags="$compiler_flags -O" + compiler_flags="$compiler_flags -O0" fi # configure will set proper compiler flags for gcc on Linux elif test "x$compiler" = "xicc" ; then @@ -1375,8 +1375,8 @@ set_solaris_configs() LDFLAGS="$LDFLAGS -O2" compiler_flags="$compiler_flags -O2" else - LDFLAGS="$LDFLAGS -O" - compiler_flags="$compiler_flags -O" + LDFLAGS="$LDFLAGS -O0" + compiler_flags="$compiler_flags -O0" fi fi else @@ -1407,7 +1407,7 @@ set_solaris_configs() elif test "x$fast_flag" = "xgeneric" ; then compiler_flags="$compiler_flags -xO2" else - compiler_flags="$compiler_flags -xO" + compiler_flags="$compiler_flags -xO0" fi else #Using SPARC cpu with SunStudio (Forte) compiler @@ -1421,7 +1421,7 @@ set_solaris_configs() elif test "x$fast_flag" = "xgeneric" ; then compiler_flags="$compiler_flags -xO2" else - compiler_flags="$compiler_flags -xO" + compiler_flags="$compiler_flags -xO0" fi fi fi @@ -1452,7 +1452,7 @@ set_macosx_configs() if test "x$fast_flag" != "xno" ; then compiler_flags="$compiler_flags -Os" else - compiler_flags="$compiler_flags -O" + compiler_flags="$compiler_flags -O0" fi set_cc_and_cxx_for_gcc } diff --git a/CMakeLists.txt b/CMakeLists.txt index c6769eca72d..6e53ff30159 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,6 +311,7 @@ ADD_SUBDIRECTORY(extra) ADD_SUBDIRECTORY(client) ADD_SUBDIRECTORY(sql) ADD_SUBDIRECTORY(libmysql) +ADD_SUBDIRECTORY(libservices) ADD_SUBDIRECTORY(tests) IF(WITH_EMBEDDED_SERVER) ADD_SUBDIRECTORY(libmysqld) diff --git a/Makefile.am b/Makefile.am index 53be49768de..c208b5b6df1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,7 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ @readline_topdir@ sql-common scripts \ - @pstack_dir@ \ + @pstack_dir@ libservices \ @sql_union_dirs@ unittest \ @sql_server@ @man_dirs@ tests \ netware @libmysqld_dirs@ \ @@ -32,7 +32,7 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ DIST_SUBDIRS = . include Docs zlib \ cmd-line-utils sql-common scripts \ - pstack \ + pstack libservices \ strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \ vio sql man tests \ netware libmysqld \ @@ -98,7 +98,8 @@ test-pr: test-ns: cd mysql-test ; \ - @PERL@ ./mysql-test-run.pl $(force) $(mem) --mysqld=--binlog-format=mixed + @PERL@ ./mysql-test-run.pl $(force) $(mem) --mysqld=--binlog-format=mixed ; \ + @PERL@ ./mysql-test-run.pl $(force) $(mem) --suite=funcs_1 test-binlog-statement: cd mysql-test ; \ @@ -198,6 +199,10 @@ test-bt-fast: -cd mysql-test ; MTR_BUILD_THREAD=auto \ @PERL@ ./mysql-test-run.pl --force --comment=stress --suite=stress $(EXP) +test-bt-fast: + -cd mysql-test ; MTR_BUILD_THREAD=auto \ + @PERL@ ./mysql-test-run.pl --force --comment=ps --ps-protocol --report-features + test-bt-debug: -cd mysql-test ; MTR_BUILD_THREAD=auto \ @PERL@ ./mysql-test-run.pl --comment=debug --force --timer \ @@ -205,6 +210,8 @@ test-bt-debug: test-bt-debug-fast: +test-bt-debug-fast: + # Keep these for a while test-pl: test test-full-pl: test-full diff --git a/client/mysql.cc b/client/mysql.cc index 35322d37c2b..04cca1a2615 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1114,7 +1114,11 @@ int main(int argc,char *argv[]) close(stdout_fileno_copy); /* Clean up dup(). */ } - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + { + my_end(0); + exit(1); + } defaults_argv=argv; if (get_options(argc, (char **) argv)) { @@ -1281,21 +1285,35 @@ sig_handler handle_sigint(int sig) MYSQL *kill_mysql= NULL; /* terminate if no query being executed, or we already tried interrupting */ - if (!executing_query || interrupted_query) + /* terminate if no query being executed, or we already tried interrupting */ + if (!executing_query || (interrupted_query == 2)) + { + tee_fprintf(stdout, "Ctrl-C -- exit!\n"); goto err; + } kill_mysql= mysql_init(kill_mysql); if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password, "", opt_mysql_port, opt_mysql_unix_port,0)) + { + tee_fprintf(stdout, "Ctrl-C -- sorry, cannot connect to server to kill query, giving up ...\n"); goto err; + } + + interrupted_query++; + + /* mysqld < 5 does not understand KILL QUERY, skip to KILL CONNECTION */ + if ((interrupted_query == 1) && (mysql_get_server_version(&mysql) < 50000)) + interrupted_query= 2; /* kill_buffer is always big enough because max length of %lu is 15 */ - sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql)); - mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer)); + sprintf(kill_buffer, "KILL %s%lu", + (interrupted_query == 1) ? "QUERY " : "", + mysql_thread_id(&mysql)); + tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", kill_buffer); + mysql_real_query(kill_mysql, kill_buffer, (uint) strlen(kill_buffer)); mysql_close(kill_mysql); - tee_fprintf(stdout, "Query aborted by Ctrl+C\n"); - - interrupted_query= 1; + tee_fprintf(stdout, "Ctrl-C -- query aborted.\n"); return; diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 05eb80e5455..1a3f61559d6 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -819,7 +819,8 @@ int main(int argc, char **argv) init_dynamic_string(&conn_args, "", 512, 256)) die("Out of memory"); - load_defaults("my", load_default_groups, &argc, &argv); + if (load_defaults("my", load_default_groups, &argc, &argv)) + die(NULL); defaults_argv= argv; /* Must be freed by 'free_defaults' */ if (handle_options(&argc, &argv, my_long_options, get_one_option)) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index a3eee14e0d1..c8cbafe72d9 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -304,7 +304,8 @@ int main(int argc,char *argv[]) MY_INIT(argv[0]); mysql_init(&mysql); - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + exit(1); save_argv = argv; /* Save for free_defaults */ if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) { diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index a9504232af2..196d355f1dc 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -995,13 +995,13 @@ static struct my_option my_long_options[] = /* 'unspec' is not mentioned because it is just a placeholder. */ "Determine when the output statements should be base64-encoded BINLOG " "statements: 'never' disables it and works only for binlogs without " - "row-based events; 'auto' is the default and prints base64 only when " - "necessary (i.e., for row-based events and format description events); " - "'decode-rows' suppresses BINLOG statements for row events, but does " - "not exit as an error if a row event is found, unlike 'never'; " - "'always' prints base64 whenever possible. 'always' is for debugging " - "only and should not be used in a production system. The default is " - "'auto'. --base64-output is a short form for --base64-output=always." + "row-based events; 'decode-rows' decodes row events into commented SQL " + "statements if the --verbose option is also given; 'auto' prints base64 " + "only when necessary (i.e., for row-based events and format description " + "events); 'always' prints base64 whenever possible. 'always' is for " + "debugging only and should not be used in a production system. If this " + "argument is not given, the default is 'auto'; if it is given with no " + "argument, 'always' is used." ,(uchar**) &opt_base64_output_mode_str, (uchar**) &opt_base64_output_mode_str, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -2014,7 +2014,8 @@ int main(int argc, char** argv) my_init_time(); // for time functions - load_defaults("my", load_default_groups, &argc, &argv); + if (load_defaults("my", load_default_groups, &argc, &argv)) + exit(1); defaults_argv= argv; parse_args(&argc, (char***)&argv); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 1affea1d189..252ee500cf6 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -344,9 +344,8 @@ static int get_options(int *argc, char ***argv) exit(0); } - load_defaults("my", load_default_groups, argc, argv); - - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error= load_defaults("my", load_default_groups, argc, argv)) || + (ho_error=handle_options(argc, argv, my_long_options, get_one_option))) exit(ho_error); if (!what_to_do) diff --git a/client/mysqldump.c b/client/mysqldump.c index bd7c8e56fe0..54e7d68e191 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -858,12 +858,13 @@ static int get_options(int *argc, char ***argv) opt_net_buffer_length= *mysql_params->p_net_buffer_length; md_result_file= stdout; - load_defaults("my",load_default_groups,argc,argv); + if (load_defaults("my",load_default_groups,argc,argv)) + return 1; defaults_argv= *argv; - if (hash_init(&ignore_table, charset_info, 16, 0, 0, - (hash_get_key) get_table_key, - (hash_free_key) free_table_ent, 0)) + if (my_hash_init(&ignore_table, charset_info, 16, 0, 0, + (my_hash_get_key) get_table_key, + (my_hash_free_key) free_table_ent, 0)) return(EX_EOM); /* Don't copy internal log tables */ if (my_hash_insert(&ignore_table, @@ -1367,8 +1368,8 @@ static void free_resources() if (md_result_file && md_result_file != stdout) my_fclose(md_result_file, MYF(0)); my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR)); - if (hash_inited(&ignore_table)) - hash_free(&ignore_table); + if (my_hash_inited(&ignore_table)) + my_hash_free(&ignore_table); if (extended_insert) dynstr_free(&extended_row); if (insert_pat_inited) @@ -3958,7 +3959,7 @@ static int init_dumping(char *database, int init_func(char*)) my_bool include_table(const uchar *hash_key, size_t len) { - return !hash_search(&ignore_table, hash_key, len); + return ! my_hash_search(&ignore_table, hash_key, len); } diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 5b8ec95c06d..867663db8be 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -592,7 +592,8 @@ int main(int argc, char **argv) char **argv_to_free; MY_INIT(argv[0]); - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + return 1; /* argv is changed in the program */ argv_to_free= argv; if (get_options(&argc, &argv)) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 206b86d07cf..588ee049546 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -63,7 +63,9 @@ int main(int argc, char **argv) char *wild; MYSQL mysql; MY_INIT(argv[0]); - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + exit(1); + get_options(&argc,&argv); wild=0; diff --git a/client/mysqlslap.c b/client/mysqlslap.c index f13b5099766..fcfd525bba7 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -299,7 +299,11 @@ int main(int argc, char **argv) MY_INIT(argv[0]); - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + { + my_end(0); + exit(1); + } defaults_argv=argv; if (get_options(&argc,&argv)) { diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 53c0d9514e0..89330b0e31d 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -115,6 +115,8 @@ static uint my_end_arg= 0; /* Number of lines of the result to include in failure report */ static uint opt_tail_lines= 0; +static uint opt_connect_timeout= 0; + static char delimiter[MAX_DELIMITER_LENGTH]= ";"; static uint delimiter_length= 1; @@ -260,8 +262,7 @@ enum enum_commands { Q_SEND, Q_REAP, Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN, Q_PING, Q_EVAL, - Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, - Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, + Q_EVAL_RESULT, Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, Q_WAIT_FOR_SLAVE_TO_STOP, @@ -283,7 +284,7 @@ enum enum_commands { Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE, Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER, - Q_MOVE_FILE, + Q_MOVE_FILE, Q_SEND_EVAL, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -320,9 +321,6 @@ const char *command_names[]= "replace_column", "ping", "eval", - "rpl_probe", - "enable_rpl_parse", - "disable_rpl_parse", "eval_result", /* Enable/disable that the _query_ is logged to result file */ "enable_query_log", @@ -381,6 +379,7 @@ const char *command_names[]= "send_shutdown", "shutdown_server", "move_file", + "send_eval", 0 }; @@ -662,14 +661,6 @@ public: LogFile log_file; LogFile progress_file; - -/* Disable functions that only exist in MySQL 4.0 */ -#if MYSQL_VERSION_ID < 40000 -void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} -void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} -int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; } -my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } -#endif void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int len); void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); @@ -1138,7 +1129,7 @@ void free_used_memory() close_connections(); close_files(); - hash_free(&var_hash); + my_hash_free(&var_hash); for (i= 0 ; i < q_lines.elements ; i++) { @@ -1171,7 +1162,6 @@ void free_used_memory() mysql_server_end(); /* Don't use DBUG after mysql_server_end() */ - DBUG_VIOLATION_HELPER_LEAVE; return; } @@ -2001,8 +1991,8 @@ VAR* var_get(const char *var_name, const char **var_name_end, my_bool raw, if (length >= MAX_VAR_NAME_LENGTH) die("Too long variable name: %s", save_var_name); - if (!(v = (VAR*) hash_search(&var_hash, (const uchar*) save_var_name, - length))) + if (!(v = (VAR*) my_hash_search(&var_hash, (const uchar*) save_var_name, + length))) { char buff[MAX_VAR_NAME_LENGTH+1]; strmake(buff, save_var_name, length); @@ -2033,7 +2023,7 @@ err: VAR *var_obtain(const char *name, int len) { VAR* v; - if ((v = (VAR*)hash_search(&var_hash, (const uchar *) name, len))) + if ((v = (VAR*)my_hash_search(&var_hash, (const uchar *) name, len))) return v; v = var_init(0, name, len, "", 0); my_hash_insert(&var_hash, (uchar*)v); @@ -3851,12 +3841,8 @@ int do_save_master_pos() MYSQL_ROW row; MYSQL *mysql = &cur_con->mysql; const char *query; - int rpl_parse; DBUG_ENTER("do_save_master_pos"); - rpl_parse = mysql_rpl_parse_enabled(mysql); - mysql_disable_rpl_parse(mysql); - #ifdef HAVE_NDB_BINLOG /* Wait for ndb binlog to be up-to-date with all changes @@ -4006,10 +3992,6 @@ int do_save_master_pos() strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); master_pos.pos = strtoul(row[1], (char**) 0, 10); mysql_free_result(res); - - if (rpl_parse) - mysql_enable_rpl_parse(mysql); - DBUG_RETURN(0); } @@ -4072,29 +4054,6 @@ void do_let(struct st_command *command) } -int do_rpl_probe(struct st_command *command __attribute__((unused))) -{ - DBUG_ENTER("do_rpl_probe"); - if (mysql_rpl_probe(&cur_con->mysql)) - die("Failed in mysql_rpl_probe(): '%s'", mysql_error(&cur_con->mysql)); - DBUG_RETURN(0); -} - - -int do_enable_rpl_parse(struct st_command *command __attribute__((unused))) -{ - mysql_enable_rpl_parse(&cur_con->mysql); - return 0; -} - - -int do_disable_rpl_parse(struct st_command *command __attribute__((unused))) -{ - mysql_disable_rpl_parse(&cur_con->mysql); - return 0; -} - - /* Sleep the number of specified seconds @@ -5025,6 +4984,11 @@ void do_connect(struct st_command *command) #endif if (!mysql_init(&con_slot->mysql)) die("Failed on mysql_init()"); + + if (opt_connect_timeout) + mysql_options(&con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT, + (void *) &opt_connect_timeout); + if (opt_compress || con_compress) mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); @@ -5814,6 +5778,11 @@ static struct my_option my_long_options[] = {"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select", (uchar**) &view_protocol, (uchar**) &view_protocol, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"connect_timeout", OPT_CONNECT_TIMEOUT, + "Number of seconds before connection timeout.", + (uchar**) &opt_connect_timeout, + (uchar**) &opt_connect_timeout, 0, GET_UINT, REQUIRED_ARG, + 120, 0, 3600 * 12, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -5987,7 +5956,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int parse_args(int argc, char **argv) { - load_defaults("my",load_default_groups,&argc,&argv); + if (load_defaults("my",load_default_groups,&argc,&argv)) + exit(1); + default_argv= argv; if ((handle_options(&argc, &argv, my_long_options, get_one_option))) @@ -6552,8 +6523,6 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!disable_result_log) { - ulonglong UNINIT_VAR(affected_rows); /* Ok to be undef if 'disable_info' is set */ - if (res) { MYSQL_FIELD *fields= mysql_fetch_fields(res); @@ -6570,10 +6539,10 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, /* Need to call mysql_affected_rows() before the "new" - query to find the warnings + query to find the warnings. */ if (!disable_info) - affected_rows= mysql_affected_rows(mysql); + append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql)); /* Add all warnings to the result. We can't do this if we are in @@ -6588,9 +6557,6 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length); } } - - if (!disable_info) - append_info(ds, affected_rows, mysql_info(mysql)); } if (res) @@ -6831,10 +6797,8 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, MYSQL_STMT *stmt; DYNAMIC_STRING ds_prepare_warnings; DYNAMIC_STRING ds_execute_warnings; - ulonglong affected_rows; DBUG_ENTER("run_query_stmt"); DBUG_PRINT("query", ("'%-.60s'", query)); - LINT_INIT(affected_rows); /* Init a new stmt if it's not already one created for this connection @@ -6966,11 +6930,12 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, } /* - Need to grab affected rows information before getting - warnings here + Fetch info before fetching warnings, since it will be reset + otherwise. */ + if (!disable_info) - affected_rows= mysql_affected_rows(mysql); + append_info(ds, mysql_stmt_affected_rows(stmt), mysql_info(mysql)); if (!disable_warnings) { @@ -6983,21 +6948,17 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, ds_warnings->length) { dynstr_append_mem(ds, "Warnings:\n", 10); - if (ds_warnings->length) - dynstr_append_mem(ds, ds_warnings->str, - ds_warnings->length); - if (ds_prepare_warnings.length) - dynstr_append_mem(ds, ds_prepare_warnings.str, - ds_prepare_warnings.length); - if (ds_execute_warnings.length) - dynstr_append_mem(ds, ds_execute_warnings.str, - ds_execute_warnings.length); + if (ds_warnings->length) + dynstr_append_mem(ds, ds_warnings->str, + ds_warnings->length); + if (ds_prepare_warnings.length) + dynstr_append_mem(ds, ds_prepare_warnings.str, + ds_prepare_warnings.length); + if (ds_execute_warnings.length) + dynstr_append_mem(ds, ds_execute_warnings.str, + ds_execute_warnings.length); } } - - if (!disable_info) - append_info(ds, affected_rows, mysql_info(mysql)); - } end: @@ -7046,6 +7007,10 @@ int util_query(MYSQL* org_mysql, const char* query){ if (!(mysql= mysql_init(mysql))) die("Failed in mysql_init()"); + if (opt_connect_timeout) + mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, + (void *) &opt_connect_timeout); + /* enable local infile, in non-binary builds often disabled by default */ mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0); safe_connect(mysql, "util", org_mysql->host, org_mysql->user, @@ -7094,7 +7059,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) /* Evaluate query if this is an eval command */ - if (command->type == Q_EVAL) + if (command->type == Q_EVAL || command->type == Q_SEND_EVAL) { init_dynamic_string(&eval_query, "", command->query_len+256, 1024); do_eval(&eval_query, command->query, command->end, FALSE); @@ -7641,8 +7606,8 @@ int main(int argc, char **argv) my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024); - if (hash_init(&var_hash, charset_info, - 1024, 0, 0, get_var_key, var_free, MYF(0))) + if (my_hash_init(&var_hash, charset_info, + 1024, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); var_set_string("$MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); @@ -7705,6 +7670,9 @@ int main(int argc, char **argv) st_connection *con= connections; if (!( mysql_init(&con->mysql))) die("Failed in mysql_init()"); + if (opt_connect_timeout) + mysql_options(&con->mysql, MYSQL_OPT_CONNECT_TIMEOUT, + (void *) &opt_connect_timeout); if (opt_compress) mysql_options(&con->mysql,MYSQL_OPT_COMPRESS,NullS); mysql_options(&con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); @@ -7809,9 +7777,6 @@ int main(int argc, char **argv) case Q_DISCONNECT: case Q_DIRTY_CLOSE: do_close_connection(command); break; - case Q_RPL_PROBE: do_rpl_probe(command); break; - case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(command); break; - case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(command); break; case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break; @@ -7918,6 +7883,7 @@ int main(int argc, char **argv) break; } case Q_SEND: + case Q_SEND_EVAL: if (!*command->first_argument) { /* diff --git a/configure.in b/configure.in index 1564033cf7a..3910422a0f7 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in client/mysqlbinlog.cc:check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.5.0-beta) +AM_INIT_AUTOMAKE(mysql, 5.6.0-beta) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -617,24 +617,6 @@ then fi fi -AC_MSG_CHECKING(whether features provided by the user community should be included.) -AC_ARG_ENABLE(community-features, - AC_HELP_STRING( - [--disable-community-features], - [Disable additional features provided by the user community.]), - [ ENABLE_COMMUNITY_FEATURES=$enableval ], - [ ENABLE_COMMUNITY_FEATURES=yes ] - ) - -if test "$ENABLE_COMMUNITY_FEATURES" = "yes" -then - AC_DEFINE([COMMUNITY_SERVER], [1], - [Whether features provided by the user community should be included]) - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - AC_ARG_WITH(server-suffix, [ --with-server-suffix Append value to the version string.], [ MYSQL_SERVER_SUFFIX=`echo "$withval" | sed -e 's/^\(...................................\)..*$/\1/'` ], @@ -700,21 +682,14 @@ fi # Add query profiler AC_MSG_CHECKING(if SHOW PROFILE should be enabled.) AC_ARG_ENABLE(profiling, - AS_HELP_STRING([--enable-profiling], [Build a version with query profiling code (req. community-features)]), + AS_HELP_STRING([--enable-profiling], [Enable profiling of query lifetime.]), [ ENABLED_PROFILING=$enableval ], - [ ENABLED_PROFILING=$ENABLE_COMMUNITY_FEATURES ]) + [ ENABLED_PROFILING=no ]) +AC_DEFINE([ENABLED_PROFILING], [1], [If SHOW PROFILE should be enabled]) if test "$ENABLED_PROFILING" = "yes" then - if test "$ENABLE_COMMUNITY_FEATURES" = "yes"; - then - AC_DEFINE([ENABLED_PROFILING], [1], - [If SHOW PROFILE should be enabled]) - AC_MSG_RESULT([yes]) - else - ENABLED_PROFILING="no" - AC_MSG_RESULT([no, overridden by community-features disabled]) - fi + AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi @@ -2946,7 +2921,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl man/Makefile BUILD/Makefile vio/Makefile dnl libmysql/Makefile libmysql_r/Makefile client/Makefile dnl sql/Makefile sql/share/Makefile dnl - sql/sql_builtin.cc sql-common/Makefile dnl + sql/sql_builtin.cc sql-common/Makefile libservices/Makefile dnl dbug/Makefile scripts/Makefile include/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile support-files/RHEL4-SElinux/Makefile dnl diff --git a/dbug/.cvsignore b/dbug/.cvsignore deleted file mode 100644 index e9955884756..00000000000 --- a/dbug/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/dbug/Makefile.am b/dbug/Makefile.am index 872ebdb7902..4091858a1af 100644 --- a/dbug/Makefile.am +++ b/dbug/Makefile.am @@ -23,19 +23,20 @@ libdbug_a_SOURCES = dbug.c sanity.c EXTRA_DIST = CMakeLists.txt example1.c example2.c example3.c \ user.r monty.doc dbug_add_tags.pl \ my_main.c main.c factorial.c dbug_analyze.c \ - CMakeLists.txt + CMakeLists.txt tests.c tests-t.pl NROFF_INC = example1.r example2.r example3.r main.r \ factorial.r output1.r output2.r output3.r \ output4.r output5.r -CLEANFILES = $(NROFF_INC) user.t user.ps +CLEANFILES = $(NROFF_INC) user.t user.ps tests-t # Must be linked with libs that are not compiled yet -noinst_PROGRAMS = factorial dbug_analyze +noinst_PROGRAMS = factorial dbug_analyze tests factorial_SOURCES = my_main.c factorial.c +tests_SOURCES = tests.c dbug_analyze_SOURCES = dbug_analyze.c -all: user.t user.ps +all: user.t user.ps tests-t user.t: user.r $(NROFF_INC) -nroff -mm user.r > $@ @@ -61,5 +62,7 @@ output5.r: factorial @RM@ -f $@ @SED@ -e 's!\\!\\\\!g' $< > $@ -# Don't update the files from bitkeeper -%::SCCS/s.% +# a hack to have executable in builddir, not in srcdir +tests-t: tests-t.pl + cp -f $(srcdir)/tests-t.pl ./tests-t + diff --git a/dbug/dbug.c b/dbug/dbug.c index 1ea160852eb..0a0c56170fa 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -57,29 +57,48 @@ * seismo!bpa!sjuvax!bbanerje * * Michael Widenius: - * DBUG_DUMP - To dump a block of memory. - * PUSH_FLAG "O" - To be used insted of "o" if we - * want flushing after each write - * PUSH_FLAG "A" - as 'O', but we will append to the out file instead - * of creating a new one. - * Check of malloc on entry/exit (option "S") + * DBUG_DUMP - To dump a block of memory. + * PUSH_FLAG "O" - To be used insted of "o" if we + * want flushing after each write + * PUSH_FLAG "A" - as 'O', but we will append to the out file instead + * of creating a new one. + * Check of malloc on entry/exit (option "S") * - * DBUG_EXECUTE_IF - * incremental mode (-#+t:-d,info ...) - * DBUG_SET, _db_explain_ - * thread-local settings + * Sergei Golubchik: + * DBUG_EXECUTE_IF + * incremental mode (-#+t:-d,info ...) + * DBUG_SET, _db_explain_ + * thread-local settings + * negative lists (-#-d,info => everything but "info") + * + * function/ syntax + * (the logic is - think of a call stack as of a path. + * "function" means only this function, "function/" means the hierarchy. + * in the future, filters like function1/function2 could be supported. + * following this logic glob(7) wildcards are supported.) * */ +/* + We can't have SAFE_MUTEX defined here as this will cause recursion + in pthread_mutex_lock +*/ +#undef SAFE_MUTEX #include #include #include + +#ifdef HAVE_FNMATCH_H +#include +#else +#define fnmatch(A,B,C) strcmp(A,B) +#endif + #if defined(MSDOS) || defined(__WIN__) #include #endif - #ifndef DBUG_OFF @@ -95,21 +114,24 @@ * The following flags are used to determine which * capabilities the user has enabled with the settings * push macro. + * + * TRACE_ON is also used in _db_stack_frame_->level + * (until we add flags to _db_stack_frame_, increasing it by 4 bytes) */ -#define TRACE_ON 000001 /* Trace enabled */ -#define DEBUG_ON 000002 /* Debug enabled */ -#define FILE_ON 000004 /* File name print enabled */ -#define LINE_ON 000010 /* Line number print enabled */ -#define DEPTH_ON 000020 /* Function nest level print enabled */ -#define PROCESS_ON 000040 /* Process name print enabled */ -#define NUMBER_ON 000100 /* Number each line of output */ -#define PROFILE_ON 000200 /* Print out profiling code */ -#define PID_ON 000400 /* Identify each line with process id */ -#define TIMESTAMP_ON 001000 /* timestamp every line of output */ -#define SANITY_CHECK_ON 002000 /* Check safemalloc on DBUG_ENTER */ -#define FLUSH_ON_WRITE 004000 /* Flush on every write */ -#define OPEN_APPEND 010000 /* Open for append */ +#define DEBUG_ON (1 << 1) /* Debug enabled */ +#define FILE_ON (1 << 2) /* File name print enabled */ +#define LINE_ON (1 << 3) /* Line number print enabled */ +#define DEPTH_ON (1 << 4) /* Function nest level print enabled */ +#define PROCESS_ON (1 << 5) /* Process name print enabled */ +#define NUMBER_ON (1 << 6) /* Number each line of output */ +#define PROFILE_ON (1 << 7) /* Print out profiling code */ +#define PID_ON (1 << 8) /* Identify each line with process id */ +#define TIMESTAMP_ON (1 << 9) /* timestamp every line of output */ +#define SANITY_CHECK_ON (1 << 10) /* Check safemalloc on DBUG_ENTER */ +#define FLUSH_ON_WRITE (1 << 11) /* Flush on every write */ +#define OPEN_APPEND (1 << 12) /* Open for append */ +#define TRACE_ON ((uint)1 << 31) /* Trace enabled. MUST be the highest bit!*/ #define TRACING (cs->stack->flags & TRACE_ON) #define DEBUGGING (cs->stack->flags & DEBUG_ON) @@ -119,11 +141,7 @@ * Typedefs to make things more obvious. */ -#ifndef __WIN__ -typedef int BOOLEAN; -#else -#define BOOLEAN BOOL -#endif +#define BOOLEAN my_bool /* * Make it easy to change storage classes if necessary. @@ -139,7 +157,7 @@ typedef int BOOLEAN; * (G?) which allowed the user to specify this. * * If the automatic variables get allocated on the stack in - * reverse order from their declarations, then define AUTOS_REVERSE. + * reverse order from their declarations, then define AUTOS_REVERSE to 1. * This is used by the code that keeps track of stack usage. For * forward allocation, the difference in the dbug frame pointers * represents stack used by the callee function. For reverse allocation, @@ -154,6 +172,8 @@ typedef int BOOLEAN; #ifdef M_I386 /* predefined by xenix 386 compiler */ #define AUTOS_REVERSE 1 +#else +#define AUTOS_REVERSE 0 #endif /* @@ -164,7 +184,11 @@ typedef int BOOLEAN; static void perror(); /* Fake system/library error print routine */ #endif +#ifdef SAFEMALLOC IMPORT int _sanity(const char *file,uint line); /* safemalloc sanity checker */ +#else +#define _sanity(X,Y) (1) +#endif /* * The user may specify a list of functions to trace or @@ -174,9 +198,18 @@ IMPORT int _sanity(const char *file,uint line); /* safemalloc sanity checker */ struct link { struct link *next_link; /* Pointer to the next link */ - char str[1]; /* Pointer to link's contents */ + char flags; + char str[1]; /* Pointer to link's contents */ }; +/* flags for struct link and return flags of InList */ +#define SUBDIR 1 /* this MUST be 1 */ +#define INCLUDE 2 +#define EXCLUDE 4 +/* this is not a struct link flag, but only a return flags of InList */ +#define MATCHED 65536 +#define NOT_MATCHED 0 + /* * Debugging settings can be pushed or popped off of a * stack which is implemented as a linked list. Note @@ -188,18 +221,18 @@ struct link { */ struct settings { - int flags; /* Current settings flags */ - int maxdepth; /* Current maximum trace depth */ - uint delay; /* Delay after each output line */ - int sub_level; /* Sub this from code_state->level */ - FILE *out_file; /* Current output stream */ - FILE *prof_file; /* Current profiling stream */ - char name[FN_REFLEN]; /* Name of output file */ - struct link *functions; /* List of functions */ - struct link *p_functions; /* List of profiled functions */ - struct link *keywords; /* List of debug keywords */ - struct link *processes; /* List of process names */ - struct settings *next; /* Next settings in the list */ + uint flags; /* Current settings flags */ + uint maxdepth; /* Current maximum trace depth */ + uint delay; /* Delay after each output line */ + uint sub_level; /* Sub this from code_state->level */ + FILE *out_file; /* Current output stream */ + FILE *prof_file; /* Current profiling stream */ + char name[FN_REFLEN]; /* Name of output file */ + struct link *functions; /* List of functions */ + struct link *p_functions; /* List of profiled functions */ + struct link *keywords; /* List of debug keywords */ + struct link *processes; /* List of process names */ + struct settings *next; /* Next settings in the list */ }; #define is_shared(S, V) ((S)->next && (S)->next->V == (S)->V) @@ -212,18 +245,19 @@ struct settings { static BOOLEAN init_done= FALSE; /* Set to TRUE when initialization done */ static struct settings init_settings; static const char *db_process= 0;/* Pointer to process name; argv[0] */ +my_bool _dbug_on_= TRUE; /* FALSE if no debugging at all */ typedef struct _db_code_state_ { const char *process; /* Pointer to process name; usually argv[0] */ - const char *func; /* Name of current user function */ - const char *file; /* Name of current user file */ - char **framep; /* Pointer to current frame */ - struct settings *stack; /* debugging settings */ - const char *jmpfunc; /* Remember current function for setjmp */ - const char *jmpfile; /* Remember current file for setjmp */ - int lineno; /* Current debugger output line number */ - int level; /* Current function nesting level */ - int jmplevel; /* Remember nesting level at setjmp() */ + const char *func; /* Name of current user function */ + const char *file; /* Name of current user file */ + struct _db_stack_frame_ *framep; /* Pointer to current frame */ + struct settings *stack; /* debugging settings */ + const char *jmpfunc; /* Remember current function for setjmp */ + const char *jmpfile; /* Remember current file for setjmp */ + int lineno; /* Current debugger output line number */ + uint level; /* Current function nesting level */ + int jmplevel; /* Remember nesting level at setjmp() */ /* * The following variables are used to hold the state information @@ -244,12 +278,16 @@ typedef struct _db_code_state_ { The test below is so we could call functions with DBUG_ENTER before my_thread_init(). */ -#define get_code_state_or_return if (!cs && !((cs=code_state()))) return +#define get_code_state_if_not_set_or_return if (!cs && !((cs=code_state()))) return +#define get_code_state_or_return if (!((cs=code_state()))) return /* Handling lists */ -static struct link *ListAdd(struct link *, const char *, const char *); -static struct link *ListDel(struct link *, const char *, const char *); +#define ListAdd(A,B,C) ListAddDel(A,B,C,INCLUDE) +#define ListDel(A,B,C) ListAddDel(A,B,C,EXCLUDE) +static struct link *ListAddDel(struct link *, const char *, const char *, int); static struct link *ListCopy(struct link *); +static int InList(struct link *linkp,const char *cp); +static uint ListFlags(struct link *linkp); static void FreeList(struct link *linkp); /* OpenClose debug output stream */ @@ -260,10 +298,18 @@ static void PushState(CODE_STATE *cs); /* Free memory associated with debug state. */ static void FreeState (CODE_STATE *cs, struct settings *state, int free_state); /* Test for tracing enabled */ -static BOOLEAN DoTrace(CODE_STATE *cs); +static int DoTrace(CODE_STATE *cs); +/* + return values of DoTrace. + Can also be used as bitmask: ret & DO_TRACE +*/ +#define DO_TRACE 1 +#define DONT_TRACE 2 +#define ENABLE_TRACE 3 +#define DISABLE_TRACE 4 /* Test to see if file is writable */ -#if !(!defined(HAVE_ACCESS) || defined(MSDOS)) +#if defined(HAVE_ACCESS) && !defined(MSDOS) static BOOLEAN Writable(const char *pathname); /* Change file owner and group */ static void ChangeOwner(CODE_STATE *cs, char *pathname); @@ -275,10 +321,10 @@ static void DoPrefix(CODE_STATE *cs, uint line); static char *DbugMalloc(size_t size); static const char *BaseName(const char *pathname); static void Indent(CODE_STATE *cs, int indent); -static BOOLEAN InList(struct link *linkp,const char *cp); -static void dbug_flush(CODE_STATE *); +static void DbugFlush(CODE_STATE *); static void DbugExit(const char *why); static const char *DbugStrTok(const char *s); +static void DbugVfprintf(FILE *stream, const char* format, va_list args); #ifndef THREAD /* Open profile output stream */ @@ -293,7 +339,7 @@ static unsigned long Clock(void); * Miscellaneous printf format strings. */ -#define ERR_MISSING_RETURN "%s: missing DBUG_RETURN or DBUG_VOID_RETURN macro in function \"%s\"\n" +#define ERR_MISSING_RETURN "missing DBUG_RETURN or DBUG_VOID_RETURN macro in function \"%s\"\n" #define ERR_OPEN "%s: can't open debug output stream \"%s\": " #define ERR_CLOSE "%s: can't close debug file: " #define ERR_ABORT "%s: debugger aborting because %s\n" @@ -322,34 +368,39 @@ static unsigned long Clock(void); #ifdef THREAD #include -pthread_mutex_t THR_LOCK_dbug; +static pthread_mutex_t THR_LOCK_dbug; static CODE_STATE *code_state(void) { - CODE_STATE *cs=0; - struct st_my_thread_var *tmp; + CODE_STATE *cs, **cs_ptr; + + /* + _dbug_on_ is reset if we don't plan to use any debug commands at all and + we want to run on maximum speed + */ + if (!_dbug_on_) + return 0; if (!init_done) { + init_done=TRUE; pthread_mutex_init(&THR_LOCK_dbug,MY_MUTEX_INIT_FAST); bzero(&init_settings, sizeof(init_settings)); init_settings.out_file=stderr; init_settings.flags=OPEN_APPEND; - init_done=TRUE; } - if ((tmp=my_thread_var)) + if (!(cs_ptr= (CODE_STATE**) my_thread_var_dbug())) + return 0; /* Thread not initialised */ + if (!(cs= *cs_ptr)) { - if (!(cs=(CODE_STATE *) tmp->dbug)) - { - cs=(CODE_STATE*) DbugMalloc(sizeof(*cs)); - bzero((uchar*) cs,sizeof(*cs)); - cs->process= db_process ? db_process : "dbug"; - cs->func="?func"; - cs->file="?file"; - cs->stack=&init_settings; - tmp->dbug= (void*) cs; - } + cs=(CODE_STATE*) DbugMalloc(sizeof(*cs)); + bzero((uchar*) cs,sizeof(*cs)); + cs->process= db_process ? db_process : "dbug"; + cs->func="?func"; + cs->file="?file"; + cs->stack=&init_settings; + *cs_ptr= cs; } return cs; } @@ -403,20 +454,19 @@ static CODE_STATE *code_state(void) void _db_process_(const char *name) { - CODE_STATE *cs=0; + CODE_STATE *cs; if (!db_process) db_process= name; - + get_code_state_or_return; cs->process= name; } - /* * FUNCTION * - * DbugParse parse control string and set current debugger setting + * DbugParse parse control string and set current debugger settings * * DESCRIPTION * @@ -438,15 +488,17 @@ void _db_process_(const char *name) * * For convenience, any leading "-#" is stripped off. * + * RETURN + * 1 - a list of functions ("f" flag) was possibly changed + * 0 - a list of functions was not changed */ -static void DbugParse(CODE_STATE *cs, const char *control) +int DbugParse(CODE_STATE *cs, const char *control) { const char *end; - int rel=0; + int rel, f_used=0; struct settings *stack; - get_code_state_or_return; stack= cs->stack; if (control[0] == '-' && control[1] == '#') @@ -455,6 +507,7 @@ static void DbugParse(CODE_STATE *cs, const char *control) rel= control[0] == '+' || control[0] == '-'; if ((!rel || (!stack->out_file && !stack->next))) { + FreeState(cs, stack, 0); stack->flags= 0; stack->delay= 0; stack->maxdepth= 0; @@ -497,7 +550,6 @@ static void DbugParse(CODE_STATE *cs, const char *control) { int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0; if (sign) control++; - if (!rel) sign=0; c= *control++; if (*control == ',') control++; /* XXX when adding new cases here, don't forget _db_explain_ ! */ @@ -526,6 +578,7 @@ static void DbugParse(CODE_STATE *cs, const char *control) stack->delay= atoi(control); break; case 'f': + f_used= 1; if (sign < 0 && control == end) { if (!is_shared(stack,functions)) @@ -664,8 +717,111 @@ static void DbugParse(CODE_STATE *cs, const char *control) control=end+1; end= DbugStrTok(control); } + return !rel || f_used; } +#define framep_trace_flag(cs, frp) (frp ? \ + frp->level & TRACE_ON : \ + (ListFlags(cs->stack->functions) & INCLUDE) ? \ + 0 : (uint)TRACE_ON) + +void FixTraceFlags_helper(CODE_STATE *cs, const char *func, + struct _db_stack_frame_ *framep) +{ + if (framep->prev) + FixTraceFlags_helper(cs, framep->func, framep->prev); + + cs->func= func; + cs->level= framep->level & ~TRACE_ON; + framep->level= cs->level | framep_trace_flag(cs, framep->prev); + /* + we don't set cs->framep correctly, even though DoTrace uses it. + It's ok, because cs->framep may only affect DO_TRACE/DONT_TRACE return + values, but we ignore them here anyway + */ + switch(DoTrace(cs)) { + case ENABLE_TRACE: + framep->level|= TRACE_ON; + break; + case DISABLE_TRACE: + framep->level&= ~TRACE_ON; + break; + } +} + +#define fflags(cs) cs->stack->out_file ? ListFlags(cs->stack->functions) : TRACE_ON; + +void FixTraceFlags(uint old_fflags, CODE_STATE *cs) +{ + const char *func; + uint new_fflags, traceon, level; + struct _db_stack_frame_ *framep; + + /* + first (a.k.a. safety) check: + if we haven't started tracing yet, no call stack at all - we're safe. + */ + framep=cs->framep; + if (framep == 0) + return; + + /* + Ok, the tracing has started, call stack isn't empty. + + second check: does the new list have a SUBDIR rule ? + */ + new_fflags=fflags(cs); + if (new_fflags & SUBDIR) + goto yuck; + + /* + Ok, new list doesn't use SUBDIR. + + third check: we do NOT need to re-scan if + neither old nor new lists used SUBDIR flag and if a default behavior + (whether an unlisted function is traced) hasn't changed. + Default behavior depends on whether there're INCLUDE elements in the list. + */ + if (!(old_fflags & SUBDIR) && !((new_fflags^old_fflags) & INCLUDE)) + return; + + /* + Ok, old list may've used SUBDIR, or defaults could've changed. + + fourth check: are we inside a currently active SUBDIR rule ? + go up the call stack, if TRACE_ON flag ever changes its value - we are. + */ + for (traceon=framep->level; framep; framep=framep->prev) + if ((traceon ^ framep->level) & TRACE_ON) + goto yuck; + + /* + Ok, TRACE_ON flag doesn't change in the call stack. + + fifth check: but is the top-most value equal to a default one ? + */ + if (((traceon & TRACE_ON) != 0) == ((new_fflags & INCLUDE) == 0)) + return; + +yuck: + /* + Yuck! function list was changed, and one of the currently active rules + was possibly affected. For example, a tracing could've been enabled or + disabled for a function somewhere up the call stack. + To react correctly, we must go up the call stack all the way to + the top and re-match rules to set TRACE_ON bit correctly. + + We must traverse the stack forwards, not backwards. + That's what a recursive helper is doing. + It'll destroy two CODE_STATE fields, save them now. + */ + func= cs->func; + level= cs->level; + FixTraceFlags_helper(cs, func, cs->framep); + /* now we only need to restore CODE_STATE fields, and we're done */ + cs->func= func; + cs->level= level; +} /* * FUNCTION @@ -683,19 +839,21 @@ static void DbugParse(CODE_STATE *cs, const char *control) * parses the control string, and sets up a current debug * settings. Pushes a new debug settings if the current is * set to the initial debugger settings. + * */ -void _db_set_(CODE_STATE *cs, const char *control) +void _db_set_(const char *control) { + CODE_STATE *cs; + uint old_fflags; get_code_state_or_return; - + old_fflags=fflags(cs); if (cs->stack == &init_settings) PushState(cs); - - DbugParse(cs, control); + if (DbugParse(cs, control)) + FixTraceFlags(old_fflags, cs); } - /* * FUNCTION * @@ -716,10 +874,25 @@ void _db_set_(CODE_STATE *cs, const char *control) void _db_push_(const char *control) { - CODE_STATE *cs=0; + CODE_STATE *cs; + uint old_fflags; get_code_state_or_return; + old_fflags=fflags(cs); PushState(cs); - DbugParse(cs, control); + if (DbugParse(cs, control)) + FixTraceFlags(old_fflags, cs); +} + + +/** + Returns TRUE if session-local settings have been set. +*/ + +int _db_is_pushed_() +{ + CODE_STATE *cs= NULL; + get_code_state_or_return FALSE; + return (cs->stack != &init_settings); } /* @@ -765,15 +938,18 @@ void _db_set_init_(const char *control) void _db_pop_() { struct settings *discard; - CODE_STATE *cs=0; + uint old_fflags; + CODE_STATE *cs; get_code_state_or_return; discard= cs->stack; - if (discard->next != NULL) + if (discard != &init_settings) { + old_fflags=fflags(cs); cs->stack= discard->next; FreeState(cs, discard, 1); + FixTraceFlags(old_fflags, cs); } } @@ -798,11 +974,16 @@ void _db_pop_() buf=strnmov(buf, (S), len+1); \ if (buf >= end) goto overflow; \ } while (0) -#define list_to_buf(l) do { \ +#define list_to_buf(l, f) do { \ struct link *listp=(l); \ while (listp) \ { \ - str_to_buf(listp->str); \ + if (listp->flags & (f)) \ + { \ + str_to_buf(listp->str); \ + if (listp->flags & SUBDIR) \ + char_to_buf('/'); \ + } \ listp=listp->next_link; \ } \ } while (0) @@ -842,9 +1023,18 @@ void _db_pop_() #define op_list_to_buf(C, val, cond) do { \ if ((cond)) \ { \ + int f=ListFlags(val); \ colon_to_buf; \ char_to_buf((C)); \ - list_to_buf(val); \ + if (f & INCLUDE) \ + list_to_buf(val, INCLUDE); \ + if (f & EXCLUDE) \ + { \ + colon_to_buf; \ + char_to_buf('-'); \ + char_to_buf((C)); \ + list_to_buf(val, EXCLUDE); \ + } \ } \ } while (0) #define op_bool_to_buf(C, cond) do { \ @@ -859,7 +1049,7 @@ int _db_explain_ (CODE_STATE *cs, char *buf, size_t len) { char *start=buf, *end=buf+len-4; - get_code_state_or_return *buf=0; + get_code_state_if_not_set_or_return *buf=0; op_list_to_buf('d', cs->stack->keywords, DEBUGGING); op_int_to_buf ('D', cs->stack->delay, 0); @@ -927,15 +1117,11 @@ int _db_explain_init_(char *buf, size_t len) * * SYNOPSIS * - * VOID _db_enter_(_func_, _file_, _line_, - * _sfunc_, _sfile_, _slevel_, _sframep_) + * VOID _db_enter_(_func_, _file_, _line_, _stack_frame_) * char *_func_; points to current function name * char *_file_; points to current file name * int _line_; called from source line number - * char **_sfunc_; save previous _func_ - * char **_sfile_; save previous _file_ - * int *_slevel_; save previous nesting level - * char ***_sframep_; save previous frame pointer + * struct _db_stack_frame_ allocated on the caller's stack * * DESCRIPTION * @@ -959,55 +1145,66 @@ int _db_explain_init_(char *buf, size_t len) */ void _db_enter_(const char *_func_, const char *_file_, - uint _line_, const char **_sfunc_, const char **_sfile_, - uint *_slevel_, char ***_sframep_ __attribute__((unused))) + uint _line_, struct _db_stack_frame_ *_stack_frame_) { - int save_errno=errno; - CODE_STATE *cs=0; - get_code_state_or_return; + int save_errno; + CODE_STATE *cs; + if (!((cs=code_state()))) + { + _stack_frame_->level= 0; /* Set to avoid valgrind warnings if dbug is enabled later */ + _stack_frame_->prev= 0; + return; + } + save_errno= errno; - *_sfunc_= cs->func; - *_sfile_= cs->file; + _stack_frame_->func= cs->func; + _stack_frame_->file= cs->file; cs->func= _func_; cs->file= _file_; - *_slevel_= ++cs->level; + _stack_frame_->prev= cs->framep; + _stack_frame_->level= ++cs->level | framep_trace_flag(cs, cs->framep); + cs->framep= _stack_frame_; #ifndef THREAD - *_sframep_= cs->framep; - cs->framep= (char **) _sframep_; if (DoProfile(cs)) { long stackused; - if (*cs->framep == NULL) + if (cs->framep->prev == NULL) stackused= 0; else { - stackused= ((long)(*cs->framep)) - ((long)(cs->framep)); + stackused= (char*)(cs->framep->prev) - (char*)(cs->framep); stackused= stackused > 0 ? stackused : -stackused; } (void) fprintf(cs->stack->prof_file, PROF_EFMT , Clock(), cs->func); -#ifdef AUTOS_REVERSE - (void) fprintf(cs->stack->prof_file, PROF_SFMT, cs->framep, stackused, *_sfunc_); -#else (void) fprintf(cs->stack->prof_file, PROF_SFMT, (ulong) cs->framep, stackused, - cs->func); -#endif + AUTOS_REVERSE ? _stack_frame_->func : cs->func); (void) fflush(cs->stack->prof_file); } #endif - if (DoTrace(cs)) - { - if (!cs->locked) - pthread_mutex_lock(&THR_LOCK_dbug); - DoPrefix(cs, _line_); - Indent(cs, cs->level); - (void) fprintf(cs->stack->out_file, ">%s\n", cs->func); - dbug_flush(cs); /* This does a unlock */ - } -#ifdef SAFEMALLOC - if (cs->stack->flags & SANITY_CHECK_ON) - if (_sanity(_file_,_line_)) /* Check of safemalloc */ + switch (DoTrace(cs)) { + case ENABLE_TRACE: + cs->framep->level|= TRACE_ON; + if (!TRACING) break; + /* fall through */ + case DO_TRACE: + if ((cs->stack->flags & SANITY_CHECK_ON) && _sanity(_file_,_line_)) cs->stack->flags &= ~SANITY_CHECK_ON; -#endif + if (TRACING) + { + if (!cs->locked) + pthread_mutex_lock(&THR_LOCK_dbug); + DoPrefix(cs, _line_); + Indent(cs, cs->level); + (void) fprintf(cs->stack->out_file, ">%s\n", cs->func); + DbugFlush(cs); /* This does a unlock */ + } + break; + case DISABLE_TRACE: + cs->framep->level&= ~TRACE_ON; + /* fall through */ + case DONT_TRACE: + break; + } errno=save_errno; } @@ -1018,11 +1215,9 @@ void _db_enter_(const char *_func_, const char *_file_, * * SYNOPSIS * - * VOID _db_return_(_line_, _sfunc_, _sfile_, _slevel_) + * VOID _db_return_(_line_, _stack_frame_) * int _line_; current source line number - * char **_sfunc_; where previous _func_ is to be retrieved - * char **_sfile_; where previous _file_ is to be retrieved - * int *_slevel_; where previous level was stashed + * struct _db_stack_frame_ allocated on the caller's stack * * DESCRIPTION * @@ -1033,52 +1228,47 @@ void _db_enter_(const char *_func_, const char *_file_, * */ -/* helper macro */ -void _db_return_(uint _line_, const char **_sfunc_, - const char **_sfile_, uint *_slevel_) +void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_) { int save_errno=errno; - CODE_STATE *cs=0; + uint _slevel_= _stack_frame_->level & ~TRACE_ON; + CODE_STATE *cs; get_code_state_or_return; - if (cs->level != (int) *_slevel_) + if (cs->framep != _stack_frame_) { - if (!cs->locked) - pthread_mutex_lock(&THR_LOCK_dbug); - (void) fprintf(cs->stack->out_file, ERR_MISSING_RETURN, cs->process, - cs->func); - dbug_flush(cs); + char buf[512]; + my_snprintf(buf, sizeof(buf), ERR_MISSING_RETURN, cs->func); + DbugExit(buf); } - else - { -#ifdef SAFEMALLOC - if (cs->stack->flags & SANITY_CHECK_ON) - { - if (_sanity(*_sfile_,_line_)) - cs->stack->flags &= ~SANITY_CHECK_ON; - } -#endif #ifndef THREAD - if (DoProfile(cs)) - (void) fprintf(cs->stack->prof_file, PROF_XFMT, Clock(), cs->func); + if (DoProfile(cs)) + (void) fprintf(cs->stack->prof_file, PROF_XFMT, Clock(), cs->func); #endif - if (DoTrace(cs)) + if (DoTrace(cs) & DO_TRACE) + { + if ((cs->stack->flags & SANITY_CHECK_ON) && + _sanity(_stack_frame_->file,_line_)) + cs->stack->flags &= ~SANITY_CHECK_ON; + if (TRACING) { if (!cs->locked) pthread_mutex_lock(&THR_LOCK_dbug); DoPrefix(cs, _line_); Indent(cs, cs->level); (void) fprintf(cs->stack->out_file, "<%s\n", cs->func); - dbug_flush(cs); + DbugFlush(cs); } } - cs->level= *_slevel_-1; - cs->func= *_sfunc_; - cs->file= *_sfile_; -#ifndef THREAD + /* + Check to not set level < 0. This can happen if DBUG was disabled when + function was entered and enabled in function. + */ + cs->level= _slevel_ != 0 ? _slevel_ - 1 : 0; + cs->func= _stack_frame_->func; + cs->file= _stack_frame_->file; if (cs->framep != NULL) - cs->framep= (char **) *cs->framep; -#endif + cs->framep= cs->framep->prev; errno=save_errno; } @@ -1105,7 +1295,7 @@ void _db_return_(uint _line_, const char **_sfunc_, void _db_pargs_(uint _line_, const char *keyword) { - CODE_STATE *cs=0; + CODE_STATE *cs; get_code_state_or_return; cs->u_line= _line_; cs->u_keyword= keyword; @@ -1141,13 +1331,12 @@ void _db_pargs_(uint _line_, const char *keyword) void _db_doprnt_(const char *format,...) { va_list args; - - CODE_STATE *cs=0; + CODE_STATE *cs; get_code_state_or_return; va_start(args,format); - if (_db_keyword_(cs, cs->u_keyword)) + if (_db_keyword_(cs, cs->u_keyword, 0)) { int save_errno=errno; if (!cs->locked) @@ -1158,14 +1347,25 @@ void _db_doprnt_(const char *format,...) else (void) fprintf(cs->stack->out_file, "%s: ", cs->func); (void) fprintf(cs->stack->out_file, "%s: ", cs->u_keyword); - (void) vfprintf(cs->stack->out_file, format, args); - (void) fputc('\n',cs->stack->out_file); - dbug_flush(cs); + DbugVfprintf(cs->stack->out_file, format, args); + DbugFlush(cs); errno=save_errno; } va_end(args); } +/* + * vfprintf clone with consistent, platform independent output for + * problematic formats like %p, %zd and %lld. + */ +static void DbugVfprintf(FILE *stream, const char* format, va_list args) +{ + char cvtbuf[1024]; + size_t len; + len = my_vsnprintf(cvtbuf, sizeof(cvtbuf), format, args); + (void) fprintf(stream, "%s\n", cvtbuf); +} + /* * FUNCTION @@ -1182,19 +1382,17 @@ void _db_doprnt_(const char *format,...) * * DESCRIPTION * Dump N characters in a binary array. - * Is used to examine corrputed memory or arrays. + * Is used to examine corrupted memory or arrays. */ void _db_dump_(uint _line_, const char *keyword, const unsigned char *memory, size_t length) { int pos; - char dbuff[90]; - - CODE_STATE *cs=0; + CODE_STATE *cs; get_code_state_or_return; - if (_db_keyword_(cs, keyword)) + if (_db_keyword_(cs, keyword, 0)) { if (!cs->locked) pthread_mutex_lock(&THR_LOCK_dbug); @@ -1208,9 +1406,8 @@ void _db_dump_(uint _line_, const char *keyword, { fprintf(cs->stack->out_file, "%s: ", cs->func); } - sprintf(dbuff,"%s: Memory: 0x%lx Bytes: (%ld)\n", + (void) fprintf(cs->stack->out_file, "%s: Memory: 0x%lx Bytes: (%ld)\n", keyword, (ulong) memory, (long) length); - (void) fputs(dbuff,cs->stack->out_file); pos=0; while (length-- > 0) @@ -1226,7 +1423,7 @@ void _db_dump_(uint _line_, const char *keyword, fputc(' ',cs->stack->out_file); } (void) fputc('\n',cs->stack->out_file); - dbug_flush(cs); + DbugFlush(cs); } } @@ -1234,93 +1431,75 @@ void _db_dump_(uint _line_, const char *keyword, /* * FUNCTION * - * ListAdd add to the list modifiers from debug control string - * - * SYNOPSIS - * - * static struct link *ListAdd(listp, ctlp, end) - * struct link *listp; - * char *ctlp; - * char *end; + * ListAddDel modify the list according to debug control string * * DESCRIPTION * * Given pointer to a comma separated list of strings in "cltp", - * parses the list, and adds it to listp, returning a pointer - * to the new list + * parses the list, and modifies "listp", returning a pointer + * to the new list. * - * Note that since each link is added at the head of the list, - * the final list will be in "reverse order", which is not - * significant for our usage here. + * The mode of operation is defined by "todo" parameter. * + * If it is INCLUDE, elements (strings from "cltp") are added to the + * list, they will have INCLUDE flag set. If the list already contains + * the string in question, new element is not added, but a flag of + * the existing element is adjusted (INCLUDE bit is set, EXCLUDE bit + * is removed). + * + * If it is EXCLUDE, elements are added to the list with the EXCLUDE + * flag set. If the list already contains the string in question, + * it is removed, new element is not added. */ -static struct link *ListAdd(struct link *head, - const char *ctlp, const char *end) -{ - const char *start; - struct link *new_malloc; - int len; - - while (ctlp < end) - { - start= ctlp; - while (ctlp < end && *ctlp != ',') - ctlp++; - len=ctlp-start; - new_malloc= (struct link *) DbugMalloc(sizeof(struct link)+len); - memcpy(new_malloc->str, start, len); - new_malloc->str[len]=0; - new_malloc->next_link= head; - head= new_malloc; - ctlp++; - } - return head; -} - -/* - * FUNCTION - * - * ListDel remove from the list modifiers in debug control string - * - * SYNOPSIS - * - * static struct link *ListDel(listp, ctlp, end) - * struct link *listp; - * char *ctlp; - * char *end; - * - * DESCRIPTION - * - * Given pointer to a comma separated list of strings in "cltp", - * parses the list, and removes these strings from the listp, - * returning a pointer to the new list. - * - */ - -static struct link *ListDel(struct link *head, - const char *ctlp, const char *end) +static struct link *ListAddDel(struct link *head, const char *ctlp, + const char *end, int todo) { const char *start; struct link **cur; - int len; + size_t len; + int subdir; - while (ctlp < end) + ctlp--; +next: + while (++ctlp < end) { start= ctlp; + subdir=0; while (ctlp < end && *ctlp != ',') ctlp++; len=ctlp-start; - cur=&head; - do + if (start[len-1] == '/') { - while (*cur && !strncmp((*cur)->str, start, len)) + len--; + subdir=SUBDIR; + } + if (len == 0) continue; + for (cur=&head; *cur; cur=&((*cur)->next_link)) + { + if (!strncmp((*cur)->str, start, len)) { - struct link *delme=*cur; - *cur=(*cur)->next_link; - free((void*) delme); + if ((*cur)->flags & todo) /* same action ? */ + (*cur)->flags|= subdir; /* just merge the SUBDIR flag */ + else if (todo == EXCLUDE) + { + struct link *delme=*cur; + *cur=(*cur)->next_link; + free((void*) delme); + } + else + { + (*cur)->flags&=~(EXCLUDE & SUBDIR); + (*cur)->flags|=INCLUDE | subdir; + } + goto next; } - } while (*cur && *(cur=&((*cur)->next_link))); + } + *cur= (struct link *) DbugMalloc(sizeof(struct link)+len); + memcpy((*cur)->str, start, len); + (*cur)->str[len]=0; + (*cur)->flags=todo | subdir; + (*cur)->next_link=0; } return head; } @@ -1352,7 +1531,7 @@ static struct link *ListCopy(struct link *orig) { struct link *new_malloc; struct link *head; - int len; + size_t len; head= NULL; while (orig != NULL) @@ -1361,6 +1540,7 @@ static struct link *ListCopy(struct link *orig) new_malloc= (struct link *) DbugMalloc(sizeof(struct link)+len); memcpy(new_malloc->str, orig->str, len); new_malloc->str[len]= 0; + new_malloc->flags=orig->flags; new_malloc->next_link= head; head= new_malloc; orig= orig->next_link; @@ -1373,47 +1553,52 @@ static struct link *ListCopy(struct link *orig) * * InList test a given string for member of a given list * - * SYNOPSIS - * - * static BOOLEAN InList(linkp, cp) - * struct link *linkp; - * char *cp; - * * DESCRIPTION * * Tests the string pointed to by "cp" to determine if it is in * the list pointed to by "linkp". Linkp points to the first - * link in the list. If linkp is NULL then the string is treated - * as if it is in the list (I.E all strings are in the null list). + * link in the list. If linkp is NULL or contains only EXCLUDE + * elements then the string is treated as if it is in the list. * This may seem rather strange at first but leads to the desired * operation if no list is given. The net effect is that all * strings will be accepted when there is no list, and when there * is a list, only those strings in the list will be accepted. * + * RETURN + * combination of SUBDIR, INCLUDE, EXCLUDE, MATCHED flags + * */ -static BOOLEAN InList(struct link *linkp, const char *cp) +static int InList(struct link *linkp, const char *cp) { - REGISTER struct link *scan; - REGISTER BOOLEAN result; + int result; - if (linkp == NULL) - result= TRUE; - else + for (result=MATCHED; linkp != NULL; linkp= linkp->next_link) { - result= FALSE; - for (scan= linkp; scan != NULL; scan= scan->next_link) - { - if (!strcmp(scan->str, cp)) - { - result= TRUE; - break; - } - } + if (!fnmatch(linkp->str, cp, 0)) + return linkp->flags; + if (!(linkp->flags & EXCLUDE)) + result=NOT_MATCHED; + if (linkp->flags & SUBDIR) + result|=SUBDIR; } return result; } +/* + * FUNCTION + * + * ListFlags returns aggregated list flags (ORed over all elements) + * + */ + +static uint ListFlags(struct link *linkp) +{ + uint f; + for (f=0; linkp != NULL; linkp= linkp->next_link) + f|= linkp->flags; + return f; +} /* * FUNCTION @@ -1440,8 +1625,8 @@ static void PushState(CODE_STATE *cs) struct settings *new_malloc; new_malloc= (struct settings *) DbugMalloc(sizeof(struct settings)); + bzero(new_malloc, sizeof(*new_malloc)); new_malloc->next= cs->stack; - new_malloc->out_file= NULL; cs->stack= new_malloc; } @@ -1472,11 +1657,17 @@ static void FreeState(CODE_STATE *cs, struct settings *state, int free_state) FreeList(state->processes); if (!is_shared(state, p_functions)) FreeList(state->p_functions); + if (!is_shared(state, out_file)) DBUGCloseFile(cs, state->out_file); - (void) fflush(cs->stack->out_file); - if (state->prof_file) + else + (void) fflush(state->out_file); + + if (!is_shared(state, prof_file)) DBUGCloseFile(cs, state->prof_file); + else + (void) fflush(state->prof_file); + if (free_state) free((void*) state); } @@ -1503,8 +1694,12 @@ void _db_end_() { struct settings *discard; static struct settings tmp; - CODE_STATE *cs=0; - + CODE_STATE *cs; + /* + Set _dbug_on_ to be able to do full reset even when DEBUGGER_OFF was + called after dbug was initialized + */ + _dbug_on_= 1; get_code_state_or_return; while ((discard= cs->stack)) @@ -1538,25 +1733,30 @@ void _db_end_() * * DoTrace check to see if tracing is current enabled * - * SYNOPSIS - * - * static BOOLEAN DoTrace(stack) - * * DESCRIPTION * - * Checks to see if tracing is enabled based on whether the - * user has specified tracing, the maximum trace depth has - * not yet been reached, the current function is selected, - * and the current process is selected. Returns TRUE if - * tracing is enabled, FALSE otherwise. + * Checks to see if dbug in this function is enabled based on + * whether the maximum trace depth has been reached, the current + * function is selected, and the current process is selected. * */ -static BOOLEAN DoTrace(CODE_STATE *cs) +static int DoTrace(CODE_STATE *cs) { - return (TRACING && cs->level <= cs->stack->maxdepth && - InList(cs->stack->functions, cs->func) && - InList(cs->stack->processes, cs->process)); + if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) && + InList(cs->stack->processes, cs->process) & (MATCHED|INCLUDE)) + switch(InList(cs->stack->functions, cs->func)) { + case INCLUDE|SUBDIR: return ENABLE_TRACE; + case INCLUDE: return DO_TRACE; + case MATCHED|SUBDIR: + case NOT_MATCHED|SUBDIR: + case MATCHED: return framep_trace_flag(cs, cs->framep) ? + DO_TRACE : DONT_TRACE; + case EXCLUDE: + case NOT_MATCHED: return DONT_TRACE; + case EXCLUDE|SUBDIR: return DISABLE_TRACE; + } + return DONT_TRACE; } @@ -1584,62 +1784,27 @@ static BOOLEAN DoProfile(CODE_STATE *cs) { return PROFILING && cs->level <= cs->stack->maxdepth && - InList(cs->stack->p_functions, cs->func) && - InList(cs->stack->processes, cs->process); + InList(cs->stack->p_functions, cs->func) & (INCLUDE|MATCHED) && + InList(cs->stack->processes, cs->process) & (INCLUDE|MATCHED); } #endif FILE *_db_fp_(void) { - CODE_STATE *cs=0; + CODE_STATE *cs; get_code_state_or_return NULL; return cs->stack->out_file; } - -/* - * FUNCTION - * - * _db_strict_keyword_ test keyword for member of keyword list - * - * SYNOPSIS - * - * BOOLEAN _db_strict_keyword_(keyword) - * char *keyword; - * - * DESCRIPTION - * - * Similar to _db_keyword_, but keyword is NOT accepted if keyword list - * is empty. Used in DBUG_EXECUTE_IF() - for actions that must not be - * executed by default. - * - * Returns TRUE if keyword accepted, FALSE otherwise. - * - */ - -BOOLEAN _db_strict_keyword_(const char *keyword) -{ - CODE_STATE *cs=0; - get_code_state_or_return FALSE; - if (!DEBUGGING || cs->stack->keywords == NULL) - return FALSE; - return _db_keyword_(cs, keyword); -} - /* * FUNCTION * * _db_keyword_ test keyword for member of keyword list * - * SYNOPSIS - * - * BOOLEAN _db_keyword_(keyword) - * char *keyword; - * * DESCRIPTION * * Test a keyword to determine if it is in the currently active - * keyword list. As with the function list, a keyword is accepted + * keyword list. If strict=0, a keyword is accepted * if the list is null, otherwise it must match one of the list * members. When debugging is not on, no keywords are accepted. * After the maximum trace level is exceeded, no keywords are @@ -1651,36 +1816,13 @@ BOOLEAN _db_strict_keyword_(const char *keyword) * */ -BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword) +BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict) { - get_code_state_or_return FALSE; + get_code_state_if_not_set_or_return FALSE; + strict=strict ? INCLUDE : INCLUDE|MATCHED; - return (DEBUGGING && - (!TRACING || cs->level <= cs->stack->maxdepth) && - InList(cs->stack->functions, cs->func) && - InList(cs->stack->keywords, keyword) && - InList(cs->stack->processes, cs->process)); -} - -/* - * FUNCTION - * - * _db_keywords_ test keyword formed by a set of strings for member - * of keyword list - * - * DESCRIPTION - * - * This function is similar to _db_keyword but receives a set of strings to - * be concatenated in order to make the keyword to be compared. - */ - -BOOLEAN _db_keywords_(const char *function, const char *type) -{ - char dest[_DBUG_MAX_FUNC_NAME_ + 1]; - - strxnmov(dest, _DBUG_MAX_FUNC_NAME_, function, type, NULL); - - return _db_strict_keyword_(dest); + return DEBUGGING && DoTrace(cs) & DO_TRACE && + InList(cs->stack->keywords, keyword) & strict; } /* @@ -1848,7 +1990,7 @@ static void DBUGOpenFile(CODE_STATE *cs, { if (end) { - int len=end-name; + size_t len=end-name; memcpy(cs->stack->name, name, len); cs->stack->name[len]=0; } @@ -1971,12 +2113,12 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name) static void DBUGCloseFile(CODE_STATE *cs, FILE *fp) { - if (fp != stderr && fp != stdout && fclose(fp) == EOF) + if (fp && fp != stderr && fp != stdout && fclose(fp) == EOF) { pthread_mutex_lock(&THR_LOCK_dbug); (void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process); perror(""); - dbug_flush(cs); + DbugFlush(cs); } } @@ -2005,7 +2147,7 @@ static void DbugExit(const char *why) CODE_STATE *cs=code_state(); (void) fprintf(stderr, ERR_ABORT, cs ? cs->process : "(null)", why); (void) fflush(stderr); - exit(1); + DBUG_ABORT(); } @@ -2193,7 +2335,7 @@ static void ChangeOwner(CODE_STATE *cs, char *pathname) EXPORT void _db_setjmp_() { - CODE_STATE *cs=0; + CODE_STATE *cs; get_code_state_or_return; cs->jmplevel= cs->level; @@ -2220,7 +2362,7 @@ EXPORT void _db_setjmp_() EXPORT void _db_longjmp_() { - CODE_STATE *cs=0; + CODE_STATE *cs; get_code_state_or_return; cs->level= cs->jmplevel; @@ -2271,11 +2413,9 @@ char *s; /* This is because some systems (MSDOS!!) dosn't flush fileheader */ /* and dbug-file isn't readable after a system crash !! */ -static void dbug_flush(CODE_STATE *cs) +static void DbugFlush(CODE_STATE *cs) { -#ifndef THREAD if (cs->stack->flags & FLUSH_ON_WRITE) -#endif { (void) fflush(cs->stack->out_file); if (cs->stack->delay) @@ -2283,12 +2423,22 @@ static void dbug_flush(CODE_STATE *cs) } if (!cs->locked) pthread_mutex_unlock(&THR_LOCK_dbug); -} /* dbug_flush */ +} /* DbugFlush */ + + +/* For debugging */ + +void _db_flush_() +{ + CODE_STATE *cs; + get_code_state_or_return; + (void) fflush(cs->stack->out_file); +} void _db_lock_file_() { - CODE_STATE *cs=0; + CODE_STATE *cs; get_code_state_or_return; pthread_mutex_lock(&THR_LOCK_dbug); cs->locked=1; @@ -2296,7 +2446,7 @@ void _db_lock_file_() void _db_unlock_file_() { - CODE_STATE *cs=0; + CODE_STATE *cs; get_code_state_or_return; cs->locked=0; pthread_mutex_unlock(&THR_LOCK_dbug); @@ -2304,7 +2454,7 @@ void _db_unlock_file_() const char* _db_get_func_(void) { - CODE_STATE *cs= 0; + CODE_STATE *cs; get_code_state_or_return NULL; return cs->func; } diff --git a/dbug/dbug_add_tags.pl b/dbug/dbug_add_tags.pl index 141a2ed85f1..3e51a54c707 100755 --- a/dbug/dbug_add_tags.pl +++ b/dbug/dbug_add_tags.pl @@ -7,7 +7,7 @@ $ctags="exctags -x -f - --c-types=f -u"; sub get_tag { local $.; local $_=; ($symbol, $line)= /^(.*\S)\s+function\s+(\d+)/; - $symbol=$1 if /\s(\S+)\s*\(/; + $symbol=$1 if /[\s*]([^\s*]+)\s*\(/; $line=1e50 unless $line; } @@ -51,7 +51,7 @@ while($src=shift) $skip=!$semicolon; $semicolon= /;\s*$/; print && next if $skip || - (/^\s+\w+((::\w+)?|<\w+>)\s+\**\w+/ && !/^\s*return/); + (/^\s+\w+((::\w+)?|<\w+>)\s+\**\w+/ && !/^\s*return\b/); last if /DBUG_ENTER/; print "$tab DBUG_ENTER(\"$symbol\");\n"; print "\n" unless $_ eq "\n"; diff --git a/dbug/doinstall.sh b/dbug/doinstall.sh deleted file mode 100644 index 707f193c761..00000000000 --- a/dbug/doinstall.sh +++ /dev/null @@ -1,15 +0,0 @@ - -# Warning - first line left blank for sh/csh/ksh compatibility. Do not -# remove it. fnf@Unisoft - -# doinstall.sh --- figure out environment and do recursive make with -# appropriate pathnames. Works under SV or BSD. - -if [ -r /usr/include/search.h ] -then - # System V - $* LLIB=/usr/lib -else - # 4.2 BSD - $* LLIB=/usr/lib/lint -fi diff --git a/dbug/install.sh b/dbug/install.sh deleted file mode 100644 index 7226e01b1cf..00000000000 --- a/dbug/install.sh +++ /dev/null @@ -1,64 +0,0 @@ - -# WARNING -- first line intentionally left blank for sh/csh/ksh -# compatibility. Do not remove it! FNF, UniSoft Systems. -# -# Usage is: -# install -# -# The file is replaced with the file , after first -# moving to a backup file. The backup file name is created -# by prepending the filename (after removing any leading pathname -# components) with "OLD". -# -# This script is currently not real robust in the face of signals -# or permission problems. It also does not do (by intention) all -# the things that the System V or BSD install scripts try to do -# - -if [ $# -ne 2 ] -then - echo "usage: $0 " - exit 1 -fi - -# Now extract the dirname and basename components. Unfortunately, BSD does -# not have dirname, so we do it the hard way. - -fd=`expr $1'/' : '\(/\)[^/]*/$' \| $1'/' : '\(.*[^/]\)//*[^/][^/]*//*$' \| .` -ff=`basename $1` -td=`expr $2'/' : '\(/\)[^/]*/$' \| $2'/' : '\(.*[^/]\)//*[^/][^/]*//*$' \| .` -tf=`basename $2` - -# Now test to make sure that they are not the same files. - -if [ $fd/$ff = $td/$tf ] -then - echo "install: input and output are same files" - exit 2 -fi - -# Save a copy of the "to" file as a backup. - -if test -f $td/$tf -then - if test -f $td/OLD$tf - then - rm -f $td/OLD$tf - fi - mv $td/$tf $td/OLD$tf - if [ $? != 0 ] - then - exit 3 - fi -fi - -# Now do the copy and return appropriate status - -cp $fd/$ff $td/$tf -if [ $? != 0 ] -then - exit 4 -else - exit 0 -fi - diff --git a/dbug/mklintlib.sh b/dbug/mklintlib.sh deleted file mode 100644 index 6963016f334..00000000000 --- a/dbug/mklintlib.sh +++ /dev/null @@ -1,30 +0,0 @@ - -# Warning - first line left blank for sh/csh/ksh compatibility. Do not -# remove it. fnf@Unisoft - -# mklintlib --- make a lint library, under either System V or 4.2 BSD -# -# usage: mklintlib -# - -if test $# -ne 2 -then - echo "usage: mklintlib " - exit 1 -fi - -if grep SIGTSTP /usr/include/signal.h >/dev/null -then # BSD - if test -r /usr/include/whoami.h # 4.1 - then - /lib/cpp -C -Dlint $1 >hlint - (/usr/lib/lint/lint1 $2) 2>&1 | grep -v warning - else # 4.2 - lint -Cxxxx $1 - mv llib-lxxxx.ln $2 - fi -else # USG - cc -E -C -Dlint $1 | /usr/lib/lint1 -vx -Hhlint >$2 - rm -f hlint -fi -exit 0 # don't kill make diff --git a/dbug/qmake.cmd b/dbug/qmake.cmd deleted file mode 100644 index ebd4432f7fc..00000000000 --- a/dbug/qmake.cmd +++ /dev/null @@ -1,4 +0,0 @@ -CL -I\my\include -AL -Gsm2 -FPi -DDBUG_OFF *.c -rm \my\lib\dbug.lib -lib.exe \my\lib\dbug dbug.obj sanity.obj; -link /NOD /STACK:8000 main factoria,factoria,,DBUG+STRINGS+LLIBCEP+DOSCALLS; diff --git a/dbug/remove_function_from_trace.pl b/dbug/remove_function_from_trace.pl new file mode 100755 index 00000000000..1da9e25f9ba --- /dev/null +++ b/dbug/remove_function_from_trace.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl + + +die <stdout) removes lines from dbug trace that were generated +by specified functions and all functions down the call stack. Produces the +same effect as if the original source had DBUG_PUSH(""); right after +DBUG_ENTER() and DBUG_POP(); right before DBUG_RETURN in every such a function. +EEE + +$re=join('|', @ARGV); +$skip=''; + +while() { + print unless $skip; + next unless /^(?:.*: )*((?:\| )*)([<>])($re)\n/o; + if ($2 eq '>') { + $skip=$1.$3 unless $skip; + next; + } + next if $skip ne $1.$3; + $skip=''; + print; +} diff --git a/dbug/tests-t.pl b/dbug/tests-t.pl new file mode 100755 index 00000000000..de9ed6f6ab9 --- /dev/null +++ b/dbug/tests-t.pl @@ -0,0 +1,496 @@ +#!/usr/bin/env perl + +# +# A driver program to test DBUG features - runs tests (shell commands) +# from the end of file to invoke tests.c, which does the real dbug work. +# + +use Test::More; + +$exe=$0; + +die unless $exe =~ s/(tests)-t(\.exe)?$/$1$2 /; + +# load tests +@tests=(); +while () { + if (/^% \.\/tests /) { + push @tests, [ $' ] + } elsif (/^#/) { + next; + } else { + push @{$tests[$#tests]}, $_ + } +} + +plan skip_all => "because dbug is disabled" if system $exe; + +plan tests => scalar(@tests); + +for (@tests) { + $t=$exe . shift @$_; + chomp($t); + open F, '-|', $t or die "open($t|): $!"; + local $"; + $out=join($", ); close(F); + # special cases are handled here: + $out =~ s/Memory: 0x[0-9A-Fa-f]+/Memory: 0x####/g if $t =~ /dump/; + # compare ("\n" at the beginning makes better output in case of errors) + is("\n$out","\n@$_", $t); +} + +__DATA__ +% ./tests -#d +func2: info: s=ok +=> execute +=> evaluate: ON +=> evaluate_if: OFF +main: explain: dbug explained: d +func2: info: s=ok +% ./tests d,ret3 +=> evaluate: OFF +=> evaluate_if: OFF +# +## Testing negative lists +# +% ./tests d:-d,ret3 +func2: info: s=ko +=> execute +=> evaluate: ON +=> evaluate_if: OFF +main: explain: dbug explained: d:-d,ret3 +func2: info: s=ko +% ./tests t:-d,ret3 +>main +| >func1 +| | >func2 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +| >func2 +| | >func3 +| | main +| >func1 +| | >func2 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +| >func2 +| | >func3 +| | main +| >func1 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +| | >func3 +| | evaluate: ON +=> evaluate_if: OFF +% ./tests t:d,info:-d,ret3:-f,func2 d,evaluate_if +=> evaluate: OFF +=> evaluate_if: ON +% ./tests t:d:-d,ret3:-f,func2 d,evaluate_if +=> evaluate: OFF +=> evaluate_if: ON +% ./tests t:d:-d,ret3:-f,func2 +>main +| >func1 +| | | >func3 +| | | execute +=> evaluate: ON +=> evaluate_if: OFF +| explain: dbug explained: d:-d,ret3:f:-f,func2:t +| | >func3 +| | main +| >func1 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: ON +| | >func3 +| | main +| >func1 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +| | >func3 +| | main +| >func1 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +| | >func3 +| | main +| >func1 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +| | >func3 +| | main +| >func1 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +| explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:t +| | >func3 +| | main +dbug-tests: | >func1 +dbug-tests: | | | >func3 +dbug-tests: | | | evaluate: OFF +=> evaluate_if: OFF +dbug-tests: | explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:P:t +dbug-tests: | | >func3 +dbug-tests: | | main +dbug-tests: tests.c: | >func1 +dbug-tests: tests.c: | | | >func3 +dbug-tests: tests.c: | | | evaluate: OFF +=> evaluate_if: OFF +dbug-tests: tests.c: | explain: dbug explained: d,dump,explain:-d,ret3:f:-f,func2:F:P:t +dbug-tests: tests.c: | | >func3 +dbug-tests: tests.c: | | main +| >func1 +| | | >func3 +| | | execute +=> evaluate: ON +=> evaluate_if: OFF +| explain: dbug explained: d:-d,ret3:f:-f,func2:t +| | >func3 +| | main +| >func1 +| | >func2 +| | | >func3 +| | | execute +=> evaluate: ON +=> evaluate_if: OFF +| explain: dbug explained: d:-d,ret3:t +| >func2 +| | >func3 +| | evaluate: OFF +=> evaluate_if: OFF +| >func2 +| | >func3 +| | evaluate: OFF +=> evaluate_if: OFF +| explain: dbug explained: d,info,push,explain:-d,ret3:t +| >func2 +| | >func3 +| | evaluate: OFF +=> evaluate_if: OFF +main: explain: dbug explained: d,info,explain:-d,ret3 +func2: info: s=ko +% ./tests d,info:-d,ret3:d,explain,pop +func2: info: s=ko +=> evaluate: OFF +=> evaluate_if: OFF +% ./tests d,info:-d,ret3:d,explain t:d,pop +>main +| >func1 +| | >func2 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +main: explain: dbug explained: d,info,explain:-d,ret3 +func2: info: s=ko +% ./tests d,info:-d,ret3:d,explain,pop +t +>main +| >func1 +| | >func2 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +main: explain: dbug explained: d,info,explain,pop:-d,ret3 +func2: info: s=ko +% ./tests d,info:-d,ret3:d,explain,set +func2: info: s=ko +=> evaluate: OFF +=> evaluate_if: OFF + tests.c: main: explain: dbug explained: d,info,explain,set:-d,ret3:F + tests.c: func2: info: s=ko +% ./tests d,info:-d,ret3:d,explain,set:t +>main +| >func1 +| | >func2 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF + tests.c: | explain: dbug explained: d,info,explain,set:-d,ret3:F:t + tests.c: | >func2 + tests.c: | | >func3 + tests.c: | | main +| >func1 +| | >func2 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF + tests.c: | explain: dbug explained: d,info,explain,set:-d,ret3:F:t + tests.c: | >func2 + tests.c: | | >func3 + tests.c: | | evaluate: OFF +=> evaluate_if: OFF +| >func2 +| | >func3 +| | func2 +| | evaluate: OFF +=> evaluate_if: OFF +| >func2 +| main +| >func1 +| execute +=> evaluate: ON +=> evaluate_if: OFF +| explain: dbug explained: d:f:-f,func2/:t +
func1 +| | >func2 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +% ./tests t:f,main/:d,pop +>main +| >func1 +| | >func2 +| | | >func3 +| | | evaluate: OFF +=> evaluate_if: OFF +% ./tests f,main/:d,push +=> evaluate: OFF +=> evaluate_if: OFF +| >func2 +| | >func3 +| | func1 +| | >func2 +| | | >func3 +| | | push1 +=> evaluate: OFF +=> evaluate_if: OFF +| | >func3 +| | main +=> push1 +| evaluate: OFF +=> evaluate_if: OFF +| >func2 +| | >func3 +| | func3 +| | | push1 +| evaluate: OFF +=> evaluate_if: OFF +| >func2 +| | >func3 +| | main +| >func1 +| | >func2 +| | | >func3 +| | | push1 +=> evaluate: OFF +=> evaluate_if: OFF +# change the defaults +% ./tests t:f,func3 --push1=t +| | | >func3 +| | | push1 +| evaluate: OFF +=> evaluate_if: OFF +| >func2 +| | >func3 +| | execute +=> evaluate: ON +=> evaluate_if: OFF +main: explain: dbug explained: d:-d,info +% ./tests d:-d,info/,info +=> execute +=> evaluate: ON +=> evaluate_if: OFF +main: explain: dbug explained: d:-d,info/ diff --git a/dbug/tests.c b/dbug/tests.c new file mode 100644 index 00000000000..d76266d34a3 --- /dev/null +++ b/dbug/tests.c @@ -0,0 +1,87 @@ +/* + A program to test DBUG features. Used by tests-t.pl +*/ + +char *push1=0; + +#include /* This includes dbug.h */ +#include +#include + +const char *func3() +{ + DBUG_ENTER("func3"); + DBUG_RETURN(DBUG_EVALUATE("ret3", "ok", "ko")); +} + +void func2() +{ + const char *s; + DBUG_ENTER("func2"); + s=func3(); + DBUG_PRINT("info", ("s=%s", s)); + DBUG_VOID_RETURN; +} + +int func1() +{ + DBUG_ENTER("func1"); + func2(); + if (push1) + { + DBUG_PUSH(push1); + fprintf(DBUG_FILE, "=> push1\n"); + } + DBUG_RETURN(10); +} + +int main (int argc, char *argv[]) +{ + int i; +#ifdef DBUG_OFF + return 1; +#endif + if (argc == 1) + return 0; + +#if defined(HAVE_PTHREAD_INIT) && defined(THREAD) + pthread_init(); /* Must be called before DBUG_ENTER */ +#endif +#ifdef THREAD + my_thread_global_init(); +#endif + dup2(1, 2); + for (i = 1; i < argc; i++) + { + if (strncmp(argv[i], "--push1=", 8) == 0) + push1=argv[i]+8; + else + DBUG_PUSH (argv[i]); + } + { + DBUG_ENTER ("main"); + DBUG_PROCESS ("dbug-tests"); + func1(); + DBUG_EXECUTE_IF("dump", + { + char s[1000]; + DBUG_EXPLAIN(s, sizeof(s)-1); + DBUG_DUMP("dump", (uchar*)s, strlen(s)); + }); + DBUG_EXECUTE_IF("push", DBUG_PUSH("+t"); ); + DBUG_EXECUTE("execute", fprintf(DBUG_FILE, "=> execute\n"); ); + DBUG_EXECUTE_IF("set", DBUG_SET("+F"); ); + fprintf(DBUG_FILE, "=> evaluate: %s\n", + DBUG_EVALUATE("evaluate", "ON", "OFF")); + fprintf(DBUG_FILE, "=> evaluate_if: %s\n", + DBUG_EVALUATE_IF("evaluate_if", "ON", "OFF")); + DBUG_EXECUTE_IF("pop", DBUG_POP(); ); + { + char s[1000] __attribute__((unused)); + DBUG_EXPLAIN(s, sizeof(s)-1); + DBUG_PRINT("explain", ("dbug explained: %s", s)); + } + func2(); + DBUG_RETURN (0); + } +} diff --git a/dbug/user.r b/dbug/user.r index ef67ef7a7cf..847ad80b30f 100644 --- a/dbug/user.r +++ b/dbug/user.r @@ -512,7 +512,7 @@ possible since all code preceding the first call to .B DBUG_PUSH is essentially invisible to -.B dbug +.I dbug (this can be worked around by inserting a temporary .B DBUG_PUSH(argv[1]) @@ -708,7 +708,7 @@ EX:\ \fCDBUG_PROCESS\ (argv[0]);\fR .SP 1 .LI DBUG_PUSH\ Sets a new debugger state by pushing the current -.B dbug +.I dbug state onto an internal stack and setting up the new state using the debug control string passed as the macro argument. The most common usage is to set the state specified by a debug control string @@ -769,14 +769,14 @@ the 'd' flag. Used to conditionally execute "dangerous" actions, e.g to crash the program testing how recovery works, or to introduce an artificial delay checking for race conditions. .SP 1 -EX:\ \fCDBUG_EXECUTE_IF\ ("crashme",\ abort\ ());\fR +EX:\ \fCDBUG_EXECUTE_IF\ ("crashme",\ DBUG_ABORT()\ ());\fR .SP 1 .LI DBUG_EVALUATE\ The DBUG_EVALUATE macro is similar to DBUG_EXECUTE, but it can be used in the expression context. The first argument is the debug keyword that is used to choose whether the second (keyword is enabled) or the third (keyword is not enabled) argument is evaluated. When -.B dbug +.I dbug is compiled off, the third argument is evaluated. .SP 1 EX:\fC @@ -796,7 +796,7 @@ EX:\fC .br if (prepare_transaction () || .br - DBUG_EVALUATE ("crashme", (abort (), 0), 0) || + DBUG_EVALUATE ("crashme", (DBUG_ABORT(), 0), 0) || .br commit_transaction () )\fR .SP 1 @@ -875,6 +875,12 @@ library. So there will be no need to disable asserts separately with NDEBUG. .SP 1 EX:\ \fCDBUG_ASSERT(\ a\ >\ 0\ );\fR .SP 1 +.LI DBUG_ABORT\ +This macro could be used instead of abort(). It flushes DBUG_FILE stream +to ensure that no +.I dbug +output is lost and then calls abort(). +.SP 1 .LI DBUG_EXPLAIN\ Generates control string corresponding to the current debug state. The macro takes two arguments - a buffer to store the result string @@ -910,17 +916,17 @@ via the .B DBUG_PUSH or .B DBUG_SET -macros. Control string consists of colon separate flags. Colons +macros. Control string consists of colon separated flags. Colons that are part of ':\\', ':/', or '::' are not considered flag separators. A flag may take an argument or a list of arguments. If a control string starts from a '+' sign it works .I incrementally, -that is, it can modify existing state without overriding it. In such a -string every flag may be preceded by a '+' or '-' to enable or disable -a corresponding option in the debugger state. This section summarizes -the currently available debugger options and the flag characters which -enable or disable them. Argument lists enclosed in '[' and ']' are -optional. +that is, it can modify existing state without overriding it. Every +flag may be preceded by a '+' or '-' to enable or disable a +corresponding option in the debugger state or to add or remove +arguments to the list. This section summarizes the currently available +debugger options and the flag characters which enable or disable them. +Argument lists enclosed in '[' and ']' are optional. .SP 2 .BL 22 .LI a[,file] @@ -936,6 +942,9 @@ a complete log file in case of crashes. This mode is implicit in multi-threaded environment. .LI d[,keywords] Enable output from macros with specified keywords. +Every keyword can be a +.I glob(7) +pattern. An empty list of keywords implies that all keywords are selected. .LI D[,time] Delay for specified time after each output line, to let output drain. @@ -943,7 +952,19 @@ Time is given in tenths of a second (value of 10 is one second). Default is zero. .LI f[,functions] Limit debugger actions to the specified list of functions. +Every function can be a +.I glob(7) +pattern. An empty list of functions implies that all functions are selected. +Every function in the list may optionally be followed by a '/' - +this will implicitly select all the functions down the call stack. +.SP 1 +EX: \fCf,func1,func2/:-f,func3,func4/\fR +.SP 1 +This would enable debugger in functions 'func1()', 'func2()' and all +functions called from it (directly or indirectly). But not in +functions 'func3()' or 'func4()' and all functions called from +it. .LI F Mark each debugger output line with the name of the source file containing the macro causing the output. @@ -952,6 +973,9 @@ Mark each debugger output line with the PID (or thread ID) of the current process. .LI g,[functions] Enable profiling for the specified list of functions. +Every function can be a +.I glob(7) +pattern. An empty list of functions enables profiling for all functions. See .B PROFILING\ WITH\ DBUG @@ -970,7 +994,11 @@ Like 'a[,file]' but overwrite old file, do not append. .LI O[,file] Like 'A[,file]' but overwrite old file, do not append. .LI p[,processes] -Limit debugger actions to the specified processes. An empty list +Limit debugger actions to the specified processes. +Every name can be a +.I glob(7) +pattern. +An empty list implies all processes. This is useful for processes which run child processes. Note that each debugger output line can be marked with the name of the current process via the 'P' flag. The process name must diff --git a/dbug/vargs.h b/dbug/vargs.h deleted file mode 100644 index 4609c8301bb..00000000000 --- a/dbug/vargs.h +++ /dev/null @@ -1,139 +0,0 @@ -/****************************************************************************** - * * - * N O T I C E * - * * - * Copyright Abandoned, 1987, Fred Fish * - * * - * * - * This previously copyrighted work has been placed into the public * - * domain by the author and may be freely used for any purpose, * - * private or commercial. * - * * - * Because of the number of inquiries I was receiving about the use * - * of this product in commercially developed works I have decided to * - * simply make it public domain to further its unrestricted use. I * - * specifically would be most happy to see this material become a * - * part of the standard Unix distributions by AT&T and the Berkeley * - * Computer Science Research Group, and a standard part of the GNU * - * system from the Free Software Foundation. * - * * - * I would appreciate it, as a courtesy, if this notice is left in * - * all copies and derivative works. Thank you. * - * * - * The author makes no warranty of any kind with respect to this * - * product and explicitly disclaims any implied warranties of mer- * - * chantability or fitness for any particular purpose. * - * * - ****************************************************************************** - */ - - -/* - * FILE - * - * vargs.h include file for environments without varargs.h - * - * SCCS - * - * @(#)vargs.h 1.2 5/8/88 - * - * SYNOPSIS - * - * #include "vargs.h" - * - * DESCRIPTION - * - * This file implements a varargs macro set for use in those - * environments where there is no system supplied varargs. This - * generally works because systems which don't supply a varargs - * package are precisely those which don't strictly need a varargs - * package. Using this one then allows us to minimize source - * code changes. So in some sense, this is a "portable" varargs - * since it is only used for convenience, when it is not strictly - * needed. - * - */ - -/* - * These macros allow us to rebuild an argument list on the stack - * given only a va_list. We can use these to fake a function like - * vfprintf, which gets a fixed number of arguments, the last of - * which is a va_list, by rebuilding a stack and calling the variable - * argument form fprintf. Of course this only works when vfprintf - * is not available in the host environment, and thus is not available - * for fprintf to call (which would give us an infinite loop). - * - * Note that ARGS_TYPE is a long, which lets us get several bytes - * at a time while also preventing lots of "possible pointer alignment - * problem" messages from lint. The messages are valid, because this - * IS nonportable, but then we should only be using it in very - * nonrestrictive environments, and using the real varargs where it - * really counts. - * - */ - -#define ARG0 a0 -#define ARG1 a1 -#define ARG2 a2 -#define ARG3 a3 -#define ARG4 a4 -#define ARG5 a5 -#define ARG6 a6 -#define ARG7 a7 -#define ARG8 a8 -#define ARG9 a9 - -#define ARGS_TYPE long -#define ARGS_LIST ARG0,ARG1,ARG2,ARG3,ARG4,ARG5,ARG6,ARG7,ARG8,ARG9 -#define ARGS_DCL auto ARGS_TYPE ARGS_LIST - -/* - * A pointer of type "va_list" points to a section of memory - * containing an array of variable sized arguments of unknown - * number. This pointer is initialized by the va_start - * macro to point to the first byte of the first argument. - * We can then use it to walk through the argument list by - * incrementing it by the size of the argument being referenced. - */ - -typedef char *va_list; - -/* - * The first variable argument overlays va_alist, which is - * nothing more than a "handle" which allows us to get the - * address of the first argument on the stack. Note that - * by definition, the va_dcl macro includes the terminating - * semicolon, which makes use of va_dcl in the source code - * appear to be missing a semicolon. - */ - -#define va_dcl ARGS_TYPE va_alist; - -/* - * The va_start macro takes a variable of type "va_list" and - * initializes it. In our case, it initializes a local variable - * of type "pointer to char" to point to the first argument on - * the stack. - */ - -#define va_start(list) list = (char *) &va_alist - -/* - * The va_end macro is a null operation for our use. - */ - -#define va_end(list) - -/* - * The va_arg macro is the tricky one. This one takes - * a va_list as the first argument, and a type as the second - * argument, and returns a value of the appropriate type - * while advancing the va_list to the following argument. - * For our case, we first increment the va_list arg by the - * size of the type being recovered, cast the result to - * a pointer of the appropriate type, and then dereference - * that pointer as an array to get the previous arg (which - * is the one we wanted. - */ - -#define va_arg(list,type) ((type *) (list += sizeof (type)))[-1] diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index 42a5cbd6877..2614946a712 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -189,6 +189,7 @@ int main(int argc, char **argv) config_file); } error= 2; + exit(error); } for (argument= arguments+1 ; *argument ; argument++) @@ -197,5 +198,5 @@ int main(int argc, char **argv) my_free((char*) load_default_groups,MYF(0)); free_defaults(arguments); - exit(error); + exit(0); } diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp index 89fd5f7c7bc..2bbc0a85e8b 100644 --- a/extra/yassl/taocrypt/src/random.cpp +++ b/extra/yassl/taocrypt/src/random.cpp @@ -27,7 +27,6 @@ #include #if defined(_WIN32) - #define _WIN32_WINNT 0x0400 #include #include #else diff --git a/include/Makefile.am b/include/Makefile.am index dd6f53f7ca2..0a7a35bd6fa 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -21,7 +21,8 @@ HEADERS_GEN_MAKE = my_config.h HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \ my_list.h my_alloc.h typelib.h mysql/plugin.h pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \ - my_xml.h mysql_embed.h \ + my_xml.h mysql_embed.h mysql/services.h \ + mysql/service_my_snprintf.h mysql/service_thd_alloc.h \ my_pthread.h my_no_pthread.h \ decimal.h errmsg.h my_global.h my_net.h \ my_getopt.h sslopt-longopts.h my_dir.h \ @@ -36,7 +37,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ - my_handler.h my_time.h \ + my_handler.h my_time.h service_versions.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \ atomic/solaris.h \ diff --git a/include/config-win.h b/include/config-win.h index 702c6bcdeae..364c4f92134 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -356,7 +356,6 @@ inline ulonglong double2ulonglong(double d) #define HAVE_OPENSSL 1 #define HAVE_YASSL 1 -#define COMMUNITY_SERVER 1 #define ENABLED_PROFILING 1 /* diff --git a/include/errmsg.h b/include/errmsg.h index 5754e99ba5e..c55c94af169 100644 --- a/include/errmsg.h +++ b/include/errmsg.h @@ -100,7 +100,8 @@ extern const char *client_errors[]; /* Error messages */ #define CR_SERVER_LOST_EXTENDED 2055 #define CR_STMT_CLOSED 2056 #define CR_NEW_STMT_METADATA 2057 -#define CR_ERROR_LAST /*Copy last error nr:*/ 2057 +#define CR_ALREADY_CONNECTED 2058 +#define CR_ERROR_LAST /*Copy last error nr:*/ 2058 /* Add error numbers before CR_ERROR_LAST and change it accordingly. */ #endif /* ERRMSG_INCLUDED */ diff --git a/include/hash.h b/include/hash.h index 629b404e8a7..d870e17c341 100644 --- a/include/hash.h +++ b/include/hash.h @@ -21,40 +21,6 @@ extern "C" { #endif -/* - There was a problem on MacOSX with a shared object ha_example.so. - It used hash_search(). During build of ha_example.so no libmysys - was specified. Since MacOSX had a hash_search() in the system - library, it built the shared object so that the dynamic linker - linked hash_search() to the system library, which caused a crash - when called. To come around this, we renamed hash_search() to - my_hash_search(), as we did long ago with hash_insert() and - hash_reset(). However, this time we made the move complete with - all names. To keep compatibility, we redefine the old names. - Since every C and C++ file, that uses HASH, needs to include - this file, the change is complete. Both names could be used - in the code, but the my_* versions are recommended now. -*/ -#define hash_get_key my_hash_get_key -#define hash_free_key my_hash_free_key -#define hash_init my_hash_init -#define hash_init2 my_hash_init2 -#define _hash_init _my_hash_init -#define hash_free my_hash_free -#define hash_reset my_hash_reset -#define hash_element my_hash_element -#define hash_search my_hash_search -#define hash_first my_hash_first -#define hash_next my_hash_next -#define hash_insert my_hash_insert -#define hash_delete my_hash_delete -#define hash_update my_hash_update -#define hash_replace my_hash_replace -#define hash_check my_hash_check -#define hash_clear my_hash_clear -#define hash_inited my_hash_inited -#define hash_init_opt my_hash_init_opt - /* Overhead to store an element in hash Can be used to approximate memory consumption for a hash diff --git a/include/m_string.h b/include/m_string.h index c24bfd7aa6c..3c4c6ea088a 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -250,16 +250,10 @@ extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...) /* LEX_STRING -- a pair of a C-string and its length. + (it's part of the plugin API as a MYSQL_LEX_STRING) */ -#ifndef _my_plugin_h -/* This definition must match the one given in mysql/plugin.h */ -struct st_mysql_lex_string -{ - char *str; - size_t length; -}; -#endif +#include typedef struct st_mysql_lex_string LEX_STRING; #define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1)) diff --git a/include/my_base.h b/include/my_base.h index a01b2ec9b82..70bd9b5e073 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -255,7 +255,17 @@ enum ha_base_keytype { HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \ HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY) -#define HA_KEY_HAS_PART_KEY_SEG 65536 /* Key contains partial segments */ +/* + Key contains partial segments. + + This flag is internal to the MySQL server by design. It is not supposed + neither to be saved in FRM-files, nor to be passed to storage engines. + It is intended to pass information into internal static sort_keys(KEY *, + KEY *) function. + + This flag can be calculated -- it's based on key lengths comparison. +*/ +#define HA_KEY_HAS_PART_KEY_SEG 65536 /* Automatic bits in key-flag */ diff --git a/include/my_dbug.h b/include/my_dbug.h index 0451a868aa4..956a5504e86 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -16,103 +16,64 @@ #ifndef _dbug_h #define _dbug_h -#if defined(__cplusplus) && !defined(DBUG_OFF) -class Dbug_violation_helper -{ -public: - inline Dbug_violation_helper() : - _entered(TRUE) - { } - - inline ~Dbug_violation_helper() - { - assert(!_entered); - } - - inline void leave() - { - _entered= FALSE; - } - -private: - bool _entered; -}; -#endif /* C++ */ - -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif #if !defined(DBUG_OFF) && !defined(_lint) -struct _db_code_state_; -extern int _db_keyword_(struct _db_code_state_ *cs, const char *keyword); -extern int _db_keywords_(const char *, const char *); -extern int _db_strict_keyword_(const char *keyword); + +struct _db_stack_frame_ { + const char *func; /* function name of the previous stack frame */ + const char *file; /* filename of the function of previous frame */ + uint level; /* this nesting level, highest bit enables tracing */ + struct _db_stack_frame_ *prev; /* pointer to the previous frame */ +}; + +struct _db_code_state_; +extern my_bool _dbug_on_; +extern my_bool _db_keyword_(struct _db_code_state_ *, const char *, int); extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len); extern int _db_explain_init_(char *buf, size_t len); -extern void _db_setjmp_(void); -extern void _db_longjmp_(void); +extern int _db_is_pushed_(void); +extern void _db_setjmp_(void); +extern void _db_longjmp_(void); extern void _db_process_(const char *name); -extern void _db_push_(const char *control); -extern void _db_pop_(void); -extern void _db_set_(struct _db_code_state_ *cs, const char *control); +extern void _db_push_(const char *control); +extern void _db_pop_(void); +extern void _db_set_(const char *control); extern void _db_set_init_(const char *control); -extern void _db_enter_(const char *_func_,const char *_file_,uint _line_, - const char **_sfunc_,const char **_sfile_, - uint *_slevel_, char ***); -extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_, - uint *_slevel_); -extern void _db_pargs_(uint _line_,const char *keyword); -extern void _db_doprnt_ _VARARGS((const char *format,...)) +extern void _db_enter_(const char *_func_, const char *_file_, uint _line_, + struct _db_stack_frame_ *_stack_frame_); +extern void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_); +extern void _db_pargs_(uint _line_,const char *keyword); +extern void _db_doprnt_ _VARARGS((const char *format,...)) ATTRIBUTE_FORMAT(printf, 1, 2); -extern void _db_dump_(uint _line_,const char *keyword, +extern void _db_dump_(uint _line_,const char *keyword, const unsigned char *memory, size_t length); -extern void _db_end_(void); -extern void _db_lock_file_(void); -extern void _db_unlock_file_(void); -extern FILE *_db_fp_(void); +extern void _db_end_(void); +extern void _db_lock_file_(void); +extern void _db_unlock_file_(void); +extern FILE *_db_fp_(void); +extern void _db_flush_(); extern const char* _db_get_func_(void); -#ifdef __cplusplus - -#define DBUG_ENTER(a) \ - const char *_db_func_, *_db_file_; \ - uint _db_level_; \ - char **_db_framep_; \ - Dbug_violation_helper dbug_violation_helper; \ - _db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \ - &_db_level_, &_db_framep_) -#define DBUG_VIOLATION_HELPER_LEAVE dbug_violation_helper.leave() - -#else /* C */ - -#define DBUG_ENTER(a) \ - const char *_db_func_, *_db_file_; \ - uint _db_level_; \ - char **_db_framep_; \ - _db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \ - &_db_level_, &_db_framep_) -#define DBUG_VIOLATION_HELPER_LEAVE do { } while(0) - -#endif /* C++ */ - -#define DBUG_LEAVE \ - DBUG_VIOLATION_HELPER_LEAVE; \ - _db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_) +#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \ + _db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_) +#define DBUG_LEAVE _db_return_ (__LINE__, &_db_stack_frame_) #define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0) #define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0) #define DBUG_EXECUTE(keyword,a1) \ - do {if (_db_keyword_(0, (keyword))) { a1 }} while(0) + do {if (_db_keyword_(0, (keyword), 0)) { a1 }} while(0) #define DBUG_EXECUTE_IF(keyword,a1) \ - do {if (_db_strict_keyword_ (keyword)) { a1 } } while(0) + do {if (_db_keyword_(0, (keyword), 1)) { a1 }} while(0) #define DBUG_EVALUATE(keyword,a1,a2) \ - (_db_keyword_(0,(keyword)) ? (a1) : (a2)) + (_db_keyword_(0,(keyword), 0) ? (a1) : (a2)) #define DBUG_EVALUATE_IF(keyword,a1,a2) \ - (_db_strict_keyword_((keyword)) ? (a1) : (a2)) + (_db_keyword_(0,(keyword), 1) ? (a1) : (a2)) #define DBUG_PRINT(keyword,arglist) \ do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0) #define DBUG_PUSH(a1) _db_push_ (a1) #define DBUG_POP() _db_pop_ () -#define DBUG_SET(a1) _db_set_ (0, (a1)) +#define DBUG_SET(a1) _db_set_ (a1) #define DBUG_SET_INITIAL(a1) _db_set_init_ (a1) #define DBUG_PROCESS(a1) _db_process_(a1) #define DBUG_FILE _db_fp_() @@ -125,54 +86,66 @@ extern const char* _db_get_func_(void); #define DBUG_ASSERT(A) assert(A) #define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len)) #define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len)) -#define IF_DBUG(A) A -#define _DBUG_MAX_FUNC_NAME_ 255 +#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0) +#define DEBUGGER_ON do { _dbug_on_= 1; } while(0) +#ifndef __WIN__ +#define DBUG_ABORT() (_db_flush_(), abort()) +#else +/* + Avoid popup with abort/retry/ignore buttons. When BUG#31745 is fixed we can + call abort() instead of _exit(3) (now it would cause a "test signal" popup). +*/ +#include +#define DBUG_ABORT() (_db_flush_(),\ + (void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE),\ + (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR),\ + _exit(3)) +#endif #define DBUG_CHECK_CRASH(func, op) \ - do { \ - if (_db_keywords_((func), (op))) \ - { abort(); } \ - } while (0) + do { char _dbuf_[255]; strxnmov(_dbuf_, sizeof(_dbuf_)-1, (func), (op)); \ + DBUG_EXECUTE_IF(_dbuf_, DBUG_ABORT()); } while(0) #define DBUG_CRASH_ENTER(func) \ DBUG_ENTER(func); DBUG_CHECK_CRASH(func, "_crash_enter") #define DBUG_CRASH_RETURN(val) \ - do {DBUG_CHECK_CRASH(_db_get_func_(), "_crash_return"); \ - DBUG_RETURN(val);} while(0) + DBUG_CHECK_CRASH(_db_get_func_(), "_crash_return") #define DBUG_CRASH_VOID_RETURN \ - do {DBUG_CHECK_CRASH (_db_get_func_(), "_crash_return"); \ - DBUG_VOID_RETURN;} while(0) -#else /* No debugger */ + DBUG_CHECK_CRASH (_db_get_func_(), "_crash_return") + +#else /* No debugger */ #define DBUG_ENTER(a1) #define DBUG_LEAVE -#define DBUG_VIOLATION_HELPER_LEAVE -#define DBUG_RETURN(a1) do { return(a1); } while(0) -#define DBUG_VOID_RETURN do { return; } while(0) -#define DBUG_EXECUTE(keyword,a1) do { } while(0) -#define DBUG_EXECUTE_IF(keyword,a1) do { } while(0) +#define DBUG_RETURN(a1) do { return(a1); } while(0) +#define DBUG_VOID_RETURN do { return; } while(0) +#define DBUG_EXECUTE(keyword,a1) do { } while(0) +#define DBUG_EXECUTE_IF(keyword,a1) do { } while(0) #define DBUG_EVALUATE(keyword,a1,a2) (a2) #define DBUG_EVALUATE_IF(keyword,a1,a2) (a2) -#define DBUG_PRINT(keyword,arglist) do { } while(0) -#define DBUG_PUSH(a1) -#define DBUG_SET(a1) do { } while(0) -#define DBUG_SET_INITIAL(a1) do { } while(0) -#define DBUG_POP() -#define DBUG_PROCESS(a1) +#define DBUG_PRINT(keyword,arglist) do { } while(0) +#define DBUG_PUSH(a1) do { } while(0) +#define DBUG_SET(a1) do { } while(0) +#define DBUG_SET_INITIAL(a1) do { } while(0) +#define DBUG_POP() do { } while(0) +#define DBUG_PROCESS(a1) do { } while(0) #define DBUG_SETJMP(a1) setjmp(a1) #define DBUG_LONGJMP(a1) longjmp(a1) -#define DBUG_DUMP(keyword,a1,a2) do { } while(0) -#define DBUG_END() -#define DBUG_ASSERT(A) do { } while(0) -#define DBUG_LOCK_FILE +#define DBUG_DUMP(keyword,a1,a2) do { } while(0) +#define DBUG_END() do { } while(0) +#define DBUG_ASSERT(A) do { } while(0) +#define DBUG_LOCK_FILE do { } while(0) #define DBUG_FILE (stderr) -#define DBUG_UNLOCK_FILE +#define DBUG_UNLOCK_FILE do { } while(0) #define DBUG_EXPLAIN(buf,len) #define DBUG_EXPLAIN_INITIAL(buf,len) -#define IF_DBUG(A) +#define DEBUGGER_OFF do { } while(0) +#define DEBUGGER_ON do { } while(0) +#define DBUG_ABORT() abort() #define DBUG_CRASH_ENTER(func) -#define DBUG_CRASH_RETURN(val) do { return(val); } while(0) -#define DBUG_CRASH_VOID_RETURN do { return; } while(0) +#define DBUG_CRASH_RETURN(val) do { return(val); } while(0) +#define DBUG_CRASH_VOID_RETURN do { return; } while(0) + #endif -#ifdef __cplusplus +#ifdef __cplusplus } #endif #endif diff --git a/include/my_global.h b/include/my_global.h index ca1e1a9d845..f6d1592fc6f 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -649,8 +649,6 @@ C_MODE_END # endif #endif -#include - #define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/ #define ASCII_BITS_USED 8 /* Bit char used */ #define NEAR_F /* No near function handling */ @@ -1177,6 +1175,8 @@ typedef char bool; /* Ordinary boolean values 0 1 */ #define reg16 register #endif +#include + /* Sometimes we want to make sure that the variable is not put into a register in debugging mode so we can see its value in the core diff --git a/include/my_pthread.h b/include/my_pthread.h index b4fe1203d2b..b6d9feae067 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -670,6 +670,7 @@ struct st_my_thread_var }; extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); +extern void **my_thread_var_dbug(); extern uint my_thread_end_wait_time; #define my_thread_var (_my_thread_var()) #define my_errno my_thread_var->thr_errno diff --git a/include/my_sys.h b/include/my_sys.h index b4366a4cd3d..3c8df28b151 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -60,7 +60,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_WME 16 /* Write message on error */ #define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */ #define MY_IGNORE_BADFD 32 /* my_sync: ignore 'bad descriptor' errors */ -#define MY_SYNC_DIR 1024 /* my_create/delete/rename: sync directory */ +#define MY_SYNC_DIR 8192 /* my_create/delete/rename: sync directory */ #define MY_RAID 64 /* Support for RAID */ #define MY_FULL_IO 512 /* For my_read - loop intil I/O is complete */ #define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */ @@ -683,6 +683,8 @@ extern void my_error _VARARGS((int nr,myf MyFlags, ...)); extern void my_printf_error _VARARGS((uint my_err, const char *format, myf MyFlags, ...)) ATTRIBUTE_FORMAT(printf, 2, 4); +extern void my_printv_error(uint error, const char *format, myf MyFlags, + va_list ap); extern int my_error_register(const char** (*get_errmsgs) (), int first, int last); extern const char **my_error_unregister(int first, int last); diff --git a/include/myisam.h b/include/myisam.h index 70c6f33f118..2df7ccf6dfa 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -432,6 +432,10 @@ typedef struct st_mi_check_param const char *db_name, *table_name; const char *op_name; enum_mi_stats_method stats_method; +#ifdef THREAD + pthread_mutex_t print_msg_mutex; + my_bool need_print_msg_lock; +#endif } MI_CHECK; typedef struct st_sort_ft_buf diff --git a/include/mysql.h b/include/mysql.h index 70faf3cb2c1..13060264ee7 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -188,24 +188,10 @@ struct st_mysql_options { unsigned long max_allowed_packet; my_bool use_ssl; /* if to use SSL or not */ my_bool compress,named_pipe; - /* - On connect, find out the replication role of the server, and - establish connections to all the peers - */ - my_bool rpl_probe; - /* - Each call to mysql_real_query() will parse it to tell if it is a read - or a write, and direct it to the slave or the master - */ - my_bool rpl_parse; - /* - If set, never read from a master, only from slave, when doing - a read that is replication-aware - */ - my_bool no_master_reads; -#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY) - my_bool separate_thread; -#endif + my_bool unused1; + my_bool unused2; + my_bool unused3; + my_bool unused4; enum mysql_option methods_to_use; char *client_ip; /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */ @@ -232,15 +218,6 @@ enum mysql_protocol_type MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY }; -/* - There are three types of queries - the ones that have to go to - the master, the ones that go to a slave, and the adminstrative - type which must happen on the pivot connectioin -*/ -enum mysql_rpl_type -{ - MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN -}; typedef struct character_set { @@ -285,21 +262,8 @@ typedef struct st_mysql /* session-wide random string */ char scramble[SCRAMBLE_LENGTH+1]; - - /* - Set if this is the original connection, not a master or a slave we have - added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() - */ - my_bool rpl_pivot; - /* - Pointers to the master, and the next slave connections, points to - itself if lone connection. - */ - struct st_mysql* master, *next_slave; - - struct st_mysql* last_used_slave; /* needed for round-robin slave pick */ - /* needed for send/read/store/use result to work correctly with replication */ - struct st_mysql* last_used_con; + my_bool unused1; + void *unused2, *unused3, *unused4, *unused5; LIST *stmts; /* list of all statements */ const struct st_mysql_methods *methods; @@ -333,35 +297,12 @@ typedef struct st_mysql_res { void *extension; } MYSQL_RES; -#define MAX_MYSQL_MANAGER_ERR 256 -#define MAX_MYSQL_MANAGER_MSG 256 - -#define MANAGER_OK 200 -#define MANAGER_INFO 250 -#define MANAGER_ACCESS 401 -#define MANAGER_CLIENT_ERR 450 -#define MANAGER_INTERNAL_ERR 500 #if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT) #define MYSQL_CLIENT #endif -typedef struct st_mysql_manager -{ - NET net; - char *host, *user, *passwd; - char *net_buf, *net_buf_pos, *net_data_end; - unsigned int port; - int cmd_status; - int last_errno; - int net_buf_size; - my_bool free_me; - my_bool eof; - char last_error[MAX_MYSQL_MANAGER_ERR]; - void *extension; -} MYSQL_MANAGER; - typedef struct st_mysql_parameters { unsigned long *p_max_allowed_packet; @@ -454,16 +395,6 @@ int STDCALL mysql_real_query(MYSQL *mysql, const char *q, MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); -/* perform query on master */ -my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, - unsigned long length); -/* perform query on slave */ -my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, - unsigned long length); void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *charset); @@ -485,37 +416,6 @@ mysql_set_local_infile_handler(MYSQL *mysql, void mysql_set_local_infile_default(MYSQL *mysql); - -/* - enable/disable parsing of all queries to decide if they go on master or - slave -*/ -void STDCALL mysql_enable_rpl_parse(MYSQL* mysql); -void STDCALL mysql_disable_rpl_parse(MYSQL* mysql); -/* get the value of the parse flag */ -int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql); - -/* enable/disable reads from master */ -void STDCALL mysql_enable_reads_from_master(MYSQL* mysql); -void STDCALL mysql_disable_reads_from_master(MYSQL* mysql); -/* get the value of the master read flag */ -my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql); - -enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len); - -/* discover the master and its slaves */ -my_bool STDCALL mysql_rpl_probe(MYSQL* mysql); - -/* set the master, close/free the old one, if it is not a pivot */ -int STDCALL mysql_set_master(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); -int STDCALL mysql_add_slave(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); - int STDCALL mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level); @@ -559,21 +459,19 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, unsigned long length); void STDCALL mysql_debug(const char *debug); +char * STDCALL mysql_odbc_escape_string(MYSQL *mysql, + char *to, + unsigned long to_length, + const char *from, + unsigned long from_length, + void *param, + char * + (*extend_buffer) + (void *, char *to, + unsigned long *length)); void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); unsigned int STDCALL mysql_thread_safe(void); my_bool STDCALL mysql_embedded(void); -MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con); -MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, - const char* host, - const char* user, - const char* passwd, - unsigned int port); -void STDCALL mysql_manager_close(MYSQL_MANAGER* con); -int STDCALL mysql_manager_command(MYSQL_MANAGER* con, - const char* cmd, int cmd_len); -int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, - char* res_buf, - int res_buf_size); my_bool STDCALL mysql_read_query_result(MYSQL *mysql); @@ -768,7 +666,7 @@ typedef struct st_mysql_methods MYSQL_RES * (*use_result)(MYSQL *mysql); void (*fetch_lengths)(unsigned long *to, MYSQL_ROW column, unsigned int field_count); - void (*flush_use_result)(MYSQL *mysql); + void (*flush_use_result)(MYSQL *mysql, my_bool flush_all_results); #if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) MYSQL_FIELD * (*list_fields)(MYSQL *mysql); my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); @@ -828,6 +726,7 @@ my_bool STDCALL mysql_rollback(MYSQL * mysql); my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode); my_bool STDCALL mysql_more_results(MYSQL *mysql); int STDCALL mysql_next_result(MYSQL *mysql); +int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt); void STDCALL mysql_close(MYSQL *sock); @@ -842,7 +741,6 @@ MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd); int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); -#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) #endif #define HAVE_MYSQL_REAL_CONNECT diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 633cde41130..78f026215b9 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -28,15 +28,15 @@ typedef struct st_net { unsigned int *return_status; unsigned char reading_or_writing; char save_char; - my_bool unused0; - my_bool unused; - my_bool compress; my_bool unused1; - unsigned char *query_cache_query; + my_bool unused2; + my_bool compress; + my_bool unused3; + unsigned char *unused; unsigned int last_errno; unsigned char error; - my_bool unused2; - my_bool return_errno; + my_bool unused4; + my_bool unused5; char last_error[512]; char sqlstate[5 +1]; void *extension; @@ -277,10 +277,10 @@ struct st_mysql_options { unsigned long max_allowed_packet; my_bool use_ssl; my_bool compress,named_pipe; - my_bool rpl_probe; - my_bool rpl_parse; - my_bool no_master_reads; - my_bool separate_thread; + my_bool unused1; + my_bool unused2; + my_bool unused3; + my_bool unused4; enum mysql_option methods_to_use; char *client_ip; my_bool secure_auth; @@ -301,10 +301,6 @@ enum mysql_protocol_type MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY }; -enum mysql_rpl_type -{ - MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN -}; typedef struct character_set { unsigned int number; @@ -344,10 +340,8 @@ typedef struct st_mysql my_bool free_me; my_bool reconnect; char scramble[20 +1]; - my_bool rpl_pivot; - struct st_mysql* master, *next_slave; - struct st_mysql* last_used_slave; - struct st_mysql* last_used_con; + my_bool unused1; + void *unused2, *unused3, *unused4, *unused5; LIST *stmts; const struct st_mysql_methods *methods; void *thd; @@ -371,20 +365,6 @@ typedef struct st_mysql_res { my_bool unbuffered_fetch_cancelled; void *extension; } MYSQL_RES; -typedef struct st_mysql_manager -{ - NET net; - char *host, *user, *passwd; - char *net_buf, *net_buf_pos, *net_data_end; - unsigned int port; - int cmd_status; - int last_errno; - int net_buf_size; - my_bool free_me; - my_bool eof; - char last_error[256]; - void *extension; -} MYSQL_MANAGER; typedef struct st_mysql_parameters { unsigned long *p_max_allowed_packet; @@ -437,14 +417,6 @@ int mysql_real_query(MYSQL *mysql, const char *q, unsigned long length); MYSQL_RES * mysql_store_result(MYSQL *mysql); MYSQL_RES * mysql_use_result(MYSQL *mysql); -my_bool mysql_master_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool mysql_master_send_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool mysql_slave_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool mysql_slave_send_query(MYSQL *mysql, const char *q, - unsigned long length); void mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *charset); void @@ -459,22 +431,6 @@ mysql_set_local_infile_handler(MYSQL *mysql, void *); void mysql_set_local_infile_default(MYSQL *mysql); -void mysql_enable_rpl_parse(MYSQL* mysql); -void mysql_disable_rpl_parse(MYSQL* mysql); -int mysql_rpl_parse_enabled(MYSQL* mysql); -void mysql_enable_reads_from_master(MYSQL* mysql); -void mysql_disable_reads_from_master(MYSQL* mysql); -my_bool mysql_reads_from_master_enabled(MYSQL* mysql); -enum mysql_rpl_type mysql_rpl_query_type(const char* q, int len); -my_bool mysql_rpl_probe(MYSQL* mysql); -int mysql_set_master(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); -int mysql_add_slave(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); int mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level); @@ -518,21 +474,19 @@ unsigned long mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, unsigned long length); void mysql_debug(const char *debug); +char * mysql_odbc_escape_string(MYSQL *mysql, + char *to, + unsigned long to_length, + const char *from, + unsigned long from_length, + void *param, + char * + (*extend_buffer) + (void *, char *to, + unsigned long *length)); void myodbc_remove_escape(MYSQL *mysql,char *name); unsigned int mysql_thread_safe(void); my_bool mysql_embedded(void); -MYSQL_MANAGER* mysql_manager_init(MYSQL_MANAGER* con); -MYSQL_MANAGER* mysql_manager_connect(MYSQL_MANAGER* con, - const char* host, - const char* user, - const char* passwd, - unsigned int port); -void mysql_manager_close(MYSQL_MANAGER* con); -int mysql_manager_command(MYSQL_MANAGER* con, - const char* cmd, int cmd_len); -int mysql_manager_fetch_line(MYSQL_MANAGER* con, - char* res_buf, - int res_buf_size); my_bool mysql_read_query_result(MYSQL *mysql); enum enum_mysql_stmt_state { @@ -616,7 +570,7 @@ typedef struct st_mysql_methods MYSQL_RES * (*use_result)(MYSQL *mysql); void (*fetch_lengths)(unsigned long *to, MYSQL_ROW column, unsigned int field_count); - void (*flush_use_result)(MYSQL *mysql); + void (*flush_use_result)(MYSQL *mysql, my_bool flush_all_results); MYSQL_FIELD * (*list_fields)(MYSQL *mysql); my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); int (*stmt_execute)(MYSQL_STMT *stmt); @@ -671,4 +625,5 @@ my_bool mysql_rollback(MYSQL * mysql); my_bool mysql_autocommit(MYSQL * mysql, my_bool auto_mode); my_bool mysql_more_results(MYSQL *mysql); int mysql_next_result(MYSQL *mysql); +int mysql_stmt_next_result(MYSQL_STMT *stmt); void mysql_close(MYSQL *sock); diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 45d0234cb67..f158dc20999 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 MySQL AB +/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc. 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 @@ -16,12 +16,6 @@ #ifndef _my_plugin_h #define _my_plugin_h -/* size_t */ -#include - -typedef struct st_mysql MYSQL; - - /* On Windows, exports from DLL need to be declared */ @@ -39,15 +33,7 @@ class Item; #define MYSQL_THD void* #endif -#ifndef _m_string_h -/* This definition must match the one given in m_string.h */ -struct st_mysql_lex_string -{ - char *str; - unsigned int length; -}; -#endif /* _m_string_h */ -typedef struct st_mysql_lex_string MYSQL_LEX_STRING; +#include #define MYSQL_XIDDATASIZE 128 /** @@ -70,7 +56,7 @@ typedef struct st_mysql_xid MYSQL_XID; Plugin API. Common for all plugin types. */ -#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0100 +#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101 /* The allowable types of plugins @@ -126,7 +112,8 @@ enum enum_mysql_show_type { SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, - SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE + SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, + SHOW_always_last }; struct st_mysql_show_var { @@ -750,54 +737,6 @@ int thd_killed(const MYSQL_THD thd); */ unsigned long thd_get_thread_id(const MYSQL_THD thd); - -/** - Allocate memory in the connection's local memory pool - - @details - When properly used in place of @c my_malloc(), this can significantly - improve concurrency. Don't use this or related functions to allocate - large chunks of memory. Use for temporary storage only. The memory - will be freed automatically at the end of the statement; no explicit - code is required to prevent memory leaks. - - @see alloc_root() -*/ -void *thd_alloc(MYSQL_THD thd, unsigned int size); -/** - @see thd_alloc() -*/ -void *thd_calloc(MYSQL_THD thd, unsigned int size); -/** - @see thd_alloc() -*/ -char *thd_strdup(MYSQL_THD thd, const char *str); -/** - @see thd_alloc() -*/ -char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size); -/** - @see thd_alloc() -*/ -void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size); - -/** - Create a LEX_STRING in this connection's local memory pool - - @param thd user thread connection handle - @param lex_str pointer to LEX_STRING object to be initialized - @param str initializer to be copied into lex_str - @param size length of str, in bytes - @param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object, - instead of using lex_str value - @return NULL on failure, or pointer to the LEX_STRING object - - @see thd_alloc() -*/ -MYSQL_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str, - const char *str, unsigned int size, - int allocate_lex_string); - /** Get the XID for this connection's transaction @@ -818,64 +757,6 @@ void mysql_query_cache_invalidate4(MYSQL_THD thd, const char *key, unsigned int key_length, int using_trx); -/** - Get the value of user variable as an integer. - - This function will return the value of variable @a name as an - integer. If the original value of the variable is not an integer, - the value will be converted into an integer. - - @param name user variable name - @param value pointer to return the value - @param null_value if not NULL, the function will set it to true if - the value of variable is null, set to false if not - - @retval 0 Success - @retval 1 Variable not found -*/ -int get_user_var_int(const char *name, - long long int *value, int *null_value); - -/** - Get the value of user variable as a double precision float number. - - This function will return the value of variable @a name as real - number. If the original value of the variable is not a real number, - the value will be converted into a real number. - - @param name user variable name - @param value pointer to return the value - @param null_value if not NULL, the function will set it to true if - the value of variable is null, set to false if not - - @retval 0 Success - @retval 1 Variable not found -*/ -int get_user_var_real(const char *name, - double *value, int *null_value); - -/** - Get the value of user variable as a string. - - This function will return the value of variable @a name as - string. If the original value of the variable is not a string, - the value will be converted into a string. - - @param name user variable name - @param value pointer to the value buffer - @param len length of the value buffer - @param precision precision of the value if it is a float number - @param null_value if not NULL, the function will set it to true if - the value of variable is null, set to false if not - - @retval 0 Success - @retval 1 Variable not found -*/ -int get_user_var_str(const char *name, - char *value, unsigned long len, - unsigned int precision, int *null_value); - - #ifdef __cplusplus } #endif diff --git a/include/mysql/plugin.h.pp b/include/mysql/plugin.h.pp index d864140333b..b7dd7bc0032 100644 --- a/include/mysql/plugin.h.pp +++ b/include/mysql/plugin.h.pp @@ -1,11 +1,38 @@ +#include +#include +#include +#include +extern struct my_snprintf_service_st { + size_t (*my_snprintf_type)(char*, size_t, const char*, ...); + size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list); +} *my_snprintf_service; +size_t my_snprintf(char* to, size_t n, const char* fmt, ...); +size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap); +#include #include -typedef struct st_mysql MYSQL; struct st_mysql_lex_string { char *str; - unsigned int length; + size_t length; }; typedef struct st_mysql_lex_string MYSQL_LEX_STRING; +extern struct thd_alloc_service_st { + void *(*thd_alloc_func)(void*, unsigned int); + void *(*thd_calloc_func)(void*, unsigned int); + char *(*thd_strdup_func)(void*, const char *); + char *(*thd_strmake_func)(void*, const char *, unsigned int); + void *(*thd_memdup_func)(void*, const void*, unsigned int); + MYSQL_LEX_STRING *(*thd_make_lex_string_func)(void*, MYSQL_LEX_STRING *, + const char *, unsigned int, int); +} *thd_alloc_service; +void *thd_alloc(void* thd, unsigned int size); +void *thd_calloc(void* thd, unsigned int size); +char *thd_strdup(void* thd, const char *str); +char *thd_strmake(void* thd, const char *str, unsigned int size); +void *thd_memdup(void* thd, const void* str, unsigned int size); +MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, + const char *str, unsigned int size, + int allocate_lex_string); struct st_mysql_xid { long formatID; long gtrid_length; @@ -17,7 +44,8 @@ enum enum_mysql_show_type { SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, - SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE + SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, + SHOW_always_last }; struct st_mysql_show_var { const char *name; @@ -107,9 +135,9 @@ struct st_mysql_information_schema { int interface_version; }; -struct Mysql_replication { - int interface_version; -}; + struct Mysql_replication { + int interface_version; + }; struct st_mysql_value { int (*value_type)(struct st_mysql_value *); @@ -130,22 +158,7 @@ void thd_inc_row_count(void* thd); int mysql_tmpfile(const char *prefix); int thd_killed(const void* thd); unsigned long thd_get_thread_id(const void* thd); -void *thd_alloc(void* thd, unsigned int size); -void *thd_calloc(void* thd, unsigned int size); -char *thd_strdup(void* thd, const char *str); -char *thd_strmake(void* thd, const char *str, unsigned int size); -void *thd_memdup(void* thd, const void* str, unsigned int size); -MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str, - const char *str, unsigned int size, - int allocate_lex_string); void thd_get_xid(const void* thd, MYSQL_XID *xid); void mysql_query_cache_invalidate4(void* thd, const char *key, unsigned int key_length, int using_trx); -int get_user_var_int(const char *name, - long long int *value, int *null_value); -int get_user_var_real(const char *name, - double *value, int *null_value); -int get_user_var_str(const char *name, - char *value, unsigned long len, - unsigned int precision, int *null_value); diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h new file mode 100644 index 00000000000..ad344864c34 --- /dev/null +++ b/include/mysql/service_my_snprintf.h @@ -0,0 +1,98 @@ +#ifndef MYSQL_SERVICE_MY_SNPRINTF_INCLUDED +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + my_snprintf service + + Portable and limited vsnprintf() implementation. + + This is a portable, limited vsnprintf() implementation, with some + extra features. "Portable" means that it'll produce identical result + on all platforms (for example, on Windows and Linux system printf %e + formats the exponent differently, on different systems %p either + prints leading 0x or not, %s may accept null pointer or crash on + it). "Limited" means that it does not support all the C89 features. + But it supports few extensions, not in any standard. + + my_vsnprintf(to, n, fmt, ap) + + @param[out] to A buffer to store the result in + @param[in] n Store up to n-1 characters, followed by an end 0 + @param[in] fmt printf-like format string + @param[in] ap Arguments + + @return a number of bytes written to a buffer *excluding* terminating '\0' + + @post + The syntax of a format string is generally the same: + % + where everithing but the format is optional. + + Three one-character flags are recognized: + '0' has the standard zero-padding semantics; + '-' is parsed, but silently ignored; + '`' (backtick) is only supported for strings (%s) and means that the + string will be quoted according to MySQL identifier quoting rules. + + Both and can be specified as numbers or '*'. + + can be 'l', 'll', or 'z'. + + Supported formats are 's' (null pointer is accepted, printed as + "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', + 'X', 'p' (works as 0x%x). + + Standard syntax for positional arguments $n is supported. + + Extensions: + + Flag '`' (backtick): see above. + + Format 'b': binary buffer, prints exactly bytes from the + argument, without stopping at '\0'. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +extern struct my_snprintf_service_st { + size_t (*my_snprintf_type)(char*, size_t, const char*, ...); + size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list); +} *my_snprintf_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +#define my_vsnprintf my_snprintf_service->my_vsnprintf_type +#define my_snprintf my_snprintf_service->my_snprintf_type + +#else + +size_t my_snprintf(char* to, size_t n, const char* fmt, ...); +size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap); + +#endif + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICE_MY_SNPRINTF_INCLUDED +#endif + diff --git a/include/mysql/service_thd_alloc.h b/include/mysql/service_thd_alloc.h new file mode 100644 index 00000000000..86158ba1359 --- /dev/null +++ b/include/mysql/service_thd_alloc.h @@ -0,0 +1,128 @@ +#ifndef MYSQL_SERVICE_THD_ALLOC_INCLUDED +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + @file + This service provdes functions to allocate memory in a connection local + memory pool. The memory allocated there will be automatically freed at the + end of the statement, don't use it for allocations that should live longer + than that. For short living allocations this is more efficient than + using my_malloc and friends, and automatic "garbage collection" allows not + to think about memory leaks. + + The pool is best for small to medium objects, don't use it for large + allocations - they are better served with my_malloc. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct st_mysql_lex_string +{ + char *str; + size_t length; +}; +typedef struct st_mysql_lex_string MYSQL_LEX_STRING; + +extern struct thd_alloc_service_st { + void *(*thd_alloc_func)(MYSQL_THD, unsigned int); + void *(*thd_calloc_func)(MYSQL_THD, unsigned int); + char *(*thd_strdup_func)(MYSQL_THD, const char *); + char *(*thd_strmake_func)(MYSQL_THD, const char *, unsigned int); + void *(*thd_memdup_func)(MYSQL_THD, const void*, unsigned int); + MYSQL_LEX_STRING *(*thd_make_lex_string_func)(MYSQL_THD, MYSQL_LEX_STRING *, + const char *, unsigned int, int); +} *thd_alloc_service; + +#ifdef MYSQL_DYNAMIC_PLUGIN + +#define thd_alloc(thd,size) (thd_alloc_service->thd_alloc_func((thd), (size))) + +#define thd_calloc(thd,size) (thd_alloc_service->thd_calloc_func((thd), (size))) + +#define thd_strdup(thd,str) (thd_alloc_service->thd_strdup_func((thd), (str))) + +#define thd_strmake(thd,str,size) \ + (thd_alloc_service->thd_strmake_func((thd), (str), (size))) + +#define thd_memdup(thd,str,size) \ + (thd_alloc_service->thd_memdup_func((thd), (str), (size))) + +#define thd_make_lex_string(thd, lex_str, str, size, allocate_lex_string) \ + (thd_alloc_service->thd_make_lex_string_func((thd), (lex_str), (str), \ + (size), (allocate_lex_string))) + +#else + +/** + Allocate memory in the connection's local memory pool + + @details + When properly used in place of @c my_malloc(), this can significantly + improve concurrency. Don't use this or related functions to allocate + large chunks of memory. Use for temporary storage only. The memory + will be freed automatically at the end of the statement; no explicit + code is required to prevent memory leaks. + + @see alloc_root() +*/ +void *thd_alloc(MYSQL_THD thd, unsigned int size); +/** + @see thd_alloc() +*/ +void *thd_calloc(MYSQL_THD thd, unsigned int size); +/** + @see thd_alloc() +*/ +char *thd_strdup(MYSQL_THD thd, const char *str); +/** + @see thd_alloc() +*/ +char *thd_strmake(MYSQL_THD thd, const char *str, unsigned int size); +/** + @see thd_alloc() +*/ +void *thd_memdup(MYSQL_THD thd, const void* str, unsigned int size); + +/** + Create a LEX_STRING in this connection's local memory pool + + @param thd user thread connection handle + @param lex_str pointer to LEX_STRING object to be initialized + @param str initializer to be copied into lex_str + @param size length of str, in bytes + @param allocate_lex_string flag: if TRUE, allocate new LEX_STRING object, + instead of using lex_str value + @return NULL on failure, or pointer to the LEX_STRING object + + @see thd_alloc() +*/ +MYSQL_LEX_STRING *thd_make_lex_string(MYSQL_THD thd, MYSQL_LEX_STRING *lex_str, + const char *str, unsigned int size, + int allocate_lex_string); + +#endif + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICE_THD_ALLOC_INCLUDED +#endif + diff --git a/include/mysql/services.h b/include/mysql/services.h new file mode 100644 index 00000000000..19003e66b96 --- /dev/null +++ b/include/mysql/services.h @@ -0,0 +1,30 @@ +#ifndef MYSQL_SERVICES_INCLUDED +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#ifdef __cplusplus +} +#endif + +#define MYSQL_SERVICES_INCLUDED +#endif + diff --git a/include/mysql_com.h b/include/mysql_com.h index 4ffcd658d7b..345ecd5dd93 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -146,6 +146,7 @@ enum enum_server_command #define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ #define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ #define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ +#define CLIENT_PS_MULTI_RESULTS (1UL << 18) /* Multi-results in PS-protocol */ #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) #define CLIENT_REMEMBER_OPTIONS (1UL << 31) @@ -169,6 +170,7 @@ enum enum_server_command CLIENT_SECURE_CONNECTION | \ CLIENT_MULTI_STATEMENTS | \ CLIENT_MULTI_RESULTS | \ + CLIENT_PS_MULTI_RESULTS | \ CLIENT_SSL_VERIFY_SERVER_CERT | \ CLIENT_REMEMBER_OPTIONS) @@ -207,6 +209,11 @@ enum enum_server_command #define SERVER_STATUS_METADATA_CHANGED 1024 #define SERVER_QUERY_WAS_SLOW 2048 +/** + To mark ResultSet containing output parameter values. +*/ +#define SERVER_PS_OUT_PARAMS 4096 + /** Server status flags that must be cleared when starting execution of a new SQL statement. @@ -257,24 +264,23 @@ typedef struct st_net { unsigned int *return_status; unsigned char reading_or_writing; char save_char; - my_bool unused0; /* Please remove with the next incompatible ABI change. */ - my_bool unused; /* Please remove with the next incompatible ABI change */ - my_bool compress; my_bool unused1; /* Please remove with the next incompatible ABI change. */ + my_bool unused2; /* Please remove with the next incompatible ABI change */ + my_bool compress; + my_bool unused3; /* Please remove with the next incompatible ABI change. */ /* Pointer to query object in query cache, do not equal NULL (0) for queries in cache that have not stored its results yet */ #endif /* - 'query_cache_query' should be accessed only via query cache - functions and methods to maintain proper locking. + Unused, please remove with the next incompatible ABI change. */ - unsigned char *query_cache_query; + unsigned char *unused; unsigned int last_errno; unsigned char error; - my_bool unused2; /* Please remove with the next incompatible ABI change. */ - my_bool return_errno; + my_bool unused4; /* Please remove with the next incompatible ABI change. */ + my_bool unused5; /* Please remove with the next incompatible ABI change. */ /** Client library error message buffer. Actually belongs to struct MYSQL. */ char last_error[MYSQL_ERRMSG_SIZE]; /** Client library sqlstate buffer. Set along with the error message. */ @@ -412,10 +418,6 @@ void my_net_set_write_timeout(NET *net, uint timeout); void my_net_set_read_timeout(NET *net, uint timeout); #endif -/* - The following function is not meant for normal usage - Currently it's used internally by manager.c -*/ struct sockaddr; int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen, unsigned int timeout); diff --git a/include/service_versions.h b/include/service_versions.h new file mode 100644 index 00000000000..114957cdd86 --- /dev/null +++ b/include/service_versions.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef _WIN32 +#define SERVICE_VERSION __declspec(dllexport) void * +#else +#define SERVICE_VERSION void * +#endif + +#define VERSION_my_snprintf 0x0100 +#define VERSION_thd_alloc 0x0100 + diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt index 805551b7ee3..84ad50e03e3 100755 --- a/libmysql/CMakeLists.txt +++ b/libmysql/CMakeLists.txt @@ -73,7 +73,7 @@ SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c ../mysys/hash.c ../mysys/my_sleep.c ../mysys/default_modify.c get_password.c ../strings/int2str.c ../strings/is_prefix.c libmysql.c ../mysys/list.c ../strings/llstr.c - ../strings/longlong2str.c manager.c ../mysys/mf_arr_appstr.c ../mysys/mf_cache.c + ../strings/longlong2str.c ../mysys/mf_arr_appstr.c ../mysys/mf_cache.c ../mysys/mf_dirname.c ../mysys/mf_fn_ext.c ../mysys/mf_format.c ../mysys/mf_iocache.c ../mysys/mf_iocache2.c ../mysys/mf_loadpath.c ../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index eb4fd75ed11..acc709bfb89 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -31,7 +31,7 @@ pkglib_LTLIBRARIES = $(target) noinst_PROGRAMS = conf_to_src -target_sources = libmysql.c password.c manager.c \ +target_sources = libmysql.c password.c \ get_password.c errmsg.c mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \ diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index 1fd8619a746..aaec08d1b1e 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -22,9 +22,13 @@ extern uint mysql_port; extern char * mysql_unix_port; -#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | \ - CLIENT_TRANSACTIONS | \ - CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION) +#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | \ + CLIENT_LONG_FLAG | \ + CLIENT_TRANSACTIONS | \ + CLIENT_PROTOCOL_41 | \ + CLIENT_SECURE_CONNECTION | \ + CLIENT_MULTI_RESULTS | \ + CLIENT_PS_MULTI_RESULTS) sig_handler my_pipe_sig_handler(int sig); void read_user_name(char *name); diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c index 6e7f3ef48d3..d0ed44bd7aa 100644 --- a/libmysql/errmsg.c +++ b/libmysql/errmsg.c @@ -85,6 +85,7 @@ const char *client_errors[]= "Lost connection to MySQL server at '%s', system error: %d", "Statement closed indirectly because of a preceeding %s() call", "The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again", + "This handle is already connected. Use a separate handle for each connection." "" }; @@ -151,6 +152,7 @@ const char *client_errors[]= "Lost connection to MySQL server at '%s', system error: %d", "Statement closed indirectly because of a preceeding %s() call", "The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again", + "This handle is already connected. Use a separate handle for each connection." "" }; @@ -215,6 +217,7 @@ const char *client_errors[]= "Lost connection to MySQL server at '%s', system error: %d", "Statement closed indirectly because of a preceeding %s() call", "The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again", + "This handle is already connected. Use a separate handle for each connection." "" }; #endif diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 1264f2765ba..477830a6ebd 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -131,7 +131,7 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)), mysql_port = MYSQL_PORT; #ifndef MSDOS { - struct servent *serv_ptr; + struct servent *serv_ptr __attribute__((unused)); char *env; /* @@ -249,16 +249,6 @@ void STDCALL mysql_thread_end() #endif } -/* - Let the user specify that we don't want SIGPIPE; This doesn't however work - with threaded applications as we can have multiple read in progress. -*/ -static MYSQL* spawn_init(MYSQL* parent, const char* host, - unsigned int port, - const char* user, - const char* passwd); - - /* Expand wildcard to a sql string @@ -320,7 +310,7 @@ mysql_debug(const char *debug __attribute__((unused))) /************************************************************************** - Close the server connection if we get a SIGPIPE + Ignore SIGPIPE handler ARGSUSED **************************************************************************/ @@ -333,305 +323,6 @@ my_pipe_sig_handler(int sig __attribute__((unused))) #endif } -/* perform query on master */ -my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, - unsigned long length) -{ - DBUG_ENTER("mysql_master_query"); - if (mysql_master_send_query(mysql, q, length)) - DBUG_RETURN(1); - DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); -} - -my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, - unsigned long length) -{ - MYSQL *master = mysql->master; - DBUG_ENTER("mysql_master_send_query"); - if (!master->net.vio && !mysql_real_connect(master,0,0,0,0,0,0,0)) - DBUG_RETURN(1); - master->reconnect= 1; - mysql->last_used_con = master; - DBUG_RETURN(simple_command(master, COM_QUERY, (const uchar*) q, length, 1)); -} - - -/* perform query on slave */ -my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, - unsigned long length) -{ - DBUG_ENTER("mysql_slave_query"); - if (mysql_slave_send_query(mysql, q, length)) - DBUG_RETURN(1); - DBUG_RETURN((*mysql->methods->read_query_result)(mysql)); -} - - -my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, - unsigned long length) -{ - MYSQL* last_used_slave, *slave_to_use = 0; - DBUG_ENTER("mysql_slave_send_query"); - - if ((last_used_slave = mysql->last_used_slave)) - slave_to_use = last_used_slave->next_slave; - else - slave_to_use = mysql->next_slave; - /* - Next_slave is always safe to use - we have a circular list of slaves - if there are no slaves, mysql->next_slave == mysql - */ - mysql->last_used_con = mysql->last_used_slave = slave_to_use; - if (!slave_to_use->net.vio && !mysql_real_connect(slave_to_use, 0,0,0, - 0,0,0,0)) - DBUG_RETURN(1); - slave_to_use->reconnect= 1; - DBUG_RETURN(simple_command(slave_to_use, COM_QUERY, (const uchar*) q, - length, 1)); -} - - -/* enable/disable parsing of all queries to decide - if they go on master or slave */ -void STDCALL mysql_enable_rpl_parse(MYSQL* mysql) -{ - mysql->options.rpl_parse = 1; -} - -void STDCALL mysql_disable_rpl_parse(MYSQL* mysql) -{ - mysql->options.rpl_parse = 0; -} - -/* get the value of the parse flag */ -int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql) -{ - return mysql->options.rpl_parse; -} - -/* enable/disable reads from master */ -void STDCALL mysql_enable_reads_from_master(MYSQL* mysql) -{ - mysql->options.no_master_reads = 0; -} - -void STDCALL mysql_disable_reads_from_master(MYSQL* mysql) -{ - mysql->options.no_master_reads = 1; -} - -/* get the value of the master read flag */ -my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql) -{ - return !(mysql->options.no_master_reads); -} - - -/* - We may get an error while doing replication internals. - In this case, we add a special explanation to the original - error -*/ - -static void expand_error(MYSQL* mysql, int error) -{ - char tmp[MYSQL_ERRMSG_SIZE]; - char *p; - uint err_length; - strmake(tmp, mysql->net.last_error, MYSQL_ERRMSG_SIZE-1); - p = strmake(mysql->net.last_error, ER(error), MYSQL_ERRMSG_SIZE-1); - err_length= (uint) (p - mysql->net.last_error); - strmake(p, tmp, MYSQL_ERRMSG_SIZE-1 - err_length); - mysql->net.last_errno = error; -} - -/* - This function assumes we have just called SHOW SLAVE STATUS and have - read the given result and row -*/ - -static my_bool get_master(MYSQL* mysql, MYSQL_RES* res, MYSQL_ROW row) -{ - MYSQL* master; - DBUG_ENTER("get_master"); - if (mysql_num_fields(res) < 3) - DBUG_RETURN(1); /* safety */ - - /* use the same username and password as the original connection */ - if (!(master = spawn_init(mysql, row[0], atoi(row[2]), 0, 0))) - DBUG_RETURN(1); - mysql->master = master; - DBUG_RETURN(0); -} - - -/* - Assuming we already know that mysql points to a master connection, - retrieve all the slaves -*/ - -static my_bool get_slaves_from_master(MYSQL* mysql) -{ - MYSQL_RES* res = 0; - MYSQL_ROW row; - my_bool error = 1; - int has_auth_info; - int port_ind; - DBUG_ENTER("get_slaves_from_master"); - - if (!mysql->net.vio && !mysql_real_connect(mysql,0,0,0,0,0,0,0)) - { - expand_error(mysql, CR_PROBE_MASTER_CONNECT); - DBUG_RETURN(1); - } - mysql->reconnect= 1; - - if (mysql_query(mysql, "SHOW SLAVE HOSTS") || - !(res = mysql_store_result(mysql))) - { - expand_error(mysql, CR_PROBE_SLAVE_HOSTS); - DBUG_RETURN(1); - } - - switch (mysql_num_fields(res)) { - case 5: - has_auth_info = 0; - port_ind=2; - break; - case 7: - has_auth_info = 1; - port_ind=4; - break; - default: - goto err; - } - - while ((row = mysql_fetch_row(res))) - { - MYSQL* slave; - const char* tmp_user, *tmp_pass; - - if (has_auth_info) - { - tmp_user = row[2]; - tmp_pass = row[3]; - } - else - { - tmp_user = mysql->user; - tmp_pass = mysql->passwd; - } - - if (!(slave = spawn_init(mysql, row[1], atoi(row[port_ind]), - tmp_user, tmp_pass))) - goto err; - - /* Now add slave into the circular linked list */ - slave->next_slave = mysql->next_slave; - mysql->next_slave = slave; - } - error = 0; -err: - if (res) - mysql_free_result(res); - DBUG_RETURN(error); -} - - -my_bool STDCALL mysql_rpl_probe(MYSQL* mysql) -{ - MYSQL_RES *res= 0; - MYSQL_ROW row; - my_bool error= 1; - DBUG_ENTER("mysql_rpl_probe"); - - /* - First determine the replication role of the server we connected to - the most reliable way to do this is to run SHOW SLAVE STATUS and see - if we have a non-empty master host. This is still not fool-proof - - it is not a sin to have a master that has a dormant slave thread with - a non-empty master host. However, it is more reliable to check - for empty master than whether the slave thread is actually running - */ - if (mysql_query(mysql, "SHOW SLAVE STATUS") || - !(res = mysql_store_result(mysql))) - { - expand_error(mysql, CR_PROBE_SLAVE_STATUS); - DBUG_RETURN(1); - } - - row= mysql_fetch_row(res); - /* - Check master host for emptiness/NULL - For MySQL 4.0 it's enough to check for row[0] - */ - if (row && row[0] && *(row[0])) - { - /* this is a slave, ask it for the master */ - if (get_master(mysql, res, row) || get_slaves_from_master(mysql)) - goto err; - } - else - { - mysql->master = mysql; - if (get_slaves_from_master(mysql)) - goto err; - } - - error = 0; -err: - if (res) - mysql_free_result(res); - DBUG_RETURN(error); -} - - -/* - Make a not so fool-proof decision on where the query should go, to - the master or the slave. Ideally the user should always make this - decision himself with mysql_master_query() or mysql_slave_query(). - However, to be able to more easily port the old code, we support the - option of an educated guess - this should work for most applications, - however, it may make the wrong decision in some particular cases. If - that happens, the user would have to change the code to call - mysql_master_query() or mysql_slave_query() explicitly in the place - where we have made the wrong decision -*/ - -enum mysql_rpl_type -STDCALL mysql_rpl_query_type(const char* q, int len) -{ - const char *q_end= q + len; - for (; q < q_end; ++q) - { - char c; - if (my_isalpha(&my_charset_latin1, (c= *q))) - { - switch (my_tolower(&my_charset_latin1,c)) { - case 'i': /* insert */ - case 'u': /* update or unlock tables */ - case 'l': /* lock tables or load data infile */ - case 'd': /* drop or delete */ - case 'a': /* alter */ - return MYSQL_RPL_MASTER; - case 'c': /* create or check */ - return my_tolower(&my_charset_latin1,q[1]) == 'h' ? MYSQL_RPL_ADMIN : - MYSQL_RPL_MASTER; - case 's': /* select or show */ - return my_tolower(&my_charset_latin1,q[1]) == 'h' ? MYSQL_RPL_ADMIN : - MYSQL_RPL_SLAVE; - case 'f': /* flush */ - case 'r': /* repair */ - case 'g': /* grant */ - return MYSQL_RPL_ADMIN; - default: - return MYSQL_RPL_SLAVE; - } - } - } - return MYSQL_RPL_MASTER; /* By default, send to master */ -} - /************************************************************************** Connect to sql server @@ -1093,68 +784,6 @@ mysql_query(MYSQL *mysql, const char *query) } -static MYSQL* spawn_init(MYSQL* parent, const char* host, - unsigned int port, const char* user, - const char* passwd) -{ - MYSQL* child; - DBUG_ENTER("spawn_init"); - if (!(child= mysql_init(0))) - DBUG_RETURN(0); - - child->options.user= my_strdup((user) ? user : - (parent->user ? parent->user : - parent->options.user), MYF(0)); - child->options.password= my_strdup((passwd) ? passwd : - (parent->passwd ? - parent->passwd : - parent->options.password), MYF(0)); - child->options.port= port; - child->options.host= my_strdup((host) ? host : - (parent->host ? - parent->host : - parent->options.host), MYF(0)); - if (parent->db) - child->options.db= my_strdup(parent->db, MYF(0)); - else if (parent->options.db) - child->options.db= my_strdup(parent->options.db, MYF(0)); - - /* - rpl_pivot is set to 1 in mysql_init(); Reset it as we are not doing - replication here - */ - child->rpl_pivot= 0; - DBUG_RETURN(child); -} - - -int -STDCALL mysql_set_master(MYSQL* mysql, const char* host, - unsigned int port, const char* user, - const char* passwd) -{ - if (mysql->master != mysql && !mysql->master->rpl_pivot) - mysql_close(mysql->master); - if (!(mysql->master = spawn_init(mysql, host, port, user, passwd))) - return 1; - return 0; -} - - -int -STDCALL mysql_add_slave(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd) -{ - MYSQL* slave; - if (!(slave = spawn_init(mysql, host, port, user, passwd))) - return 1; - slave->next_slave = mysql->next_slave; - mysql->next_slave = slave; - return 0; -} - /************************************************************************** Return next field of the query results **************************************************************************/ @@ -1483,17 +1112,17 @@ MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res) unsigned int STDCALL mysql_field_count(MYSQL *mysql) { - return mysql->last_used_con->field_count; + return mysql->field_count; } my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql) { - return mysql->last_used_con->affected_rows; + return mysql->affected_rows; } my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql) { - return mysql->last_used_con->insert_id; + return mysql->insert_id; } const char *STDCALL mysql_sqlstate(MYSQL *mysql) @@ -1629,6 +1258,20 @@ mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length); } + +char * STDCALL +mysql_odbc_escape_string(MYSQL *mysql __attribute__((unused)), + char *to __attribute__((unused)), + ulong to_length __attribute__((unused)), + const char *from __attribute__((unused)), + ulong from_length __attribute__((unused)), + void *param __attribute__((unused)), + char * (*extend_buffer)(void *, char *, ulong *) + __attribute__((unused))) +{ + return NULL; +} + void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name) { @@ -1858,7 +1501,6 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) MYSQL_DATA *fields_data; DBUG_ENTER("cli_read_prepare_result"); - mysql= mysql->last_used_con; if ((packet_length= cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); mysql->warning_count= 0; @@ -2092,7 +1734,9 @@ static void alloc_stmt_fields(MYSQL_STMT *stmt) { MYSQL_FIELD *fields, *field, *end; MEM_ROOT *alloc= &stmt->mem_root; - MYSQL *mysql= stmt->mysql->last_used_con; + MYSQL *mysql= stmt->mysql; + + DBUG_ASSERT(mysql->field_count); stmt->field_count= mysql->field_count; @@ -2115,18 +1759,21 @@ static void alloc_stmt_fields(MYSQL_STMT *stmt) field= stmt->fields; field && fields < end; fields++, field++) { - field->db = strdup_root(alloc,fields->db); - field->table = strdup_root(alloc,fields->table); - field->org_table= strdup_root(alloc,fields->org_table); - field->name = strdup_root(alloc,fields->name); - field->org_name = strdup_root(alloc,fields->org_name); - field->charsetnr= fields->charsetnr; - field->length = fields->length; - field->type = fields->type; - field->flags = fields->flags; - field->decimals = fields->decimals; - field->def = fields->def ? strdup_root(alloc,fields->def): 0; - field->max_length= 0; + *field= *fields; /* To copy all numeric parts. */ + field->catalog= strmake_root(alloc, fields->catalog, + fields->catalog_length); + field->db= strmake_root(alloc, fields->db, fields->db_length); + field->table= strmake_root(alloc, fields->table, fields->table_length); + field->org_table= strmake_root(alloc, fields->org_table, + fields->org_table_length); + field->name= strmake_root(alloc, fields->name, fields->name_length); + field->org_name= strmake_root(alloc, fields->org_name, + fields->org_name_length); + field->def= fields->def ? strmake_root(alloc, fields->def, + fields->def_length) : 0; + field->def_length= field->def ? fields->def_length : 0; + field->extension= 0; /* Avoid dangling links. */ + field->max_length= 0; /* max_length is set in mysql_stmt_store_result() */ } } @@ -2479,7 +2126,6 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length) DBUG_ENTER("execute"); DBUG_DUMP("packet", (uchar *) packet, length); - mysql->last_used_con= mysql; int4store(buff, stmt->stmt_id); /* Send stmt id to server */ buff[4]= (char) stmt->flags; int4store(buff+5, 1); /* iteration count */ @@ -2854,6 +2500,33 @@ static void reinit_result_set_metadata(MYSQL_STMT *stmt) } +static void prepare_to_fetch_result(MYSQL_STMT *stmt) +{ + if (stmt->server_status & SERVER_STATUS_CURSOR_EXISTS) + { + stmt->mysql->status= MYSQL_STATUS_READY; + stmt->read_row_func= stmt_read_row_from_cursor; + } + else if (stmt->flags & CURSOR_TYPE_READ_ONLY) + { + /* + This is a single-row result set, a result set with no rows, EXPLAIN, + SHOW VARIABLES, or some other command which either a) bypasses the + cursors framework in the server and writes rows directly to the + network or b) is more efficient if all (few) result set rows are + precached on client and server's resources are freed. + */ + mysql_stmt_store_result(stmt); + } + else + { + stmt->mysql->unbuffered_fetch_owner= &stmt->unbuffered_fetch_cancelled; + stmt->unbuffered_fetch_cancelled= FALSE; + stmt->read_row_func= stmt_read_row_unbuffered; + } +} + + /* Send placeholders data to server (if there are placeholders) and execute prepared statement. @@ -2921,28 +2594,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt) if (mysql->field_count) { reinit_result_set_metadata(stmt); - if (stmt->server_status & SERVER_STATUS_CURSOR_EXISTS) - { - mysql->status= MYSQL_STATUS_READY; - stmt->read_row_func= stmt_read_row_from_cursor; - } - else if (stmt->flags & CURSOR_TYPE_READ_ONLY) - { - /* - This is a single-row result set, a result set with no rows, EXPLAIN, - SHOW VARIABLES, or some other command which either a) bypasses the - cursors framework in the server and writes rows directly to the - network or b) is more efficient if all (few) result set rows are - precached on client and server's resources are freed. - */ - mysql_stmt_store_result(stmt); - } - else - { - stmt->mysql->unbuffered_fetch_owner= &stmt->unbuffered_fetch_cancelled; - stmt->unbuffered_fetch_cancelled= FALSE; - stmt->read_row_func= stmt_read_row_unbuffered; - } + prepare_to_fetch_result(stmt); } DBUG_RETURN(test(stmt->last_errno)); } @@ -4407,7 +4059,6 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field) field->max_length= 10; /* 2003-11-11 */ param->skip_result= skip_result_with_length; break; - break; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: param->skip_result= skip_result_with_length; @@ -4689,7 +4340,6 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) } net = &mysql->net; - mysql= mysql->last_used_con; while ((pkt_len= cli_safe_read(mysql)) != packet_error) { @@ -4787,8 +4437,6 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) DBUG_RETURN(1); } - mysql= mysql->last_used_con; - if (!stmt->field_count) DBUG_RETURN(0); @@ -4990,7 +4638,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags) if (stmt->field_count && mysql->status != MYSQL_STATUS_READY) { /* There is a result set and it belongs to this statement */ - (*mysql->methods->flush_use_result)(mysql); + (*mysql->methods->flush_use_result)(mysql, FALSE); if (mysql->unbuffered_fetch_owner) *mysql->unbuffered_fetch_owner= TRUE; mysql->status= MYSQL_STATUS_READY; @@ -5074,7 +4722,7 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt) Flush result set of the connection. If it does not belong to this statement, set a warning. */ - (*mysql->methods->flush_use_result)(mysql); + (*mysql->methods->flush_use_result)(mysql, TRUE); if (mysql->unbuffered_fetch_owner) *mysql->unbuffered_fetch_owner= TRUE; mysql->status= MYSQL_STATUS_READY; @@ -5193,8 +4841,7 @@ my_bool STDCALL mysql_more_results(MYSQL *mysql) my_bool res; DBUG_ENTER("mysql_more_results"); - res= ((mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) ? - 1: 0); + res= ((mysql->server_status & SERVER_MORE_RESULTS_EXISTS) ? 1: 0); DBUG_PRINT("exit",("More results exists ? %d", res)); DBUG_RETURN(res); } @@ -5216,13 +4863,56 @@ int STDCALL mysql_next_result(MYSQL *mysql) net_clear_error(&mysql->net); mysql->affected_rows= ~(my_ulonglong) 0; - if (mysql->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) + if (mysql->server_status & SERVER_MORE_RESULTS_EXISTS) DBUG_RETURN((*mysql->methods->next_result)(mysql)); DBUG_RETURN(-1); /* No more results */ } +int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt) +{ + MYSQL *mysql= stmt->mysql; + int rc; + DBUG_ENTER("mysql_stmt_next_result"); + + if (!mysql) + DBUG_RETURN(1); + + if (stmt->last_errno) + DBUG_RETURN(stmt->last_errno); + + if (mysql->server_status & SERVER_MORE_RESULTS_EXISTS) + { + if (reset_stmt_handle(stmt, RESET_STORE_RESULT)) + DBUG_RETURN(1); + } + + rc= mysql_next_result(mysql); + + if (rc) + { + set_stmt_errmsg(stmt, &mysql->net); + DBUG_RETURN(rc); + } + + stmt->state= MYSQL_STMT_EXECUTE_DONE; + stmt->bind_result_done= FALSE; + + if (mysql->field_count) + { + alloc_stmt_fields(stmt); + prepare_to_fetch_result(stmt); + } + else + { + stmt->field_count= mysql->field_count; + } + + DBUG_RETURN(0); +} + + MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql) { return (*mysql->methods->use_result)(mysql); diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index 81f86dc8726..e435a14b005 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -78,6 +78,7 @@ EXPORTS mysql_next_result mysql_num_fields mysql_num_rows + mysql_odbc_escape_string mysql_options mysql_stmt_param_count mysql_stmt_param_metadata @@ -135,15 +136,6 @@ EXPORTS client_errors mysql_set_local_infile_default mysql_set_local_infile_handler - mysql_disable_reads_from_master - mysql_disable_rpl_parse - mysql_enable_reads_from_master - mysql_enable_rpl_parse - mysql_master_query - mysql_rpl_parse_enabled - mysql_rpl_probe - mysql_rpl_query_type - mysql_slave_query mysql_embedded mysql_server_init mysql_server_end diff --git a/libmysql/manager.c b/libmysql/manager.c deleted file mode 100644 index 53ffffa55c0..00000000000 --- a/libmysql/manager.c +++ /dev/null @@ -1,269 +0,0 @@ -/* Copyright (C) 2000-2004 MySQL AB - - 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 - the Free Software Foundation. - - There are special exceptions to the terms and conditions of the GPL as it - is applied to this software. View the full text of the exception in file - EXCEPTIONS-CLIENT in the directory of this software distribution. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include -#if defined(THREAD) -#include /* because of signal() */ -#endif -#include "mysql.h" -#include "mysql_version.h" -#include "mysqld_error.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__NETWARE__) -#include -#include -#include -#elif !defined( __WIN__) -#include -#ifdef HAVE_SYS_UN_H -# include -#endif -#include -#ifdef HAVE_SELECT_H -# include -#endif -#ifdef HAVE_SYS_SELECT_H -#include -#endif -#include -#endif /* __WIN__ */ - -#ifndef INADDR_NONE -#define INADDR_NONE -1 -#endif - -#define RES_BUF_SHIFT 5 -#define NET_BUF_SIZE 2048 - -MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con) -{ - int net_buf_size=NET_BUF_SIZE; - if (!con) - { - if (!(con=(MYSQL_MANAGER*)my_malloc(sizeof(*con)+net_buf_size, - MYF(MY_WME|MY_ZEROFILL)))) - return 0; - con->free_me=1; - con->net_buf=(char*)con+sizeof(*con); - } - else - { - bzero((char*)con,sizeof(*con)); - if (!(con->net_buf=my_malloc(net_buf_size,MYF(0)))) - return 0; - } - con->net_buf_pos=con->net_data_end=con->net_buf; - con->net_buf_size=net_buf_size; - return con; -} - -MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, - const char* host, - const char* user, - const char* passwd, - unsigned int port) -{ - my_socket sock; - struct sockaddr_in sock_addr; - in_addr_t ip_addr; - char msg_buf[MAX_MYSQL_MANAGER_MSG]; - int msg_len; - Vio* vio; - my_bool not_used; - - if (!host) - host="localhost"; - if (!user) - user="root"; - if (!passwd) - passwd=""; - - if ((sock=(my_socket)socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET) - { - con->last_errno=errno; - strmov(con->last_error,"Cannot create socket"); - goto err; - } - if (!(vio=vio_new(sock,VIO_TYPE_TCPIP,FALSE))) - { - con->last_errno=ENOMEM; - strmov(con->last_error,"Cannot create network I/O object"); - goto err; - } - vio_blocking(vio, TRUE, ¬_used); - my_net_init(&con->net,vio); - bzero((char*) &sock_addr,sizeof(sock_addr)); - sock_addr.sin_family = AF_INET; - if ((int) (ip_addr = inet_addr(host)) != (int) INADDR_NONE) - { - memcpy_fixed(&sock_addr.sin_addr,&ip_addr,sizeof(ip_addr)); - } - else - { - int tmp_errno; - struct hostent tmp_hostent,*hp; - char buff2[GETHOSTBYNAME_BUFF_SIZE]; - hp = my_gethostbyname_r(host,&tmp_hostent,buff2,sizeof(buff2), - &tmp_errno); - if (!hp) - { - con->last_errno=tmp_errno; - sprintf(con->last_error,"Could not resolve host '%-.64s'",host); - my_gethostbyname_r_free(); - goto err; - } - memcpy(&sock_addr.sin_addr,hp->h_addr, (size_t) hp->h_length); - my_gethostbyname_r_free(); - } - sock_addr.sin_port = (ushort) htons((ushort) port); - if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr), - 0)) - { - con->last_errno=errno; - sprintf(con->last_error ,"Could not connect to %-.64s", host); - goto err; - } - /* read the greating */ - if (my_net_read(&con->net) == packet_error) - { - con->last_errno=errno; - strmov(con->last_error,"Read error on socket"); - goto err; - } - sprintf(msg_buf,"%-.16s %-.16s\n",user,passwd); - msg_len=strlen(msg_buf); - if (my_net_write(&con->net,(uchar*) msg_buf,msg_len) || net_flush(&con->net)) - { - con->last_errno=con->net.last_errno; - strmov(con->last_error,"Write error on socket"); - goto err; - } - if (my_net_read(&con->net) == packet_error) - { - con->last_errno=errno; - strmov(con->last_error,"Read error on socket"); - goto err; - } - if ((con->cmd_status=atoi((char*) con->net.read_pos)) != MANAGER_OK) - { - strmov(con->last_error,"Access denied"); - goto err; - } - if (!my_multi_malloc(MYF(0), &con->host, (uint)strlen(host)+1, - &con->user, (uint)strlen(user)+1, - &con->passwd, (uint)strlen(passwd)+1, - NullS)) - { - con->last_errno=ENOMEM; - strmov(con->last_error,"Out of memory"); - goto err; - } - strmov(con->host,host); - strmov(con->user,user); - strmov(con->passwd,passwd); - return con; - -err: - { - my_bool free_me=con->free_me; - con->free_me=0; - mysql_manager_close(con); - con->free_me=free_me; - } - return 0; -} - -void STDCALL mysql_manager_close(MYSQL_MANAGER* con) -{ - /* - No need to free con->user and con->passwd, because they were - allocated in my_multimalloc() along with con->host, freeing - con->hosts frees the whole block - */ - my_free((uchar*)con->host,MYF(MY_ALLOW_ZERO_PTR)); - net_end(&con->net); - if (con->free_me) - my_free((uchar*)con,MYF(0)); -} - - -int STDCALL mysql_manager_command(MYSQL_MANAGER* con,const char* cmd, - int cmd_len) -{ - if (!cmd_len) - cmd_len=strlen(cmd); - if (my_net_write(&con->net,(const uchar*)cmd,cmd_len) || net_flush(&con->net)) - { - con->last_errno=errno; - strmov(con->last_error,"Write error on socket"); - return 1; - } - con->eof=0; - return 0; -} - - -int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, char* res_buf, - int res_buf_size) -{ - char* res_buf_end=res_buf+res_buf_size; - char* net_buf=(char*) con->net.read_pos, *net_buf_end; - int res_buf_shift=RES_BUF_SHIFT; - ulong num_bytes; - - if (res_buf_sizelast_errno=ENOMEM; - strmov(con->last_error,"Result buffer too small"); - return 1; - } - - if ((num_bytes=my_net_read(&con->net)) == packet_error) - { - con->last_errno=errno; - strmov(con->last_error,"socket read failed"); - return 1; - } - - net_buf_end=net_buf+num_bytes; - - if ((con->eof=(net_buf[3]==' '))) - res_buf_shift--; - net_buf+=res_buf_shift; - res_buf_end[-1]=0; - for (;net_bufthd; } -#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) +#if defined(ENABLED_PROFILING) thd->profiling.start_new_query(); #endif @@ -119,7 +119,6 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, thd->current_stmt= stmt; thd->store_globals(); // Fix if more than one connect - lex_start(thd); /* We have to call free_old_query before we start to fill mysql->fields for new query. In the case of embedded server we collect field data @@ -144,13 +143,13 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, thd->mysys_var= 0; -#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) +#if defined(ENABLED_PROFILING) thd->profiling.finish_current_query(); #endif return result; } -static void emb_flush_use_result(MYSQL *mysql) +static void emb_flush_use_result(MYSQL *mysql, my_bool) { THD *thd= (THD*) mysql->thd; if (thd->cur_data) @@ -656,7 +655,7 @@ int check_embedded_connection(MYSQL *mysql, const char *db) strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1); sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0)); result= check_user(thd, COM_CONNECT, NULL, 0, db, true); - net_end_statement(thd); + thd->protocol->end_statement(); emb_read_query_result(mysql); return result; } @@ -882,7 +881,7 @@ void Protocol_text::remove_last_row() } -bool Protocol::send_fields(List *list, uint flags) +bool Protocol::send_result_set_metadata(List *list, uint flags) { List_iterator_fast it(*list); Item *item; @@ -891,7 +890,7 @@ bool Protocol::send_fields(List *list, uint flags) CHARSET_INFO *thd_cs= thd->variables.character_set_results; CHARSET_INFO *cs= system_charset_info; MYSQL_DATA *data; - DBUG_ENTER("send_fields"); + DBUG_ENTER("send_result_set_metadata"); if (!thd->mysql) // bootstrap file handling DBUG_RETURN(0); @@ -985,7 +984,7 @@ bool Protocol::send_fields(List *list, uint flags) write_eof_packet(thd, thd->server_status, thd->warning_info->statement_warn_count()); - DBUG_RETURN(prepare_for_send(list)); + DBUG_RETURN(prepare_for_send(list->elements)); err: my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index c7b37d98f2b..bca076fa938 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "client_settings.h" #ifdef HAVE_PWD_H #include @@ -77,17 +78,6 @@ static my_bool is_NT(void) } #endif -/************************************************************************** -** Shut down connection -**************************************************************************/ - -static void end_server(MYSQL *mysql) -{ - DBUG_ENTER("end_server"); - free_old_query(mysql); - DBUG_VOID_RETURN; -} - int mysql_init_character_set(MYSQL *mysql); @@ -104,6 +94,13 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, db ? db : "(Null)", user ? user : "(Null)")); + /* Test whether we're already connected */ + if (mysql->server_version) + { + set_mysql_error(mysql, CR_ALREADY_CONNECTED, unknown_sqlstate); + DBUG_RETURN(0); + } + if (!host || !host[0]) host= mysql->options.host; @@ -216,7 +213,7 @@ error: { /* Free alloced memory */ my_bool free_me=mysql->free_me; - end_server(mysql); + free_old_query(mysql); mysql->free_me=0; mysql_close(mysql); mysql->free_me=free_me; diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index 047cfe0fe57..706f6ba945d 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -13,9 +13,7 @@ EXPORTS mysql_commit mysql_data_seek mysql_debug - mysql_disable_rpl_parse mysql_dump_debug_info - mysql_enable_rpl_parse mysql_eof mysql_errno mysql_error @@ -50,6 +48,7 @@ EXPORTS mysql_next_result mysql_num_fields mysql_num_rows + mysql_odbc_escape_string mysql_options mysql_ping mysql_query @@ -61,8 +60,6 @@ EXPORTS mysql_rollback mysql_row_seek mysql_row_tell - mysql_rpl_parse_enabled - mysql_rpl_probe mysql_select_db mysql_send_query mysql_shutdown diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt new file mode 100644 index 00000000000..ddfa2495ade --- /dev/null +++ b/libservices/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2006 MySQL AB +# +# 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 +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c) + +ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES}) diff --git a/libservices/HOWTO b/libservices/HOWTO new file mode 100644 index 00000000000..b4960cb11dc --- /dev/null +++ b/libservices/HOWTO @@ -0,0 +1,100 @@ +How to create a new service +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A "service" is a set of C functions in a structure that a +service dynamic linker uses when a dynamic plugin is loaded. + +If you want to export C++ class you need to provide an +extern "C" function that will create a new instance of your class, +and put it in a service. + +Data structures are not part of the service structure, but they are part +of the API you create and usually need to be declared in the same +service_*.h file. + +To turn a set of functions (foo_func1, foo_func2) +into a service "foo" you need to + +1. create a new file include/mysql/service_foo.h + +2. the template is +================================================================== + #ifndef MYSQL_SERVICE_FOO_INCLUDED + /* standard GPL header */ + + /** + @file + *exhaustive* description of the interface you provide. + This file is the main user documentation of the new service + */ + #ifdef __cplusplus + extern "C" { + #endif + + extern struct foo_service_st { + int (*foo_func1_type)(...); /* fix the prototype as appropriate */ + void (*foo_func2_type)(...); /* fix the prototype as appropriate */ + } *foo_service; + + #ifdef MYSQL_DYNAMIC_PLUGIN + + #define foo_func1(...) foo_service->foo_func1_type(...) + #define foo_func2(...) foo_service->foo_func2_type(...) + + #else + + int foo_func1_type(...); /* fix the prototype as appropriate */ + void foo_func2_type(...); /* fix the prototype as appropriate */ + + #endif + + #ifdef __cplusplus + } + #endif + + #define MYSQL_SERVICE_FOO_INCLUDED + #endif +================================================================== + +the service_foo.h file should be self-contained, if it needs system headers - +include them in it, e.g. if you use size_t - #include + +it should also declare all the accompanying data structures, as necessary +(e.g. thd_alloc_service declares MYSQL_LEX_STRING). + +3. add the new file to include/Makefile.am (pkginclude_HEADERS) +4. add the new file to include/mysql/services.h +5. increase the minor plugin ABI version in include/mysql/plugin.h + (MYSQL_PLUGIN_INTERFACE_VERSION = MYSQL_PLUGIN_INTERFACE_VERSION+1) +6. add the version of your service to include/service_versions.h: +================================================================== + #define VERSION_foo 0x0100 +================================================================== + +7. create a new file libservices/foo_service.h using the following template: +================================================================== + /* GPL header */ + #include + SERVICE_VERSION *foo_service= (void*)VERSION_foo; +================================================================== + +8. add the new file to libservices/CMakeLists.txt (MYSQLSERVICES_SOURCES) +9. add the new file to libservices/Makefile.am (libmysqlservices_a_SOURCES) +10. and finally, register your service for dynamic linking in + sql/sql_plugin_services.h +10.1 fill in the service structure: +================================================================== + static struct foo_service_st foo_handler = { + foo_func1, + foo_func2 + } +================================================================== + +10.2 and add it to the list of services + +================================================================== + { "foo_service", VERSION_foo, &foo_handler } +================================================================== + +that's all. + diff --git a/libservices/Makefile.am b/libservices/Makefile.am new file mode 100644 index 00000000000..642081859c1 --- /dev/null +++ b/libservices/Makefile.am @@ -0,0 +1,19 @@ +# Copyright 2009 Sun Microsystems, Inc. +# +# 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 +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +AM_CPPFLAGS = -I$(top_srcdir)/include +pkglib_LIBRARIES = libmysqlservices.a +libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c +EXTRA_DIST = CMakeLists.txt diff --git a/libservices/my_snprintf_service.c b/libservices/my_snprintf_service.c new file mode 100644 index 00000000000..40d778e4b8d --- /dev/null +++ b/libservices/my_snprintf_service.c @@ -0,0 +1,17 @@ +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +SERVICE_VERSION my_snprintf_service= (void*)VERSION_my_snprintf; diff --git a/libservices/thd_alloc_service.c b/libservices/thd_alloc_service.c new file mode 100644 index 00000000000..5d4d496774c --- /dev/null +++ b/libservices/thd_alloc_service.c @@ -0,0 +1,17 @@ +/* Copyright (C) 2009 Sun Microsystems, Inc. + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +SERVICE_VERSION *thd_alloc_service= (void*)VERSION_thd_alloc; diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 2d113972b45..3bb66c0eb1a 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -6,8 +6,6 @@ binlog.binlog_multi_engine # joro : NDB tests marked as experiment funcs_1.charset_collation_1 # depends on compile-time decisions -innodb.innodb_information_schema # Bug#47449 2009-09-19 alik main.information_schema and innodb.innodb_information_schema fail sporadically - main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists main.information_schema # Bug#47449 2009-09-19 alik main.information_schema and innodb.innodb_information_schema fail sporadically main.innodb-autoinc* # Bug#47809 2009-10-04 joro innodb-autoinc.test fails with valgrind errors with the innodb plugin @@ -17,11 +15,12 @@ main.log_tables # Bug#47924 2009-10-08 alik main.log_ta main.plugin # Bug#47146 Linking problem with example plugin when dtrace enabled main.plugin_load # Bug#47146 +rpl.rpl_cross_version* # Bug #43913 2009-10-26 joro rpl_cross_version can't pass on conflicts complainig clash with --slave-load-tm rpl.rpl_innodb_bug28430* # Bug#46029 rpl.rpl_innodb_bug30888* @solaris # Bug#47646 2009-09-25 alik rpl.rpl_innodb_bug30888 fails sporadically on Solaris +rpl.rpl_log_pos* # Bug#47743 2009-10-02 alik rpl.rpl_log_pos fails sporadically rpl.rpl_plugin_load* @solaris # Bug#47146 rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2 -rpl.rpl_log_pos* # Bug#47743 2009-10-02 alik rpl.rpl_log_pos fails sporadically rpl.rpl_timezone* # Bug#47017 2009-10-27 alik rpl_timezone fails on PB-2 with mismatch error rpl.rpl_trigger* # Bug#46656 2009-09-25 alik InnoDB plugin: memory leaks (Valgrind) rpl.rpl_heartbeat_basic # BUG#43828 2009-10-22 luis fails sporadically diff --git a/mysql-test/extra/binlog_tests/drop_temp_table.test b/mysql-test/extra/binlog_tests/drop_temp_table.test index 5616fb4a643..63833c10c14 100644 --- a/mysql-test/extra/binlog_tests/drop_temp_table.test +++ b/mysql-test/extra/binlog_tests/drop_temp_table.test @@ -48,6 +48,16 @@ DROP TABLE IF EXISTS tmp2, t; --enable_warnings SELECT GET_LOCK("a",10); + +# +# BUG48216 Replication fails on all slaves after upgrade to 5.0.86 on master +# +# When the session is closed, any temporary tables of the session are dropped +# and are binlogged. But it will be binlogged with a wrong database name when +# the length of the database name('drop-temp-table-test') is greater than the +# current database name('test'). +# +USE test; disconnect con1; connection con2; diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 129a39ac509..e159242ed10 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -158,4 +158,65 @@ LOAD DATA INFILE "../../std_data/words.dat" INTO TABLE t1; DROP TABLE IF EXISTS t1; +# BUG#48297: Schema name is ignored when LOAD DATA is written into binlog, +# replication aborts +-- source include/master-slave-reset.inc + +-- let $db1= b48297_db1 +-- let $db2= b42897_db2 + +-- connection master + +-- disable_warnings +-- eval drop database if exists $db1 +-- eval drop database if exists $db2 +-- enable_warnings + +-- eval create database $db1 +-- eval create database $db2 + +-- eval use $db1 +-- eval CREATE TABLE t1 (c1 VARCHAR(256)) engine=$engine_type; + +-- eval use $db2 + +-- echo ### assertion: works with cross-referenced database +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 + +-- eval use $db1 +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- echo ### assertion: works with fully qualified name on current database +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 + +-- echo ### assertion: works without fully qualified name on current database +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1 + +-- echo ### create connection without default database +-- echo ### connect (conn2,localhost,root,,*NO-ONE*); +connect (conn2,localhost,root,,*NO-ONE*); +-- connection conn2 +-- echo ### assertion: works without stating the default database +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 +-- echo ### disconnect and switch back to master connection +-- disconnect conn2 +-- connection master + +-- sync_slave_with_master +-- eval use $db1 + +let $diff_table_1=master:$db1.t1; +let $diff_table_2=slave:$db1.t1; +source include/diff_tables.inc; + +-- connection master + +-- eval DROP DATABASE $db1 +-- eval DROP DATABASE $db2 + +-- sync_slave_with_master + # End of 4.1 tests diff --git a/mysql-test/extra/rpl_tests/rpl_stm_000001.test b/mysql-test/extra/rpl_tests/rpl_stm_000001.test index 1f5eb5786dd..869a9e3b07c 100644 --- a/mysql-test/extra/rpl_tests/rpl_stm_000001.test +++ b/mysql-test/extra/rpl_tests/rpl_stm_000001.test @@ -93,7 +93,7 @@ kill @id; # We don't drop t3 as this is a temporary table drop table t2; connection master; ---error 1053,2013 +--error 1317,2013 reap; connection slave; # The SQL slave thread should now have stopped because the query was killed on diff --git a/mysql-test/include/bug38347.inc b/mysql-test/include/bug38347.inc new file mode 100644 index 00000000000..ca1dbfa1bd2 --- /dev/null +++ b/mysql-test/include/bug38347.inc @@ -0,0 +1,21 @@ + +--echo +SHOW GRANTS FOR mysqltest_u1@localhost; + +--echo +--echo # connection: con1 (mysqltest_u1@mysqltest_db1) +--connect (con1,localhost,mysqltest_u1,,mysqltest_db1) +--connection con1 + +--echo +SHOW CREATE TABLE t1; + +--echo +--echo # connection: default +--connection default + +--disconnect con1 + +--echo +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; diff --git a/mysql-test/include/have_case_insensitive_fs.inc b/mysql-test/include/have_case_insensitive_fs.inc new file mode 100644 index 00000000000..de4ad73d780 --- /dev/null +++ b/mysql-test/include/have_case_insensitive_fs.inc @@ -0,0 +1,4 @@ +--require r/case_insensitive_fs.require +--disable_query_log +show variables like 'lower_case_file_system'; +--enable_query_log diff --git a/mysql-test/include/have_community_features.inc b/mysql-test/include/have_community_features.inc deleted file mode 100644 index 66697d8dd00..00000000000 --- a/mysql-test/include/have_community_features.inc +++ /dev/null @@ -1,4 +0,0 @@ ---require r/have_community_features.require ---disable_query_log -show variables like 'have_community_features'; ---enable_query_log diff --git a/mysql-test/include/have_profiling.inc b/mysql-test/include/have_profiling.inc new file mode 100644 index 00000000000..48f6668ff92 --- /dev/null +++ b/mysql-test/include/have_profiling.inc @@ -0,0 +1,4 @@ +--require r/have_profiling.require +--disable_query_log +show variables like 'have_profiling'; +--enable_query_log diff --git a/mysql-test/include/query_cache_sql_prepare.inc b/mysql-test/include/query_cache_sql_prepare.inc index 1842d5412bb..baa041aa058 100644 --- a/mysql-test/include/query_cache_sql_prepare.inc +++ b/mysql-test/include/query_cache_sql_prepare.inc @@ -1,11 +1,13 @@ ############### include/query_cache_sql_prepare.inc ################ # # This is to see how statements prepared via the PREPARE SQL command -# go into the query cache: if using parameters they cannot; if not -# using parameters they can. +# go into the query cache. # Query cache is abbreviated as "QC" # # Last update: +# 2008-05-26 Kostja +# - Add test coverage for automatic statement reprepare +# # 2007-05-03 ML - Move t/query_cache_sql_prepare.test # to include/query_cache_sql_prepare.inc # - Create two toplevel tests sourcing this routine @@ -490,6 +492,37 @@ use test; --echo --echo ######################################################################## +--echo # +--echo # Bug#27430 Crash in subquery code when in PS and table DDL changed +--echo # after PREPARE +--echo # Check the effect of automatic reprepare on query cache +--echo # +--echo ######################################################################## +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a varchar(255)); +insert into t1 (a) values ("Pack my box with five dozen liquor jugs."); +flush status; +prepare stmt from "select a from t1"; +execute stmt; +set @@global.query_cache_size=0; +alter table t1 add column b int; +execute stmt; +set @@global.query_cache_size=100000; +execute stmt; +execute stmt; +--echo # +--echo # Sic: ALTER TABLE caused an automatic reprepare +--echo # of the prepared statement. Since the query cache was disabled +--echo # at the time of reprepare, the new prepared statement doesn't +--echo # work with it. +--echo # +show status like 'Qcache_hits'; +show status like 'Qcache_queries_in_cache'; +--echo # Cleanup +deallocate prepare stmt; +drop table t1; ############################################################################### diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc index 455262b29f5..aa9093fb2b4 100755 --- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc @@ -50,9 +50,6 @@ is killed. */ -/* Requires Windows 2000 or higher */ -#define _WIN32_WINNT 0x0500 - #include #include #include diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index db7173d0b47..15171798279 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -1330,4 +1330,20 @@ ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6','a7','a8','a9', affected rows: 2 info: Records: 2 Duplicates: 0 Warnings: 0 DROP TABLE t1; +CREATE TABLE t1 (f1 TIMESTAMP NULL DEFAULT NULL, +f2 INT(11) DEFAULT NULL) ENGINE=MYISAM DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES (NULL, NULL), ("2009-10-09 11:46:19", 2); +this should affect no rows as there is no real change +ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +DROP TABLE t1; End of 5.1 tests +CREATE TABLE t1(c CHAR(10), +i INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY); +INSERT INTO t1 VALUES('a',2),('b',4),('c',6); +ALTER TABLE t1 +DROP i, +ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT, +AUTO_INCREMENT = 1; +DROP TABLE t1; diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result index 6eaa8731dc6..1820782d2f8 100644 --- a/mysql-test/r/analyse.result +++ b/mysql-test/r/analyse.result @@ -19,81 +19,10 @@ test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL create table t2 select * from t1 procedure analyse(); -select * from t2; -Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype -test.t1.i 1 7 1 1 0 0 4.0000 2.2361 ENUM('1','3','5','7') NOT NULL -test.t1.j 2 8 1 1 0 0 5.0000 2.2361 ENUM('2','4','6','8') NOT NULL -test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL -test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL -test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL -drop table t1,t2; +ERROR HY000: Incorrect usage of PROCEDURE and non-SELECT +drop table t1; EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(); ERROR HY000: Incorrect usage of PROCEDURE and subquery -create table t1 (a int not null); -create table t2 select * from t1 where 0=1 procedure analyse(); -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `Field_name` varbinary(255) NOT NULL DEFAULT '', - `Min_value` varbinary(255) DEFAULT NULL, - `Max_value` varbinary(255) DEFAULT NULL, - `Min_length` bigint(11) NOT NULL DEFAULT '0', - `Max_length` bigint(11) NOT NULL DEFAULT '0', - `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0', - `Nulls` bigint(11) NOT NULL DEFAULT '0', - `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '', - `Std` varbinary(255) DEFAULT NULL, - `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT '' -) ENGINE=MyISAM DEFAULT CHARSET=latin1 -select * from t1 where 0=1 procedure analyse(); -Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype -insert into t1 values(1); -drop table t2; -create table t2 select * from t1 where 0=1 procedure analyse(); -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `Field_name` varbinary(255) NOT NULL DEFAULT '', - `Min_value` varbinary(255) DEFAULT NULL, - `Max_value` varbinary(255) DEFAULT NULL, - `Min_length` bigint(11) NOT NULL DEFAULT '0', - `Max_length` bigint(11) NOT NULL DEFAULT '0', - `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0', - `Nulls` bigint(11) NOT NULL DEFAULT '0', - `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '', - `Std` varbinary(255) DEFAULT NULL, - `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT '' -) ENGINE=MyISAM DEFAULT CHARSET=latin1 -select * from t2; -Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype -insert into t2 select * from t1 procedure analyse(); -select * from t2; -Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype -test.t1.a 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL -insert into t1 values(2); -drop table t2; -create table t2 select * from t1 where 0=1 procedure analyse(); -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `Field_name` varbinary(255) NOT NULL DEFAULT '', - `Min_value` varbinary(255) DEFAULT NULL, - `Max_value` varbinary(255) DEFAULT NULL, - `Min_length` bigint(11) NOT NULL DEFAULT '0', - `Max_length` bigint(11) NOT NULL DEFAULT '0', - `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0', - `Nulls` bigint(11) NOT NULL DEFAULT '0', - `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '', - `Std` varbinary(255) DEFAULT NULL, - `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT '' -) ENGINE=MyISAM DEFAULT CHARSET=latin1 -select * from t2; -Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype -insert into t2 select * from t1 procedure analyse(); -select * from t2; -Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype -test.t1.a 1 2 1 1 0 0 1.5000 0.5000 ENUM('1','2') NOT NULL -drop table t1,t2; create table t1 (v varchar(128)); insert into t1 values ('abc'),('abc\'def\\hij\"klm\0opq'),('\''),('\"'),('\\'),('a\0'),('b\''),('c\"'),('d\\'),('\'b'),('\"c'),('\\d'),('a\0\0\0b'),('a\'\'\'\'b'),('a\"\"\"\"b'),('a\\\\\\\\b'),('\'\0\\\"'),('\'\''),('\"\"'),('\\\\'),('The\ZEnd'); select * from t1 procedure analyse(); @@ -157,3 +86,40 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE(); ERROR HY000: Incorrect usage of PROCEDURE and subquery DROP TABLE t1; End of 4.1 tests +# +# Bug #48293: crash with procedure analyse, view with > 10 columns, +# having clause... +# +CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT, +f INT, g INT, h INT, i INT, j INT,k INT); +INSERT INTO t1 VALUES (),(); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; +#should have a derived table +EXPLAIN SELECT * FROM v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 +#should not crash +SELECT * FROM v1 PROCEDURE analyse(); +ERROR HY000: Incorrect usage of PROCEDURE and view +#should not crash +SELECT * FROM t1 a, v1, t1 b PROCEDURE analyse(); +ERROR HY000: Incorrect usage of PROCEDURE and view +#should not crash +SELECT * FROM (SELECT * FROM t1 having a > 1) x PROCEDURE analyse(); +ERROR HY000: Incorrect usage of PROCEDURE and subquery +#should not crash +SELECT * FROM t1 a, (SELECT * FROM t1 having a > 1) x, t1 b PROCEDURE analyse(); +ERROR HY000: Incorrect usage of PROCEDURE and subquery +#should not crash +SELECT 1 FROM t1 group by a having a > 1 order by 1 PROCEDURE analyse(); +ERROR HY000: Can't use ORDER clause with this procedure +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2); +# should not crash +CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE(); +ERROR HY000: Incorrect usage of PROCEDURE and non-SELECT +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/bug40113.result b/mysql-test/r/bug40113.result deleted file mode 100644 index 289037a3f35..00000000000 --- a/mysql-test/r/bug40113.result +++ /dev/null @@ -1,29 +0,0 @@ -# -# Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout -# without error -# -CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB; -INSERT INTO t1 (a,b) VALUES (1070109,99); -CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB; -INSERT INTO t2 (b,a) VALUES (7,1070109); -SELECT * FROM t1; -a b -1070109 99 -BEGIN; -SELECT b FROM t2 WHERE b=7 FOR UPDATE; -b -7 -BEGIN; -SELECT b FROM t2 WHERE b=7 FOR UPDATE; -ERROR HY000: Lock wait timeout exceeded; try restarting transaction -INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7)); -ERROR HY000: Lock wait timeout exceeded; try restarting transaction -UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7); -ERROR HY000: Lock wait timeout exceeded; try restarting transaction -DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7); -ERROR HY000: Lock wait timeout exceeded; try restarting transaction -SELECT * FROM t1; -a b -1070109 99 -DROP TABLE t2, t1; -End of 5.0 tests diff --git a/mysql-test/r/case_insensitive_fs.require b/mysql-test/r/case_insensitive_fs.require new file mode 100644 index 00000000000..062ac610ddd --- /dev/null +++ b/mysql-test/r/case_insensitive_fs.require @@ -0,0 +1,2 @@ +Variable_name Value +lower_case_file_system ON diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index b829ef30fb1..471cc6e9a3d 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1922,3 +1922,37 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp # -- End of Bug#45829 End of 5.1 tests + +# -- +# -- Bug #43054 Assertion `!table->auto_increment_field_not_null' +# -- failed when redefining trigger + +CREATE TABLE B ( +pk INTEGER AUTO_INCREMENT, +int_key INTEGER NOT NULL, +PRIMARY KEY (pk), +KEY (int_key) +); +INSERT IGNORE INTO B VALUES ('9', '9'); +CREATE TABLE IF NOT EXISTS t1 ( +`pk` INTEGER NOT NULL AUTO_INCREMENT , +`int` INTEGER , +PRIMARY KEY ( `pk` ) +) SELECT `pk` , `int_key` FROM B ; +CREATE TRIGGER f BEFORE INSERT ON t1 FOR EACH ROW +BEGIN +INSERT INTO t1 ( `int` ) VALUES (4 ),( 8 ),( 2 ) ; +END ; | +CREATE TABLE IF NOT EXISTS t1 ( +`pk` INTEGER NOT NULL AUTO_INCREMENT , +`int` INTEGER , +PRIMARY KEY ( `pk` ) +) SELECT `pk` , `int_key` FROM B ; +ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. +CREATE TRIGGER f BEFORE INSERT ON t1 FOR EACH ROW +BEGIN +UPDATE A SET `pk`=1 WHERE `pk`=0 ; +END ;| +ERROR 42000: This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table' +DROP TABLE t1; +DROP TABLE B; diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index b42094550bd..67262a4935d 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -548,6 +548,36 @@ SELECT * FROM t1 WHERE s2 = s3; s1 s2 s3 a A A DROP TABLE t1; +create table t1 (a varchar(1) character set latin1 collate latin1_general_ci); +insert into t1 values ('A'),('a'),('B'),('b'),('C'),('c'); +select * from t1 where a > 'B' collate latin1_bin; +a +a +b +C +c +select * from t1 where a <> 'B' collate latin1_bin; +a +A +a +b +C +c +create index i on t1 (a); +select * from t1 where a > 'B' collate latin1_bin; +a +a +b +C +c +select * from t1 where a <> 'B' collate latin1_bin; +a +A +a +b +C +c +drop table t1; SET NAMES latin1; CREATE TABLE t1 (s1 char(10) COLLATE latin1_german1_ci, diff --git a/mysql-test/r/ctype_ldml.result b/mysql-test/r/ctype_ldml.result index 388b1373cf9..222351cd5e2 100644 --- a/mysql-test/r/ctype_ldml.result +++ b/mysql-test/r/ctype_ldml.result @@ -73,6 +73,14 @@ efgh efgh ijkl ijkl DROP TABLE t1; # +# Bug#45645 Mysql server close all connection and restart using lower function +# +CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8 COLLATE utf8_test_ci; +INSERT INTO t1 (a) VALUES ('hello!'); +SELECT * FROM t1 WHERE LOWER(a)=LOWER('N'); +a +DROP TABLE t1; +# # Bug#43827 Server closes connections and restarts # CREATE TABLE t1 (c1 VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci); diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result index b26b029759c..0645be35b10 100644 --- a/mysql-test/r/delayed.result +++ b/mysql-test/r/delayed.result @@ -311,3 +311,25 @@ a b drop table t1; set global low_priority_updates = @old_delayed_updates; End of 5.1 tests +# +# Bug #47274 assert in open_table on CREATE TABLE +# +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +CREATE TABLE t1 ( f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1)); +# The following CREATE TABLEs before gave an assert. +INSERT DELAYED t1 VALUES (4); +CREATE TABLE t1 AS SELECT 1 AS f1; +ERROR 42S01: Table 't1' already exists +REPLACE DELAYED t1 VALUES (5); +CREATE TABLE t1 AS SELECT 1 AS f1; +ERROR 42S01: Table 't1' already exists +INSERT DELAYED t1 VALUES (6); +CREATE TABLE t1 (f1 INTEGER); +ERROR 42S01: Table 't1' already exists +CREATE TABLE t2 (f1 INTEGER); +INSERT DELAYED t1 VALUES (7); +CREATE TABLE t1 LIKE t2; +ERROR 42S01: Table 't1' already exists +DROP TABLE t2; +DROP TABLE t1; diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index b798b49dd34..42739b10d50 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -121,3 +121,17 @@ ERROR 42000: Incorrect table name '#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa use test; drop database mysqltestbug26703; End of 5.1 tests + +# -- +# -- Bug#37431 (DROP TABLE does not report errors correctly). +# -- +DROP TABLE IF EXISTS t1; +DROP TABLE t1; +ERROR 42S02: Unknown table 't1' +SHOW WARNINGS; +Level Code Message +Error 1051 Unknown table 't1' + +# -- +# -- End of Bug#37431. +# -- diff --git a/mysql-test/r/drop_debug.result b/mysql-test/r/drop_debug.result new file mode 100644 index 00000000000..75346b88bc6 --- /dev/null +++ b/mysql-test/r/drop_debug.result @@ -0,0 +1,21 @@ + +# -- +# -- Bug#43138: DROP DATABASE failure does not clean up message list. +# -- + +DROP DATABASE IF EXISTS mysql_test; + +CREATE DATABASE mysql_test; +CREATE TABLE mysql_test.t1(a INT); + +SET SESSION DEBUG = "+d,bug43138"; + +DROP DATABASE mysql_test; +Warnings: +Error 1051 Unknown table 't1' + +SET SESSION DEBUG = "-d,bug43138"; + +# -- +# -- End of Bug#43138. +# -- diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index bb177fe3475..efe6df41ac6 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -77,7 +77,7 @@ set sql_mode='traditional'; alter event e_16407 do select 1; select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name; event_schema event_name sql_mode -events_test e_16407 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +events_test e_16407 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION drop event e_16407; set sql_mode="ansi"; select get_lock('ee_16407_2', 60); @@ -114,8 +114,8 @@ insert into events_test.events_smode_test values ('ee_16407_4','10-11-1956'); end| select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name; event_schema event_name sql_mode -events_test ee_16407_2 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER -events_test ee_16407_3 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +events_test ee_16407_2 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION +events_test ee_16407_3 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION events_test ee_16407_4 select /*2*/ user, host, db, info from information_schema.processlist where state = 'User lock' and info = 'select get_lock(\'ee_16407_2\', 60)'; @@ -138,8 +138,8 @@ ee_16407_4 0000-00-00 "OK, last check before we drop them" select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name; event_schema event_name sql_mode -events_test ee_16407_2 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER -events_test ee_16407_3 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +events_test ee_16407_2 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION +events_test ee_16407_3 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION events_test ee_16407_4 drop event ee_16407_2; drop event ee_16407_3; @@ -185,8 +185,8 @@ ee_16407_6 2004-02-29 "And here we check one more time before we drop the events" select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name; event_schema event_name sql_mode -events_test ee_16407_5 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER -events_test ee_16407_6 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +events_test ee_16407_5 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION +events_test ee_16407_6 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION drop event ee_16407_5; drop event ee_16407_6; drop procedure ee_16407_5_pendant; diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index fbeea8bab45..3c449cf11a1 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -195,6 +195,22 @@ dt 2001-01-01 01:01:01 drop tables t1, t2; # +# Bug#48295: +# explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode +# +CREATE TABLE t1 (f1 INT); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED SELECT 1 FROM t1 +WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t ); +ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause +SHOW WARNINGS; +Level Code Message +Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause +Note 1003 select 1 AS `1` from `test`.`t1` where ((...)) +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1; +# # Bug#30302: Tables that were optimized away are printed in the # EXPLAIN EXTENDED warning. # diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index d8b8a14afc6..33ae2e0a5a4 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -382,6 +382,9 @@ y SELECT b DIV 900 y FROM t1 GROUP BY y; y 0 +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'str1' +Warning 1292 Truncated incorrect INTEGER value: 'str2' SELECT c DIV 900 y FROM t1 GROUP BY y; y 0 diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 779a125c5cc..35ce190feb3 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1151,6 +1151,9 @@ INSERT INTO t2 VALUES (0), (1); SELECT * FROM t1, t2 WHERE num=str; str num notnumber 0 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'notnumber' +Warning 1292 Truncated incorrect DOUBLE value: 'notnumber' SELECT * FROM t1, t2 WHERE num=substring(str from 1 for 6); str num notnumber 0 diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index b030139e40e..68c4a6a13e5 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -1487,4 +1487,43 @@ MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') ); COUNT(*) 2 DROP TABLE t1; +# +# Bug #48258: Assertion failed when using a spatial index +# +CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a)); +INSERT INTO t1 VALUES +(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')), +(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')); +EXPLAIN SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where +SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +1 +1 +1 +EXPLAIN SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where +SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +1 +EXPLAIN SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where +SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +1 +1 +1 +EXPLAIN SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where +SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +1 +EXPLAIN SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where +SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'); +1 +1 +1 +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index a3708d06a1c..b40ff6be160 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -972,6 +972,18 @@ select min(`col002`) from t1 union select `col002` from t1; min(`col002`) NULL drop table t1; +# +# Bug #47780: crash when comparing GIS items from subquery +# +CREATE TABLE t1(a INT, b MULTIPOLYGON); +INSERT INTO t1 VALUES +(0, +GEOMFROMTEXT( +'multipolygon(((1 2,3 4,5 6,7 8,9 8),(7 6,5 4,3 2,1 2,3 4)))')); +# must not crash +SELECT 1 FROM t1 WHERE a <> (SELECT GEOMETRYCOLLECTIONFROMWKB(b) FROM t1); +1 +DROP TABLE t1; End of 5.0 tests create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime); create view v1 as select * from t1; diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 70181987c74..542a056c68c 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -13,8 +13,8 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3 GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' grant delete on mysqltest.* to mysqltest_1@localhost; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' @@ -44,15 +44,15 @@ delete from mysql.user where user='mysqltest_1'; flush privileges; grant usage on *.* to mysqltest_1@localhost with max_queries_per_hour 10; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 0 0 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 20 max_connections_per_hour 30; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 10 20 30 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30 @@ -483,6 +483,7 @@ Show view Tables To see views with SHOW CREATE VIEW Shutdown Server Admin To shut down the server Super Server Admin To use KILL thread, SET GLOBAL, CHANGE MASTER, etc. Trigger Tables To use triggers +Create tablespace Server Admin To create/alter/drop tablespaces Update Tables To update existing rows Usage Server Admin No privileges - allow connect only create database mysqltest; @@ -914,13 +915,13 @@ SHOW CREATE VIEW mysqltest2.v_ny; View Create View character_set_client collation_connection v_ny CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` latin1 latin1_swedish_ci SHOW CREATE TABLE mysqltest3.t_nn; -ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't_nn' +ERROR 42000: SHOW command denied to user 'mysqltest_1'@'localhost' for table 't_nn' SHOW CREATE VIEW mysqltest3.t_nn; ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't_nn' SHOW CREATE VIEW mysqltest3.v_nn; ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v_nn' SHOW CREATE TABLE mysqltest3.v_nn; -ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v_nn' +ERROR 42000: SHOW command denied to user 'mysqltest_1'@'localhost' for table 'v_nn' SHOW CREATE TABLE mysqltest2.t_nn; Table Create Table t_nn CREATE TABLE `t_nn` ( @@ -1007,8 +1008,8 @@ DROP TABLE mysqltest1.t2; SHOW GRANTS; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' -GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost' GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost' +GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost' RENAME TABLE t1 TO t2; RENAME TABLE t2 TO t1; ALTER TABLE t1 RENAME TO t2; @@ -1018,8 +1019,8 @@ REVOKE DROP, INSERT ON mysqltest1.t2 FROM mysqltest_1@localhost; SHOW GRANTS; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' -GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost' GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost' +GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost' RENAME TABLE t1 TO t2; ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1' ALTER TABLE t1 RENAME TO t2; @@ -1413,3 +1414,713 @@ DROP USER 'user1'; DROP USER 'user1'@'localhost'; DROP USER 'user2'; DROP DATABASE db1; +# +# Bug #25863 No database selected error, but documentation +# says * for global allowed +# +GRANT ALL ON * TO mysqltest_1; +ERROR 3D000: No database selected +GRANT ALL ON *.* TO mysqltest_1; +SHOW GRANTS FOR mysqltest_1; +Grants for mysqltest_1@% +GRANT ALL PRIVILEGES ON *.* TO 'mysqltest_1'@'%' +DROP USER mysqltest_1; +USE test; +GRANT ALL ON * TO mysqltest_1; +SHOW GRANTS FOR mysqltest_1; +Grants for mysqltest_1@% +GRANT USAGE ON *.* TO 'mysqltest_1'@'%' +GRANT ALL PRIVILEGES ON `test`.* TO 'mysqltest_1'@'%' +DROP USER mysqltest_1; +GRANT ALL ON *.* TO mysqltest_1; +SHOW GRANTS FOR mysqltest_1; +Grants for mysqltest_1@% +GRANT ALL PRIVILEGES ON *.* TO 'mysqltest_1'@'%' +DROP USER mysqltest_1; +######################################################################### +# +# Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE. +# +######################################################################### + +# -- +# -- Prepare the environment. +# -- +DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%'; +DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%'; +DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%'; +DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%'; +FLUSH PRIVILEGES; +DROP DATABASE IF EXISTS mysqltest_db1; +CREATE DATABASE mysqltest_db1; +CREATE TABLE mysqltest_db1.t1(a INT); + +# -- +# -- Check that global privileges don't allow SHOW CREATE TABLE. +# -- +GRANT EVENT ON mysqltest_db1.* TO mysqltest_u1@localhost; +GRANT CREATE TEMPORARY TABLES ON mysqltest_db1.* TO mysqltest_u1@localhost; +GRANT LOCK TABLES ON mysqltest_db1.* TO mysqltest_u1@localhost; +GRANT ALTER ROUTINE ON mysqltest_db1.* TO mysqltest_u1@localhost; +GRANT CREATE ROUTINE ON mysqltest_db1.* TO mysqltest_u1@localhost; +GRANT EXECUTE ON mysqltest_db1.* TO mysqltest_u1@localhost; +GRANT FILE ON *.* TO mysqltest_u1@localhost; +GRANT CREATE USER ON *.* TO mysqltest_u1@localhost; +GRANT PROCESS ON *.* TO mysqltest_u1@localhost; +GRANT RELOAD ON *.* TO mysqltest_u1@localhost; +GRANT REPLICATION CLIENT ON *.* TO mysqltest_u1@localhost; +GRANT REPLICATION SLAVE ON *.* TO mysqltest_u1@localhost; +GRANT SHOW DATABASES ON *.* TO mysqltest_u1@localhost; +GRANT SHUTDOWN ON *.* TO mysqltest_u1@localhost; +GRANT USAGE ON *.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT RELOAD, SHUTDOWN, PROCESS, FILE, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT, CREATE USER ON *.* TO 'mysqltest_u1'@'localhost' +GRANT CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE ROUTINE, ALTER ROUTINE, EVENT ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +ERROR 42000: SHOW command denied to user 'mysqltest_u1'@'localhost' for table 't1' + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global SELECT allows SHOW CREATE TABLE. +# -- + +GRANT SELECT ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT SELECT ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global INSERT allows SHOW CREATE TABLE. +# -- + +GRANT INSERT ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT INSERT ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global UPDATE allows SHOW CREATE TABLE. +# -- + +GRANT UPDATE ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT UPDATE ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global DELETE allows SHOW CREATE TABLE. +# -- + +GRANT DELETE ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT DELETE ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global CREATE allows SHOW CREATE TABLE. +# -- + +GRANT CREATE ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT CREATE ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global DROP allows SHOW CREATE TABLE. +# -- + +GRANT DROP ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT DROP ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global ALTER allows SHOW CREATE TABLE. +# -- + +GRANT ALTER ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT ALTER ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global INDEX allows SHOW CREATE TABLE. +# -- + +GRANT INDEX ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT INDEX ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global REFERENCES allows SHOW CREATE TABLE. +# -- + +GRANT REFERENCES ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT REFERENCES ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global GRANT OPTION allows SHOW CREATE TABLE. +# -- + +GRANT GRANT OPTION ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT USAGE ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' WITH GRANT OPTION + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global CREATE VIEW allows SHOW CREATE TABLE. +# -- + +GRANT CREATE VIEW ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT CREATE VIEW ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that global SHOW VIEW allows SHOW CREATE TABLE. +# -- + +GRANT SHOW VIEW ON mysqltest_db1.* TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT SHOW VIEW ON `mysqltest_db1`.* TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level SELECT allows SHOW CREATE TABLE. +# -- + +GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT SELECT ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level INSERT allows SHOW CREATE TABLE. +# -- + +GRANT INSERT ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT INSERT ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level UPDATE allows SHOW CREATE TABLE. +# -- + +GRANT UPDATE ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT UPDATE ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level DELETE allows SHOW CREATE TABLE. +# -- + +GRANT DELETE ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT DELETE ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level CREATE allows SHOW CREATE TABLE. +# -- + +GRANT CREATE ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT CREATE ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level DROP allows SHOW CREATE TABLE. +# -- + +GRANT DROP ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT DROP ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level ALTER allows SHOW CREATE TABLE. +# -- + +GRANT ALTER ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT ALTER ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level INDEX allows SHOW CREATE TABLE. +# -- + +GRANT INDEX ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT INDEX ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level REFERENCES allows SHOW CREATE TABLE. +# -- + +GRANT REFERENCES ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT REFERENCES ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level GRANT OPTION allows SHOW CREATE TABLE. +# -- + +GRANT GRANT OPTION ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT USAGE ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' WITH GRANT OPTION + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level CREATE VIEW allows SHOW CREATE TABLE. +# -- + +GRANT CREATE VIEW ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT CREATE VIEW ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Check that table-level SHOW VIEW allows SHOW CREATE TABLE. +# -- + +GRANT SHOW VIEW ON mysqltest_db1.t1 TO mysqltest_u1@localhost; + +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' +GRANT SHOW VIEW ON `mysqltest_db1`.`t1` TO 'mysqltest_u1'@'localhost' + +# connection: con1 (mysqltest_u1@mysqltest_db1) + +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +# connection: default + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_u1@localhost; +SHOW GRANTS FOR mysqltest_u1@localhost; +Grants for mysqltest_u1@localhost +GRANT USAGE ON *.* TO 'mysqltest_u1'@'localhost' + +# -- +# -- Cleanup. +# -- + +DROP DATABASE mysqltest_db1; +DROP USER mysqltest_u1@localhost; + +# End of Bug#38347. + diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 461ad78bbb6..eae12491a4d 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -391,7 +391,7 @@ grant all on mysqltest_1.* to mysqltest_u1@localhost; use mysqltest_2; create table t1 (i int); show create table mysqltest_2.t1; -ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +ERROR 42000: SHOW command denied to user 'mysqltest_u1'@'localhost' for table 't1' create table t1 like mysqltest_2.t1; ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' grant select on mysqltest_2.t1 to mysqltest_u1@localhost; diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result index f38848111ad..59c64ee84ae 100644 --- a/mysql-test/r/grant3.result +++ b/mysql-test/r/grant3.result @@ -154,4 +154,42 @@ SELECT * FROM mysqltest_1.t1; a DROP USER 'mysqltest1'@'%'; DROP DATABASE mysqltest_1; +# +# Bug#41597 - After rename of user, there are additional grants +# when grants are reapplied. +# +CREATE DATABASE temp; +CREATE TABLE temp.t1(a INT, b VARCHAR(10)); +INSERT INTO temp.t1 VALUES(1, 'name1'); +INSERT INTO temp.t1 VALUES(2, 'name2'); +INSERT INTO temp.t1 VALUES(3, 'name3'); +CREATE USER 'user1'@'%'; +RENAME USER 'user1'@'%' TO 'user2'@'%'; +# Show privileges after rename and BEFORE grant +SHOW GRANTS FOR 'user2'@'%'; +Grants for user2@% +GRANT USAGE ON *.* TO 'user2'@'%' +GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'; +# Show privileges after rename and grant +SHOW GRANTS FOR 'user2'@'%'; +Grants for user2@% +GRANT USAGE ON *.* TO 'user2'@'%' +GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%' +# Connect as the renamed user +SHOW GRANTS; +Grants for user2@% +GRANT USAGE ON *.* TO 'user2'@'%' +GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%' +SELECT a FROM temp.t1; +a +1 +2 +3 +# Check for additional privileges by accessing a +# non privileged column. We shouldn't be able to +# access this column. +SELECT b FROM temp.t1; +ERROR 42000: SELECT command denied to user 'user2'@'localhost' for column 'b' in table 't1' +DROP USER 'user2'@'%'; +DROP DATABASE temp; End of 5.0 tests diff --git a/mysql-test/r/grant4.result b/mysql-test/r/grant4.result new file mode 100644 index 00000000000..28ad9d04151 --- /dev/null +++ b/mysql-test/r/grant4.result @@ -0,0 +1,123 @@ +drop database if exists mysqltest_db1; +create database mysqltest_db1; +use mysqltest_db1; +create table t_column_priv_only (a int, b int); +create table t_select_priv like t_column_priv_only; +create table t_no_priv like t_column_priv_only; +grant all privileges on test.* to mysqltest_u1@localhost; +grant insert (a) on mysqltest_db1.t_column_priv_only to mysqltest_u1@localhost; +grant select on mysqltest_db1.t_select_priv to mysqltest_u1@localhost; +** Connect as restricted user mysqltest_u1. + +** Test column level privileges only. No SELECT privileges on the table. +** INSERT INTO ... VALUES ... +** Attempting to insert values to a table with only column privileges +** should work. +insert into mysqltest_db1.t_column_priv_only (a) VALUES (1); + +** SHOW COLUMNS +** Should succeed because we have privileges (any) on at least one of the columns. +select column_name as 'Field',column_type as 'Type',is_nullable as 'Null',column_key as 'Key',column_default as 'Default',extra as 'Extra' from information_schema.columns where table_schema='mysqltest_db1' and table_name='t_column_priv_only'; +Field Type Null Key Default Extra +a int(11) YES NULL +show columns from mysqltest_db1.t_column_priv_only; +Field Type Null Key Default Extra +a int(11) YES NULL +** SHOW COLUMNS +** Should fail because there are no privileges on any column combination. +show columns from mysqltest_db1.t_no_priv; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't_no_priv' +** However, select from I_S.COLUMNS will succeed but not show anything: +select column_name as 'Field',column_type as 'Type',is_nullable as 'Null',column_key as 'Key',column_default as 'Default',extra as 'Extra' from information_schema.columns where table_schema='mysqltest_db1' and table_name='t_no_priv'; +Field Type Null Key Default Extra + +** CREATE TABLE ... LIKE ... require SELECT privleges and will fail. +create table test.t_no_priv like mysqltest_db1.column_priv_only; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'column_priv_only' + +** Just to be sure... SELECT also fails. +select * from mysqltest_db1.t_column_priv_only; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't_column_priv_only' + +** SHOW CREATE TABLE ... require any privileges on all columns (the entire table). +** First we try and fail on a table with only one column privilege. +show create table mysqltest_db1.t_column_priv_only; +ERROR 42000: SHOW command denied to user 'mysqltest_u1'@'localhost' for table 't_column_priv_only' + +** Now we do the same on a table with SELECT privileges. + +** SHOW COLUMNS +** Success because we got some privileges on the table (SELECT_ACL) +show columns from mysqltest_db1.t_select_priv; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES NULL + +** CREATE TABLE ... LIKE ... require SELECT privleges and will SUCCEED. +drop table if exists test.t_duplicated; +create table test.t_duplicated like mysqltest_db1.t_select_priv; +drop table test.t_duplicated; + +** SHOW CREATE TABLE will succeed because we have a privilege on all columns in the table (table-level privilege). +show create table mysqltest_db1.t_select_priv; +Table Create Table +t_select_priv CREATE TABLE `t_select_priv` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +** SHOW CREATE TABLE will fail if there is no grants at all: +show create table mysqltest_db1.t_no_priv; +ERROR 42000: SHOW command denied to user 'mysqltest_u1'@'localhost' for table 't_no_priv' + +use mysqltest_db1; +CREATE TABLE t5 (s1 INT); +CREATE INDEX i ON t5 (s1); +CREATE TABLE t6 (s1 INT, s2 INT); +CREATE VIEW v5 AS SELECT * FROM t5; +CREATE VIEW v6 AS SELECT * FROM t6; +CREATE VIEW v2 AS SELECT * FROM t_select_priv; +CREATE VIEW v3 AS SELECT * FROM t_select_priv; +CREATE INDEX i ON t6 (s1); +GRANT UPDATE (s2) ON t6 to mysqltest_u1@localhost; +GRANT UPDATE (s2) ON v6 to mysqltest_u1@localhost; +GRANT SHOW VIEW ON v2 to mysqltest_u1@localhost; +GRANT SHOW VIEW, SELECT ON v3 to mysqltest_u1@localhost; +use mysqltest_db1; +** Connect as restricted user mysqltest_u1. +** SELECT FROM INFORMATION_SCHEMA.STATISTICS will succeed because any privileges will do (authentication is enough). +SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='t5'; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT +def mysqltest_db1 t5 1 mysqltest_db1 i 1 s1 A NULL NULL NULL YES BTREE +** SHOW INDEX FROM t5 will fail because we don't have any privileges on any column combination. +SHOW INDEX FROM t5; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't5' +** SHOW INDEX FROM t6 will succeed because there exist a privilege on a column combination on t6. +SHOW INDEX FROM t6; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t6 1 i 1 s1 A NULL NULL NULL YES BTREE +** CHECK TABLE requires any privilege on any column combination and should succeed for t6: +CHECK TABLE t6; +Table Op Msg_type Msg_text +mysqltest_db1.t6 check status OK +** With no privileges access is naturally denied: +CHECK TABLE t5; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't5' +** CHECKSUM TABLE requires SELECT privileges on the table. The following should fail: +CHECKSUM TABLE t6; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't6' +** And this should work: +CHECKSUM TABLE t_select_priv; +Table Checksum +mysqltest_db1.t_select_priv 0 +SHOW CREATE VIEW v5; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'v5' +SHOW CREATE VIEW v6; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'v6' +SHOW CREATE VIEW v2; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'v2' +SHOW CREATE VIEW v3; +View Create View character_set_client collation_connection +v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t_select_priv`.`a` AS `a`,`t_select_priv`.`b` AS `b` from `t_select_priv` latin1 latin1_swedish_ci +drop database mysqltest_db1; +drop user mysqltest_u1@localhost; diff --git a/mysql-test/r/grant_lowercase_fs.result b/mysql-test/r/grant_lowercase_fs.result new file mode 100644 index 00000000000..5a3087ed5cd --- /dev/null +++ b/mysql-test/r/grant_lowercase_fs.result @@ -0,0 +1,16 @@ +create database db1; +GRANT CREATE ON db1.* to user_1@localhost; +GRANT SELECT ON db1.* to USER_1@localhost; +CREATE TABLE t1(f1 int); +SELECT * FROM t1; +ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1' +SELECT * FROM t1; +f1 +CREATE TABLE t2(f1 int); +ERROR 42000: CREATE command denied to user 'USER_1'@'localhost' for table 't2' +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost; +DROP USER user_1@localhost; +DROP USER USER_1@localhost; +DROP DATABASE db1; +use test; diff --git a/mysql-test/r/have_community_features.require b/mysql-test/r/have_community_features.require deleted file mode 100644 index 9233bba91e1..00000000000 --- a/mysql-test/r/have_community_features.require +++ /dev/null @@ -1,2 +0,0 @@ -Variable_name Value -have_community_features YES diff --git a/mysql-test/r/have_profiling.require b/mysql-test/r/have_profiling.require new file mode 100644 index 00000000000..453ee5bb084 --- /dev/null +++ b/mysql-test/r/have_profiling.require @@ -0,0 +1,2 @@ +Variable_name Value +have_profiling YES diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 79e97b7a06d..04234eb3cc4 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -592,7 +592,7 @@ proc definer char(77) proc created timestamp proc modified timestamp proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') -proc comment char(64) +proc comment text proc character_set_client char(32) proc collation_connection char(32) proc db_collation char(32) @@ -771,6 +771,7 @@ information_schema PARTITIONS PARTITION_DESCRIPTION information_schema PLUGINS PLUGIN_DESCRIPTION information_schema PROCESSLIST INFO information_schema ROUTINES ROUTINE_DEFINITION +information_schema ROUTINES ROUTINE_COMMENT information_schema TRIGGERS ACTION_CONDITION information_schema TRIGGERS ACTION_STATEMENT information_schema VIEWS VIEW_DEFINITION diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index 34a413afc1b..bed73d9faf7 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -3,7 +3,7 @@ drop view if exists v1,v2; drop function if exists f1; drop function if exists f2; use INFORMATION_SCHEMA; -show tables where Tables_in_information_schema not like "Innodb%"; +show tables where Tables_in_information_schema NOT LIKE 'Innodb%'; Tables_in_information_schema CHARACTER_SETS COLLATIONS @@ -119,12 +119,12 @@ create table t1 (f1 char(4)); create view v1 as select f1 from t1; grant insert on v1 to testdb_2@localhost; create view v5 as select f1 from t1; -grant show view on v5 to testdb_2@localhost; +grant select, show view on v5 to testdb_2@localhost; create definer=`no_such_user`@`no_such_host` view v6 as select f1 from t1; ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation use testdb_1; create view v6 as select f1 from t1; -grant show view on v6 to testdb_2@localhost; +grant select, show view on v6 to testdb_2@localhost; create table t2 (f1 char(4)); create definer=`no_such_user`@`no_such_host` view v7 as select * from t2; Warnings: @@ -152,11 +152,13 @@ create view v2 as select f1 from testdb_1.v1; create view v4 as select f1,f2 from testdb_1.v3; show fields from testdb_1.v5; Field Type Null Key Default Extra +f1 char(4) YES NULL show create view testdb_1.v5; View Create View character_set_client collation_connection v5 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_1`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v5` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1` latin1 latin1_swedish_ci show fields from testdb_1.v6; Field Type Null Key Default Extra +f1 char(4) YES NULL show create view testdb_1.v6; View Create View character_set_client collation_connection v6 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v6` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1` latin1 latin1_swedish_ci @@ -171,9 +173,9 @@ v7 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY Warnings: Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist revoke insert(f1) on v3 from testdb_2@localhost; -revoke show view on v5 from testdb_2@localhost; +revoke select,show view on v5 from testdb_2@localhost; use testdb_1; -revoke show view on v6 from testdb_2@localhost; +revoke select,show view on v6 from testdb_2@localhost; show fields from testdb_1.v5; ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v5' show create view testdb_1.v5; @@ -203,7 +205,7 @@ show create view v2; View Create View character_set_client collation_connection v2 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v1`.`f1` AS `f1` from `testdb_1`.`v1` latin1 latin1_swedish_ci show create view testdb_1.v1; -ERROR 42000: SHOW VIEW command denied to user 'testdb_2'@'localhost' for table 'v1' +ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v1' select table_name from information_schema.columns a where a.table_name = 'v2'; table_name diff --git a/mysql-test/r/innodb-autoinc.result b/mysql-test/r/innodb-autoinc.result index d2e8eb19e0c..abb8f3da072 100644 --- a/mysql-test/r/innodb-autoinc.result +++ b/mysql-test/r/innodb-autoinc.result @@ -867,6 +867,7 @@ INSERT INTO t2 SELECT NULL FROM t1; Got one of the listed errors DROP TABLE t1; DROP TABLE t2; +SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; INSERT INTO t1 VALUES (null); INSERT INTO t1 VALUES (null); @@ -874,18 +875,254 @@ ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT; SELECT * FROM t1; d1 1 -3 +2 SELECT * FROM t1; d1 1 -3 +2 INSERT INTO t1 VALUES(null); Got one of the listed errors ALTER TABLE t1 AUTO_INCREMENT = 3; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`d1`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 INSERT INTO t1 VALUES(null); SELECT * FROM t1; d1 1 +2 3 -4 DROP TABLE t1; +SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; +SHOW VARIABLES LIKE "%auto_inc%"; +Variable_name Value +auto_increment_increment 1 +auto_increment_offset 1 +CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +INSERT INTO t1 VALUES (-127, 'innodb'); +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` tinyint(4) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +-127 innodb +-1 innodb +1 NULL +2 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (-127, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` tinyint(3) unsigned NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +1 NULL +2 innodb +3 innodb +4 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +INSERT INTO t1 VALUES (-32767, 'innodb'); +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` smallint(6) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +-32767 innodb +-1 innodb +1 NULL +2 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (-32757, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +1 NULL +2 innodb +3 innodb +4 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +INSERT INTO t1 VALUES (-8388607, 'innodb'); +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` mediumint(9) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +-8388607 innodb +-1 innodb +1 NULL +2 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (-8388607, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +1 NULL +2 innodb +3 innodb +4 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +INSERT INTO t1 VALUES (-2147483647, 'innodb'); +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +-2147483647 innodb +-1 innodb +1 NULL +2 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (-2147483647, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(10) unsigned NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +1 NULL +2 innodb +3 innodb +4 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +INSERT INTO t1 VALUES (-9223372036854775807, 'innodb'); +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +-9223372036854775807 innodb +-1 innodb +1 NULL +2 NULL +DROP TABLE t1; +CREATE TABLE t1 (c1 BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (-1, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (-9223372036854775807, 'innodb'); +Warnings: +Warning 1264 Out of range value for column 'c1' at row 1 +INSERT INTO t1 VALUES (NULL, NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 +SELECT * FROM t1; +c1 c2 +1 NULL +2 innodb +3 innodb +4 NULL +DROP TABLE t1; +CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; +CREATE INDEX i1 on T1(c2); +SHOW CREATE TABLE T1; +Table Create Table +T1 CREATE TABLE `T1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `i1` (`c2`) +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 +INSERT INTO T1 (c2) values (0); +SELECT * FROM T1; +c1 c2 +10 0 +DROP TABLE T1; diff --git a/mysql-test/r/innodb_bug46000.result b/mysql-test/r/innodb_bug46000.result index ccff888a48d..c8e3db8d641 100644 --- a/mysql-test/r/innodb_bug46000.result +++ b/mysql-test/r/innodb_bug46000.result @@ -1,17 +1,19 @@ create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb; -ERROR HY000: Can't create table 'test.bug46000' (errno: -1) +ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX' create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb; -ERROR HY000: Can't create table 'test.bug46000' (errno: -1) -show errors; +ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX' +show warnings; Level Code Message -Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index. +Warning 1280 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index. +Error 1280 Incorrect index name 'GEN_CLUST_INDEX' Error 1005 Can't create table 'test.bug46000' (errno: -1) create table bug46000(id int) engine=innodb; create index GEN_CLUST_INDEX on bug46000(id); -ERROR HY000: Can't create table '#sql-temporary' (errno: -1) -show errors; +ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX' +show warnings; Level Code Message -Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index. -Error 1005 Can't create table '#sql-temporary' (errno: -1) +Warning 1280 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index. +Error 1280 Incorrect index name 'GEN_CLUST_INDEX' +Error 1030 Got error -1 from storage engine create index idx on bug46000(id); drop table bug46000; diff --git a/mysql-test/r/innodb_bug47777.result b/mysql-test/r/innodb_bug47777.result new file mode 100644 index 00000000000..fbba47edcfc --- /dev/null +++ b/mysql-test/r/innodb_bug47777.result @@ -0,0 +1,13 @@ +create table bug47777(c2 linestring not null, primary key (c2(1))) engine=innodb; +insert into bug47777 values (geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)')); +select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)'); +count(*) +1 +update bug47777 set c2=GeomFromText('POINT(1 1)'); +select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)'); +count(*) +0 +select count(*) from bug47777 where c2 = GeomFromText('POINT(1 1)'); +count(*) +1 +drop table bug47777; diff --git a/mysql-test/r/innodb_lock_wait_timeout_1.result b/mysql-test/r/innodb_lock_wait_timeout_1.result new file mode 100644 index 00000000000..a635b0d527a --- /dev/null +++ b/mysql-test/r/innodb_lock_wait_timeout_1.result @@ -0,0 +1,357 @@ +# +# Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout +# without error +# +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1070109,99); +CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB; +INSERT INTO t2 (b,a) VALUES (7,1070109); +SELECT * FROM t1; +a b +1070109 99 +BEGIN; +SELECT b FROM t2 WHERE b=7 FOR UPDATE; +b +7 +BEGIN; +SELECT b FROM t2 WHERE b=7 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7)); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1; +a b +1070109 99 +DROP TABLE t2, t1; +# End of 5.0 tests +# +# Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT +# FOR UPDATE +# +drop table if exists t1; +create table t1 (a int primary key auto_increment, +b int, index(b)) engine=innodb; +insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +set autocommit=0; +begin; +select * from t1 where b=5 for update; +a b +5 5 +insert ignore into t1 (b) select a as b from t1; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Cleanup +# +commit; +set autocommit=default; +drop table t1; +# +# Bug#41756 Strange error messages about locks from InnoDB +# +drop table if exists t1; +# In the default transaction isolation mode, and/or with +# innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row() +# in InnoDB does nothing. +# Thus in order to reproduce the condition that led to the +# warning, one needs to relax isolation by either +# setting a weaker tx_isolation value, or by turning on +# the unsafe replication switch. +# For testing purposes, choose to tweak the isolation level, +# since it's settable at runtime, unlike +# innodb_locks_unsafe_for_binlog, which is +# only a command-line switch. +# +set @@session.tx_isolation="read-committed"; +# Prepare data. We need a table with a unique index, +# for join_read_key to be used. The other column +# allows to control what passes WHERE clause filter. +create table t1 (a int primary key, b int) engine=innodb; +# Let's make sure t1 has sufficient amount of rows +# to exclude JT_ALL access method when reading it, +# i.e. make sure that JT_EQ_REF(a) is always preferred. +insert into t1 values (1,1), (2,null), (3,1), (4,1), +(5,1), (6,1), (7,1), (8,1), (9,1), (10,1), +(11,1), (12,1), (13,1), (14,1), (15,1), +(16,1), (17,1), (18,1), (19,1), (20,1); +# +# Demonstrate that for the SELECT statement +# used later in the test JT_EQ_REF access method is used. +# +explain +select 1 from t1 natural join (select 2 as a, 1 as b union all +select 2 as a, 2 as b) as t2 for update; +id 1 +select_type PRIMARY +table +type ALL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows 2 +Extra +id 1 +select_type PRIMARY +table t1 +type eq_ref +possible_keys PRIMARY +key PRIMARY +key_len 4 +ref t2.a +rows 1 +Extra Using where +id 2 +select_type DERIVED +table NULL +type NULL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra No tables used +id 3 +select_type UNION +table NULL +type NULL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra No tables used +id NULL +select_type UNION RESULT +table +type ALL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra +# +# Demonstrate that the reported SELECT statement +# no longer produces warnings. +# +select 1 from t1 natural join (select 2 as a, 1 as b union all +select 2 as a, 2 as b) as t2 for update; +1 +commit; +# +# Demonstrate that due to lack of inter-sweep "reset" function, +# we keep some non-matching records locked, even though we know +# we could unlock them. +# To do that, show that if there is only one distinct value +# for a in t2 (a=2), we will keep record (2,null) in t1 locked. +# But if we add another value for "a" to t2, say 6, +# join_read_key cache will be pruned at least once, +# and thus record (2, null) in t1 will get unlocked. +# +begin; +select 1 from t1 natural join (select 2 as a, 1 as b union all +select 2 as a, 2 as b) as t2 for update; +1 +# +# Switching to connection con1 +# We should be able to delete all records from t1 except (2, null), +# since they were not locked. +begin; +# Delete in series of 3 records so that full scan +# is not used and we're not blocked on record (2,null) +delete from t1 where a in (1,3,4); +delete from t1 where a in (5,6,7); +delete from t1 where a in (8,9,10); +delete from t1 where a in (11,12,13); +delete from t1 where a in (14,15,16); +delete from t1 where a in (17,18); +delete from t1 where a in (19,20); +# +# Record (2, null) is locked. This is actually unnecessary, +# because the previous select returned no rows. +# Just demonstrate the effect. +# +delete from t1; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +# +# Switching to connection default +# +# Show that the original contents of t1 is intact: +select * from t1; +a b +1 1 +2 NULL +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +commit; +# +# Have a one more record in t2 to show that +# if join_read_key cache is purned, the current +# row under the cursor is unlocked (provided, this row didn't +# match the partial WHERE clause, of course). +# Sic: the result of this test dependent on the order of retrieval +# of records --echo # from the derived table, if ! +# We use DELETE to disable the JOIN CACHE. This DELETE modifies no +# records. It also should leave no InnoDB row locks. +# +begin; +delete t1.* from t1 natural join (select 2 as a, 2 as b union all +select 0 as a, 0 as b) as t2; +# Demonstrate that nothing was deleted form t1 +select * from t1; +a b +1 1 +2 NULL +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +# +# Switching to connection con1 +begin; +# Since there is another distinct record in the derived table +# the previous matching record in t1 -- (2,null) -- was unlocked. +delete from t1; +# We will need the contents of the table again. +rollback; +select * from t1; +a b +1 1 +2 NULL +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +commit; +# +# Switching to connection default +rollback; +begin; +# +# Before this patch, we could wrongly unlock a record +# that was cached and later used in a join. Demonstrate that +# this is no longer the case. +# Sic: this test is also order-dependent (i.e. the +# the bug would show up only if the first record in the union +# is retreived and processed first. +# +# Verify that JT_EQ_REF is used. +explain +select 1 from t1 natural join (select 3 as a, 2 as b union all +select 3 as a, 1 as b) as t2 for update; +id 1 +select_type PRIMARY +table +type ALL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows 2 +Extra +id 1 +select_type PRIMARY +table t1 +type eq_ref +possible_keys PRIMARY +key PRIMARY +key_len 4 +ref t2.a +rows 1 +Extra Using where +id 2 +select_type DERIVED +table NULL +type NULL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra No tables used +id 3 +select_type UNION +table NULL +type NULL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra No tables used +id NULL +select_type UNION RESULT +table +type ALL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra +# Lock the record. +select 1 from t1 natural join (select 3 as a, 2 as b union all +select 3 as a, 1 as b) as t2 for update; +1 +1 +# Switching to connection con1 +# +# We should not be able to delete record (3,1) from t1, +# (previously it was possible). +# +delete from t1 where a=3; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Switching to connection default +commit; +set @@session.tx_isolation=default; +drop table t1; +# +# End of 5.1 tests +# diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index b112bde4f27..d6aa6a02468 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -2209,4 +2209,66 @@ EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL 128 Using where DROP TABLE t1; +# +# Bug #47963: Wrong results when index is used +# +CREATE TABLE t1( +a VARCHAR(5) NOT NULL, +b VARCHAR(5) NOT NULL, +c DATETIME NOT NULL, +KEY (c) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES('TEST', 'TEST', '2009-10-09 00:00:00'); +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00.0'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00.0'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.000' AND c <= '2009-10-09 00:00:00.000'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.00' AND c <= '2009-10-09 00:00:00.001'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00'; +a b c +EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +DROP TABLE t1; End of 5.1 tests +# +# Test for bug #39932 "create table fails if column for FK is in different +# case than in corr index". +# +drop tables if exists t1, t2; +create table t1 (pk int primary key) engine=InnoDB; +# Even although the below statement uses uppercased field names in +# foreign key definition it still should be able to find explicitly +# created supporting index. So it should succeed and should not +# create any additional supporting indexes. +create table t2 (fk int, key x (fk), +constraint x foreign key (FK) references t1 (PK)) engine=InnoDB; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `fk` int(11) DEFAULT NULL, + KEY `x` (`fk`), + CONSTRAINT `x` FOREIGN KEY (`fk`) REFERENCES `t1` (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t2, t1; diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 4ed56bf3c56..36d2b9ef348 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -639,3 +639,43 @@ CREATE TABLE t2(f1 CHAR(1)); INSERT INTO t2 SELECT f1 FROM t1; DROP TABLE t1, t2; End of 5.0 tests. +# +# Bug#34898 "mysql_info() reports 0 warnings while +# mysql_warning_count() reports 1" +# Check that the number of warnings reported by +# mysql_info() is correct. +# +drop table if exists t1; +create table t1 (data varchar(4) not null); +set sql_mode='error_for_division_by_zero'; +# +# Demonstrate that the number of warnings matches +# the information in mysql_info(). +# +insert t1 (data) values ('letter'), (1/0); +affected rows: 2 +info: Records: 2 Duplicates: 0 Warnings: 3 +Warnings: +Warning 1265 Data truncated for column 'data' at row 1 +Warning 1365 Division by 0 +Warning 1048 Column 'data' cannot be null +update t1 set data='envelope' where 1/0 or 1; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 3 +Warnings: +Warning 1365 Division by 0 +Warning 1265 Data truncated for column 'data' at row 1 +Warning 1265 Data truncated for column 'data' at row 2 +insert t1 (data) values (default), (1/0), ('dead beef'); +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 4 +Warnings: +Warning 1364 Field 'data' doesn't have a default value +Warning 1365 Division by 0 +Warning 1048 Column 'data' cannot be null +Warning 1265 Data truncated for column 'data' at row 3 +set sql_mode=default; +drop table t1; +# +# End of 5.4 tests +# diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index e589bdac48e..d443e20df76 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -1063,6 +1063,60 @@ a b c d 127 NULL 127 NULL 128 NULL 128 NULL DROP TABLE IF EXISTS t1,t2; +# +# Bug #42116: Mysql crash on specific query +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT, INDEX (a)); +CREATE TABLE t4 (a INT); +CREATE TABLE t5 (a INT); +CREATE TABLE t6 (a INT); +INSERT INTO t1 VALUES (1), (1), (1); +INSERT INTO t2 VALUES +(2), (2), (2), (2), (2), (2), (2), (2), (2), (2); +INSERT INTO t3 VALUES +(3), (3), (3), (3), (3), (3), (3), (3), (3), (3); +EXPLAIN +SELECT * +FROM +t1 JOIN t2 ON t1.a = t2.a +LEFT JOIN +( +( +t3 LEFT JOIN t4 ON t3.a = t4.a +) +LEFT JOIN +( +t5 LEFT JOIN t6 ON t5.a = t6.a +) +ON t4.a = t5.a +) +ON t1.a = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t3 ref a a 5 test.t1.a 2 Using index +1 SIMPLE t4 ALL NULL NULL NULL NULL 0 +1 SIMPLE t5 ALL NULL NULL NULL NULL 0 +1 SIMPLE t6 ALL NULL NULL NULL NULL 0 +1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer +SELECT * +FROM +t1 JOIN t2 ON t1.a = t2.a +LEFT JOIN +( +( +t3 LEFT JOIN t4 ON t3.a = t4.a +) +LEFT JOIN +( +t5 LEFT JOIN t6 ON t5.a = t6.a +) +ON t4.a = t5.a +) +ON t1.a = t3.a; +a a a a a a +DROP TABLE t1,t2,t3,t4,t5,t6; End of 5.0 tests. CREATE TABLE t1 (f1 int); CREATE TABLE t2 (f1 int); diff --git a/mysql-test/r/loadxml.result b/mysql-test/r/loadxml.result index d7967a105f8..55e6759748a 100644 --- a/mysql-test/r/loadxml.result +++ b/mysql-test/r/loadxml.result @@ -58,11 +58,7 @@ select 1 as xml; xml 1 create table t2(fl text); -LOAD XML LOCAL INFILE "$MYSQLTEST_VARDIR/tmp/loadxml-dump.xml" INTO TABLE t2 ROWS IDENTIFIED BY '';; -show processlist; -Id User Host db Command Time State Info -# root localhost test Query # NULL show processlist -# root localhost test Query # Reading from net LOAD XML LOCAL INFILE "$MYSQLTEST_VARDIR/tmp/loadxml-dump.xml" INTO TABLE t2 ROWS IDENTIFIED BY '

';; drop table t1; drop table t2; create table t1 ( diff --git a/mysql-test/r/locale.result b/mysql-test/r/locale.result index 30c4c928a96..af7f9e3c132 100644 --- a/mysql-test/r/locale.result +++ b/mysql-test/r/locale.result @@ -49,11 +49,44 @@ DROP TABLE t1; # # Bug#46633 Obsolete Serbian locale name # -set lc_messages=sr_YU; -ERROR HY000: Unknown locale: 'sr_YU' -set lc_messages=sr_RS; -set lc_time_names=sr_RS; -select format(123456.789, 3, 'sr_RS'); +SET lc_messages=sr_YU; +Warnings: +Warning 1287 'sr_YU' is deprecated; use 'sr_RS' instead +SHOW VARIABLES LIKE 'lc_messages'; +Variable_name Value +lc_messages sr_RS +SET lc_messages=sr_RS; +SHOW VARIABLES LIKE 'lc_messages'; +Variable_name Value +lc_messages sr_RS +SET lc_time_names=sr_RS; +SELECT format(123456.789, 3, 'sr_RS'); format(123456.789, 3, 'sr_RS') 123456.789 +# +# Bug#43207 wrong LC_TIME names for romanian locale +# +SET NAMES utf8; +SET lc_time_names=ro_RO; +SELECT DATE_FORMAT('2001-01-01', '%w %a %W'); +DATE_FORMAT('2001-01-01', '%w %a %W') +1 Lu Luni +SELECT DATE_FORMAT('2001-01-02', '%w %a %W'); +DATE_FORMAT('2001-01-02', '%w %a %W') +2 Ma MarÅ£i +SELECT DATE_FORMAT('2001-01-03', '%w %a %W'); +DATE_FORMAT('2001-01-03', '%w %a %W') +3 Mi Miercuri +SELECT DATE_FORMAT('2001-01-04', '%w %a %W'); +DATE_FORMAT('2001-01-04', '%w %a %W') +4 Jo Joi +SELECT DATE_FORMAT('2001-01-05', '%w %a %W'); +DATE_FORMAT('2001-01-05', '%w %a %W') +5 Vi Vineri +SELECT DATE_FORMAT('2001-01-06', '%w %a %W'); +DATE_FORMAT('2001-01-06', '%w %a %W') +6 Sâ Sâmbătă +SELECT DATE_FORMAT('2001-01-07', '%w %a %W'); +DATE_FORMAT('2001-01-07', '%w %a %W') +0 Du Duminică End of 5.4 tests diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result index 5c3e3d789a1..56e30ac59f8 100644 --- a/mysql-test/r/log_state.result +++ b/mysql-test/r/log_state.result @@ -309,6 +309,30 @@ SET @@global.general_log_file = @old_general_log_file; SET @@global.slow_query_log = @old_slow_query_log; SET @@global.slow_query_log_file = @old_slow_query_log_file; End of 5.1 tests + +# -- +# -- Bug#38124: "general_log_file" variable silently unset when +# -- using expression +# -- +SET GLOBAL general_log_file = DEFAULT; +SELECT @@general_log_file INTO @my_glf; +SET GLOBAL general_log_file = 'BUG38124.LOG'; +SELECT @@general_log_file; +@@general_log_file +BUG38124.LOG +SET GLOBAL general_log_file = concat('BUG38124-2.LOG'); +SELECT @@general_log_file; +@@general_log_file +BUG38124-2.LOG +SET GLOBAL general_log_file = substr('BUG38124-2.LOG',3,6); +SELECT @@general_log_file; +@@general_log_file +G38124 +SET GLOBAL general_log_file = DEFAULT; +SELECT @@general_log_file = @my_glf; +@@general_log_file = @my_glf +1 +SET GLOBAL general_log_file = @old_general_log_file; # Close connection con1 SET global general_log = @old_general_log; SET global general_log_file = @old_general_log_file; diff --git a/mysql-test/r/log_state_bug33693.result b/mysql-test/r/log_state_bug33693.result new file mode 100644 index 00000000000..abf20fc7aa7 --- /dev/null +++ b/mysql-test/r/log_state_bug33693.result @@ -0,0 +1,3 @@ +SELECT INSTR(@@general_log_file, 'MYSQLTEST_VARDIR/run');; +INSTR(@@general_log_file, 'MYSQLTEST_VARDIR/run') +0 diff --git a/mysql-test/r/lowercase_fs_off.result b/mysql-test/r/lowercase_fs_off.result index ecb21261987..30f835a8ea3 100644 --- a/mysql-test/r/lowercase_fs_off.result +++ b/mysql-test/r/lowercase_fs_off.result @@ -10,3 +10,48 @@ create database D1; ERROR 42000: Access denied for user 'sample'@'localhost' to database 'D1' drop user 'sample'@'localhost'; drop database if exists d1; +CREATE DATABASE d1; +USE d1; +CREATE TABLE T1(f1 INT); +CREATE TABLE t1(f1 INT); +GRANT SELECT ON T1 to user_1@localhost; +select * from t1; +ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1' +select * from T1; +f1 +GRANT SELECT ON t1 to user_1@localhost; +select * from information_schema.table_privileges; +GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE +'user_1'@'localhost' def d1 T1 SELECT NO +'user_1'@'localhost' def d1 t1 SELECT NO +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost; +DROP USER user_1@localhost; +DROP DATABASE d1; +USE test; +CREATE DATABASE db1; +USE db1; +CREATE PROCEDURE p1() BEGIN END; +CREATE FUNCTION f1(i INT) RETURNS INT RETURN i+1; +GRANT USAGE ON db1.* to user_1@localhost; +GRANT EXECUTE ON PROCEDURE db1.P1 to user_1@localhost; +GRANT EXECUTE ON FUNCTION db1.f1 to user_1@localhost; +GRANT UPDATE ON db1.* to USER_1@localhost; +call p1(); +call P1(); +select f1(1); +f1(1) +2 +call p1(); +ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.p1' +call P1(); +ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.p1' +select f1(1); +ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.f1' +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost; +DROP FUNCTION f1; +DROP PROCEDURE p1; +DROP USER user_1@localhost; +DROP USER USER_1@localhost; +DROP DATABASE db1; +use test; diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result index 51c2ac0faf5..cf87fd1b5a4 100644 --- a/mysql-test/r/lowercase_table2.result +++ b/mysql-test/r/lowercase_table2.result @@ -174,3 +174,74 @@ TABLE_SCHEMA TABLE_NAME mysqltest_LC2 myUC use test; drop database mysqltest_LC2; +# End of 5.1 tests +# +# Test for bug #44738 "fill_schema_table_from_frm() opens tables without +# lowercasing table name". Due to not properly normalizing table names +# in lower_case_table_names modes in this function queries to I_S which +# were executed through it left entries with incorrect key in table +# definition cache. As result further queries to I_S that used this +# function produced stale results in cases when table definition was +# changed by a DDL statement. Also combination of this issue and a +# similar problem in CREATE TABLE (it also has peeked into table +# definition cache using non-normalized key) led to spurious +# ER_TABLE_EXISTS_ERROR errors when one tried to create table with the +# same name as a previously existing but dropped table. +# +drop database if exists mysqltest_UPPERCASE; +drop table if exists t_bug44738_UPPERCASE; +create database mysqltest_UPPERCASE; +use mysqltest_UPPERCASE; +create table t_bug44738_UPPERCASE (i int) comment='Old comment'; +create table t_bug44738_lowercase (i int) comment='Old comment'; +select table_schema, table_name, table_comment from information_schema.tables +where table_schema like 'mysqltest_%' and table_name like 't_bug44738_%' + order by table_name; +table_schema table_name table_comment +mysqltest_UPPERCASE t_bug44738_lowercase Old comment +mysqltest_UPPERCASE t_bug44738_UPPERCASE Old comment +alter table t_bug44738_UPPERCASE comment='New comment'; +alter table t_bug44738_lowercase comment='New comment'; +# There should be no stale entries in TDC for our tables after the +# above ALTER TABLE statements so new version of comments should be +# returned by the below query to I_S. +select table_schema, table_name, table_comment from information_schema.tables +where table_schema like 'mysqltest_%' and table_name like 't_bug44738_%' + order by table_name; +table_schema table_name table_comment +mysqltest_UPPERCASE t_bug44738_lowercase New comment +mysqltest_UPPERCASE t_bug44738_UPPERCASE New comment +drop database mysqltest_UPPERCASE; +use test; +# Let us check that the original test case which led to discovery +# of this problem also works. +create table t_bug44738_UPPERCASE (i int); +select table_schema, table_name, table_comment from information_schema.tables +where table_schema = 'test' and table_name like 't_bug44738_%'; +table_schema table_name table_comment +test t_bug44738_UPPERCASE +drop table t_bug44738_UPPERCASE; +# After the above DROP TABLE there are no entries in TDC which correspond +# to our table and therefore the below statement should succeed. +create table t_bug44738_UPPERCASE (i int); +drop table t_bug44738_UPPERCASE; +# Finally, let us check that another issue which was exposed by +# the original test case is solved. I.e. that fuse in CREATE TABLE +# which ensures that table is not created if there is an entry for +# it in TDC even though it was removed from disk uses normalized +# version of the table name. +create table t_bug44738_UPPERCASE (i int) engine = myisam; +# Load table definition in TDC. +select table_schema, table_name, table_comment from information_schema.tables +where table_schema = 'test' and table_name like 't_bug44738_%'; +table_schema table_name table_comment +test t_bug44738_UPPERCASE +# Simulate manual removal of the table. +# After manual removal of table still there should be an entry for table +# in TDC so attempt to create table with the same name should fail. +create table t_bug44738_UPPERCASE (i int); +ERROR 42S01: Table 't_bug44738_uppercase' already exists +# And should succeed after FLUSH TABLES. +flush tables; +create table t_bug44738_UPPERCASE (i int); +drop table t_bug44738_UPPERCASE; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 297eb3b9c58..83152a0dd8d 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2220,3 +2220,39 @@ tr1 CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON t3 FOR EACH R DROP TRIGGER tr1; DROP TABLE t1, t2, t3; End of 5.1 tests +# +# An additional test case for Bug#27430 Crash in subquery code +# when in PS and table DDL changed after PREPARE +# +# Test merge table with too many merge children. +# +drop table if exists t_parent; +set @save_table_definition_cache=@@global.table_definition_cache; +# +# Set @@global.table_definition_cache to minimum +# +set @@global.table_definition_cache=400; +set @a=null; +# +# Create 400 merge children +# +set @a=concat("create table t_parent (a int) union(", @a, +") insert_method=first engine=mrg_myisam"); +prepare stmt from @a; +execute stmt; +prepare stmt from "select * from t_parent"; +execute stmt; +ERROR HY000: Prepared statement needs to be re-prepared +execute stmt; +ERROR HY000: Prepared statement needs to be re-prepared +execute stmt; +ERROR HY000: Prepared statement needs to be re-prepared +deallocate prepare stmt; +# +# Create merge parent +# +# +# Cleanup +# +drop table t_parent; +set @@global.table_definition_cache=@save_table_definition_cache; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index f5050ccf1c0..95fdc4fb93d 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2290,6 +2290,12 @@ Table Op Msg_type Msg_text test.t1 repair error myisam_sort_buffer_size is too small test.t1 repair warning Number of rows changed from 0 to 7168 test.t1 repair status OK +SET myisam_repair_threads=2; +REPAIR TABLE t1; +SET myisam_repair_threads=@@global.myisam_repair_threads; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/myisam_crash_before_flush_keys.result b/mysql-test/r/myisam_crash_before_flush_keys.result index 372f2e41590..d3545ea47d0 100644 --- a/mysql-test/r/myisam_crash_before_flush_keys.result +++ b/mysql-test/r/myisam_crash_before_flush_keys.result @@ -15,31 +15,13 @@ SET SESSION debug="d,crash_before_flush_keys"; # Run the crashing query FLUSH TABLE t1; ERROR HY000: Lost connection to MySQL server during query -# Run MYISAMCHK tool to check the table t1 and repair -myisamchk: MyISAM file MYSQLD_DATADIR/test/t1 -myisamchk: warning: 1 client is using or hasn't closed the table properly -myisamchk: error: Size of indexfile is: 1024 Should be: 3072 -MYISAMCHK: Unknown error 126 -myisamchk: error: Can't read indexpage from filepos: 1024 -MyISAM-table 'MYSQLD_DATADIR/test/t1' is corrupted -Fix it using switch "-r" or "-o" # Write file to make mysql-test-run.pl start the server # Turn on reconnect # Call script that will poll the server waiting for # it to be back online again -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` int(11) NOT NULL DEFAULT '0', - `b` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`a`,`b`), - KEY `b` (`b`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 -SELECT * FROM t1 FORCE INDEX (PRIMARY); -a b -1 2 -2 3 -3 4 -4 5 -5 6 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check warning 1 client is using or hasn't closed the table properly +test.t1 check error Size of indexfile is: 1024 Should be: 3072 +test.t1 check error Corrupt DROP TABLE t1; diff --git a/mysql-test/r/mysqlbinlog_row.result b/mysql-test/r/mysqlbinlog_row.result index 9b562ac0fff..85416138c6d 100644 --- a/mysql-test/r/mysqlbinlog_row.result +++ b/mysql-test/r/mysqlbinlog_row.result @@ -339,7 +339,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C latin1 *//*!*/; diff --git a/mysql-test/r/mysqlbinlog_row_innodb.result b/mysql-test/r/mysqlbinlog_row_innodb.result index 86f0b67ebb3..cf59d23bcf1 100644 --- a/mysql-test/r/mysqlbinlog_row_innodb.result +++ b/mysql-test/r/mysqlbinlog_row_innodb.result @@ -2256,7 +2256,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; @@ -3879,7 +3879,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; @@ -4246,7 +4246,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; @@ -4807,7 +4807,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; diff --git a/mysql-test/r/mysqlbinlog_row_myisam.result b/mysql-test/r/mysqlbinlog_row_myisam.result index b9366d941f8..973786d698e 100644 --- a/mysql-test/r/mysqlbinlog_row_myisam.result +++ b/mysql-test/r/mysqlbinlog_row_myisam.result @@ -2256,7 +2256,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; @@ -3901,7 +3901,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; @@ -4274,7 +4274,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; @@ -4845,7 +4845,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; diff --git a/mysql-test/r/mysqlbinlog_row_trans.result b/mysql-test/r/mysqlbinlog_row_trans.result index 9c3348a9e76..43a9a6182f8 100644 --- a/mysql-test/r/mysqlbinlog_row_trans.result +++ b/mysql-test/r/mysqlbinlog_row_trans.result @@ -135,7 +135,7 @@ ROLLBACK/*!*/; use test/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.pseudo_thread_id=#/*!*/; -SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C latin1 *//*!*/; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index cf79a970033..13d36fab2f1 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -2391,7 +2391,7 @@ trg3 UPDATE t1 begin if new.a = -1 then set @fired:= "Yes"; end if; -end AFTER 0000-00-00 00:00:00 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +end AFTER 0000-00-00 00:00:00 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci INSERT INTO t1 (a) VALUES (1),(2),(3),(22); update t1 set a = 4 where a=3; @@ -2468,7 +2468,7 @@ DELIMITER ; /*!50003 SET character_set_results = latin1 */ ; /*!50003 SET collation_connection = latin1_swedish_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER' */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger trg3 after update on t1 for each row begin @@ -2500,7 +2500,7 @@ UNLOCK TABLES; /*!50003 SET character_set_results = latin1 */ ; /*!50003 SET collation_connection = latin1_swedish_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; -/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER' */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger trg4 before insert on t2 for each row begin @@ -2594,12 +2594,12 @@ trg3 UPDATE t1 begin if new.a = -1 then set @fired:= "Yes"; end if; -end AFTER # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +end AFTER # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci trg4 INSERT t2 begin if new.a > 10 then set @fired:= "No"; end if; -end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci DROP TABLE t1, t2; # # Bug#9136 my_print_defaults changed behaviour between 4.1.7 and 4.1.10a diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result index 4540c9d5218..a7516d97888 100644 --- a/mysql-test/r/olap.result +++ b/mysql-test/r/olap.result @@ -733,4 +733,24 @@ SELECT 1 FROM t1 GROUP BY (DATE(NULL)) WITH ROLLUP; 1 1 DROP TABLE t1; +# +# Bug #48131: crash group by with rollup, distinct, +# filesort, with temporary tables +# +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY); +INSERT INTO t1 VALUES (1), (2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (100); +SELECT a, b FROM t1, t2 GROUP BY a, b WITH ROLLUP; +a b +1 100 +1 NULL +2 100 +2 NULL +NULL NULL +SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP; +b +100 +NULL +DROP TABLE t1, t2; End of 5.0 tests diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result index e5f5a53c1f3..84ef17857f4 100644 Binary files a/mysql-test/r/outfile.result and b/mysql-test/r/outfile.result differ diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 065c427bfd3..065e46dbf92 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -420,14 +420,12 @@ create table t1 (a bigint) partition by range (a) (partition p0 values less than (0xFFFFFFFFFFFFFFFF), partition p1 values less than (10)); -ERROR 42000: VALUES value must be of same type as partition function near '), -partition p1 values less than (10))' at line 3 +ERROR HY000: VALUES value must be of same type as partition function create table t1 (a bigint) partition by list (a) (partition p0 values in (0xFFFFFFFFFFFFFFFF), partition p1 values in (10)); -ERROR 42000: VALUES value must be of same type as partition function near '), -partition p1 values in (10))' at line 3 +ERROR HY000: VALUES value must be of same type as partition function create table t1 (a bigint unsigned) partition by range (a) (partition p0 values less than (100), @@ -1421,7 +1419,7 @@ DROP TABLE t1; CREATE TABLE t1 (a int) PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (NULL)); -ERROR 42000: Not allowed to use NULL value in VALUES LESS THAN near '))' at line 3 +ERROR HY000: Not allowed to use NULL value in VALUES LESS THAN create table t1 (s1 int auto_increment primary key) partition by list (s1) (partition p1 values in (1), diff --git a/mysql-test/r/partition_column.result b/mysql-test/r/partition_column.result new file mode 100644 index 00000000000..249de9f3496 --- /dev/null +++ b/mysql-test/r/partition_column.result @@ -0,0 +1,568 @@ +drop table if exists t1; +create table t1 (a varchar(1) character set latin1 collate latin1_general_ci) +partition by range columns(a) +( partition p0 values less than ('a'), +partition p1 values less than ('b'), +partition p2 values less than ('c'), +partition p3 values less than ('d')); +insert into t1 values ('A'),('a'),('B'),('b'),('C'),('c'); +select * from t1 where a > 'B' collate latin1_bin; +a +a +b +C +c +select * from t1 where a <> 'B' collate latin1_bin; +a +A +a +b +C +c +alter table t1 remove partitioning; +select * from t1 where a > 'B' collate latin1_bin; +a +a +b +C +c +select * from t1 where a <> 'B' collate latin1_bin; +a +A +a +b +C +c +drop table t1; +create table t1 (a varchar(2) character set latin1, +b varchar(2) character set latin1) +partition by list columns(a,b) +(partition p0 values in (('a','a'))); +insert into t1 values ('A','A'); +select * from t1 where b <> 'a' collate latin1_bin AND +a = 'A' collate latin1_bin; +a b +A A +alter table t1 remove partitioning; +select * from t1 where b <> 'a' collate latin1_bin AND +a = 'A' collate latin1_bin; +a b +A A +drop table t1; +create table t1 (a varchar(5)) +partition by list columns(a) +( partition p0 values in ('\''), + partition p1 values in ('\\'), + partition p2 values in ('\0')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(5) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST COLUMNS(a) +(PARTITION p0 VALUES IN ('''') ENGINE = MyISAM, + PARTITION p1 VALUES IN ('\\') ENGINE = MyISAM, + PARTITION p2 VALUES IN ('\0') ENGINE = MyISAM) */ +drop table t1; +set @@sql_mode=allow_invalid_dates; +create table t1 (a char, b char, c date) +partition by range columns (a,b,c) +( partition p0 values less than (0,0,to_days('3000-11-31'))); +ERROR HY000: Partition column values of incorrect type +create table t1 (a char, b char, c date) +partition by range columns (a,b,c) +( partition p0 values less than (0,0,'3000-11-31')); +ERROR HY000: Partition column values of incorrect type +set @@sql_mode=''; +create table t1 (a int, b char(10), c varchar(25), d datetime) +partition by range columns(a,b,c,d) +subpartition by hash (to_seconds(d)) +subpartitions 4 +( partition p0 values less than (1, 0, MAXVALUE, '1900-01-01'), +partition p1 values less than (1, 'a', MAXVALUE, '1999-01-01'), +partition p2 values less than (1, 'a', MAXVALUE, MAXVALUE), +partition p3 values less than (1, MAXVALUE, MAXVALUE, MAXVALUE)); +ERROR HY000: Partition column values of incorrect type +create table t1 (a int, b char(10), c varchar(25), d datetime) +partition by range columns(a,b,c,d) +subpartition by hash (to_seconds(d)) +subpartitions 4 +( partition p0 values less than (1, '0', MAXVALUE, '1900-01-01'), +partition p1 values less than (1, 'a', MAXVALUE, '1999-01-01'), +partition p2 values less than (1, 'a', MAXVALUE, MAXVALUE), +partition p3 values less than (1, MAXVALUE, MAXVALUE, MAXVALUE)); +select partition_method, partition_expression, partition_description +from information_schema.partitions where table_name = "t1"; +partition_method partition_expression partition_description +RANGE COLUMNS a,b,c,d 1,'0',MAXVALUE,'1900-01-01' +RANGE COLUMNS a,b,c,d 1,'0',MAXVALUE,'1900-01-01' +RANGE COLUMNS a,b,c,d 1,'0',MAXVALUE,'1900-01-01' +RANGE COLUMNS a,b,c,d 1,'0',MAXVALUE,'1900-01-01' +RANGE COLUMNS a,b,c,d 1,'a',MAXVALUE,'1999-01-01' +RANGE COLUMNS a,b,c,d 1,'a',MAXVALUE,'1999-01-01' +RANGE COLUMNS a,b,c,d 1,'a',MAXVALUE,'1999-01-01' +RANGE COLUMNS a,b,c,d 1,'a',MAXVALUE,'1999-01-01' +RANGE COLUMNS a,b,c,d 1,'a',MAXVALUE,MAXVALUE +RANGE COLUMNS a,b,c,d 1,'a',MAXVALUE,MAXVALUE +RANGE COLUMNS a,b,c,d 1,'a',MAXVALUE,MAXVALUE +RANGE COLUMNS a,b,c,d 1,'a',MAXVALUE,MAXVALUE +RANGE COLUMNS a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE +RANGE COLUMNS a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE +RANGE COLUMNS a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE +RANGE COLUMNS a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` char(10) DEFAULT NULL, + `c` varchar(25) DEFAULT NULL, + `d` datetime DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY RANGE COLUMNS(a,b,c,d) +SUBPARTITION BY HASH (to_seconds(d)) +SUBPARTITIONS 4 +(PARTITION p0 VALUES LESS THAN (1,'0',MAXVALUE,'1900-01-01') ENGINE = MyISAM, + PARTITION p1 VALUES LESS THAN (1,'a',MAXVALUE,'1999-01-01') ENGINE = MyISAM, + PARTITION p2 VALUES LESS THAN (1,'a',MAXVALUE,MAXVALUE) ENGINE = MyISAM, + PARTITION p3 VALUES LESS THAN (1,MAXVALUE,MAXVALUE,MAXVALUE) ENGINE = MyISAM) */ +drop table t1; +create table t1 (a int, b int) +partition by range columns (a,b) +(partition p0 values less than (NULL, maxvalue)); +ERROR HY000: Not allowed to use NULL value in VALUES LESS THAN +create table t1 (a int, b int) +partition by list columns(a,b) +( partition p0 values in ((maxvalue, 0))); +Got one of the listed errors +create table t1 (a int, b int) +partition by list columns (a,b) +( partition p0 values in ((0,0))); +alter table t1 add partition +(partition p1 values in (maxvalue, maxvalue)); +Got one of the listed errors +drop table t1; +create table t1 (a int, b int) +partition by key (a,a); +ERROR HY000: Duplicate partition field name 'a' +create table t1 (a int, b int) +partition by list columns(a,a) +( partition p values in ((1,1))); +ERROR HY000: Duplicate partition field name 'a' +create table t1 (a int signed) +partition by list (a) +( partition p0 values in (1, 3, 5, 7, 9, NULL), +partition p1 values in (2, 4, 6, 8, 0)); +insert into t1 values (NULL),(0),(1),(2),(2),(4),(4),(4),(8),(8); +select * from t1 where NULL <= a; +a +select * from t1 where a is null; +a +NULL +explain partitions select * from t1 where a is null; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where +select * from t1 where a <= 1; +a +1 +0 +drop table t1; +create table t1 (a int signed) +partition by list columns(a) +( partition p0 values in (1, 3, 5, 7, 9, NULL), +partition p1 values in (2, 4, 6, 8, 0)); +insert into t1 values (NULL),(0),(1),(2),(2),(4),(4),(4),(8),(8); +select * from t1 where a <= NULL; +a +select * from t1 where a is null; +a +NULL +explain partitions select * from t1 where a is null; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where +select * from t1 where a <= 1; +a +1 +0 +drop table t1; +create table t1 (a int, b int) +partition by list columns(a,b) +( partition p0 values in ((1, NULL), (2, NULL), (NULL, NULL)), +partition p1 values in ((1,1), (2,2)), +partition p2 values in ((3, NULL), (NULL, 1))); +select partition_method, partition_expression, partition_description +from information_schema.partitions where table_name = "t1"; +partition_method partition_expression partition_description +LIST COLUMNS a,b (1,NULL),(2,NULL),(NULL,NULL) +LIST COLUMNS a,b (1,1),(2,2) +LIST COLUMNS a,b (3,NULL),(NULL,1) +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST COLUMNS(a,b) +(PARTITION p0 VALUES IN ((1,NULL),(2,NULL),(NULL,NULL)) ENGINE = MyISAM, + PARTITION p1 VALUES IN ((1,1),(2,2)) ENGINE = MyISAM, + PARTITION p2 VALUES IN ((3,NULL),(NULL,1)) ENGINE = MyISAM) */ +insert into t1 values (3, NULL); +insert into t1 values (NULL, 1); +insert into t1 values (NULL, NULL); +insert into t1 values (1, NULL); +insert into t1 values (2, NULL); +insert into t1 values (1,1); +insert into t1 values (2,2); +select * from t1 where a = 1; +a b +1 NULL +1 1 +select * from t1 where a = 2; +a b +2 NULL +2 2 +select * from t1 where a > 8; +a b +select * from t1 where a not between 8 and 8; +a b +2 NULL +2 2 +3 NULL +1 NULL +1 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST COLUMNS(a,b) +(PARTITION p0 VALUES IN ((1,NULL),(2,NULL),(NULL,NULL)) ENGINE = MyISAM, + PARTITION p1 VALUES IN ((1,1),(2,2)) ENGINE = MyISAM, + PARTITION p2 VALUES IN ((3,NULL),(NULL,1)) ENGINE = MyISAM) */ +drop table t1; +create table t1 (a int) +partition by list (a) +( partition p0 values in (1), +partition p1 values in (1)); +ERROR HY000: Multiple definition of same constant in list partitioning +create table t1 (a int) +partition by list (a) +( partition p0 values in (2, 1), +partition p1 values in (4, NULL, 3)); +select partition_method, partition_expression, partition_description +from information_schema.partitions where table_name = "t1"; +partition_method partition_expression partition_description +LIST a 2,1 +LIST a NULL,4,3 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (2,1) ENGINE = MyISAM, + PARTITION p1 VALUES IN (NULL,4,3) ENGINE = MyISAM) */ +insert into t1 values (1); +insert into t1 values (2); +insert into t1 values (3); +insert into t1 values (4); +insert into t1 values (NULL); +insert into t1 values (5); +ERROR HY000: Table has no partition for value 5 +drop table t1; +create table t1 (a int) +partition by list columns(a) +( partition p0 values in (2, 1), +partition p1 values in ((4), (NULL), (3))); +ERROR 42000: Row expressions in VALUES IN only allowed for multi-field column partitioning near '))' at line 4 +create table t1 (a int) +partition by list columns(a) +( partition p0 values in (2, 1), +partition p1 values in (4, NULL, 3)); +select partition_method, partition_expression, partition_description +from information_schema.partitions where table_name = "t1"; +partition_method partition_expression partition_description +LIST COLUMNS a 2,1 +LIST COLUMNS a 4,NULL,3 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST COLUMNS(a) +(PARTITION p0 VALUES IN (2,1) ENGINE = MyISAM, + PARTITION p1 VALUES IN (4,NULL,3) ENGINE = MyISAM) */ +insert into t1 values (1); +insert into t1 values (2); +insert into t1 values (3); +insert into t1 values (4); +insert into t1 values (NULL); +insert into t1 values (5); +ERROR HY000: Table has no partition for value from column_list +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST COLUMNS(a) +(PARTITION p0 VALUES IN (2,1) ENGINE = MyISAM, + PARTITION p1 VALUES IN (4,NULL,3) ENGINE = MyISAM) */ +drop table t1; +create table t1 (a int, b char(10), c varchar(5), d int) +partition by range columns(a,b,c) +subpartition by key (c,d) +subpartitions 3 +( partition p0 values less than (1,'abc','abc'), +partition p1 values less than (2,'abc','abc'), +partition p2 values less than (3,'abc','abc'), +partition p3 values less than (4,'abc','abc')); +select partition_method, partition_expression, partition_description +from information_schema.partitions where table_name = "t1"; +partition_method partition_expression partition_description +RANGE COLUMNS a,b,c 1,'abc','abc' +RANGE COLUMNS a,b,c 1,'abc','abc' +RANGE COLUMNS a,b,c 1,'abc','abc' +RANGE COLUMNS a,b,c 2,'abc','abc' +RANGE COLUMNS a,b,c 2,'abc','abc' +RANGE COLUMNS a,b,c 2,'abc','abc' +RANGE COLUMNS a,b,c 3,'abc','abc' +RANGE COLUMNS a,b,c 3,'abc','abc' +RANGE COLUMNS a,b,c 3,'abc','abc' +RANGE COLUMNS a,b,c 4,'abc','abc' +RANGE COLUMNS a,b,c 4,'abc','abc' +RANGE COLUMNS a,b,c 4,'abc','abc' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` char(10) DEFAULT NULL, + `c` varchar(5) DEFAULT NULL, + `d` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY RANGE COLUMNS(a,b,c) +SUBPARTITION BY KEY (c,d) +SUBPARTITIONS 3 +(PARTITION p0 VALUES LESS THAN (1,'abc','abc') ENGINE = MyISAM, + PARTITION p1 VALUES LESS THAN (2,'abc','abc') ENGINE = MyISAM, + PARTITION p2 VALUES LESS THAN (3,'abc','abc') ENGINE = MyISAM, + PARTITION p3 VALUES LESS THAN (4,'abc','abc') ENGINE = MyISAM) */ +insert into t1 values (1,'a','b',1),(2,'a','b',2),(3,'a','b',3); +insert into t1 values (1,'b','c',1),(2,'b','c',2),(3,'b','c',3); +insert into t1 values (1,'c','d',1),(2,'c','d',2),(3,'c','d',3); +insert into t1 values (1,'d','e',1),(2,'d','e',2),(3,'d','e',3); +select * from t1 where (a = 1 AND b < 'd' AND (c = 'b' OR (c = 'c' AND d = 1)) OR +(a = 1 AND b >= 'a' AND (c = 'c' OR (c = 'd' AND d = 2)))); +a b c d +1 a b 1 +1 b c 1 +drop table t1; +create table t1 (a int, b varchar(2), c int) +partition by range columns (a, b, c) +(partition p0 values less than (1, 'A', 1), +partition p1 values less than (1, 'B', 1)); +select partition_method, partition_expression, partition_description +from information_schema.partitions where table_name = "t1"; +partition_method partition_expression partition_description +RANGE COLUMNS a,b,c 1,'A',1 +RANGE COLUMNS a,b,c 1,'B',1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(2) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY RANGE COLUMNS(a,b,c) +(PARTITION p0 VALUES LESS THAN (1,'A',1) ENGINE = MyISAM, + PARTITION p1 VALUES LESS THAN (1,'B',1) ENGINE = MyISAM) */ +insert into t1 values (1, 'A', 1); +explain partitions select * from t1 where a = 1 AND b <= 'A' and c = 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 system NULL NULL NULL NULL 1 +select * from t1 where a = 1 AND b <= 'A' and c = 1; +a b c +1 A 1 +drop table t1; +create table t1 (a char, b char, c char) +partition by list columns(a) +( partition p0 values in ('a')); +insert into t1 (a) values ('a'); +select * from t1 where a = 'a'; +a b c +a NULL NULL +drop table t1; +create table t1 (d time) +partition by range columns(d) +( partition p0 values less than ('2000-01-01'), +partition p1 values less than ('2040-01-01')); +ERROR HY000: Partition column values of incorrect type +create table t1 (d timestamp) +partition by range columns(d) +( partition p0 values less than ('2000-01-01'), +partition p1 values less than ('2040-01-01')); +ERROR HY000: Field 'd' is of a not allowed type for this type of partitioning +create table t1 (d bit(1)) +partition by range columns(d) +( partition p0 values less than (0), +partition p1 values less than (1)); +ERROR HY000: Field 'd' is of a not allowed type for this type of partitioning +create table t1 (a int, b int) +partition by range columns(a,b) +(partition p0 values less than (maxvalue, 10)); +drop table t1; +create table t1 (d date) +partition by range columns(d) +( partition p0 values less than ('2000-01-01'), +partition p1 values less than ('2009-01-01')); +drop table t1; +create table t1 (d date) +partition by range columns(d) +( partition p0 values less than ('1999-01-01'), +partition p1 values less than ('2000-01-01')); +drop table t1; +create table t1 (d date) +partition by range columns(d) +( partition p0 values less than ('2000-01-01'), +partition p1 values less than ('3000-01-01')); +drop table t1; +create table t1 (a int, b int) +partition by range columns(a,b) +(partition p2 values less than (99,99), +partition p1 values less than (99,999)); +insert into t1 values (99,998); +select * from t1 where b = 998; +a b +99 998 +drop table t1; +create table t1 as select to_seconds(null) as to_seconds; +select data_type from information_schema.columns +where column_name='to_seconds'; +data_type +int +drop table t1; +create table t1 (a int, b int) +partition by list columns(a,b) +(partition p0 values in ((maxvalue,maxvalue))); +ERROR 42000: Cannot use MAXVALUE as value in VALUES IN near 'maxvalue,maxvalue)))' at line 3 +create table t1 (a int, b int) +partition by range columns(a,b) +(partition p0 values less than (maxvalue,maxvalue)); +drop table t1; +create table t1 (a int) +partition by list columns(a) +(partition p0 values in (0)); +select partition_method from information_schema.partitions where table_name='t1'; +partition_method +LIST COLUMNS +drop table t1; +create table t1 (a char(6)) +partition by range columns(a) +(partition p0 values less than ('H23456'), +partition p1 values less than ('M23456')); +insert into t1 values ('F23456'); +select * from t1; +a +F23456 +drop table t1; +create table t1 (a char(6)) +partition by range columns(a) +(partition p0 values less than (H23456), +partition p1 values less than (M23456)); +ERROR 42S22: Unknown column 'H23456' in 'field list' +create table t1 (a char(6)) +partition by range columns(a) +(partition p0 values less than (23456), +partition p1 values less than (23456)); +ERROR HY000: Partition column values of incorrect type +create table t1 (a int, b int) +partition by range columns(a,b) +(partition p0 values less than (10)); +ERROR 42000: Inconsistency in usage of column lists for partitioning near '))' at line 3 +create table t1 (a int, b int) +partition by range columns(a,b) +(partition p0 values less than (1,1,1); +ERROR HY000: Inconsistency in usage of column lists for partitioning +create table t1 (a int, b int) +partition by range columns(a,b) +(partition p0 values less than (1, 0), +partition p1 values less than (2, maxvalue), +partition p2 values less than (3, 3), +partition p3 values less than (10, maxvalue)); +insert into t1 values (11,0); +ERROR HY000: Table has no partition for value from column_list +insert into t1 values (0,1),(1,1),(2,1),(3,1),(3,4),(4,9),(9,1); +select * from t1; +a b +0 1 +1 1 +2 1 +3 1 +3 4 +4 9 +9 1 +alter table t1 +partition by range columns(b,a) +(partition p0 values less than (1,2), +partition p1 values less than (3,3), +partition p2 values less than (9,5)); +explain partitions select * from t1 where b < 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 7 Using where +select * from t1 where b < 2; +a b +0 1 +1 1 +2 1 +3 1 +9 1 +explain partitions select * from t1 where b < 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2 ALL NULL NULL NULL NULL 7 Using where +select * from t1 where b < 4; +a b +0 1 +1 1 +2 1 +3 1 +9 1 +alter table t1 reorganize partition p1 into +(partition p11 values less than (2,2), +partition p12 values less than (3,3)); +alter table t1 reorganize partition p0 into +(partition p01 values less than (0,3), +partition p02 values less than (1,1)); +ERROR HY000: Reorganize of range partitions cannot change total ranges except for last partition where it can extend the range +alter table t1 reorganize partition p2 into +(partition p2 values less than(9,6,1)); +ERROR HY000: Inconsistency in usage of column lists for partitioning +alter table t1 reorganize partition p2 into +(partition p2 values less than (10)); +ERROR HY000: Inconsistency in usage of column lists for partitioning +alter table t1 reorganize partition p2 into +(partition p21 values less than (4,7), +partition p22 values less than (9,5)); +explain partitions select * from t1 where b < 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p11,p12,p21 ALL NULL NULL NULL NULL 7 Using where +select * from t1 where b < 4; +a b +0 1 +1 1 +2 1 +3 1 +9 1 +drop table t1; +create table t1 (a int, b int) +partition by list columns(a,b) +subpartition by hash (b) +subpartitions 2 +(partition p0 values in ((0,0), (1,1)), +partition p1 values in ((1000,1000))); +insert into t1 values (1000,1000); +drop table t1; +create table t1 (a char, b char, c char) +partition by range columns(a,b,c) +( partition p0 values less than ('a','b','c')); +alter table t1 add partition +(partition p1 values less than ('b','c','d')); +drop table t1; diff --git a/mysql-test/r/partition_column_prune.result b/mysql-test/r/partition_column_prune.result new file mode 100644 index 00000000000..82c49453d43 --- /dev/null +++ b/mysql-test/r/partition_column_prune.result @@ -0,0 +1,66 @@ +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +create table t1 (a char, b char, c char) +partition by range columns(a,b,c) +( partition p0 values less than ('a','b','c')); +insert into t1 values ('a', NULL, 'd'); +explain partitions select * from t1 where a = 'a' AND c = 'd'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 system NULL NULL NULL NULL 1 +select * from t1 where a = 'a' AND c = 'd'; +a b c +a NULL d +drop table t1; +create table t1 (a int not null) partition by range columns(a) ( +partition p0 values less than (10), +partition p1 values less than (20), +partition p2 values less than (30), +partition p3 values less than (40), +partition p4 values less than (50), +partition p5 values less than (60), +partition p6 values less than (70) +); +insert into t1 values (5),(15),(25),(35),(45),(55),(65); +insert into t1 values (5),(15),(25),(35),(45),(55),(65); +create table t2 (a int not null) partition by range(a) ( +partition p0 values less than (10), +partition p1 values less than (20), +partition p2 values less than (30), +partition p3 values less than (40), +partition p4 values less than (50), +partition p5 values less than (60), +partition p6 values less than (70) +); +insert into t2 values (5),(15),(25),(35),(45),(55),(65); +insert into t2 values (5),(15),(25),(35),(45),(55),(65); +explain partitions select * from t1 where a > 35 and a < 45; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3,p4 ALL NULL NULL NULL NULL 4 Using where +explain partitions select * from t2 where a > 35 and a < 45; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t2 p3,p4 ALL NULL NULL NULL NULL 4 Using where +drop table t1, t2; +create table t1 (a int not null, b int not null ) +partition by range columns(a,b) ( +partition p01 values less than (2,10), +partition p02 values less than (2,20), +partition p03 values less than (2,30), +partition p11 values less than (4,10), +partition p12 values less than (4,20), +partition p13 values less than (4,30), +partition p21 values less than (6,10), +partition p22 values less than (6,20), +partition p23 values less than (6,30) +); +insert into t1 values (2,5), (2,15), (2,25), +(4,5), (4,15), (4,25), (6,5), (6,15), (6,25); +insert into t1 select * from t1; +explain partitions select * from t1 where a=2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p01,p02,p03,p11 ALL NULL NULL NULL NULL 13 Using where +explain partitions select * from t1 where a=4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p11,p12,p13,p21 ALL NULL NULL NULL NULL 16 Using where +explain partitions select * from t1 where a=2 and b < 22; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p01,p02,p03 ALL NULL NULL NULL NULL 16 Using where +drop table t1; diff --git a/mysql-test/r/partition_datatype.result b/mysql-test/r/partition_datatype.result index 607afb71da5..47ea799f497 100644 --- a/mysql-test/r/partition_datatype.result +++ b/mysql-test/r/partition_datatype.result @@ -273,7 +273,7 @@ select * from t1 where a = 'y'; a y drop table t1; -create table t1 (a varchar(65531)) partition by key (a); +create table t1 (a varchar(3068)) partition by key (a); insert into t1 values ('bbbb'); insert into t1 values ('aaaa'); select * from t1 where a = 'aaaa'; @@ -286,7 +286,7 @@ select * from t1 where a = 'bbbb'; a bbbb drop table t1; -create table t1 (a varchar(65532)) partition by key (a); +create table t1 (a varchar(3069)) partition by key (a); insert into t1 values ('bbbb'); insert into t1 values ('aaaa'); select * from t1 where a = 'aaaa'; @@ -299,7 +299,7 @@ select * from t1 where a = 'bbbb'; a bbbb drop table t1; -create table t1 (a varchar(65533) not null) partition by key (a); +create table t1 (a varchar(3070) not null) partition by key (a); insert into t1 values ('bbbb'); insert into t1 values ('aaaa'); select * from t1 where a = 'aaaa'; @@ -312,6 +312,8 @@ select * from t1 where a = 'bbbb'; a bbbb drop table t1; +create table t1 (a varchar(3070)) partition by key (a); +ERROR HY000: The total length of the partitioning fields is too large create table t1 (a varchar(65533)) partition by key (a); ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs create table t1 (a varchar(65534) not null) partition by key (a); diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 511806d64bd..d24c3de3cc0 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -361,8 +361,7 @@ partition by range (a) partitions 2 (partition x1 values less than (4.0) tablespace ts1, partition x2 values less than (8) tablespace ts2); -ERROR 42000: VALUES value must be of same type as partition function near ') tablespace ts1, -partition x2 values less than (8) tablespace ts2)' at line 8 +ERROR HY000: VALUES value must be of same type as partition function CREATE TABLE t1 ( a int not null, b int not null, @@ -412,8 +411,7 @@ partition by list (a) partitions 2 (partition x1 values less than 4, partition x2 values less than (5)); -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '4, -partition x2 values less than (5))' at line 8 +ERROR HY000: Only RANGE PARTITIONING can use VALUES LESS THAN in partition definition CREATE TABLE t1 ( a int not null, b int not null, @@ -423,7 +421,7 @@ partition by range (a) partitions 2 (partition x1 values less than maxvalue, partition x2 values less than (5)); -ERROR 42000: MAXVALUE can only be used in last partition definition near '))' at line 9 +ERROR HY000: MAXVALUE can only be used in last partition definition CREATE TABLE t1 ( a int not null, b int not null, @@ -433,7 +431,7 @@ partition by range (a) partitions 2 (partition x1 values less than maxvalue, partition x2 values less than maxvalue); -ERROR 42000: MAXVALUE can only be used in last partition definition near 'maxvalue)' at line 9 +ERROR HY000: MAXVALUE can only be used in last partition definition CREATE TABLE t1 ( a int not null, b int not null, @@ -602,8 +600,7 @@ partition by list (a) partitions 2 (partition x1 values in (4.0, 12+8), partition x2 values in (3, 21)); -ERROR 42000: VALUES value must be of same type as partition function near ' 12+8), -partition x2 values in (3, 21))' at line 8 +ERROR HY000: VALUES value must be of same type as partition function CREATE TABLE t1 ( a int not null, b int not null, diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index 4323d167b10..d95e7dc43fd 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -1,4 +1,39 @@ drop table if exists t1; +create table t1 (a varchar(5), b int signed, c varchar(10), d datetime) +partition by range columns(b,c) +subpartition by hash(to_seconds(d)) +( partition p0 values less than (2, 'b'), +partition p1 values less than (4, 'd'), +partition p2 values less than (10, 'za')); +insert into t1 values ('a', 3, 'w', '2001-10-27 04:34:00'); +insert into t1 values ('r', 7, 'w', '2001-10-27 05:34:00'); +insert into t1 values ('g', 10, 'w', '2001-10-27 06:34:00'); +update t1 set a = 'c' where a > 'f'; +drop table t1; +create table t1 (a varchar(5)) +engine=memory +partition by range columns(a) +( partition p0 values less than ('m'), +partition p1 values less than ('za')); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; +create table t1 (a varchar(5)) +engine=myisam +partition by range columns(a) +( partition p0 values less than ('m'), +partition p1 values less than ('za')); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; +create table t1 (a varchar(5)) +engine=innodb +partition by range columns(a) +( partition p0 values less than ('m'), +partition p1 values less than ('za')); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; create table t1 (a int not null, b datetime not null, primary key (a,b)) diff --git a/mysql-test/r/partition_list.result b/mysql-test/r/partition_list.result index a68a67c6386..e22fc11e5bb 100644 --- a/mysql-test/r/partition_list.result +++ b/mysql-test/r/partition_list.result @@ -54,6 +54,17 @@ subpartitions 2 partition p1 values in (1), partition pnull values in (null, 2), partition p3 values in (3)); +select partition_method, partition_expression, partition_description +from information_schema.partitions where table_name = "t1"; +partition_method partition_expression partition_description +LIST a 0 +LIST a 0 +LIST a 1 +LIST a 1 +LIST a NULL,2 +LIST a NULL,2 +LIST a 3 +LIST a 3 insert into t1 values (0,0),(0,1),(1,0),(1,1),(null,0),(null,1); insert into t1 values (2,0),(2,1),(3,0),(3,1); explain partitions select * from t1 where a is null; diff --git a/mysql-test/r/partition_mgm_err.result b/mysql-test/r/partition_mgm_err.result index f8403988f47..a13278d724e 100644 --- a/mysql-test/r/partition_mgm_err.result +++ b/mysql-test/r/partition_mgm_err.result @@ -41,7 +41,7 @@ ERROR HY000: Reorganize of range partitions cannot change total ranges except fo ALTER TABLE t1 REORGANIZE PARTITION x0,x1 INTO (PARTITION x01 VALUES LESS THAN (4), PARTITION x11 VALUES LESS THAN (2)); -ERROR HY000: Reorganize of range partitions cannot change total ranges except for last partition where it can extend the range +ERROR HY000: VALUES LESS THAN value must be strictly increasing for each partition ALTER TABLE t1 REORGANIZE PARTITION x0,x1 INTO (PARTITION x01 VALUES LESS THAN (6), PARTITION x11 VALUES LESS THAN (4)); diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index d8bff2cbe01..d7790cd8075 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -656,6 +656,335 @@ EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01 id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where DROP TABLE t1; +# TO_SECONDS, test of LIST and index +CREATE TABLE t1 (a DATE, KEY(a)) +PARTITION BY LIST (TO_SECONDS(a)) +(PARTITION `p0001-01-01` VALUES IN (TO_SECONDS('0001-01-01')), +PARTITION `p2001-01-01` VALUES IN (TO_SECONDS('2001-01-01')), +PARTITION `pNULL` VALUES IN (NULL), +PARTITION `p0000-01-02` VALUES IN (TO_SECONDS('0000-01-02')), +PARTITION `p1001-01-01` VALUES IN (TO_SECONDS('1001-01-01'))); +INSERT INTO t1 VALUES ('0000-00-00'), ('0000-01-02'), ('0001-01-01'), +('1001-00-00'), ('1001-01-01'), ('1002-00-00'), ('2001-01-01'); +SELECT * FROM t1 WHERE a < '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a <= '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a >= '1001-01-01'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-01-01'; +a +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-01-01'; +a +1001-01-01 +SELECT * FROM t1 WHERE a < '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +SELECT * FROM t1 WHERE a <= '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a >= '1001-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-00-00'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-00-00'; +a +1001-00-00 +# Disabling warnings for the invalid date +SELECT * FROM t1 WHERE a < '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a <= '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a >= '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a > '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a = '1999-02-31'; +a +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +a +0001-01-01 +1001-00-00 +1001-01-01 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 3 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p1001-01-01 system a NULL NULL NULL 1 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 range a a 4 NULL 3 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 range a a 4 NULL 4 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 pNULL ref a a 4 const 1 Using where; Using index +# Disabling warnings for the invalid date +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 2 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL range a a 4 NULL 2 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 pNULL ref a a 4 const 1 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 5 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 range a a 4 NULL 4 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 pNULL,p1001-01-01 range a a 4 NULL 2 Using where; Using index +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 range a a 4 NULL 3 Using where; Using index +# test without index +ALTER TABLE t1 DROP KEY a; +SELECT * FROM t1 WHERE a < '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a <= '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a >= '1001-01-01'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-01-01'; +a +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-01-01'; +a +1001-01-01 +SELECT * FROM t1 WHERE a < '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +SELECT * FROM t1 WHERE a <= '1001-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +SELECT * FROM t1 WHERE a >= '1001-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a > '1001-00-00'; +a +1001-01-01 +1002-00-00 +2001-01-01 +SELECT * FROM t1 WHERE a = '1001-00-00'; +a +1001-00-00 +# Disabling warnings for the invalid date +SELECT * FROM t1 WHERE a < '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a <= '1999-02-31'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a >= '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a > '1999-02-31'; +a +2001-01-01 +SELECT * FROM t1 WHERE a = '1999-02-31'; +a +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +a +0000-00-00 +0000-01-02 +0001-01-01 +1001-00-00 +1001-01-01 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +a +1001-00-00 +1001-01-01 +1002-00-00 +SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +a +0001-01-01 +1001-00-00 +1001-01-01 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p1001-01-01 system NULL NULL NULL NULL 1 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1001-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where +# Disabling warnings for the invalid date +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2001-01-01,pNULL ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = '1999-02-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 pNULL ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1002-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0000-00-00' AND '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p0000-01-02,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-02' AND '1002-00-00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a BETWEEN '0001-01-01' AND '1001-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0001-01-01,pNULL,p1001-01-01 ALL NULL NULL NULL NULL 7 Using where +DROP TABLE t1; # Test with DATETIME column NOT NULL CREATE TABLE t1 ( a int(10) unsigned NOT NULL, @@ -1272,10 +1601,9 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (2, NULL); # test with an invalid date, which lead to item->null_value is set. EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-99' AS DATETIME); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t1 p20090401 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: Warning 1292 Incorrect datetime value: '2009-04-99' -Warning 1292 Incorrect datetime value: '2009-04-99' DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT, diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result index 02d2f6359c5..87cb4fba306 100644 --- a/mysql-test/r/partition_range.result +++ b/mysql-test/r/partition_range.result @@ -1,6 +1,99 @@ drop table if exists t1, t2; create table t1 (a int) partition by range (a) +( partition p0 values less than (NULL), +partition p1 values less than (MAXVALUE)); +ERROR HY000: Not allowed to use NULL value in VALUES LESS THAN +create table t1 (a datetime not null) +partition by range (TO_SECONDS(a)) +( partition p0 VALUES LESS THAN (TO_SECONDS('2007-03-08 00:00:00')), +partition p1 VALUES LESS THAN (TO_SECONDS('2007-04-01 00:00:00'))); +select partition_method, partition_expression, partition_description +from information_schema.partitions where table_name = "t1"; +partition_method partition_expression partition_description +RANGE TO_SECONDS(a) 63340531200 +RANGE TO_SECONDS(a) 63342604800 +INSERT INTO t1 VALUES ('2007-03-01 12:00:00'), ('2007-03-07 12:00:00'); +INSERT INTO t1 VALUES ('2007-03-08 12:00:00'), ('2007-03-15 12:00:00'); +explain partitions select * from t1 where a < '2007-03-08 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 2 Using where +explain partitions select * from t1 where a < '2007-03-08 00:00:01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 4 Using where +explain partitions select * from t1 where a <= '2007-03-08 00:00:00'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 4 Using where +explain partitions select * from t1 where a <= '2007-03-07 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where +explain partitions select * from t1 where a < '2007-03-07 23:59:59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 ALL NULL NULL NULL NULL 4 Using where +drop table t1; +create table t1 (a date) +partition by range(to_seconds(a)) +(partition p0 values less than (to_seconds('2004-01-01')), +partition p1 values less than (to_seconds('2005-01-01'))); +insert into t1 values ('2003-12-30'),('2004-12-31'); +select * from t1; +a +2003-12-30 +2004-12-31 +explain partitions select * from t1 where a <= '2003-12-31'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 system NULL NULL NULL NULL 1 +select * from t1 where a <= '2003-12-31'; +a +2003-12-30 +explain partitions select * from t1 where a <= '2005-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 2 Using where +select * from t1 where a <= '2005-01-01'; +a +2003-12-30 +2004-12-31 +drop table t1; +create table t1 (a datetime) +partition by range(to_seconds(a)) +(partition p0 values less than (to_seconds('2004-01-01 12:00:00')), +partition p1 values less than (to_seconds('2005-01-01 12:00:00'))); +insert into t1 values ('2004-01-01 11:59:29'),('2005-01-01 11:59:59'); +select * from t1; +a +2004-01-01 11:59:29 +2005-01-01 11:59:59 +explain partitions select * from t1 where a <= '2004-01-01 11:59.59'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 system NULL NULL NULL NULL 1 +select * from t1 where a <= '2004-01-01 11:59:59'; +a +2004-01-01 11:59:29 +explain partitions select * from t1 where a <= '2005-01-01'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 ALL NULL NULL NULL NULL 2 Using where +select * from t1 where a <= '2005-01-01'; +a +2004-01-01 11:59:29 +drop table t1; +create table t1 (a int, b char(20)) +partition by range columns(a,b) +(partition p0 values less than (1)); +ERROR 42000: Inconsistency in usage of column lists for partitioning near '))' at line 3 +create table t1 (a int, b char(20)) +partition by range(a) +(partition p0 values less than (1,"b")); +ERROR HY000: Cannot have more than one value for this type of RANGE partitioning +create table t1 (a int, b char(20)) +partition by range(a) +(partition p0 values less than (1,"b")); +ERROR HY000: Cannot have more than one value for this type of RANGE partitioning +create table t1 (a int, b char(20)) +partition by range columns(b) +(partition p0 values less than ("b")); +drop table t1; +create table t1 (a int) +partition by range (a) ( partition p0 values less than (maxvalue)); alter table t1 add partition (partition p1 values less than (100000)); ERROR HY000: MAXVALUE can only be used in last partition definition diff --git a/mysql-test/r/partition_utf8.result b/mysql-test/r/partition_utf8.result new file mode 100644 index 00000000000..0fae7bb16b6 --- /dev/null +++ b/mysql-test/r/partition_utf8.result @@ -0,0 +1,53 @@ +set names utf8; +create table t1 (a varchar(2) character set cp1250) +partition by list columns (a) +( partition p0 values in (0x81)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(2) CHARACTER SET cp1250 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST COLUMNS(a) +(PARTITION p0 VALUES IN (_cp1250 0x81) ENGINE = MyISAM) */ +drop table t1; +create table t1 (a varchar(2) character set cp1250) +partition by list columns (a) +( partition p0 values in (0x80)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(2) CHARACTER SET cp1250 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST COLUMNS(a) +(PARTITION p0 VALUES IN ('€') ENGINE = MyISAM) */ +drop table t1; +create table t1 (a varchar(1500), b varchar(1570)) +partition by list columns(a,b) +( partition p0 values in (('a','b'))); +ERROR HY000: The total length of the partitioning fields is too large +create table t1 (a varchar(1023) character set utf8 collate utf8_spanish2_ci) +partition by range columns(a) +( partition p0 values less than ('CZ'), +partition p1 values less than ('CH'), +partition p2 values less than ('D')); +insert into t1 values ('czz'),('chi'),('ci'),('cg'); +select * from t1 where a between 'cg' AND 'ci'; +a +ci +cg +drop table t1; +create table t1 (a varchar(2) character set ucs2) +partition by list columns (a) +(partition p0 values in (0x2020), +partition p1 values in ('')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(2) CHARACTER SET ucs2 DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST COLUMNS(a) +(PARTITION p0 VALUES IN ('†') ENGINE = MyISAM, + PARTITION p1 VALUES IN ('') ENGINE = MyISAM) */ +insert into t1 values (''); +insert into t1 values (_ucs2 0x2020); +drop table t1; diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index 782d2a5a9a4..85fbd1353cc 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -12,6 +12,15 @@ CREATE TABLE t1(a int) ENGINE=EXAMPLE; SELECT * FROM t1; a DROP TABLE t1; +set global example_ulong_var=500; +set global example_enum_var= e1; +show status like 'example%'; +Variable_name Value +example_func_example enum_var is 0, ulong_var is 500, really +show variables like 'example%'; +Variable_name Value +example_enum_var e1 +example_ulong_var 500 UNINSTALL PLUGIN example; UNINSTALL PLUGIN EXAMPLE; ERROR 42000: PLUGIN EXAMPLE does not exist diff --git a/mysql-test/r/profiling.result b/mysql-test/r/profiling.result index c96074eb830..f20c459d7dc 100644 --- a/mysql-test/r/profiling.result +++ b/mysql-test/r/profiling.result @@ -298,6 +298,13 @@ id 1 2 3 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'hello' +Warning 1292 Truncated incorrect DOUBLE value: 'hello' +Warning 1292 Truncated incorrect DOUBLE value: 'hello' +Warning 1292 Truncated incorrect DOUBLE value: 'hello' +Warning 1292 Truncated incorrect DOUBLE value: 'hello' +Warning 1292 Truncated incorrect DOUBLE value: 'hello' select @@profiling; @@profiling 1 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 06e6b8167fd..6c7e83134d7 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1194,13 +1194,13 @@ SET @aux= "SELECT COUNT(*) prepare my_stmt from @aux; execute my_stmt; COUNT(*) -39 +40 execute my_stmt; COUNT(*) -39 +40 execute my_stmt; COUNT(*) -39 +40 deallocate prepare my_stmt; drop procedure if exists p1| drop table if exists t1| @@ -2926,4 +2926,165 @@ execute stmt; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation drop table t1; deallocate prepare stmt; + End of 5.1 tests. + +# +# WL#4435: Support OUT-parameters in prepared statements. +# + +DROP PROCEDURE IF EXISTS p_string; +DROP PROCEDURE IF EXISTS p_double; +DROP PROCEDURE IF EXISTS p_int; +DROP PROCEDURE IF EXISTS p_decimal; + +CREATE PROCEDURE p_string( +IN v0 INT, +OUT v1 CHAR(32), +IN v2 CHAR(32), +INOUT v3 CHAR(32)) +BEGIN +SET v0 = -1; +SET v1 = 'test_v1'; +SET v2 = 'n/a'; +SET v3 = 'test_v3'; +END| + +CREATE PROCEDURE p_double( +IN v0 INT, +OUT v1 DOUBLE(4, 2), +IN v2 DOUBLE(4, 2), +INOUT v3 DOUBLE(4, 2)) +BEGIN +SET v0 = -1; +SET v1 = 12.34; +SET v2 = 98.67; +SET v3 = 56.78; +END| + +CREATE PROCEDURE p_int( +IN v0 CHAR(10), +OUT v1 INT, +IN v2 INT, +INOUT v3 INT) +BEGIN +SET v0 = 'n/a'; +SET v1 = 1234; +SET v2 = 9876; +SET v3 = 5678; +END| + +CREATE PROCEDURE p_decimal( +IN v0 INT, +OUT v1 DECIMAL(4, 2), +IN v2 DECIMAL(4, 2), +INOUT v3 DECIMAL(4, 2)) +BEGIN +SET v0 = -1; +SET v1 = 12.34; +SET v2 = 98.67; +SET v3 = 56.78; +END| + +PREPARE stmt_str FROM 'CALL p_string(?, ?, ?, ?)'; +PREPARE stmt_dbl FROM 'CALL p_double(?, ?, ?, ?)'; +PREPARE stmt_int FROM 'CALL p_int(?, ?, ?, ?)'; +PREPARE stmt_dec FROM 'CALL p_decimal(?, ?, ?, ?)'; + +SET @x_str_1 = NULL; +SET @x_str_2 = NULL; +SET @x_str_3 = NULL; +SET @x_dbl_1 = NULL; +SET @x_dbl_2 = NULL; +SET @x_dbl_3 = NULL; +SET @x_int_1 = NULL; +SET @x_int_2 = NULL; +SET @x_int_3 = NULL; +SET @x_dec_1 = NULL; +SET @x_dec_2 = NULL; +SET @x_dec_3 = NULL; + +-- Testing strings... + +EXECUTE stmt_str USING @x_int_1, @x_str_1, @x_str_2, @x_str_3; +SELECT @x_int_1, @x_str_1, @x_str_2, @x_str_3; +@x_int_1 @x_str_1 @x_str_2 @x_str_3 +NULL test_v1 NULL test_v3 + +EXECUTE stmt_str USING @x_int_1, @x_str_1, @x_str_2, @x_str_3; +SELECT @x_int_1, @x_str_1, @x_str_2, @x_str_3; +@x_int_1 @x_str_1 @x_str_2 @x_str_3 +NULL test_v1 NULL test_v3 + +-- Testing doubles... + +EXECUTE stmt_dbl USING @x_int_1, @x_dbl_1, @x_dbl_2, @x_dbl_3; +SELECT @x_int_1, @x_dbl_1, @x_dbl_2, @x_dbl_3; +@x_int_1 @x_dbl_1 @x_dbl_2 @x_dbl_3 +NULL 12.34 NULL 56.78 + +EXECUTE stmt_dbl USING @x_int_1, @x_dbl_1, @x_dbl_2, @x_dbl_3; +SELECT @x_int_1, @x_dbl_1, @x_dbl_2, @x_dbl_3; +@x_int_1 @x_dbl_1 @x_dbl_2 @x_dbl_3 +NULL 12.34 NULL 56.78 + +-- Testing ints... + +EXECUTE stmt_int USING @x_str_1, @x_int_1, @x_int_2, @x_int_3; +SELECT @x_str_1, @x_int_1, @x_int_2, @x_int_3; +@x_str_1 @x_int_1 @x_int_2 @x_int_3 +test_v1 1234 NULL 5678 + +EXECUTE stmt_int USING @x_str_1, @x_int_1, @x_int_2, @x_int_3; +SELECT @x_str_1, @x_int_1, @x_int_2, @x_int_3; +@x_str_1 @x_int_1 @x_int_2 @x_int_3 +test_v1 1234 NULL 5678 + +-- Testing decs... + +EXECUTE stmt_dec USING @x_int_1, @x_dec_1, @x_dec_2, @x_dec_3; +SELECT @x_int_1, @x_dec_1, @x_dec_2, @x_dec_3; +@x_int_1 @x_dec_1 @x_dec_2 @x_dec_3 +1234 12.34 NULL 56.78 + +EXECUTE stmt_dec USING @x_int_1, @x_dec_1, @x_dec_2, @x_dec_3; +SELECT @x_int_1, @x_dec_1, @x_dec_2, @x_dec_3; +@x_int_1 @x_dec_1 @x_dec_2 @x_dec_3 +1234 12.34 NULL 56.78 + +DEALLOCATE PREPARE stmt_str; +DEALLOCATE PREPARE stmt_dbl; +DEALLOCATE PREPARE stmt_int; +DEALLOCATE PREPARE stmt_dec; + +DROP PROCEDURE p_string; +DROP PROCEDURE p_double; +DROP PROCEDURE p_int; +DROP PROCEDURE p_decimal; + +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; + +CREATE PROCEDURE p1(OUT v1 CHAR(10)) +SET v1 = 'test1'; + +CREATE PROCEDURE p2(OUT v2 CHAR(10)) +BEGIN +SET @query = 'CALL p1(?)'; +PREPARE stmt1 FROM @query; +EXECUTE stmt1 USING @u1; +DEALLOCATE PREPARE stmt1; +SET v2 = @u1; +END| + +CALL p2(@a); +SELECT @a; +@a +test1 + +DROP PROCEDURE p1; +DROP PROCEDURE p2; + +# End of WL#4435. + +End of 6.0 tests. diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 1b2a0cc50b2..3ab65c24040 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -279,6 +279,9 @@ b char(10) YES NULL SET @arg00=1; execute stmt4 using @arg00; Field Type Null Key Default Extra +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'a' +Warning 1292 Truncated incorrect DOUBLE value: 'b' prepare stmt4 from ' show columns from t2 from test like ''a%'' '; execute stmt4; Field Type Null Key Default Extra diff --git a/mysql-test/r/ps_grant.result b/mysql-test/r/ps_grant.result index 8b16123ccea..672db74d9c0 100644 --- a/mysql-test/r/ps_grant.result +++ b/mysql-test/r/ps_grant.result @@ -32,19 +32,19 @@ identified by 'looser' ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' drop table mysqltest.t9 ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' prepare s_t1 from 'select a as my_col from t1' ; execute s_t1 ; my_col diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 6c6d357a462..b67fa9322ee 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -1707,6 +1707,7 @@ Qcache_hits 2 DROP TABLE t1; SET GLOBAL query_cache_size= default; End of 5.0 tests +SET GLOBAL query_cache_size=1024*1024*512; CREATE TABLE t1 (a ENUM('rainbow')); INSERT INTO t1 VALUES (),(),(),(),(); SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID())); @@ -1721,4 +1722,5 @@ SELECT 1 FROM t1 GROUP BY 1 1 DROP TABLE t1; +SET GLOBAL query_cache_size= default; End of 5.1 tests diff --git a/mysql-test/r/query_cache_disabled.result b/mysql-test/r/query_cache_disabled.result new file mode 100644 index 00000000000..f2f58580ca2 --- /dev/null +++ b/mysql-test/r/query_cache_disabled.result @@ -0,0 +1,14 @@ +SHOW GLOBAL VARIABLES LIKE 'query_cache_type'; +Variable_name Value +query_cache_type OFF +SET GLOBAL query_cache_type=ON; +ERROR HY000: Query cache is disabled; restart the server with query_cache_type=1 to enable it +SET GLOBAL query_cache_type=DEMAND; +ERROR HY000: Query cache is disabled; restart the server with query_cache_type=1 to enable it +SET GLOBAL query_cache_type=OFF; +ERROR HY000: Query cache is disabled; restart the server with query_cache_type=1 to enable it +SET GLOBAL query_cache_size=1024*1024; +SHOW GLOBAL VARIABLES LIKE 'query_cache_size'; +Variable_name Value +query_cache_size 1048576 +SET GLOBAL query_cache_size=0; diff --git a/mysql-test/r/query_cache_ps_no_prot.result b/mysql-test/r/query_cache_ps_no_prot.result index 0efb2540c64..f686e876a60 100644 --- a/mysql-test/r/query_cache_ps_no_prot.result +++ b/mysql-test/r/query_cache_ps_no_prot.result @@ -529,5 +529,46 @@ DROP DATABASE mysqltest1; use test; ######################################################################## +# +# Bug#27430 Crash in subquery code when in PS and table DDL changed +# after PREPARE +# Check the effect of automatic reprepare on query cache +# +######################################################################## +drop table if exists t1; +create table t1 (a varchar(255)); +insert into t1 (a) values ("Pack my box with five dozen liquor jugs."); +flush status; +prepare stmt from "select a from t1"; +execute stmt; +a +Pack my box with five dozen liquor jugs. +set @@global.query_cache_size=0; +alter table t1 add column b int; +execute stmt; +a +Pack my box with five dozen liquor jugs. +set @@global.query_cache_size=100000; +execute stmt; +a +Pack my box with five dozen liquor jugs. +execute stmt; +a +Pack my box with five dozen liquor jugs. +# +# Sic: ALTER TABLE caused an automatic reprepare +# of the prepared statement. Since the query cache was disabled +# at the time of reprepare, the new prepared statement doesn't +# work with it. +# +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 0 +show status like 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 0 +# Cleanup +deallocate prepare stmt; +drop table t1; set @@global.query_cache_size=@initial_query_cache_size; flush status; diff --git a/mysql-test/r/query_cache_ps_ps_prot.result b/mysql-test/r/query_cache_ps_ps_prot.result index dc0c4a0193a..e594161f2e9 100644 --- a/mysql-test/r/query_cache_ps_ps_prot.result +++ b/mysql-test/r/query_cache_ps_ps_prot.result @@ -529,5 +529,46 @@ DROP DATABASE mysqltest1; use test; ######################################################################## +# +# Bug#27430 Crash in subquery code when in PS and table DDL changed +# after PREPARE +# Check the effect of automatic reprepare on query cache +# +######################################################################## +drop table if exists t1; +create table t1 (a varchar(255)); +insert into t1 (a) values ("Pack my box with five dozen liquor jugs."); +flush status; +prepare stmt from "select a from t1"; +execute stmt; +a +Pack my box with five dozen liquor jugs. +set @@global.query_cache_size=0; +alter table t1 add column b int; +execute stmt; +a +Pack my box with five dozen liquor jugs. +set @@global.query_cache_size=100000; +execute stmt; +a +Pack my box with five dozen liquor jugs. +execute stmt; +a +Pack my box with five dozen liquor jugs. +# +# Sic: ALTER TABLE caused an automatic reprepare +# of the prepared statement. Since the query cache was disabled +# at the time of reprepare, the new prepared statement doesn't +# work with it. +# +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 0 +show status like 'Qcache_queries_in_cache'; +Variable_name Value +Qcache_queries_in_cache 0 +# Cleanup +deallocate prepare stmt; +drop table t1; set @@global.query_cache_size=@initial_query_cache_size; flush status; diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index c98a7696ea6..7ed8d23d533 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1398,3 +1398,209 @@ a < 10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index DROP TABLE t1, t2, t3; +# +# Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN +# +CREATE TABLE t1(a INT, KEY(a)); +INSERT INTO t1 VALUES (1), (NULL); +SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL); +a +DROP TABLE t1; +# +# Bug#47925: regression of range optimizer and date comparison in 5.1.39! +# +CREATE TABLE t1 ( a DATE, KEY ( a ) ); +CREATE TABLE t2 ( a DATETIME, KEY ( a ) ); +# Make optimizer choose range scan +INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22'); +INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23'); +INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'), +('2009-09-22 12:00:00'); +INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'), +('2009-09-23 12:00:00'); +# DATE vs DATE +EXPLAIN +SELECT * FROM t1 WHERE a >= '2009/09/23'; +id select_type table type possible_keys key key_len ref rows Extra +X X X range a a X X X X +SELECT * FROM t1 WHERE a >= '2009/09/23'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '20090923'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= 20090923; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '2009-9-23'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '2009.09.23'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '2009:09:23'; +a +2009-09-23 +2009-09-23 +2009-09-23 +# DATE vs DATETIME +EXPLAIN +SELECT * FROM t2 WHERE a >= '2009/09/23'; +id select_type table type possible_keys key key_len ref rows Extra +X X X range a a X X X X +SELECT * FROM t2 WHERE a >= '2009/09/23'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '2009/09/23'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '20090923'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= 20090923; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '2009-9-23'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '2009.09.23'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '2009:09:23'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +# DATETIME vs DATETIME +EXPLAIN +SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +X X X range a a X X X X +SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '20090923120000'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= 20090923120000; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '2009-9-23 12:00:00'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '2009.09.23 12:00:00'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +SELECT * FROM t2 WHERE a >= '2009:09:23 12:00:00'; +a +2009-09-23 12:00:00 +2009-09-23 12:00:00 +2009-09-23 12:00:00 +# DATETIME vs DATE +EXPLAIN +SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +X X X range a a X X X X +SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '20090923000000'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= 20090923000000; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '2009-9-23 00:00:00'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '2009.09.23 00:00:00'; +a +2009-09-23 +2009-09-23 +2009-09-23 +SELECT * FROM t1 WHERE a >= '2009:09:23 00:00:00'; +a +2009-09-23 +2009-09-23 +2009-09-23 +# Test of the new get_date_from_str implementation +# Behavior differs slightly between the trunk and mysql-pe. +# The former may give errors for the truncated values, while the latter +# gives warnings. The purpose of this test is not to interfere, and only +# preserve existing behavior. +SELECT str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND +str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20'; +str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND +str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20' +1 +Warnings: +Warning 1292 Truncated incorrect date value: '' +SELECT str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND +str_to_date('2007-20-00', '%Y-%m-%d') <= ''; +str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND +str_to_date('2007-20-00', '%Y-%m-%d') <= '' +NULL +Warnings: +Warning 1292 Truncated incorrect date value: '' +Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date +Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date +SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'; +str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20' +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '' +SELECT str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND ''; +str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND '' +NULL +Warnings: +Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date +SELECT str_to_date('', '%Y-%m-%d'); +str_to_date('', '%Y-%m-%d') +0000-00-00 +DROP TABLE t1, t2; +End of 5.1 tests diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 485bd4e5687..1944edf6ade 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4386,6 +4386,47 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2 DROP TABLE t1; +# +# Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when +# forcing a spatial index +# +CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a)); +INSERT INTO t1 VALUES +(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')), +(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')); +EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL a NULL NULL NULL 2 +SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2; +1 +1 +1 +1 +1 +EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL a NULL NULL NULL 2 +SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a); +1 +1 +1 +1 +1 +DROP TABLE t1; +# +# Bug #48291 : crash with row() operator,select into @var, and +# subquery returning multiple rows +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (2),(3); +# Should not crash +SELECT 1 FROM t1 WHERE a <> 1 AND NOT +ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1)) +INTO @var0; +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1; End of 5.0 tests create table t1(a INT, KEY (a)); INSERT INTO t1 VALUES (1),(2),(3),(4),(5); diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 442511de2b1..091d932a6fc 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1126,7 +1126,7 @@ def information_schema ROUTINES ROUTINES SQL_DATA_ACCESS SQL_DATA_ACCESS 253 192 def information_schema ROUTINES ROUTINES SQL_PATH SQL_PATH 253 192 0 Y 0 0 33 def information_schema ROUTINES ROUTINES SECURITY_TYPE SECURITY_TYPE 253 21 7 N 1 0 33 def information_schema ROUTINES ROUTINES SQL_MODE SQL_MODE 253 24576 0 N 1 0 33 -def information_schema ROUTINES ROUTINES ROUTINE_COMMENT ROUTINE_COMMENT 253 192 0 N 1 0 33 +def information_schema ROUTINES ROUTINES ROUTINE_COMMENT ROUTINE_COMMENT 252 589815 0 N 17 0 33 def information_schema ROUTINES ROUTINES DEFINER DEFINER 253 231 14 N 1 0 33 SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE SQL_MODE ROUTINE_COMMENT DEFINER p1 def test p1 PROCEDURE NULL SQL SELECT 1 NULL NULL SQL NO CONTAINS SQL NULL DEFINER root@localhost @@ -1181,7 +1181,7 @@ def information_schema ROUTINES ROUTINES SQL_DATA_ACCESS SQL_DATA_ACCESS 253 192 def information_schema ROUTINES ROUTINES SQL_PATH SQL_PATH 253 192 0 Y 0 0 33 def information_schema ROUTINES ROUTINES SECURITY_TYPE SECURITY_TYPE 253 21 7 N 1 0 33 def information_schema ROUTINES ROUTINES SQL_MODE SQL_MODE 253 24576 0 N 1 0 33 -def information_schema ROUTINES ROUTINES ROUTINE_COMMENT ROUTINE_COMMENT 253 192 0 N 1 0 33 +def information_schema ROUTINES ROUTINES ROUTINE_COMMENT ROUTINE_COMMENT 252 589815 0 N 17 0 33 def information_schema ROUTINES ROUTINES DEFINER DEFINER 253 231 14 N 1 0 33 SPECIFIC_NAME ROUTINE_CATALOG ROUTINE_SCHEMA ROUTINE_NAME ROUTINE_TYPE DTD_IDENTIFIER ROUTINE_BODY ROUTINE_DEFINITION EXTERNAL_NAME EXTERNAL_LANGUAGE PARAMETER_STYLE IS_DETERMINISTIC SQL_DATA_ACCESS SQL_PATH SECURITY_TYPE SQL_MODE ROUTINE_COMMENT DEFINER f1 def test f1 FUNCTION int(11) SQL RETURN 1 NULL NULL SQL NO CONTAINS SQL NULL DEFINER root@localhost diff --git a/mysql-test/r/sp-bugs.result b/mysql-test/r/sp-bugs.result new file mode 100644 index 00000000000..14c5311bbe5 --- /dev/null +++ b/mysql-test/r/sp-bugs.result @@ -0,0 +1,47 @@ +# +# Bug #47412: Valgrind warnings / user can read uninitalized memory +# using SP variables +# +CREATE SCHEMA testdb; +USE testdb; +CREATE FUNCTION f2 () RETURNS INTEGER +BEGIN +DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1; +RETURN f_not_exists () ; +END| +CREATE PROCEDURE p3 ( arg1 VARCHAR(32) ) +BEGIN +CALL p_not_exists ( ); +END| +# should not return valgrind warnings +CALL p3 ( f2 () ); +ERROR 42000: PROCEDURE testdb.p_not_exists does not exist +DROP SCHEMA testdb; +CREATE SCHEMA testdb; +USE testdb; +CREATE FUNCTION f2 () RETURNS INTEGER +BEGIN +DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1; +RETURN f_not_exists () ; +END| +CREATE PROCEDURE p3 ( arg2 INTEGER ) +BEGIN +CALL p_not_exists ( ); +END| +# should not return valgrind warnings +CALL p3 ( f2 () ); +ERROR 42000: PROCEDURE testdb.p_not_exists does not exist +DROP SCHEMA testdb; +CREATE SCHEMA testdb; +USE testdb; +CREATE FUNCTION f2 () RETURNS INTEGER +BEGIN +DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1; +RETURN f_not_exists () ; +END| +# should not return valgrind warnings +SELECT f2 (); +f2 () +NULL +DROP SCHEMA testdb; +End of 5.1 tests diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 17ab2b79043..b3968ea7eb6 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1670,3 +1670,19 @@ NULL SELECT non_existent (a) FROM t1 WHERE b = 999999; ERROR 42000: FUNCTION test.non_existent does not exist DROP TABLE t1; +# +# Bug #47788: Crash in TABLE_LIST::hide_view_error on UPDATE + VIEW + +# SP + MERGE + ALTER +# +CREATE TABLE t1 (pk INT, b INT, KEY (b)); +CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1; +CREATE PROCEDURE p1 (a int) UPDATE IGNORE v1 SET b = a; +CALL p1(5); +ERROR HY000: The target table v1 of the UPDATE is not updatable +ALTER TABLE t1 CHANGE COLUMN b b2 INT; +CALL p1(7); +ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +DROP PROCEDURE p1; +DROP VIEW v1; +DROP TABLE t1; +End of 5.1 tests diff --git a/mysql-test/r/sp-vars.result b/mysql-test/r/sp-vars.result index f532a5284a9..f167986e82c 100644 --- a/mysql-test/r/sp-vars.result +++ b/mysql-test/r/sp-vars.result @@ -1158,3 +1158,30 @@ f1() @b 0 abc drop function f1; drop table t1; + +--------------------------------------------------------------- +BUG#28299 +--------------------------------------------------------------- + +CREATE PROCEDURE ctest() +BEGIN +DECLARE i CHAR(16); +DECLARE j INT; +SET i= 'string'; +SET j= 1 + i; +END| +CALL ctest(); +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'string ' +DROP PROCEDURE ctest; +CREATE PROCEDURE vctest() +BEGIN +DECLARE i VARCHAR(16); +DECLARE j INT; +SET i= 'string'; +SET j= 1 + i; +END| +CALL vctest(); +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'string' +DROP PROCEDURE vctest; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index fce588f704c..45dac2f5523 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6926,3 +6926,35 @@ DROP TABLE t1, t2; # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ +DROP FUNCTION IF EXISTS f1; +DROP TABLE IF EXISTS t_non_existing; +DROP TABLE IF EXISTS t1; +CREATE FUNCTION f1() RETURNS INT +BEGIN +DECLARE v INT; +SELECT a INTO v FROM t_non_existing; +RETURN 1; +END| +CREATE TABLE t1 (a INT) ENGINE = myisam; +INSERT INTO t1 VALUES (1); +SELECT * FROM t1 WHERE a = f1(); +ERROR 42S02: Table 'test.t_non_existing' doesn't exist +DROP FUNCTION f1; +DROP TABLE t1; +# +# Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non +# strict SQL mode +# +DROP PROCEDURE IF EXISTS p1; +CREATE PROCEDURE p1 () +COMMENT +'12345678901234567890123456789012345678901234567890123456789012345678901234567890' +BEGIN +END; +SELECT comment FROM mysql.proc WHERE name = "p1"; +comment +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +SELECT routine_comment FROM information_schema.routines WHERE routine_name = "p1"; +routine_comment +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +DROP PROCEDURE p1; diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result index 3cc251bc0a6..be45e5ff5d7 100644 --- a/mysql-test/r/sp_trans.result +++ b/mysql-test/r/sp_trans.result @@ -556,3 +556,30 @@ f1 bug13575(f1) 3 ccc drop function bug13575| drop table t3| +# +# End of 5.1 tests +# +# +# Bug #35877 Update .. WHERE with function, constraint violation, crash +# +DROP TABLE IF EXISTS t1_aux| +DROP TABLE IF EXISTS t1_not_null| +DROP FUNCTION IF EXISTS f1_two_inserts| +# MyISAM test +CREATE TABLE t1_not_null (f1 BIGINT, f2 BIGINT NOT NULL)| +CREATE TABLE t1_aux (f1 BIGINT, f2 BIGINT)| +INSERT INTO t1_aux VALUES (1,1)| +CREATE FUNCTION f1_two_inserts() returns INTEGER +BEGIN +INSERT INTO t1_not_null SET f1 = 10, f2 = NULL; +RETURN 1; +END| +UPDATE t1_aux SET f2 = 2 WHERE f1 = f1_two_inserts()| +ERROR 23000: Column 'f2' cannot be null +# InnoDB test +ALTER TABLE t1_not_null ENGINE = InnoDB| +ALTER TABLE t1_aux ENGINE = InnoDB| +UPDATE t1_aux SET f2 = 2 WHERE f1 = f1_two_inserts()| +ERROR 23000: Column 'f2' cannot be null +DROP TABLE t1_aux, t1_not_null| +DROP FUNCTION f1_two_inserts| diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index 0b0d5a38d0b..e83879274a1 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -506,6 +506,12 @@ mysqltest_32753@localhost set session sql_mode=@OLD_SQL_MODE; flush privileges; drop user mysqltest_32753@localhost; +SET @org_mode=@@sql_mode; +SET @@sql_mode='traditional'; +SELECT @@sql_mode LIKE '%NO_ENGINE_SUBSTITUTION%'; +@@sql_mode LIKE '%NO_ENGINE_SUBSTITUTION%' +1 +SET sql_mode=@org_mode; DROP TABLE IF EXISTS t1,t2; CREATE USER 'user_PCTFL'@'localhost' identified by 'PWD'; CREATE USER 'user_no_PCTFL'@'localhost' identified by 'PWD'; diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index a9e0d7f457d..897c9072203 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -2,7 +2,7 @@ set @org_mode=@@sql_mode; set @@sql_mode='ansi,traditional'; select @@sql_mode; @@sql_mode -REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (col1 date); INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29'); diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index e00946a1b9e..6325dc4f2fc 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -75,7 +75,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1)); ERROR HY000: Incorrect usage of PROCEDURE and subquery SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1)); -ERROR HY000: Incorrect usage of PROCEDURE and subquery +ERROR HY000: Incorrect parameters to procedure 'ANALYSE' SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL; ERROR 42S22: Unknown column 'a' in 'field list' SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL; @@ -4412,8 +4412,7 @@ FROM t1 WHERE a = 230; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -2 DEPENDENT SUBQUERY st1 index NULL a 5 NULL 2 Using index -2 DEPENDENT SUBQUERY st2 index b b 5 NULL 2 Using where; Using index; Using join buffer +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b) FROM t1 WHERE a = 230; @@ -4837,4 +4836,18 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v ); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTO @v )' at line 1 DROP TABLE t1, t2; +CREATE TABLE t1 (a ENUM('rainbow')); +INSERT INTO t1 VALUES (),(),(),(),(); +SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID())); +1 +1 +DROP TABLE t1; +CREATE TABLE t1 (a LONGBLOB); +INSERT INTO t1 SET a = 'aaaa'; +INSERT INTO t1 SET a = 'aaaa'; +SELECT 1 FROM t1 GROUP BY +(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1); +1 +1 +DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index f20ae6a31be..3a0576768b2 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -895,3 +895,72 @@ t1.a < (select t4.a+10 from t4, t5 limit 2)); ERROR 21000: Subquery returns more than 1 row drop table t0, t1, t2, t3, t4, t5; +# +# BUG#48177 - SELECTs with NOT IN subqueries containing NULL +# values return too many records +# +CREATE TABLE t1 ( +i1 int DEFAULT NULL, +i2 int DEFAULT NULL +) ; +INSERT INTO t1 VALUES (1, NULL); +INSERT INTO t1 VALUES (2, 3); +INSERT INTO t1 VALUES (4, NULL); +INSERT INTO t1 VALUES (4, 0); +INSERT INTO t1 VALUES (NULL, NULL); +CREATE TABLE t2 ( +i1 int DEFAULT NULL, +i2 int DEFAULT NULL +) ; +INSERT INTO t2 VALUES (4, NULL); +INSERT INTO t2 VALUES (5, 0); + +Data in t1 +SELECT i1, i2 FROM t1; +i1 i2 +1 NULL +2 3 +4 NULL +4 0 +NULL NULL + +Data in subquery (should be filtered out) +SELECT i1, i2 FROM t2 ORDER BY i1; +i1 i2 +4 NULL +5 0 +FLUSH STATUS; + +SELECT i1, i2 +FROM t1 +WHERE (i1, i2) +NOT IN (SELECT i1, i2 FROM t2); +i1 i2 +1 NULL +2 3 + +# Check that the subquery only has to be evaluated once +# for all-NULL values even though there are two (NULL,NULL) records +# Baseline: +SHOW STATUS LIKE '%Handler_read_rnd_next'; +Variable_name Value +Handler_read_rnd_next 17 + +INSERT INTO t1 VALUES (NULL, NULL); +FLUSH STATUS; + +SELECT i1, i2 +FROM t1 +WHERE (i1, i2) +NOT IN (SELECT i1, i2 FROM t2); +i1 i2 +1 NULL +2 3 + +# Handler_read_rnd_next should be one more than baseline +# (read record from t1, but do not read from t2) +SHOW STATUS LIKE '%Handler_read_rnd_next'; +Variable_name Value +Handler_read_rnd_next 18 +DROP TABLE t1,t2; +End of 5.1 tests diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index e252331cd1a..679e50fcad9 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -110,6 +110,7 @@ user CREATE TABLE `user` ( `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', + `Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '', `ssl_cipher` blob NOT NULL, `x509_issuer` blob NOT NULL, @@ -161,7 +162,7 @@ procs_priv CREATE TABLE `procs_priv` ( `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '', `Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '', `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '', - `Routine_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '', + `Routine_name` char(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `Routine_type` enum('FUNCTION','PROCEDURE') COLLATE utf8_bin NOT NULL, `Grantor` char(77) COLLATE utf8_bin NOT NULL DEFAULT '', `Proc_priv` set('Execute','Alter Routine','Grant') CHARACTER SET utf8 NOT NULL DEFAULT '', @@ -201,7 +202,7 @@ proc CREATE TABLE `proc` ( `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '', - `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', + `comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, `db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 000b08113c1..1a6494e03ad 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -2088,3 +2088,30 @@ SELECT * FROM t2; a b DROP TABLE t1, t2; End of 5.1 tests. +# +# Bug#34453 Can't change size of file (Errcode: 1224) +# +DROP TRIGGER IF EXISTS t1_bi; +DROP TRIGGER IF EXISTS t1_bd; +DROP TABLE IF EXISTS t1; +DROP TEMPORARY TABLE IF EXISTS t2; +CREATE TABLE t1 (s1 INT); +CREATE TEMPORARY TABLE t2 (s1 INT); +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (0); +CREATE TRIGGER t1_bd BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t2; +INSERT INTO t1 VALUES (0); +INSERT INTO t1 VALUES (0); +SELECT * FROM t1; +s1 +0 +0 +SELECT * FROM t2; +s1 +0 +0 +# Reported to give ERROR 14 (HY000): +# Can't change size of file (Errcode: 1224) +# on Windows +DELETE FROM t1; +DROP TABLE t1; +DROP TEMPORARY TABLE t2; diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index 76c5ea8f756..67898b7f335 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -3,13 +3,13 @@ SET SQL_WARNINGS=1; CREATE TABLE t1 ( id int(11) NOT NULL auto_increment, datatype_id int(11) DEFAULT '0' NOT NULL, -minvalue decimal(20,10) DEFAULT '0.0000000000' NOT NULL, -maxvalue decimal(20,10) DEFAULT '0.0000000000' NOT NULL, +min_value decimal(20,10) DEFAULT '0.0000000000' NOT NULL, +max_value decimal(20,10) DEFAULT '0.0000000000' NOT NULL, valuename varchar(20), forecolor int(11), backcolor int(11), PRIMARY KEY (id), -UNIQUE datatype_id (datatype_id, minvalue, maxvalue) +UNIQUE datatype_id (datatype_id, min_value, max_value) ); INSERT INTO t1 VALUES ( '1', '4', '0.0000000000', '0.0000000000', 'Ei saja', '0', '16776960'); INSERT INTO t1 VALUES ( '2', '4', '1.0000000000', '1.0000000000', 'Sajab', '16777215', '255'); @@ -143,12 +143,12 @@ INSERT INTO t1 VALUES ( '139', '21', '326.0000000000', '326.0000000000', 'Lumine INSERT INTO t1 VALUES ( '143', '16', '-4.9000000000', '-0.1000000000', '', NULL, '15774720'); INSERT INTO t1 VALUES ( '145', '15', '0.0000000000', '1.9000000000', '', '0', '16769024'); INSERT INTO t1 VALUES ( '146', '16', '0.0000000000', '1.9000000000', '', '0', '16769024'); -select * from t1 where minvalue<=1 and maxvalue>=-1 and datatype_id=16; -id datatype_id minvalue maxvalue valuename forecolor backcolor +select * from t1 where min_value<=1 and max_value>=-1 and datatype_id=16; +id datatype_id min_value max_value valuename forecolor backcolor 143 16 -4.9000000000 -0.1000000000 NULL 15774720 146 16 0.0000000000 1.9000000000 0 16769024 -select * from t1 where minvalue<=-1 and maxvalue>=-1 and datatype_id=16; -id datatype_id minvalue maxvalue valuename forecolor backcolor +select * from t1 where min_value<=-1 and max_value>=-1 and datatype_id=16; +id datatype_id min_value max_value valuename forecolor backcolor 143 16 -4.9000000000 -0.1000000000 NULL 15774720 drop table t1; create table t1 (a decimal(10,2)); diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 1ad46821bb7..ed10fa5d67f 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1495,9 +1495,9 @@ CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL); INSERT INTO t1 VALUES (3,30), (1,10), (2,10); SELECT a+CAST(1 AS decimal(65,30)) AS aa, SUM(b) FROM t1 GROUP BY aa; aa SUM(b) -2.00000000000000000000000000000 10 -3.00000000000000000000000000000 10 -4.00000000000000000000000000000 30 +2.000000000000000000000000000000 10 +3.000000000000000000000000000000 10 +4.000000000000000000000000000000 30 SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa; ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30. DROP TABLE t1; @@ -1521,13 +1521,13 @@ f1 DROP TABLE t1; CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1; Warnings: -Note 1265 Data truncated for column 'f1' at row 1 +Warning 1264 Out of range value for column 'f1' at row 1 DESC t1; Field Type Null Key Default Extra -f1 decimal(65,20) NO 0.00000000000000000000 +f1 decimal(65,30) NO 0.000000000000000000000000000000 SELECT f1 FROM t1; f1 -123451234512345123451234512345123451234512345.67890678906789067891 +99999999999999999999999999999999999.999999999999999999999999999999 DROP TABLE t1; select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 * 1.01500000 * 1.01500000 * 0.99500000); @@ -1595,7 +1595,7 @@ Warnings: Note 1265 Data truncated for column 'my_col' at row 1 DESCRIBE t1; Field Type Null Key Default Extra -my_col decimal(32,30) NO 0.000000000000000000000000000000 +my_col decimal(65,30) NO 0.000000000000000000000000000000 SELECT my_col FROM t1; my_col 1.123456789123456789123456789123 @@ -1625,212 +1625,8 @@ Warnings: Note 1265 Data truncated for column 'my_col' at row 1 DESCRIBE t1; Field Type Null Key Default Extra -my_col decimal(30,30) YES NULL +my_col decimal(65,30) YES NULL SELECT my_col FROM t1; my_col 0.012345687012345687012345687012 DROP TABLE t1; -# -# Bug#45261: Crash, stored procedure + decimal -# -DROP TABLE IF EXISTS t1; -CREATE TABLE t1 SELECT -/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001 -AS c1; -Warnings: -Warning 1264 Out of range value for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,0) NO 0 -SELECT * FROM t1; -c1 -99999999999999999999999999999999999999999999999999999999999999999 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001. -AS c1; -Warnings: -Warning 1264 Out of range value for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,0) NO 0 -SELECT * FROM t1; -c1 -99999999999999999999999999999999999999999999999999999999999999999 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */ -AS c1; -Warnings: -Warning 1264 Out of range value for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,0) NO 0 -SELECT * FROM t1; -c1 -99999999999999999999999999999999999999999999999999999999999999999 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001 -AS c1; -Warnings: -Warning 1292 Truncated incorrect DECIMAL value: '' -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,0) NO 0 -SELECT * FROM t1; -c1 -99999999999999999999999999999999999999999999999999999999999999999 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */ -AS c1; -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,25) NO 0.0000000000000000000000000 -SELECT * FROM t1; -c1 -1000000000000000000000000000000000000001.1000000000000000000000000 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */ -AS c1; -DESC t1; -Field Type Null Key Default Extra -c1 decimal(31,30) NO 0.000000000000000000000000000000 -SELECT * FROM t1; -c1 -1.100000000000000000000000000000 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */ -AS c1; -DESC t1; -Field Type Null Key Default Extra -c1 decimal(31,30) NO 0.000000000000000000000000000000 -SELECT * FROM t1; -c1 -1.100000000000000000000000000000 -DROP TABLE t1; -CREATE TABLE t1 SELECT -.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */ -AS c1; -Warnings: -Note 1265 Data truncated for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(30,30) NO 0.000000000000000000000000000000 -SELECT * FROM t1; -c1 -0.100000000000000000000000000000 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */ -AS c1; -Warnings: -Note 1265 Data truncated for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,20) NO 0.00000000000000000000 -SELECT * FROM t1; -c1 -123456789012345678901234567890123456789012345.12345678901234567890 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */ -AS c1; -Warnings: -Note 1265 Data truncated for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,0) NO 0 -SELECT * FROM t1; -c1 -12345678901234567890123456789012345678901234567890123456789012345 -DROP TABLE t1; -CREATE TABLE t1 SELECT -/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */ -AS c1; -Warnings: -Warning 1264 Out of range value for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,0) NO 0 -SELECT * FROM t1; -c1 -99999999999999999999999999999999999999999999999999999999999999999 -DROP TABLE t1; -CREATE TABLE t1 SELECT -.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */ -AS c1; -Warnings: -Note 1265 Data truncated for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(30,30) NO 0.000000000000000000000000000000 -SELECT * FROM t1; -c1 -0.123456789012345678901234567890 -DROP TABLE t1; -CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1; -Warnings: -Note 1265 Data truncated for column 'c1' at row 1 -DESC t1; -Field Type Null Key Default Extra -c1 decimal(33,30) NO 0.000000000000000000000000000000 -SELECT * FROM t1; -c1 -123.123456789012345678901234567890 -DROP TABLE t1; -CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1; -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,29) NO 0.00000000000000000000000000000 -SELECT * FROM t1; -c1 -2.10000000000000000000000000000 -DROP TABLE t1; -# -# Test that the integer and decimal parts are properly calculated. -# -CREATE TABLE t1 (a DECIMAL(30,30)); -INSERT INTO t1 VALUES (0.1),(0.2),(0.3); -CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1; -Warnings: -Note 1265 Data truncated for column 'c1' at row 4 -DESC t2; -Field Type Null Key Default Extra -c1 decimal(32,30) YES NULL -DROP TABLE t1,t2; -CREATE TABLE t1 (a DECIMAL(30,30)); -INSERT INTO t1 VALUES (0.1),(0.2),(0.3); -CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1; -Warnings: -Note 1265 Data truncated for column 'c1' at row 1 -Note 1265 Data truncated for column 'c1' at row 2 -Note 1265 Data truncated for column 'c1' at row 3 -DESC t2; -Field Type Null Key Default Extra -c1 decimal(32,30) YES NULL -DROP TABLE t1,t2; -CREATE TABLE t1 (a DECIMAL(30,30)); -INSERT INTO t1 VALUES (0.1),(0.2),(0.3); -CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1; -Warnings: -Note 1265 Data truncated for column 'c1' at row 1 -DESC t2; -Field Type Null Key Default Extra -c1 decimal(31,30) YES NULL -DROP TABLE t1,t2; -# -# Test that variables get maximum precision. -# -SET @decimal= 1.1; -CREATE TABLE t1 SELECT @decimal AS c1; -DESC t1; -Field Type Null Key Default Extra -c1 decimal(65,30) YES NULL -SELECT * FROM t1; -c1 -1.100000000000000000000000000000 -DROP TABLE t1; diff --git a/mysql-test/r/type_varchar.result b/mysql-test/r/type_varchar.result index 96042a91bae..6b614960422 100644 --- a/mysql-test/r/type_varchar.result +++ b/mysql-test/r/type_varchar.result @@ -489,3 +489,23 @@ Warnings: Warning 1292 Truncated incorrect INTEGER value: '1a' Warning 1292 Truncated incorrect INTEGER value: 't' DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(16)); +INSERT INTO t1 VALUES ('5'), ('s'), (''); +SELECT 5 = a FROM t1; +5 = a +1 +0 +0 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 's' +DROP TABLE t1; +CREATE TABLE t1 (a CHAR(16)); +INSERT INTO t1 VALUES ('5'), ('s'), (''); +SELECT 5 = a FROM t1; +5 = a +1 +0 +0 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 's ' +DROP TABLE t1; diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 7a51649fac5..d859579e835 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -503,3 +503,14 @@ ERROR HY000: Recursive stored functions and triggers are not allowed. DROP TABLE t1; DROP FUNCTION f1; End of 5.0 tests +# +# Bug #47919 assert in open_table during ALTER temporary table +# +CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1)); +CREATE TEMPORARY TABLE t2 LIKE t1; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +ALTER TABLE t2 COMMENT = 'ABC'; +UPDATE t2, t1 SET t2.f1 = 2, t1.f1 = 9; +ALTER TABLE t2 COMMENT = 'DEF'; +DROP TABLE t1, t2; diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index a9d4164cda4..65fbf2d87b6 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -799,12 +799,12 @@ CREATE USER u29908_1@localhost; CREATE DEFINER = u29908_1@localhost VIEW v1 AS SELECT f1 FROM t1; CREATE DEFINER = u29908_1@localhost SQL SECURITY INVOKER VIEW v2 AS SELECT f1 FROM t1; -GRANT DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v1 TO u29908_1@localhost; -GRANT DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v2 TO u29908_1@localhost; +GRANT SELECT, DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v1 TO u29908_1@localhost; +GRANT SELECT, DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v2 TO u29908_1@localhost; GRANT SELECT ON mysqltest_29908.t1 TO u29908_1@localhost; CREATE USER u29908_2@localhost; -GRANT DROP, CREATE VIEW ON mysqltest_29908.v1 TO u29908_2@localhost; -GRANT DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v2 TO u29908_2@localhost; +GRANT SELECT, DROP, CREATE VIEW ON mysqltest_29908.v1 TO u29908_2@localhost; +GRANT SELECT, DROP, CREATE VIEW, SHOW VIEW ON mysqltest_29908.v2 TO u29908_2@localhost; GRANT SELECT ON mysqltest_29908.t1 TO u29908_2@localhost; ALTER VIEW v1 AS SELECT f2 FROM t1; ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation @@ -1218,3 +1218,22 @@ Warnings: Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist DROP TABLE t1; DROP VIEW v1; +# +# Bug #46019: ERROR 1356 When selecting from within another +# view that has Group By +# +CREATE DATABASE mysqltest1; +USE mysqltest1; +CREATE TABLE t1 (a INT); +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT a FROM t1 GROUP BY a; +CREATE SQL SECURITY INVOKER VIEW v2 AS SELECT a FROM v1; +CREATE USER mysqluser1; +GRANT SELECT ON TABLE t1 TO mysqluser1; +GRANT SELECT, SHOW VIEW ON TABLE v1 TO mysqluser1; +GRANT SELECT, SHOW VIEW ON TABLE v2 TO mysqluser1; +SELECT a FROM v1; +a +SELECT a FROM v2; +a +DROP USER mysqluser1; +DROP DATABASE mysqltest1; diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index a597806d897..d23c8e672b0 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -89,3 +89,28 @@ xa start 'a'; xa end 'a'; xa prepare 'a'; xa commit 'a'; +CREATE TABLE t1(a INT, KEY(a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1),(2); +BEGIN; +UPDATE t1 SET a=3 WHERE a=1; +BEGIN; +UPDATE t1 SET a=4 WHERE a=2; +UPDATE t1 SET a=5 WHERE a=2; +UPDATE t1 SET a=5 WHERE a=1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +ROLLBACK; +ROLLBACK; +BEGIN; +UPDATE t1 SET a=3 WHERE a=1; +XA START 'xid1'; +UPDATE t1 SET a=4 WHERE a=2; +UPDATE t1 SET a=5 WHERE a=2; +UPDATE t1 SET a=5 WHERE a=1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +XA END 'xid1'; +ERROR XA102: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected +XA ROLLBACK 'xid1'; +XA START 'xid1'; +XA END 'xid1'; +XA ROLLBACK 'xid1'; +DROP TABLE t1; diff --git a/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result b/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result new file mode 100644 index 00000000000..036ccf131bb --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result @@ -0,0 +1,50 @@ +RESET MASTER; +CREATE TABLE t1 (a int); +### assertion: index file contains regular entries +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000001 + +### assertion: show original binlogs +show binary logs; +Log_name File_size +master-bin.000001 # +### assertion: binlog contents from regular entries +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int) +FLUSH LOGS; +### assertion: index file contains renamed binlog and the new one +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin-b34582.000001 +master-bin.000002 + +### assertion: original binlog content still exists, despite we +### renamed and changed the index file +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin-b34582.000001 # Query # # use `test`; CREATE TABLE t1 (a int) +### assertion: user changed binlog index shows correct entries +show binary logs; +Log_name File_size +master-bin-b34582.000001 # +master-bin.000002 # +DROP TABLE t1; +### assertion: purging binlogs up to binlog created after instrumenting index file should work +PURGE BINARY LOGS TO 'master-bin.000002'; +### assertion: show binary logs should only contain latest binlog +show binary logs; +Log_name File_size +master-bin.000002 # +### assertion: assert that binlog files were indeed purged (using file_exists calls) +### assertion: assert that not purged binlog file exists +### assertion: show index file contents and these should match show binary logs issued above +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000002 + +RESET MASTER; diff --git a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result index 0a6ff1d4400..75c088e595d 100644 --- a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result +++ b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result @@ -19,6 +19,7 @@ DROP TABLE IF EXISTS tmp2, t; SELECT GET_LOCK("a",10); GET_LOCK("a",10) 1 +USE test; SELECT GET_LOCK("a",10); GET_LOCK("a",10) 1 diff --git a/mysql-test/suite/binlog/r/binlog_stm_do_db.result b/mysql-test/suite/binlog/r/binlog_stm_do_db.result new file mode 100644 index 00000000000..ab4ba7cdca1 --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_stm_do_db.result @@ -0,0 +1,42 @@ +SET @old_isolation_level= @@session.tx_isolation; +SET @@session.tx_isolation= 'READ-COMMITTED'; +CREATE DATABASE b42829; +use b42829; +CREATE TABLE t1 (x int, y int) engine=InnoDB; +CREATE TABLE t2 (x int, y int) engine=InnoDB; +CREATE DATABASE b42829_filtered; +use b42829_filtered; +CREATE TABLE t1 (x int, y int) engine=InnoDB; +CREATE TABLE t2 (x int, y int) engine=InnoDB; +SET @@session.sql_log_bin= 0; +INSERT INTO b42829_filtered.t1 VALUES (100,100); +INSERT INTO b42829.t1 VALUES (100,100); +SET @@session.sql_log_bin= 1; +### assertion: the inserts will not raise log error because +### binlog-do-db is filtering used database +INSERT INTO t2 VALUES (1,2), (1,3), (1,4); +INSERT INTO t1 SELECT * FROM t2; +### assertion: assert that despite updating a not filtered +### database this wont trigger an error as the +### used database is the filtered one. +UPDATE b42829_filtered.t1 ft1, b42829.t1 nft1 SET ft1.x=1, nft1.x=2; +use b42829; +### assertion: the statements *will* raise log error because +### binlog-do-db is not filtering used database +BEGIN; +INSERT INTO t2 VALUES (1,2), (1,3), (1,4); +ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT' +UPDATE b42829_filtered.t1 ft1, b42829.t1 nft1 SET ft1.x=1, nft1.x=2; +ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT' +INSERT INTO t1 SELECT * FROM t2; +ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT' +COMMIT; +### assertion: filtered events did not make into the binlog +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # CREATE DATABASE b42829 +master-bin.000001 # Query # # use `b42829`; CREATE TABLE t1 (x int, y int) engine=InnoDB +master-bin.000001 # Query # # use `b42829`; CREATE TABLE t2 (x int, y int) engine=InnoDB +DROP DATABASE b42829; +DROP DATABASE b42829_filtered; +SET @@session.tx_isolation= @old_isolation_level; diff --git a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result index 8bbf1bccc63..19ddcf49080 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result +++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result @@ -19,6 +19,7 @@ DROP TABLE IF EXISTS tmp2, t; SELECT GET_LOCK("a",10); GET_LOCK("a",10) 1 +USE test; SELECT GET_LOCK("a",10); GET_LOCK("a",10) 1 diff --git a/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test new file mode 100644 index 00000000000..84c83687486 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test @@ -0,0 +1,114 @@ +# BUG#34582: FLUSH LOGS does not close and reopen the binlog index +# file +# +# WHAT +# ==== +# +# We want to test that FLUSH LOGS closes and reopens binlog index +# file. +# +# HOW +# === +# +# PREPARE: +# 1. create some binlog events +# 2. show index content, binlog events and binlog contents +# for mysql-bin.000001 +# 3. copy the mysql-bin.000001 to mysql-bin-b34582.000001 +# 4. change the index file so that mysql-bin.000001 is replaced +# with mysql-bin-b34582.000001 +# 5. FLUSH the logs so that new index is closed and reopened +# +# ASSERTIONS: +# 1. index file contents shows mysql-bin-b34582.000001 and +# mysql-bin.000002 +# 1. show binary logs shows current index entries +# 2. binlog contents for mysql-bin-b34582.000001 are displayed +# 3. Purge binlogs up to the latest one succeeds +# 4. SHOW BINARY LOGS presents the latest one only after purging +# 5. Purged binlogs files don't exist in the filesystem +# 6. Not purged binlog file exists in the filesystem +# +# CLEAN UP: +# 1. RESET MASTER +# + +-- source include/have_log_bin.inc + +RESET MASTER; + +-- let $datadir= `SELECT @@datadir` +-- let $index=$datadir/master-bin.index +-- chmod 0644 $index + +# action: issue one command so that binlog gets some event +CREATE TABLE t1 (a int); + +-- echo ### assertion: index file contains regular entries +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo ### assertion: show original binlogs +-- source include/show_binary_logs.inc + +--echo ### assertion: binlog contents from regular entries +-- source include/show_binlog_events.inc + +# action: copy binlogs to other names and change entries in index file +-- copy_file $datadir/master-bin.000001 $datadir/master-bin-b34582.000001 +let INDEX_FILE=$index; +perl; +$file= $ENV{'INDEX_FILE'}; +open(FILE, ">$file") || die "Unable to open $file."; +truncate(FILE,0); +close ($file); +EOF + +-- append_file $index +master-bin-b34582.000001 +EOF + +# action: should cause rotation, and creation of new binlogs +FLUSH LOGS; + +# file is not used anymore - remove it (mysql closed on flush logs). +-- remove_file $datadir/master-bin.000001 + +-- echo ### assertion: index file contains renamed binlog and the new one +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +-- echo ### assertion: original binlog content still exists, despite we +-- echo ### renamed and changed the index file +-- source include/show_binlog_events.inc + +-- echo ### assertion: user changed binlog index shows correct entries +-- source include/show_binary_logs.inc + +DROP TABLE t1; + +-- echo ### assertion: purging binlogs up to binlog created after instrumenting index file should work +-- let $current_binlog= query_get_value(SHOW MASTER STATUS, File, 1) +-- eval PURGE BINARY LOGS TO '$current_binlog' + +-- echo ### assertion: show binary logs should only contain latest binlog +-- source include/show_binary_logs.inc + +-- echo ### assertion: assert that binlog files were indeed purged (using file_exists calls) +-- error 1 +-- file_exists $datadir/master-bin-b34852.000001 + +-- echo ### assertion: assert that not purged binlog file exists +-- file_exists $datadir/$current_binlog + +-- echo ### assertion: show index file contents and these should match show binary logs issued above +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +RESET MASTER; diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt new file mode 100644 index 00000000000..e2cfcb299cf --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt @@ -0,0 +1 @@ +--binlog-do-db=b42829 diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db.test b/mysql-test/suite/binlog/t/binlog_stm_do_db.test new file mode 100644 index 00000000000..858bc8cc683 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_stm_do_db.test @@ -0,0 +1,90 @@ +# BUG#42829: binlogging enabled for all schemas regardless of +# binlog-db-db / binlog-ignore-db +# +# WHAT +# ==== +# +# We want to test whether filtered events from binlog will cause +# raising an error mentioning that statement is unable to be logged or +# not, when: +# +# 1. isolation level READ-COMMITTED; AND +# +# 2. using InnoDB engine; AND +# +# 3. using SBL (in which case InnoDB will only allow RBL). +# +# HOW +# === +# +# The test is implemented as follows: +# +# i) set tx_isolation to read-committed. +# +# ii) create two databases (one filtered other not - using +# binlog-do-db) +# +# iii) Create statements that are to be filtered on filtered db +# +# - At this point, before fix, an error would be raised +# +# iv) do the same thing for not the filtered database and check +# that events throw an error: +# +# - Error: ER_BINLOG_STMT_MODE_AND_ROW_ENGINE +# + +-- source include/have_log_bin.inc +-- source include/have_innodb.inc +-- source include/have_binlog_format_statement.inc + +SET @old_isolation_level= @@session.tx_isolation; +SET @@session.tx_isolation= 'READ-COMMITTED'; + +-- let $engine= InnoDB +-- let $filtered= b42829_filtered +-- let $not_filtered= b42829 + +-- eval CREATE DATABASE $not_filtered +-- eval use $not_filtered +-- eval CREATE TABLE t1 (x int, y int) engine=$engine +-- eval CREATE TABLE t2 (x int, y int) engine=$engine + +-- eval CREATE DATABASE $filtered +-- eval use $filtered +-- eval CREATE TABLE t1 (x int, y int) engine=$engine +-- eval CREATE TABLE t2 (x int, y int) engine=$engine + +SET @@session.sql_log_bin= 0; +-- eval INSERT INTO $filtered.t1 VALUES (100,100) +-- eval INSERT INTO $not_filtered.t1 VALUES (100,100) +SET @@session.sql_log_bin= 1; + +-- echo ### assertion: the inserts will not raise log error because +-- echo ### binlog-do-db is filtering used database +INSERT INTO t2 VALUES (1,2), (1,3), (1,4); +INSERT INTO t1 SELECT * FROM t2; + +-- echo ### assertion: assert that despite updating a not filtered +-- echo ### database this wont trigger an error as the +-- echo ### used database is the filtered one. +-- eval UPDATE $filtered.t1 ft1, $not_filtered.t1 nft1 SET ft1.x=1, nft1.x=2 + +-- eval use $not_filtered +-- echo ### assertion: the statements *will* raise log error because +-- echo ### binlog-do-db is not filtering used database +BEGIN; +-- error ER_BINLOG_LOGGING_IMPOSSIBLE +INSERT INTO t2 VALUES (1,2), (1,3), (1,4); +-- error ER_BINLOG_LOGGING_IMPOSSIBLE +-- eval UPDATE $filtered.t1 ft1, $not_filtered.t1 nft1 SET ft1.x=1, nft1.x=2 +-- error ER_BINLOG_LOGGING_IMPOSSIBLE +INSERT INTO t1 SELECT * FROM t2; +COMMIT; + +-- echo ### assertion: filtered events did not make into the binlog +source include/show_binlog_events.inc; + +-- eval DROP DATABASE $not_filtered +-- eval DROP DATABASE $filtered +SET @@session.tx_isolation= @old_isolation_level; diff --git a/mysql-test/suite/funcs_1/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result index ca68e92aaa9..b19252e4dd7 100644 --- a/mysql-test/suite/funcs_1/r/innodb_func_view.result +++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result @@ -2096,6 +2096,9 @@ IS NOT TRUE 2 IS NOT TRUE <---------1000 characters--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------> 3 IS NOT TRUE ---äÖüß@µ*$-- 4 IS TRUE -1 5 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '<---------1000 characters-------------------------------------------------------------------------------------------------------' +Warning 1292 Truncated incorrect DOUBLE value: ' ---äÖüß@µ*$-- ' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select if(`t1_values`.`my_varbinary_1000`,'IS TRUE','IS NOT TRUE') AS `IF(my_varbinary_1000, 'IS TRUE', 'IS NOT TRUE')`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2108,6 +2111,9 @@ IS NOT TRUE 2 IS NOT TRUE <---------1000 characters--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------> 3 IS NOT TRUE ---äÖüß@µ*$-- 4 IS TRUE -1 5 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '<---------1000 characters-------------------------------------------------------------------------------------------------------' +Warning 1292 Truncated incorrect DOUBLE value: ' ---äÖüß@µ*$-- ' DROP VIEW v1; @@ -2158,6 +2164,9 @@ IS NOT TRUE 2 IS NOT TRUE <---------1000 characters--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------> 3 IS NOT TRUE ---äÖüß@µ*$-- 4 IS TRUE -1 5 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '<---------1000 characters-------------------------------------------------------------------------------------------------------' +Warning 1292 Truncated incorrect DOUBLE value: ' ---äÖüß@µ*$-- ' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select if(`t1_values`.`my_varchar_1000`,'IS TRUE','IS NOT TRUE') AS `IF(my_varchar_1000, 'IS TRUE', 'IS NOT TRUE')`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -2170,6 +2179,9 @@ IS NOT TRUE 2 IS NOT TRUE <---------1000 characters--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------> 3 IS NOT TRUE ---äÖüß@µ*$-- 4 IS TRUE -1 5 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '<---------1000 characters-------------------------------------------------------------------------------------------------------' +Warning 1292 Truncated incorrect DOUBLE value: ' ---äÖüß@µ*$-- ' DROP VIEW v1; @@ -3373,8 +3385,11 @@ NULL NULL 1 -3333.33 -3333.3333 29 Warnings: Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: '<---------1000 characters-------------------------------------------------------------------------------------------------------' Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varbinary_1000` as decimal(37,2)) AS `CAST(my_varbinary_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3390,8 +3405,11 @@ NULL NULL 1 -3333.33 -3333.3333 29 Warnings: Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: '<---------1000 characters-------------------------------------------------------------------------------------------------------' Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' DROP VIEW v1; @@ -3455,8 +3473,11 @@ NULL NULL 1 -3333.33 -3333.3333 27 Warnings: Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: '<---------1000 characters-------------------------------------------------------------------------------------------------------' Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' SHOW CREATE VIEW v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(`t1_values`.`my_varchar_1000` as decimal(37,2)) AS `CAST(my_varchar_1000 AS DECIMAL(37,2))`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci @@ -3472,8 +3493,11 @@ NULL NULL 1 -3333.33 -3333.3333 27 Warnings: Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: '' Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: '<---------1000 characters-------------------------------------------------------------------------------------------------------' Warning 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: ' ---äÖüß@µ*$-- ' DROP VIEW v1; diff --git a/mysql-test/suite/funcs_1/r/innodb_storedproc_07.result b/mysql-test/suite/funcs_1/r/innodb_storedproc_07.result index 5a2c0bb6bdf..a520bdfac36 100644 --- a/mysql-test/suite/funcs_1/r/innodb_storedproc_07.result +++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_07.result @@ -80,7 +80,7 @@ CREATE TABLE result (f1 text(200), f2 char(20)); set @@sql_mode='traditional'; SHOW VARIABLES LIKE 'sql_mode'; Variable_name Value -sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE PROCEDURE sp1() BEGIN declare a tinyint; @@ -97,7 +97,7 @@ END if; END// SHOW CREATE PROCEDURE sp1; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -sp1 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`() +sp1 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`() BEGIN declare a tinyint; declare count_ int default 1; @@ -117,10 +117,10 @@ Variable_name Value sql_mode CALL sp1(); Variable_name Value -sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SELECT * from result; f1 f2 -STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER value restored +STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION value restored SHOW VARIABLES LIKE 'sql_mode'; Variable_name Value sql_mode @@ -142,7 +142,7 @@ DROP PROCEDURE IF EXISTS sp2; ... show initial value SHOW VARIABLES LIKE 'sql_mode'; Variable_name Value -sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE PROCEDURE sp2() BEGIN SET @@sql_mode='MAXDB'; @@ -150,7 +150,7 @@ SHOW VARIABLES LIKE 'sql_mode'; END// SHOW CREATE PROCEDURE sp2; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation -sp2 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`() +sp2 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`() BEGIN SET @@sql_mode='MAXDB'; SHOW VARIABLES LIKE 'sql_mode'; @@ -158,7 +158,7 @@ END latin1 latin1_swedish_ci latin1_swedish_ci ... show value prior calling procedure SHOW VARIABLES LIKE 'sql_mode'; Variable_name Value -sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION ... call procedure that changes sql_mode CALL sp2(); Variable_name Value @@ -166,7 +166,7 @@ sql_mode PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,MAXDB,NO_KEY_OPTIONS,NO_TABLE_ ... check whether old value is re-set SHOW VARIABLES LIKE 'sql_mode'; Variable_name Value -sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER +sql_mode STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION DROP PROCEDURE sp2; --source suite/funcs_1/storedproc/cleanup_sp_tb.inc diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03.result b/mysql-test/suite/funcs_1/r/innodb_trig_03.result index b02fba0f38d..012977ae4a3 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_03.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_03.result @@ -77,7 +77,7 @@ grant ALL on *.* to test_noprivs@localhost; revoke TRIGGER on *.* from test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost -GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; grant TRIGGER on *.* to test_yesprivs@localhost; grant SELECT on priv_db.t1 to test_yesprivs@localhost; @@ -155,7 +155,7 @@ grant ALL on *.* to test_noprivs@localhost; revoke UPDATE on *.* from test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost -GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' +GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; grant TRIGGER, UPDATE on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; @@ -169,7 +169,7 @@ test_noprivs@localhost use priv_db; show grants; Grants for test_noprivs@localhost -GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' +GRANT SELECT, INSERT, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' select f1 from t1 order by f1; f1 insert 3.5.3.2-no @@ -401,7 +401,7 @@ grant ALL on *.* to test_noprivs@localhost; revoke SELECT on *.* from test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost -GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' +GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; grant TRIGGER, SELECT on *.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; @@ -415,7 +415,7 @@ test_noprivs@localhost use priv_db; show grants; Grants for test_noprivs@localhost -GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' +GRANT INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'test_noprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' create trigger trg5a_1 before INSERT on t1 for each row set @test_var = new.f1; set @test_var = 'before trig 3.5.3.8-1a'; diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result index 25edc0f68bb..bc3f7daf5bc 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result @@ -562,7 +562,7 @@ trig 1_1-yes revoke TRIGGER on *.* from test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost -GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' connect(localhost,test_yesprivs,PWD,test,MASTER_MYPORT,MASTER_MYSOCK); select current_user; current_user @@ -609,7 +609,7 @@ root@localhost grant TRIGGER on priv_db.* to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost -GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, CREATE TABLESPACE ON *.* TO 'test_yesprivs'@'localhost' IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT TRIGGER ON `priv_db`.* TO 'test_yesprivs'@'localhost' trigger privilege on db level for create: diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result index a335e135a4f..9511aa973e5 100644 --- a/mysql-test/suite/funcs_1/r/innodb_views.result +++ b/mysql-test/suite/funcs_1/r/innodb_views.result @@ -3546,11 +3546,11 @@ CREATE VIEW v1 or REPLACE AS Select * from tb2 my_table; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'or REPLACE AS Select * from tb2 my_table' at line 1 CREATE VIEW v1 WITH CASCADED CHECK OPTION AS Select * from tb2 my_table limit 50; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WITH CASCADED CHECK OPTION AS Select * +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASCADED CHECK OPTION AS Select * from tb2 my_table limit 50' at line 1 CREATE VIEW v1 WITH LOCAL CHECK OPTION AS Select * from tb2 my_table limit 50; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WITH LOCAL CHECK OPTION AS Select * +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOCAL CHECK OPTION AS Select * from tb2 my_table limit 50' at line 1 SELECT * FROM tb2 my_table CREATE VIEW As v1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE VIEW As v1' at line 1 @@ -3580,7 +3580,7 @@ FROM test.tb2 my_table CHECK OPTION WITH CASCADED; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHECK OPTION WITH CASCADED' at line 2 CREATE OR REPLACE VIEW v1 WITH CASCADED CHECK OPTION AS SELECT F59, F60 FROM test.tb2 my_table; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WITH CASCADED CHECK OPTION +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASCADED CHECK OPTION AS SELECT F59, F60 FROM test.tb2 my_table' at line 1 CREATE OR REPLACE AS SELECT F59, F60 FROM test.tb2 my_table VIEW v1 WITH CASCADED CHECK OPTION; @@ -3609,7 +3609,7 @@ FROM test.tb2 my_table CHECK OPTION WITH LOCAL; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHECK OPTION WITH LOCAL' at line 2 CREATE OR REPLACE VIEW v1 WITH CASCADED CHECK OPTION AS SELECT F59, F60 FROM test.tb2 my_table; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WITH CASCADED CHECK OPTION +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASCADED CHECK OPTION AS SELECT F59, F60 FROM test.tb2 my_table' at line 1 CREATE OR REPLACE AS SELECT F59, F60 FROM test.tb2 my_table VIEW v1 WITH LOCAL CHECK OPTION; @@ -22843,6 +22843,9 @@ SELECT * FROM v1 order by 2; f1 my_sqrt ABC 0 ABC 1.73205080756888 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'DEF' +Warning 1292 Truncated incorrect DOUBLE value: 'DEF' SELECT SQRT('DEF'); SQRT('DEF') 0 @@ -22863,7 +22866,12 @@ SELECT * FROM v2 order by 2; f1 my_sqrt ABC 0 ABC 1.73205080756888 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'DEF' +Warning 1292 Truncated incorrect DOUBLE value: 'DEF' CREATE TABLE t2 AS SELECT f1, SQRT(f2) my_sqrt FROM t1; +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'DEF' SELECT * FROM t2 order by 2; f1 ABC my_sqrt 0 @@ -22871,6 +22879,8 @@ f1 ABC my_sqrt 1.73205080756888 DROP TABLE t2; CREATE TABLE t2 AS SELECT * FROM v1; +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'DEF' SELECT * FROM t2 order by 2; f1 ABC my_sqrt 0 @@ -22878,6 +22888,8 @@ f1 ABC my_sqrt 1.73205080756888 DROP TABLE t2; CREATE TABLE t2 AS SELECT * FROM v2; +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'DEF' SELECT * FROM t2 order by 2; f1 ABC my_sqrt 0 diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index 47eb14a459f..e10c775c227 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -137,7 +137,7 @@ def information_schema PARTITIONS NODEGROUP 24 NO varchar 12 36 NULL NULL utf8 def information_schema PARTITIONS PARTITION_COMMENT 23 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select def information_schema PARTITIONS PARTITION_DESCRIPTION 12 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select def information_schema PARTITIONS PARTITION_EXPRESSION 10 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select -def information_schema PARTITIONS PARTITION_METHOD 8 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select +def information_schema PARTITIONS PARTITION_METHOD 8 NULL YES varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select def information_schema PARTITIONS PARTITION_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select def information_schema PARTITIONS SUBPARTITION_EXPRESSION 11 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select @@ -192,7 +192,7 @@ def information_schema ROUTINES LAST_ALTERED 17 0000-00-00 00:00:00 NO datetime def information_schema ROUTINES PARAMETER_STYLE 11 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) select def information_schema ROUTINES ROUTINE_BODY 7 NO varchar 8 24 NULL NULL utf8 utf8_general_ci varchar(8) select def information_schema ROUTINES ROUTINE_CATALOG 2 NO varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select -def information_schema ROUTINES ROUTINE_COMMENT 19 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ROUTINES ROUTINE_COMMENT 19 NULL NO longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select def information_schema ROUTINES ROUTINE_DEFINITION 8 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select def information_schema ROUTINES ROUTINE_NAME 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select def information_schema ROUTINES ROUTINE_SCHEMA 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -487,7 +487,7 @@ NULL information_schema KEY_COLUMN_USAGE POSITION_IN_UNIQUE_CONSTRAINT bigint NU 3.0000 information_schema PARTITIONS SUBPARTITION_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION bigint NULL NULL NULL NULL bigint(21) unsigned NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION bigint NULL NULL NULL NULL bigint(21) unsigned -3.0000 information_schema PARTITIONS PARTITION_METHOD varchar 12 36 utf8 utf8_general_ci varchar(12) +3.0000 information_schema PARTITIONS PARTITION_METHOD varchar 18 54 utf8 utf8_general_ci varchar(18) 3.0000 information_schema PARTITIONS SUBPARTITION_METHOD varchar 12 36 utf8 utf8_general_ci varchar(12) 1.0000 information_schema PARTITIONS PARTITION_EXPRESSION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 1.0000 information_schema PARTITIONS SUBPARTITION_EXPRESSION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext @@ -552,7 +552,7 @@ NULL information_schema PROCESSLIST TIME int NULL NULL NULL NULL int(7) NULL information_schema ROUTINES CREATED datetime NULL NULL NULL NULL datetime NULL information_schema ROUTINES LAST_ALTERED datetime NULL NULL NULL NULL datetime 3.0000 information_schema ROUTINES SQL_MODE varchar 8192 24576 utf8 utf8_general_ci varchar(8192) -3.0000 information_schema ROUTINES ROUTINE_COMMENT varchar 64 192 utf8 utf8_general_ci varchar(64) +1.0000 information_schema ROUTINES ROUTINE_COMMENT longtext 4294967295 4294967295 utf8 utf8_general_ci longtext 3.0000 information_schema ROUTINES DEFINER varchar 77 231 utf8 utf8_general_ci varchar(77) 3.0000 information_schema ROUTINES CHARACTER_SET_CLIENT varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema ROUTINES COLLATION_CONNECTION varchar 32 96 utf8 utf8_general_ci varchar(32) diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index a7f5c3ce52e..bd548ac0a25 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -110,7 +110,7 @@ def mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NUL def mysql proc body_utf8 20 NULL YES longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references def mysql proc character_set_client 17 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references def mysql proc collation_connection 18 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references -def mysql proc comment 16 NO char 64 192 NULL NULL utf8 utf8_bin char(64) select,insert,update,references +def mysql proc comment 16 NULL NO text 65535 65535 NULL NULL utf8 utf8_bin text select,insert,update,references def mysql proc created 13 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references def mysql proc db 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references def mysql proc db_collation 19 NULL YES char 32 96 NULL NULL utf8 utf8_bin char(32) select,insert,update,references @@ -130,7 +130,7 @@ def mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI def mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references def mysql procs_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references def mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant') select,insert,update,references -def mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references +def mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references def mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references def mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references def mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references @@ -180,6 +180,7 @@ def mysql user Alter_priv 17 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum(' def mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Create_priv 8 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references +def mysql user Create_tablespace_priv 32 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Create_user_priv 29 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Create_view_priv 25 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references @@ -193,10 +194,10 @@ def mysql user Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI sele def mysql user Index_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Insert_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Lock_tables_priv 21 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references -def mysql user max_connections 38 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references -def mysql user max_questions 36 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references -def mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references -def mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references +def mysql user max_connections 39 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references +def mysql user max_questions 37 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references +def mysql user max_updates 38 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references +def mysql user max_user_connections 40 0 NO int NULL NULL 10 0 NULL NULL int(11) unsigned select,insert,update,references def mysql user Password 3 NO char 41 41 NULL NULL latin1 latin1_bin char(41) select,insert,update,references def mysql user Process_priv 12 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user References_priv 15 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references @@ -207,14 +208,14 @@ def mysql user Select_priv 4 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum(' def mysql user Show_db_priv 18 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Show_view_priv 26 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Shutdown_priv 11 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references -def mysql user ssl_cipher 33 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references -def mysql user ssl_type 32 NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') select,insert,update,references +def mysql user ssl_cipher 34 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references +def mysql user ssl_type 33 NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') select,insert,update,references def mysql user Super_priv 19 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Trigger_priv 31 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user Update_priv 6 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references def mysql user User 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references -def mysql user x509_issuer 34 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references -def mysql user x509_subject 35 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references +def mysql user x509_issuer 35 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references +def mysql user x509_subject 36 NULL NO blob 65535 65535 NULL NULL NULL NULL blob select,insert,update,references ########################################################################## # Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH ########################################################################## @@ -233,6 +234,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME 1.0000 char latin1 latin1_bin 1.0000 char latin1 latin1_swedish_ci 1.0000 varchar latin1 latin1_swedish_ci +1.0000 text utf8 utf8_bin 1.0000 mediumtext utf8 utf8_general_ci 1.0000 text utf8 utf8_general_ci SELECT DISTINCT @@ -403,7 +405,7 @@ NULL mysql ndb_binlog_index schemaops bigint NULL NULL NULL NULL bigint(20) unsi NULL mysql proc created timestamp NULL NULL NULL NULL timestamp NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp 3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') -3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64) +1.0000 mysql proc comment text 65535 65535 utf8 utf8_bin text 3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32) 3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32) 3.0000 mysql proc db_collation char 32 96 utf8 utf8_bin char(32) @@ -411,7 +413,7 @@ NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp 3.0000 mysql procs_priv Host char 60 180 utf8 utf8_bin char(60) 3.0000 mysql procs_priv Db char 64 192 utf8 utf8_bin char(64) 3.0000 mysql procs_priv User char 16 48 utf8 utf8_bin char(16) -3.0000 mysql procs_priv Routine_name char 64 192 utf8 utf8_bin char(64) +3.0000 mysql procs_priv Routine_name char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql procs_priv Routine_type enum 9 27 utf8 utf8_bin enum('FUNCTION','PROCEDURE') 3.0000 mysql procs_priv Grantor char 77 231 utf8 utf8_bin char(77) 3.0000 mysql procs_priv Proc_priv set 27 81 utf8 utf8_general_ci set('Execute','Alter Routine','Grant') @@ -489,6 +491,7 @@ NULL mysql time_zone_transition_type Is_DST tinyint NULL NULL NULL NULL tinyint( 3.0000 mysql user Create_user_priv enum 1 3 utf8 utf8_general_ci enum('N','Y') 3.0000 mysql user Event_priv enum 1 3 utf8 utf8_general_ci enum('N','Y') 3.0000 mysql user Trigger_priv enum 1 3 utf8 utf8_general_ci enum('N','Y') +3.0000 mysql user Create_tablespace_priv enum 1 3 utf8 utf8_general_ci enum('N','Y') 3.0000 mysql user ssl_type enum 9 27 utf8 utf8_general_ci enum('','ANY','X509','SPECIFIED') 1.0000 mysql user ssl_cipher blob 65535 65535 NULL NULL blob 1.0000 mysql user x509_issuer blob 65535 65535 NULL NULL blob diff --git a/mysql-test/suite/funcs_1/r/is_routines.result b/mysql-test/suite/funcs_1/r/is_routines.result index c362b6f59d4..8e37b995322 100644 --- a/mysql-test/suite/funcs_1/r/is_routines.result +++ b/mysql-test/suite/funcs_1/r/is_routines.result @@ -46,7 +46,7 @@ SECURITY_TYPE varchar(7) NO CREATED datetime NO 0000-00-00 00:00:00 LAST_ALTERED datetime NO 0000-00-00 00:00:00 SQL_MODE varchar(8192) NO -ROUTINE_COMMENT varchar(64) NO +ROUTINE_COMMENT longtext NO NULL DEFINER varchar(77) NO CHARACTER_SET_CLIENT varchar(32) NO COLLATION_CONNECTION varchar(32) NO @@ -72,7 +72,7 @@ ROUTINES CREATE TEMPORARY TABLE `ROUTINES` ( `CREATED` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `LAST_ALTERED` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `SQL_MODE` varchar(8192) NOT NULL DEFAULT '', - `ROUTINE_COMMENT` varchar(64) NOT NULL DEFAULT '', + `ROUTINE_COMMENT` longtext NOT NULL, `DEFINER` varchar(77) NOT NULL DEFAULT '', `CHARACTER_SET_CLIENT` varchar(32) NOT NULL DEFAULT '', `COLLATION_CONNECTION` varchar(32) NOT NULL DEFAULT '', @@ -98,7 +98,7 @@ SECURITY_TYPE varchar(7) NO CREATED datetime NO 0000-00-00 00:00:00 LAST_ALTERED datetime NO 0000-00-00 00:00:00 SQL_MODE varchar(8192) NO -ROUTINE_COMMENT varchar(64) NO +ROUTINE_COMMENT longtext NO NULL DEFINER varchar(77) NO CHARACTER_SET_CLIENT varchar(32) NO COLLATION_CONNECTION varchar(32) NO diff --git a/mysql-test/suite/funcs_1/r/is_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result index 6d8d6c664c1..cbb794a9a91 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics.result +++ b/mysql-test/suite/funcs_1/r/is_statistics.result @@ -214,8 +214,8 @@ def db_datadict_2 t4 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' -GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost' GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION +GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost' SHOW GRANTS FOR 'testuser2'@'localhost'; Grants for testuser2@localhost GRANT USAGE ON *.* TO 'testuser2'@'localhost' @@ -233,8 +233,8 @@ def db_datadict_2 t3 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' -GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost' GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION +GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost' SHOW GRANTS FOR 'testuser2'@'localhost'; ERROR 42000: Access denied for user 'testuser1'@'localhost' to database 'mysql' # Switch to connection testuser2 diff --git a/mysql-test/suite/funcs_1/r/is_user_privileges.result b/mysql-test/suite/funcs_1/r/is_user_privileges.result index 1dc9694180e..8f68f8c802d 100644 --- a/mysql-test/suite/funcs_1/r/is_user_privileges.result +++ b/mysql-test/suite/funcs_1/r/is_user_privileges.result @@ -76,10 +76,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' def USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 # # Add GRANT OPTION db_datadict.* to testuser1; GRANT UPDATE ON db_datadict.* TO 'testuser1'@'localhost' WITH GRANT OPTION; @@ -93,10 +93,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' def USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 # Establish connection testuser1 (user=testuser1) SELECT * FROM information_schema.user_privileges WHERE grantee LIKE '''testuser%''' @@ -105,10 +105,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser1'@'localhost' def USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections +localhost testuser1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 SHOW GRANTS; Grants for testuser1@localhost GRANT USAGE ON *.* TO 'testuser1'@'localhost' @@ -130,10 +130,10 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'testuser3'@'localhost' def USAGE NO SELECT * FROM mysql.user WHERE user LIKE 'testuser%' ORDER BY host, user; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections -localhost testuser1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 -localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections +localhost testuser1 Y N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser2 N Y Y N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 +localhost testuser3 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0 0 0 0 GRANT SELECT ON *.* TO 'testuser1'@'localhost' WITH GRANT OPTION; # # Here