diff options
389 files changed, 12322 insertions, 7252 deletions
diff --git a/BUILD/cmake_configure.sh b/BUILD/cmake_configure.sh index 668d6a81b5c..5d7c317f86f 100644 --- a/BUILD/cmake_configure.sh +++ b/BUILD/cmake_configure.sh @@ -18,7 +18,7 @@ # MA 02110-1301, USA # Ensure cmake and perl are there -cmake -P cmake/check_minimal_version.cmake >/dev/null 2>&1 || HAVE_CMAKE=no +cmake --help >/dev/null 2>&1 || HAVE_CMAKE=no perl --version >/dev/null 2>&1 || HAVE_PERL=no scriptdir=`dirname $0` if test "$HAVE_CMAKE" = "no" diff --git a/CMakeLists.txt b/CMakeLists.txt index ab981bc330f..5f8ae5b2d9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,11 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -# Avoid warnings in higher versions -if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" GREATER 2.6) - CMAKE_POLICY(VERSION 2.8) -endif() +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3) # explicitly set the policy to OLD # (cannot use NEW, not everyone is on cmake-2.8.12 yet) @@ -40,12 +36,6 @@ MESSAGE(STATUS "Running cmake version ${CMAKE_VERSION}") SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake) -# Distinguish between community and non-community builds, with the -# default being a community build. This does not impact the feature -# set that will be compiled in; it's merely provided as a hint to -# custom packaging steps. -OPTION(COMMUNITY_BUILD "Set to true if this is a community build" ON) - # Use a default manufacturer if no manufacturer was identified. IF(NOT DEFINED MANUFACTURER) SET(MANUFACTURER "Built from Source" CACHE STRING @@ -140,6 +130,7 @@ IF (NOT CPACK_GENERATOR) ENDIF(WIN32) ENDIF(NOT CPACK_GENERATOR) +INCLUDE(misc) INCLUDE(mysql_version) INCLUDE(cpack_source_ignore_files) INCLUDE(install_layout) @@ -170,13 +161,11 @@ IF(DISABLE_SHARED) SET(WITHOUT_DYNAMIC_PLUGINS 1) ENDIF() OPTION(ENABLED_PROFILING "Enable profiling" ON) -OPTION(CYBOZU "" OFF) OPTION(WITHOUT_SERVER "Build only the client library and clients" OFF) IF(UNIX) OPTION(WITH_VALGRIND "Valgrind instrumentation" OFF) ENDIF() OPTION (WITH_UNIT_TESTS "Compile MySQL with unit tests" ON) -MARK_AS_ADVANCED(CYBOZU) OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system libraries. Only set it you never plan to distribute the resulting binaries" OFF) @@ -235,9 +224,6 @@ MY_CHECK_AND_SET_COMPILER_FLAG(-ggdb3 DEBUG) OPTION(ENABLED_LOCAL_INFILE "If we should should enable LOAD DATA LOCAL by default" ${IF_WIN}) -OPTION(WITH_FAST_MUTEXES "Compile with fast mutexes" OFF) -MARK_AS_ADVANCED(WITH_FAST_MUTEXES) - OPTION(WITH_INNODB_DISALLOW_WRITES "InnoDB freeze writes patch from Google" ${WITH_WSREP}) IF (WITH_INNODB_DISALLOW_WRITES) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWITH_INNODB_DISALLOW_WRITES") @@ -252,10 +238,6 @@ FOREACH(BUILD_TYPE RELEASE RELWITHDEBINFO MINSIZEREL) SET(CMAKE_${LANG}_FLAGS_${BUILD_TYPE} "${CMAKE_${LANG}_FLAGS_${BUILD_TYPE}} -DDBUG_OFF") ENDIF() - IF(WITH_FAST_MUTEXES) - SET(CMAKE_${LANG}_FLAGS_${BUILD_TYPE} - "${CMAKE_${LANG}_FLAGS_${BUILD_TYPE}} -DMY_PTHREAD_FASTMUTEX=1") - ENDIF() ENDFOREACH() ENDFOREACH() @@ -440,8 +422,8 @@ CONFIGURE_FILE( IF(DEB) CONFIGURE_FILE( - ${CMAKE_SOURCE_DIR}/debian/mariadb-server-10.1.files.in - ${CMAKE_SOURCE_DIR}/debian/mariadb-server-10.1.files) + ${CMAKE_SOURCE_DIR}/debian/mariadb-server-10.2.files.in + ${CMAKE_SOURCE_DIR}/debian/mariadb-server-10.2.files) ENDIF(DEB) # Handle the "INFO_*" files. @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 -MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=13 +MYSQL_VERSION_MINOR=2 +MYSQL_VERSION_PATCH=0 diff --git a/client/mysql.cc b/client/mysql.cc index e1f7ba0e5c6..9c6320fe10a 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1955,7 +1955,7 @@ static int get_options(int argc, char **argv) connect_flag|= CLIENT_IGNORE_SPACE; if (opt_progress_reports) - connect_flag|= CLIENT_PROGRESS; + connect_flag|= CLIENT_PROGRESS_OBSOLETE; return(0); } @@ -3486,7 +3486,6 @@ static char *fieldflags2str(uint f) { ff2s_check_flag(NUM); ff2s_check_flag(PART_KEY); ff2s_check_flag(GROUP); - ff2s_check_flag(UNIQUE); ff2s_check_flag(BINCMP); ff2s_check_flag(ON_UPDATE_NOW); #undef ff2s_check_flag @@ -4644,10 +4643,10 @@ sql_real_connect(char *host,char *database,char *user,char *password, mysql.reconnect= debug_info_flag; // We want to know if this happens /* - CLIENT_PROGRESS is set only if we requsted it in mysql_real_connect() - and the server also supports it + CLIENT_PROGRESS_OBSOLETE is set only if we requested it in + mysql_real_connect() and the server also supports it */ - if (mysql.client_flag & CLIENT_PROGRESS) + if (mysql.client_flag & CLIENT_PROGRESS_OBSOLETE) mysql_options(&mysql, MYSQL_PROGRESS_CALLBACK, (void*) report_progress); #else mysql.reconnect= 1; diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index bb0dd4040af..0463a9857bc 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -73,6 +73,8 @@ ulong opt_binlog_rows_event_max_size; uint test_flags = 0; static uint opt_protocol= 0; static FILE *result_file; +static char *result_file_name= 0; +static const char *output_prefix= ""; #ifndef DBUG_OFF static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; @@ -96,6 +98,8 @@ static char* database= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0; static my_bool debug_info_flag, debug_check_flag; static my_bool force_if_open_opt= 1; +static my_bool opt_raw_mode= 0, opt_stop_never= 0; +static ulong opt_stop_never_slave_server_id= 0; static my_bool opt_verify_binlog_checksum= 1; static ulonglong offset = 0; static char* host = 0; @@ -120,7 +124,6 @@ static ulonglong start_position, stop_position; static char *start_datetime_str, *stop_datetime_str; static my_time_t start_datetime= 0, stop_datetime= MY_TIME_T_MAX; static ulonglong rec_count= 0; -static short binlog_flags = 0; static MYSQL* mysql = NULL; static const char* dirname_for_local_load= 0; static bool opt_skip_annotate_row_events= 0; @@ -142,7 +145,9 @@ enum Exit_status { /** An error occurred and execution should stop. */ ERROR_STOP, /** No error occurred but execution should stop. */ - OK_STOP + OK_STOP, + /** No error occurred - end of file reached. */ + OK_EOF, }; /** @@ -1368,8 +1373,14 @@ static struct my_option my_options[] = {"read-from-remote-server", 'R', "Read binary logs from a MySQL server.", &remote_opt, &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"result-file", 'r', "Direct output to a given file.", 0, 0, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"raw", 0, "Requires -R. Output raw binlog data instead of SQL " + "statements. Output files named after server logs.", + &opt_raw_mode, &opt_raw_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, + {"result-file", 'r', "Direct output to a given file. With --raw this is a " + "prefix for the file names.", + &result_file_name, &result_file_name, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"server-id", 0, "Extract only binlog entries created by the server having the given id.", &server_id, &server_id, 0, GET_ULONG, @@ -1418,6 +1429,14 @@ static struct my_option my_options[] = "(you should probably use quotes for your shell to set it properly).", &stop_datetime_str, &stop_datetime_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"stop-never", 0, "Wait for more data from the server " + "instead of stopping at the end of the last log. Implies --to-last-log.", + &opt_stop_never, &opt_stop_never, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"stop-never-slave-server-id", 0, + "The slave server_id used for --read-from-remote-server --stop-never.", + &opt_stop_never_slave_server_id, &opt_stop_never_slave_server_id, 0, + GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"stop-position", OPT_STOP_POSITION, "Stop reading the binlog at position N. Applies to the last binlog " "passed on the command line.", @@ -1620,10 +1639,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), else tty_password=1; break; - case 'r': - if (!(result_file = my_fopen(argument, O_WRONLY | O_BINARY, MYF(MY_WME)))) - exit(1); - break; case 'R': remote_opt= 1; break; @@ -1719,7 +1734,6 @@ static int parse_args(int *argc, char*** argv) { int ho_error; - result_file = stdout; if ((ho_error=handle_options(argc, argv, my_options, get_one_option))) exit(ho_error); if (debug_info_flag) @@ -1809,7 +1823,8 @@ static Exit_status dump_log_entries(const char* logname) Set safe delimiter, to dump things like CREATE PROCEDURE safely */ - fprintf(result_file, "DELIMITER /*!*/;\n"); + if (!opt_raw_mode) + fprintf(result_file, "DELIMITER /*!*/;\n"); strmov(print_event_info.delimiter, "/*!*/;"); print_event_info.verbose= short_form ? 0 : verbose; @@ -1818,7 +1833,8 @@ static Exit_status dump_log_entries(const char* logname) dump_local_log_entries(&print_event_info, logname)); /* Set delimiter back to semicolon */ - fprintf(result_file, "DELIMITER ;\n"); + if (!opt_raw_mode) + fprintf(result_file, "DELIMITER ;\n"); strmov(print_event_info.delimiter, ";"); return rc; } @@ -1924,6 +1940,247 @@ err: } +static Exit_status handle_event_text_mode(PRINT_EVENT_INFO *print_event_info, + ulong *len, + const char* logname, + uint logname_len, my_off_t old_off) +{ + const char *error_msg; + Log_event *ev; + NET *net= &mysql->net; + DBUG_ENTER("handle_event_text_mode"); + + if (net->read_pos[5] == ANNOTATE_ROWS_EVENT) + { + if (!(ev= read_remote_annotate_event(net->read_pos + 1, *len - 1, + &error_msg))) + { + error("Could not construct annotate event object: %s", error_msg); + DBUG_RETURN(ERROR_STOP); + } + } + else + { + if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 , + *len - 1, &error_msg, + glob_description_event, + opt_verify_binlog_checksum))) + { + error("Could not construct log event object: %s", error_msg); + DBUG_RETURN(ERROR_STOP); + } + /* + If reading from a remote host, ensure the temp_buf for the + Log_event class is pointing to the incoming stream. + */ + ev->register_temp_buf((char *) net->read_pos + 1, FALSE); + } + + Log_event_type type= ev->get_type_code(); + if (glob_description_event->binlog_version >= 3 || + (type != LOAD_EVENT && type != CREATE_FILE_EVENT)) + { + /* + If this is a Rotate event, maybe it's the end of the requested binlog; + in this case we are done (stop transfer). + This is suitable for binlogs, not relay logs (but for now we don't read + relay logs remotely because the server is not able to do that). If one + day we read relay logs remotely, then we will have a problem with the + detection below: relay logs contain Rotate events which are about the + binlogs, so which would trigger the end-detection below. + */ + if (type == ROTATE_EVENT) + { + Rotate_log_event *rev= (Rotate_log_event *)ev; + /* + If this is a fake Rotate event, and not about our log, we can stop + transfer. If this a real Rotate event (so it's not about our log, + it's in our log describing the next log), we print it (because it's + part of our log) and then we will stop when we receive the fake one + soon. + */ + if (rev->when == 0) + { + *len= 1; // fake Rotate, so don't increment old_off + if (!to_last_remote_log) + { + if ((rev->ident_len != logname_len) || + memcmp(rev->new_log_ident, logname, logname_len)) + { + delete ev; + DBUG_RETURN(OK_EOF); + } + /* + Otherwise, this is a fake Rotate for our log, at the very + beginning for sure. Skip it, because it was not in the original + log. If we are running with to_last_remote_log, we print it, + because it serves as a useful marker between binlogs then. + */ + delete ev; + DBUG_RETURN(OK_CONTINUE); + } + } + } + else if (type == FORMAT_DESCRIPTION_EVENT) + { + /* + This could be an fake Format_description_log_event that server + (5.0+) automatically sends to a slave on connect, before sending + a first event at the requested position. If this is the case, + don't increment old_off. Real Format_description_log_event always + starts from BIN_LOG_HEADER_SIZE position. + */ + if (old_off != BIN_LOG_HEADER_SIZE) + *len= 1; // fake event, don't increment old_off + } + Exit_status retval= process_event(print_event_info, ev, old_off, logname); + if (retval != OK_CONTINUE) + DBUG_RETURN(retval); + } + else + { + Load_log_event *le= (Load_log_event*)ev; + const char *old_fname= le->fname; + uint old_len= le->fname_len; + File file; + Exit_status retval; + char fname[FN_REFLEN+1]; + + if ((file= load_processor.prepare_new_file_for_old_format(le,fname)) < 0) + { + DBUG_RETURN(ERROR_STOP); + } + + retval= process_event(print_event_info, ev, old_off, logname); + if (retval != OK_CONTINUE) + { + my_close(file,MYF(MY_WME)); + DBUG_RETURN(retval); + } + retval= load_processor.load_old_format_file(net,old_fname,old_len,file); + my_close(file,MYF(MY_WME)); + if (retval != OK_CONTINUE) + DBUG_RETURN(retval); + } + + DBUG_RETURN(OK_CONTINUE); +} + + +static char out_file_name[FN_REFLEN + 1]; + +static Exit_status handle_event_raw_mode(PRINT_EVENT_INFO *print_event_info, + ulong *len, + const char* logname, uint logname_len) +{ + const char *error_msg; + const unsigned char *read_pos= mysql->net.read_pos + 1; + Log_event_type type; + DBUG_ENTER("handle_event_raw_mode"); + DBUG_ASSERT(opt_raw_mode && remote_opt); + + type= (Log_event_type) read_pos[EVENT_TYPE_OFFSET]; + + if (type == HEARTBEAT_LOG_EVENT) + DBUG_RETURN(OK_CONTINUE); + + if (type == ROTATE_EVENT || type == FORMAT_DESCRIPTION_EVENT) + { + Log_event *ev; + if (!(ev= Log_event::read_log_event((const char*) read_pos , + *len - 1, &error_msg, + glob_description_event, + opt_verify_binlog_checksum))) + { + error("Could not construct %s event object: %s", + type == ROTATE_EVENT ? "rotate" : "format description", error_msg); + DBUG_RETURN(ERROR_STOP); + } + /* + If reading from a remote host, ensure the temp_buf for the + Log_event class is pointing to the incoming stream. + */ + ev->register_temp_buf((char *) read_pos, FALSE); + + if (type == ROTATE_EVENT) + { + Exit_status ret_val= OK_CONTINUE; + Rotate_log_event *rev= (Rotate_log_event *)ev; + char *pe= strmake(out_file_name, output_prefix, sizeof(out_file_name)-1); + strmake(pe, rev->new_log_ident, sizeof(out_file_name) - (pe-out_file_name)); + + /* + If this is a fake Rotate event, and not about our log, we can stop + transfer. If this a real Rotate event (so it's not about our log, + it's in our log describing the next log), we print it (because it's + part of our log) and then we will stop when we receive the fake one + soon. + */ + if (rev->when == 0) + { + if (!to_last_remote_log) + { + if ((rev->ident_len != logname_len) || + memcmp(rev->new_log_ident, logname, logname_len)) + { + ret_val= OK_EOF; + } + /* + Otherwise, this is a fake Rotate for our log, at the very + beginning for sure. Skip it, because it was not in the original + log. If we are running with to_last_remote_log, we print it, + because it serves as a useful marker between binlogs then. + */ + } + *len= 1; // fake Rotate, so don't increment old_off + ev->temp_buf= 0; + delete ev; + DBUG_RETURN(ret_val); + } + ev->temp_buf= 0; + delete ev; + } + else /* if (type == FORMAT_DESCRIPTION_EVENT) */ + { + DBUG_ASSERT(type == FORMAT_DESCRIPTION_EVENT); + + if (result_file) + my_fclose(result_file, MYF(0)); + + if (!(result_file= my_fopen(out_file_name, + O_WRONLY | O_BINARY, MYF(MY_WME)))) + { + error("Could not create output log file: %s", out_file_name); + DBUG_RETURN(ERROR_STOP); + } + /* TODO - add write error simulation here */ + + if (my_fwrite(result_file, (const uchar *) BINLOG_MAGIC, + BIN_LOG_HEADER_SIZE, MYF(MY_NABP))) + { + error("Could not write into log file '%s'", out_file_name); + DBUG_RETURN(ERROR_STOP); + } + + delete glob_description_event; + glob_description_event= (Format_description_log_event*) ev; + print_event_info->common_header_len= + glob_description_event->common_header_len; + ev->temp_buf= 0; + /* We do not want to delete the event here. */ + } + } + + if (my_fwrite(result_file, read_pos, *len - 1, MYF(MY_NABP))) + { + error("Could not write into log file '%s'", out_file_name); + DBUG_RETURN(ERROR_STOP); + } + + DBUG_RETURN(OK_CONTINUE); +} + + /** Requests binlog dump from a remote server and prints the events it receives. @@ -1946,8 +2203,9 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, uint logname_len; NET* net; my_off_t old_off= start_position_mot; - char fname[FN_REFLEN+1]; Exit_status retval= OK_CONTINUE; + short binlog_flags = 0; + ulong slave_id; DBUG_ENTER("dump_remote_log_entries"); /* @@ -1970,6 +2228,9 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, int4store(buf, (uint32)start_position); if (!opt_skip_annotate_row_events) binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT; + if (!opt_stop_never) + binlog_flags|= BINLOG_DUMP_NON_BLOCK; + int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags); size_t tlen = strlen(logname); @@ -1979,7 +2240,15 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, DBUG_RETURN(ERROR_STOP); } logname_len = (uint) tlen; - int4store(buf + 6, 0); + if (opt_stop_never) + { + DBUG_ASSERT(to_last_remote_log); + slave_id= (opt_stop_never_slave_server_id == 0) ? + 1 : opt_stop_never_slave_server_id; + } + else + slave_id= 0; + int4store(buf + 6, slave_id); memcpy(buf + 10, logname, logname_len); if (simple_command(mysql, COM_BINLOG_DUMP, buf, logname_len + 10, 1)) { @@ -1989,9 +2258,6 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, for (;;) { - const char *error_msg; - Log_event *ev; - len= cli_safe_read(mysql); if (len == packet_error) { @@ -2002,117 +2268,23 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, break; // end of data DBUG_PRINT("info",( "len: %lu net->read_pos[5]: %d\n", len, net->read_pos[5])); - if (net->read_pos[5] == ANNOTATE_ROWS_EVENT) + if (opt_raw_mode) { - if (!(ev= read_remote_annotate_event(net->read_pos + 1, len - 1, - &error_msg))) - { - error("Could not construct annotate event object: %s", error_msg); - DBUG_RETURN(ERROR_STOP); - } + retval= handle_event_raw_mode(print_event_info, &len, + logname, logname_len); } else { - if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 , - len - 1, &error_msg, - glob_description_event, - opt_verify_binlog_checksum))) - { - error("Could not construct log event object: %s", error_msg); - DBUG_RETURN(ERROR_STOP); - } - /* - If reading from a remote host, ensure the temp_buf for the - Log_event class is pointing to the incoming stream. - */ - ev->register_temp_buf((char *) net->read_pos + 1, FALSE); + retval= handle_event_text_mode(print_event_info, &len, + logname, logname_len, old_off); } - - Log_event_type type= ev->get_type_code(); - if (glob_description_event->binlog_version >= 3 || - (type != LOAD_EVENT && type != CREATE_FILE_EVENT)) + if (retval != OK_CONTINUE) { - /* - If this is a Rotate event, maybe it's the end of the requested binlog; - in this case we are done (stop transfer). - This is suitable for binlogs, not relay logs (but for now we don't read - relay logs remotely because the server is not able to do that). If one - day we read relay logs remotely, then we will have a problem with the - detection below: relay logs contain Rotate events which are about the - binlogs, so which would trigger the end-detection below. - */ - if (type == ROTATE_EVENT) - { - Rotate_log_event *rev= (Rotate_log_event *)ev; - /* - If this is a fake Rotate event, and not about our log, we can stop - transfer. If this a real Rotate event (so it's not about our log, - it's in our log describing the next log), we print it (because it's - part of our log) and then we will stop when we receive the fake one - soon. - */ - if (rev->when == 0) - { - if (!to_last_remote_log) - { - if ((rev->ident_len != logname_len) || - memcmp(rev->new_log_ident, logname, logname_len)) - { - delete ev; - DBUG_RETURN(OK_CONTINUE); - } - /* - Otherwise, this is a fake Rotate for our log, at the very - beginning for sure. Skip it, because it was not in the original - log. If we are running with to_last_remote_log, we print it, - because it serves as a useful marker between binlogs then. - */ - delete ev; - continue; - } - len= 1; // fake Rotate, so don't increment old_off - } - } - else if (type == FORMAT_DESCRIPTION_EVENT) - { - /* - This could be an fake Format_description_log_event that server - (5.0+) automatically sends to a slave on connect, before sending - a first event at the requested position. If this is the case, - don't increment old_off. Real Format_description_log_event always - starts from BIN_LOG_HEADER_SIZE position. - */ - if (old_off != BIN_LOG_HEADER_SIZE) - len= 1; // fake event, don't increment old_off - } - Exit_status retval= process_event(print_event_info, ev, old_off, logname); - if (retval != OK_CONTINUE) - DBUG_RETURN(retval); + if (retval == OK_EOF) + break; + DBUG_RETURN(retval); } - else - { - Load_log_event *le= (Load_log_event*)ev; - const char *old_fname= le->fname; - uint old_len= le->fname_len; - File file; - Exit_status retval; - - if ((file= load_processor.prepare_new_file_for_old_format(le,fname)) < 0) - { - DBUG_RETURN(ERROR_STOP); - } - retval= process_event(print_event_info, ev, old_off, logname); - if (retval != OK_CONTINUE) - { - my_close(file,MYF(MY_WME)); - DBUG_RETURN(retval); - } - retval= load_processor.load_old_format_file(net,old_fname,old_len,file); - my_close(file,MYF(MY_WME)); - if (retval != OK_CONTINUE) - DBUG_RETURN(retval); - } /* Let's adjust offset for remote log as for local log to produce similar text and to have --stop-position to work identically. @@ -2449,8 +2621,6 @@ end: return retval; } -/* Used in sql_alloc(). Inited and freed in main() */ -MEM_ROOT s_mem_root; int main(int argc, char** argv) { @@ -2464,7 +2634,6 @@ int main(int argc, char** argv) my_init_time(); // for time functions tzset(); // set tzname - init_alloc_root(&s_mem_root, 16384, 0, MYF(0)); if (load_defaults("my", load_groups, &argc, &argv)) exit(1); @@ -2499,6 +2668,43 @@ int main(int argc, char** argv) my_set_max_open_files(open_files_limit); + if (opt_stop_never) + to_last_remote_log= TRUE; + + if (opt_raw_mode) + { + if (!remote_opt) + { + error("The --raw mode only works with --read-from-remote-server"); + exit(1); + } + if (one_database) + warning("The --database option is ignored in raw mode"); + + if (stop_position != (ulonglong)(~(my_off_t)0)) + warning("The --stop-position option is ignored in raw mode"); + + if (stop_datetime != MY_TIME_T_MAX) + warning("The --stop-datetime option is ignored in raw mode"); + result_file= 0; + if (result_file_name) + output_prefix= result_file_name; + } + else + { + if (result_file_name) + { + if (!(result_file= my_fopen(result_file_name, + O_WRONLY | O_BINARY, MYF(MY_WME)))) + { + error("Could not create log file '%s'", result_file_name); + exit(1); + } + } + else + result_file= stdout; + } + MY_TMPDIR tmpdir; tmpdir.list= 0; if (!dirname_for_local_load) @@ -2521,29 +2727,32 @@ int main(int argc, char** argv) else load_processor.init_by_cur_dir(); - fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;\n"); - - fprintf(result_file, - "/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n"); + if (!opt_raw_mode) + { + fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;\n"); - if (disable_log_bin) fprintf(result_file, - "/*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/;\n"); + "/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n"); - /* - In mysqlbinlog|mysql, don't want mysql to be disconnected after each - transaction (which would be the case with GLOBAL.COMPLETION_TYPE==2). - */ - fprintf(result_file, - "/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE," - "COMPLETION_TYPE=0*/;\n"); + if (disable_log_bin) + fprintf(result_file, + "/*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/;\n"); - if (charset) + /* + In mysqlbinlog|mysql, don't want mysql to be disconnected after each + transaction (which would be the case with GLOBAL.COMPLETION_TYPE==2). + */ fprintf(result_file, - "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" - "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" - "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" - "\n/*!40101 SET NAMES %s */;\n", charset); + "/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE," + "COMPLETION_TYPE=0*/;\n"); + + if (charset) + fprintf(result_file, + "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" + "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" + "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" + "\n/*!40101 SET NAMES %s */;\n", charset); + } for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ; (--argc >= 0) ; ) @@ -2557,31 +2766,33 @@ int main(int argc, char** argv) start_position= BIN_LOG_HEADER_SIZE; } - /* - Issue a ROLLBACK in case the last printed binlog was crashed and had half - of transaction. - */ - fprintf(result_file, - "# End of log file\nROLLBACK /* added by mysqlbinlog */;\n" - "/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;\n"); - if (disable_log_bin) - fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n"); - - if (charset) + if (!opt_raw_mode) + { + /* + Issue a ROLLBACK in case the last printed binlog was crashed and had half + of transaction. + */ fprintf(result_file, - "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n" - "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n" - "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n"); - - fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;\n"); + "# End of log file\nROLLBACK /* added by mysqlbinlog */;\n" + "/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;\n"); + if (disable_log_bin) + fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n"); + + if (charset) + fprintf(result_file, + "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n" + "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n" + "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n"); + + fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;\n"); + } if (tmpdir.list) free_tmpdir(&tmpdir); - if (result_file != stdout) + if (result_file && result_file != stdout) my_fclose(result_file, MYF(0)); cleanup(); free_annotate_event(); - free_root(&s_mem_root, MYF(0)); free_defaults(defaults_argv); my_free_open_file_info(); load_processor.destroy(); @@ -2602,11 +2813,6 @@ err: } -void *sql_alloc(size_t size) -{ - return alloc_root(&s_mem_root, size); -} - struct encryption_service_st encryption_handler= { 0, 0, 0, 0, 0, 0, 0 diff --git a/cmake/cat.cmake b/cmake/cat.cmake deleted file mode 100644 index 1ffe2ecfa1d..00000000000 --- a/cmake/cat.cmake +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2009 Sun Microsystems, Inc. -# Use is subject to license terms. -# -# 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 - -# Concatenate files -# -# Parameters : -# IN - input files (list) -# OUT - output file -FILE(WRITE ${OUT} "") -FOREACH(FILENAME ${IN}) - FILE(READ ${FILENAME} CONTENTS) - FILE(APPEND ${OUT} "${CONTENTS}") -ENDFOREACH() - - diff --git a/cmake/check_compiler_flag.cmake b/cmake/check_compiler_flag.cmake index 303d5d8d3c8..8192f077344 100644 --- a/cmake/check_compiler_flag.cmake +++ b/cmake/check_compiler_flag.cmake @@ -15,7 +15,7 @@ SET(fail_patterns ) MACRO (MY_CHECK_C_COMPILER_FLAG flag) - STRING(REGEX REPLACE "[-,= ]" "_" result "HAVE_C_${flag}") + STRING(REGEX REPLACE "[-,= ]" "_" result "have_C_${flag}") SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}") CHECK_C_SOURCE_COMPILES("int main(void) { return 0; }" ${result} @@ -24,7 +24,7 @@ MACRO (MY_CHECK_C_COMPILER_FLAG flag) ENDMACRO() MACRO (MY_CHECK_CXX_COMPILER_FLAG flag) - STRING(REGEX REPLACE "[-,= ]" "_" result "HAVE_CXX_${flag}") + STRING(REGEX REPLACE "[-,= ]" "_" result "have_CXX_${flag}") SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}") CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${result} @@ -42,7 +42,7 @@ FUNCTION(MY_CHECK_AND_SET_COMPILER_FLAG flag) MY_CHECK_CXX_COMPILER_FLAG(${flag}) STRING(REGEX REPLACE "[-,= ]" "_" result "${flag}") FOREACH(lang C CXX) - IF (HAVE_${lang}_${result}) + IF (have_${lang}_${result}) IF(ARGN) FOREACH(type ${ARGN}) SET(CMAKE_${lang}_FLAGS_${type} "${CMAKE_${lang}_FLAGS_${type}} ${flag}" PARENT_SCOPE) diff --git a/cmake/check_minimal_version.cmake b/cmake/check_minimal_version.cmake deleted file mode 100644 index d96c6a93418..00000000000 --- a/cmake/check_minimal_version.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2009 Sun Microsystems, Inc. -# Use is subject to license terms. -# -# 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 - -# This is a helper script is used to check for the minimal required version -# It helps to decide whether to use autoconf based configure or cmake's -# configure -CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR) diff --git a/cmake/cmake_parse_arguments.cmake b/cmake/cmake_parse_arguments.cmake deleted file mode 100644 index 487fe2bacd9..00000000000 --- a/cmake/cmake_parse_arguments.cmake +++ /dev/null @@ -1,47 +0,0 @@ - -# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. -# -# 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 - -# Handy macro to parse macro arguments -MACRO(MYSQL_PARSE_ARGUMENTS prefix arg_names option_names) - SET(DEFAULT_ARGS) - FOREACH(arg_name ${arg_names}) - SET(${prefix}_${arg_name}) - ENDFOREACH(arg_name) - FOREACH(option ${option_names}) - SET(${prefix}_${option} FALSE) - ENDFOREACH(option) - - SET(current_arg_name DEFAULT_ARGS) - SET(current_arg_list) - FOREACH(arg ${ARGN}) - SET(larg_names ${arg_names}) - LIST(FIND larg_names "${arg}" is_arg_name) - IF (is_arg_name GREATER -1) - SET(${prefix}_${current_arg_name} ${current_arg_list}) - SET(current_arg_name ${arg}) - SET(current_arg_list) - ELSE (is_arg_name GREATER -1) - SET(loption_names ${option_names}) - LIST(FIND loption_names "${arg}" is_option) - IF (is_option GREATER -1) - SET(${prefix}_${arg} TRUE) - ELSE (is_option GREATER -1) - SET(current_arg_list ${current_arg_list} ${arg}) - ENDIF (is_option GREATER -1) - ENDIF (is_arg_name GREATER -1) - ENDFOREACH(arg) - SET(${prefix}_${current_arg_name} ${current_arg_list}) -ENDMACRO()
\ No newline at end of file diff --git a/cmake/compile_flags.cmake b/cmake/compile_flags.cmake deleted file mode 100644 index b39bf7b79d6..00000000000 --- a/cmake/compile_flags.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. -# -# 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 - - -## ADD_COMPILE_FLAGS(<source files> COMPILE_FLAGS <flags>) -MACRO(ADD_COMPILE_FLAGS) - SET(FILES "") - SET(FLAGS "") - SET(COMPILE_FLAGS_SEEN) - FOREACH(ARG ${ARGV}) - IF(ARG STREQUAL "COMPILE_FLAGS") - SET(COMPILE_FLAGS_SEEN 1) - ELSEIF(COMPILE_FLAGS_SEEN) - LIST(APPEND FLAGS ${ARG}) - ELSE() - LIST(APPEND FILES ${ARG}) - ENDIF() - ENDFOREACH() - FOREACH(FILE ${FILES}) - FOREACH(FLAG ${FLAGS}) - GET_SOURCE_FILE_PROPERTY(PROP ${FILE} COMPILE_FLAGS) - IF(NOT PROP) - SET(PROP ${FLAG}) - ELSE() - SET(PROP "${PROP} ${FLAG}") - ENDIF() - SET_SOURCE_FILES_PROPERTIES( - ${FILE} PROPERTIES COMPILE_FLAGS "${PROP}" - ) - ENDFOREACH() - ENDFOREACH() -ENDMACRO() diff --git a/cmake/cpack_source_ignore_files.cmake b/cmake/cpack_source_ignore_files.cmake index 0654fa38388..2627e6cb697 100644 --- a/cmake/cpack_source_ignore_files.cmake +++ b/cmake/cpack_source_ignore_files.cmake @@ -39,7 +39,6 @@ scripts/mysql_fix_extensions$ scripts/mysql_install_db$ scripts/mysql_secure_installation$ scripts/mysql_setpermission$ -scripts/mysql_zap$ scripts/mysqlaccess$ scripts/mysqld_multi$ scripts/mysqld_safe$ diff --git a/cmake/ctest.cmake b/cmake/ctest.cmake index 08852a366f6..5bc1ce5f832 100644 --- a/cmake/ctest.cmake +++ b/cmake/ctest.cmake @@ -1,12 +1,12 @@ -INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) +INCLUDE(CMakeParseArguments) MACRO(MY_ADD_TEST name) ADD_TEST(${name} ${name}-t) ENDMACRO() -MACRO (MY_ADD_TESTS) - MYSQL_PARSE_ARGUMENTS(ARG "LINK_LIBRARIES;EXT" "" ${ARGN}) +MACRO(MY_ADD_TESTS) + CMAKE_PARSE_ARGUMENTS(ARG "" "EXT" "LINK_LIBRARIES" ${ARGN}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/unittest/mytap) @@ -15,7 +15,7 @@ MACRO (MY_ADD_TESTS) SET(ARG_EXT "c") ENDIF() - FOREACH(name ${ARG_DEFAULT_ARGS}) + FOREACH(name ${ARG_UNPARSED_ARGUMENTS}) ADD_EXECUTABLE(${name}-t "${name}-t.${ARG_EXT}") TARGET_LINK_LIBRARIES(${name}-t mytap ${ARG_LINK_LIBRARIES}) MY_ADD_TEST(${name}) diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index 00edcc737ce..17ee3c61554 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -13,12 +13,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -GET_FILENAME_COMPONENT(MYSQL_CMAKE_SCRIPT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) -INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) +INCLUDE(CMakeParseArguments) FUNCTION (INSTALL_DEBUG_SYMBOLS) IF(MSVC) - MYSQL_PARSE_ARGUMENTS(ARG + CMAKE_PARSE_ARGUMENTS(ARG + "" "COMPONENT;INSTALL_LOCATION" "" ${ARGN} @@ -30,7 +30,7 @@ FUNCTION (INSTALL_DEBUG_SYMBOLS) IF(NOT ARG_INSTALL_LOCATION) SET(ARG_INSTALL_LOCATION lib) ENDIF() - SET(targets ${ARG_DEFAULT_ARGS}) + SET(targets ${ARG_UNPARSED_ARGUMENTS}) FOREACH(target ${targets}) GET_TARGET_PROPERTY(type ${target} TYPE) GET_TARGET_PROPERTY(location ${target} LOCATION) @@ -109,13 +109,14 @@ FUNCTION(INSTALL_MANPAGE file) ENDFUNCTION() FUNCTION(INSTALL_SCRIPT) - MYSQL_PARSE_ARGUMENTS(ARG + CMAKE_PARSE_ARGUMENTS(ARG + "" "DESTINATION;COMPONENT" "" ${ARGN} ) - SET(script ${ARG_DEFAULT_ARGS}) + SET(script ${ARG_UNPARSED_ARGUMENTS}) IF(NOT ARG_DESTINATION) SET(ARG_DESTINATION ${INSTALL_BINDIR}) ENDIF() @@ -131,8 +132,8 @@ ENDFUNCTION() FUNCTION(INSTALL_DOCUMENTATION) - MYSQL_PARSE_ARGUMENTS(ARG "COMPONENT" "" ${ARGN}) - SET(files ${ARG_DEFAULT_ARGS}) + CMAKE_PARSE_ARGUMENTS(ARG "" "COMPONENT" "" ${ARGN}) + SET(files ${ARG_UNPARSED_ARGUMENTS}) IF(NOT ARG_COMPONENT) SET(ARG_COMPONENT Server) ENDIF() @@ -211,8 +212,8 @@ IF(WIN32) ENDIF() MACRO(SIGN_TARGET) - MYSQL_PARSE_ARGUMENTS(ARG "COMPONENT" "" ${ARGN}) - SET(target ${ARG_DEFAULT_ARGS}) + CMAKE_PARSE_ARGUMENTS(ARG "" "COMPONENT" "" ${ARGN}) + SET(target ${ARG_UNPARSED_ARGUMENTS}) IF(ARG_COMPONENT) SET(comp COMPONENT ${ARG_COMPONENT}) ELSE() @@ -247,8 +248,9 @@ ENDMACRO() # FUNCTION(MYSQL_INSTALL_TARGETS) - MYSQL_PARSE_ARGUMENTS(ARG - "DESTINATION;COMPONENT" + CMAKE_PARSE_ARGUMENTS(ARG + "" + "DESTINATION;COMPONENT" "" ${ARGN} ) @@ -258,7 +260,7 @@ FUNCTION(MYSQL_INSTALL_TARGETS) MESSAGE(FATAL_ERROR "COMPONENT argument required") ENDIF() - SET(TARGETS ${ARG_DEFAULT_ARGS}) + SET(TARGETS ${ARG_UNPARSED_ARGUMENTS}) IF(NOT TARGETS) MESSAGE(FATAL_ERROR "Need target list for MYSQL_INSTALL_TARGETS") ENDIF() @@ -266,10 +268,9 @@ FUNCTION(MYSQL_INSTALL_TARGETS) MESSAGE(FATAL_ERROR "Need DESTINATION parameter for MYSQL_INSTALL_TARGETS") ENDIF() - FOREACH(target ${TARGETS}) # If signing is required, sign executables before installing - IF(SIGNCODE) + IF(SIGNCODE) SIGN_TARGET(${target} ${COMP}) ENDIF() # Install man pages on Unix @@ -292,7 +293,8 @@ SET(DEBUGBUILDDIR "${BINARY_PARENTDIR}/debug" CACHE INTERNAL "Directory of debug FUNCTION(INSTALL_DEBUG_TARGET target) - MYSQL_PARSE_ARGUMENTS(ARG + CMAKE_PARSE_ARGUMENTS(ARG + "" "DESTINATION;RENAME;PDB_DESTINATION;COMPONENT" "" ${ARGN} diff --git a/cmake/libutils.cmake b/cmake/libutils.cmake index 5125b9482cd..bcba924dfa8 100644 --- a/cmake/libutils.cmake +++ b/cmake/libutils.cmake @@ -57,7 +57,7 @@ IF(WIN32 OR CYGWIN OR APPLE OR WITH_PIC OR DISABLE_SHARED OR NOT CMAKE_SHARED_LI SET(_SKIP_PIC 1) ENDIF() -INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) +INCLUDE(CMakeParseArguments) # CREATE_EXPORT_FILE (VAR target api_functions) # Internal macro, used to create source file for shared libraries that # otherwise consists entirely of "convenience" libraries. On Windows, @@ -218,13 +218,14 @@ ENDMACRO() # [OUTPUT_NAME output_name] #) MACRO(MERGE_LIBRARIES) - MYSQL_PARSE_ARGUMENTS(ARG - "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION" + CMAKE_PARSE_ARGUMENTS(ARG "STATIC;SHARED;MODULE;NOINSTALL" + "OUTPUT_NAME;COMPONENT;VERSION;SOVERSION" + "EXPORTS" ${ARGN} ) - LIST(GET ARG_DEFAULT_ARGS 0 TARGET) - SET(LIBS ${ARG_DEFAULT_ARGS}) + LIST(GET ARG_UNPARSED_ARGUMENTS 0 TARGET) + SET(LIBS ${ARG_UNPARSED_ARGUMENTS}) LIST(REMOVE_AT LIBS 0) IF(ARG_STATIC) IF (NOT ARG_OUTPUT_NAME) diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake index 367b78afd0d..bb7c8862dc7 100644 --- a/cmake/maintainer.cmake +++ b/cmake/maintainer.cmake @@ -16,7 +16,7 @@ # Common warning flags for GCC, G++, Clang and Clang++ SET(MY_WARNING_FLAGS "-Wall -Wextra -Wformat-security -Wno-init-self") MY_CHECK_C_COMPILER_FLAG("-Wvla") # Requires GCC 4.3+ or Clang -IF(HAVE_C__Wvla) +IF(have_C__Wvla) SET(MY_WARNING_FLAGS "${MY_WARNING_FLAGS} -Wvla") ENDIF() diff --git a/cmake/misc.cmake b/cmake/misc.cmake new file mode 100644 index 00000000000..c87fc41e8e3 --- /dev/null +++ b/cmake/misc.cmake @@ -0,0 +1,6 @@ +FUNCTION(MESSAGE_ONCE id out) + IF(NOT __msg1_${id} STREQUAL "${out}") + MESSAGE(STATUS "${out}") + ENDIF() + SET(__msg1_${id} "${out}" CACHE INTERNAL "") +ENDFUNCTION() diff --git a/cmake/mysql_add_executable.cmake b/cmake/mysql_add_executable.cmake index 0c93fb179f5..c8027eeea51 100644 --- a/cmake/mysql_add_executable.cmake +++ b/cmake/mysql_add_executable.cmake @@ -24,21 +24,37 @@ # - add version resource # - instruct CPack to do autenticode signing if SIGNCODE is set -INCLUDE(cmake_parse_arguments) +INCLUDE(CMakeParseArguments) FUNCTION (MYSQL_ADD_EXECUTABLE) # Pass-through arguments for ADD_EXECUTABLE - MYSQL_PARSE_ARGUMENTS(ARG - "WIN32;MACOSX_BUNDLE;EXCLUDE_FROM_ALL;DESTINATION;COMPONENT" + CMAKE_PARSE_ARGUMENTS(ARG + "WIN32;MACOSX_BUNDLE;EXCLUDE_FROM_ALL" + "DESTINATION;COMPONENT" "" ${ARGN} ) - LIST(GET ARG_DEFAULT_ARGS 0 target) - LIST(REMOVE_AT ARG_DEFAULT_ARGS 0) + LIST(GET ARG_UNPARSED_ARGUMENTS 0 target) + LIST(REMOVE_AT ARG_UNPARSED_ARGUMENTS 0) - SET(sources ${ARG_DEFAULT_ARGS}) + SET(sources ${ARG_UNPARSED_ARGUMENTS}) ADD_VERSION_INFO(${target} EXECUTABLE sources) - ADD_EXECUTABLE(${target} ${ARG_WIN32} ${ARG_MACOSX_BUNDLE} ${ARG_EXCLUDE_FROM_ALL} ${sources}) + IF (ARG_WIN32) + SET(WIN32 WIN32) + ELSE() + UNSET(WIN32) + ENDIF() + IF (ARG_MACOSX_BUNDLE) + SET(MACOSX_BUNDLE MACOSX_BUNDLE) + ELSE() + UNSET(MACOSX_BUNDLE) + ENDIF() + IF (ARG_EXCLUDE_FROM_ALL) + SET(EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL) + ELSE() + UNSET(EXCLUDE_FROM_ALL) + ENDIF() + ADD_EXECUTABLE(${target} ${WIN32} ${MACOSX_BUNDLE} ${EXCLUDE_FROM_ALL} ${sources}) # tell CPack where to install IF(NOT ARG_EXCLUDE_FROM_ALL) IF(NOT ARG_DESTINATION) diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index 07a8085a411..e8c46c1888a 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -22,8 +22,6 @@ IF(MSVC) SET(BFD_H_EXISTS 0 CACHE INTERNAL "") SET(HAVE_ACCESS 1 CACHE INTERNAL "") -SET(HAVE_AIO_H CACHE INTERNAL "") -SET(HAVE_AIO_READ CACHE INTERNAL "") SET(HAVE_ALARM CACHE INTERNAL "") SET(HAVE_ALLOCA_H CACHE INTERNAL "") SET(HAVE_ARPA_INET_H CACHE INTERNAL "") @@ -32,56 +30,41 @@ SET(HAVE_BACKTRACE CACHE INTERNAL "") SET(HAVE_BACKTRACE_SYMBOLS CACHE INTERNAL "") SET(HAVE_BACKTRACE_SYMBOLS_FD CACHE INTERNAL "") SET(HAVE_BFILL CACHE INTERNAL "") -SET(HAVE_BMOVE CACHE INTERNAL "") SET(HAVE_BSD_SIGNALS CACHE INTERNAL "") -SET(HAVE_BSEARCH 1 CACHE INTERNAL "") SET(HAVE_BSS_START CACHE INTERNAL "") -SET(HAVE_BZERO CACHE INTERNAL "") -SET(HAVE_CHOWN CACHE INTERNAL "") SET(HAVE_CLOCK_GETTIME CACHE INTERNAL "") SET(HAVE_COMPRESS CACHE INTERNAL "") SET(HAVE_CRYPT CACHE INTERNAL "") SET(HAVE_CRYPT_H CACHE INTERNAL "") SET(HAVE_CUSERID CACHE INTERNAL "") -SET(HAVE_CXX_NEW 1 CACHE INTERNAL "") SET(HAVE_DECL_MADVISE CACHE INTERNAL "") -SET(HAVE_DIRECTIO CACHE INTERNAL "") SET(HAVE_DIRENT_H CACHE INTERNAL "") SET(HAVE_DLERROR CACHE INTERNAL "") SET(HAVE_DLFCN_H CACHE INTERNAL "") SET(HAVE_DLOPEN CACHE INTERNAL "") -SET(HAVE_DOPRNT CACHE INTERNAL "") SET(HAVE_EXECINFO_H CACHE INTERNAL "") SET(HAVE_FCHMOD CACHE INTERNAL "") SET(HAVE_FCNTL CACHE INTERNAL "") SET(HAVE_FCNTL_H 1 CACHE INTERNAL "") SET(HAVE_FCNTL_NONBLOCK CACHE INTERNAL "") -SET(HAVE_FCONVERT CACHE INTERNAL "") SET(HAVE_FDATASYNC CACHE INTERNAL "") SET(HAVE_DECL_FDATASYNC CACHE INTERNAL "") SET(HAVE_FEDISABLEEXCEPT CACHE INTERNAL "") SET(HAVE_FENV_H CACHE INTERNAL "") SET(HAVE_FESETROUND CACHE INTERNAL "") -SET(HAVE_FGETLN CACHE INTERNAL "") SET(HAVE_FINITE CACHE INTERNAL "") SET(HAVE_FINITE_IN_MATH_H CACHE INTERNAL "") -SET(HAVE_FLOATINGPOINT_H CACHE INTERNAL "") SET(HAVE_FLOAT_H 1 CACHE INTERNAL "") -SET(HAVE_FLOCKFILE CACHE INTERNAL "") SET(HAVE_FNMATCH_H CACHE INTERNAL "") -SET(HAVE_FPSETMASK CACHE INTERNAL "") SET(HAVE_FPU_CONTROL_H CACHE INTERNAL "") SET(HAVE_FSEEKO CACHE INTERNAL "") SET(HAVE_FSYNC CACHE INTERNAL "") SET(HAVE_FTIME 1 CACHE INTERNAL "") SET(HAVE_FTRUNCATE CACHE INTERNAL "") -SET(HAVE_GETADDRINFO 1 CACHE INTERNAL "") SET(HAVE_GETIFADDRS CACHE INTERNAL "") SET(HAVE_GETCWD 1 CACHE INTERNAL "") SET(HAVE_GETHOSTBYADDR_R CACHE INTERNAL "") SET(HAVE_GETHRTIME CACHE INTERNAL "") -SET(HAVE_GETLINE CACHE INTERNAL "") -SET(HAVE_GETNAMEINFO CACHE INTERNAL "") SET(HAVE_GETPAGESIZE CACHE INTERNAL "") SET(HAVE_GETPASS CACHE INTERNAL "") SET(HAVE_GETPASSPHRASE CACHE INTERNAL "") @@ -102,18 +85,12 @@ SET(HAVE_IPPROTO_IPV6 CACHE INTERNAL "") SET(HAVE_IPV6 TRUE CACHE INTERNAL "") SET(HAVE_IPV6_V6ONLY 1 CACHE INTERNAL "") SET(HAVE_ISINF CACHE INTERNAL "") -SET(HAVE_ISSETUGID CACHE INTERNAL "") -SET(HAVE_GETUID CACHE INTERNAL "") -SET(HAVE_GETEUID CACHE INTERNAL "") -SET(HAVE_GETGID CACHE INTERNAL "") -SET(HAVE_GETEGID CACHE INTERNAL "") SET(HAVE_LANGINFO_H CACHE INTERNAL "") SET(HAVE_LDIV 1 CACHE INTERNAL "") SET(HAVE_LIMITS_H 1 CACHE INTERNAL "") SET(HAVE_LOCALE_H 1 CACHE INTERNAL "") SET(HAVE_LOCALTIME_R 1 CACHE INTERNAL "") SET(HAVE_LOG2 CACHE INTERNAL "") -SET(HAVE_LONGJMP 1 CACHE INTERNAL "") SET(HAVE_LRAND48 CACHE INTERNAL "") SET(HAVE_LSTAT CACHE INTERNAL "") SET(HAVE_MADVISE CACHE INTERNAL "") @@ -141,8 +118,6 @@ SET(HAVE_PAM_APPL_H CACHE INTERNAL "") SET(HAVE_POLL_H CACHE INTERNAL "") SET(HAVE_POPEN CACHE INTERNAL "") SET(HAVE_POLL CACHE INTERNAL "") -SET(HAVE_PORT_CREATE CACHE INTERNAL "") -SET(HAVE_PORT_H CACHE INTERNAL "") SET(HAVE_POSIX_FALLOCATE CACHE INTERNAL "") SET(HAVE_POSIX_SIGNALS CACHE INTERNAL "") SET(HAVE_PREAD CACHE INTERNAL "") @@ -152,12 +127,10 @@ SET(HAVE_PTHREAD_ATTR_GETSTACKSIZE CACHE INTERNAL "") SET(HAVE_PTHREAD_ATTR_SETSCOPE CACHE INTERNAL "") SET(HAVE_PTHREAD_ATTR_SETSTACKSIZE CACHE INTERNAL "") SET(HAVE_PTHREAD_CONDATTR_CREATE CACHE INTERNAL "") -SET(HAVE_PTHREAD_CONDATTR_SETCLOCK CACHE INTERNAL "") SET(HAVE_PTHREAD_INIT CACHE INTERNAL "") SET(HAVE_PTHREAD_KEY_DELETE CACHE INTERNAL "") SET(HAVE_PTHREAD_RWLOCK_RDLOCK CACHE INTERNAL "") SET(HAVE_PTHREAD_SIGMASK CACHE INTERNAL "") -SET(HAVE_PTHREAD_THREADMASK CACHE INTERNAL "") SET(HAVE_PTHREAD_YIELD_NP CACHE INTERNAL "") SET(HAVE_PTHREAD_YIELD_ZERO_ARG CACHE INTERNAL "") SET(HAVE_PUTENV 1 CACHE INTERNAL "") @@ -167,27 +140,16 @@ SET(HAVE_READDIR_R CACHE INTERNAL "") SET(HAVE_READLINK CACHE INTERNAL "") SET(HAVE_READ_REAL_TIME CACHE INTERNAL "") SET(HAVE_REALPATH CACHE INTERNAL "") -SET(HAVE_REGCOMP CACHE INTERNAL "") SET(HAVE_RENAME 1 CACHE INTERNAL "") -SET(HAVE_RE_COMP CACHE INTERNAL "") SET(HAVE_RINT CACHE INTERNAL "") SET(HAVE_RWLOCK_INIT CACHE INTERNAL "") SET(HAVE_SCHED_H CACHE INTERNAL "") SET(HAVE_SCHED_YIELD CACHE INTERNAL "") SET(HAVE_SELECT 1 CACHE INTERNAL "") SET(HAVE_SELECT_H CACHE INTERNAL "") -SET(HAVE_SEMAPHORE_H CACHE INTERNAL "") SET(HAVE_SETENV CACHE INTERNAL "") -SET(HAVE_SETFD CACHE INTERNAL "") SET(HAVE_SETLOCALE 1 CACHE INTERNAL "") -SET(HAVE_SHMAT CACHE INTERNAL "") -SET(HAVE_SHMCTL CACHE INTERNAL "") -SET(HAVE_SHMDT CACHE INTERNAL "") -SET(HAVE_SHMGET CACHE INTERNAL "") SET(HAVE_SIGACTION CACHE INTERNAL "") -SET(HAVE_SIGADDSET CACHE INTERNAL "") -SET(HAVE_SIGEMPTYSET CACHE INTERNAL "") -SET(HAVE_SIGHOLD CACHE INTERNAL "") SET(HAVE_SIGINT 1 CACHE INTERNAL "") SET(HAVE_SIGPIPE CACHE INTERNAL "") SET(HAVE_SIGQUIT CACHE INTERNAL "") @@ -195,9 +157,6 @@ SET(HAVE_SIGSET CACHE INTERNAL "") SET(HAVE_SIGTERM 1 CACHE INTERNAL "") SET(HAVE_SIGTHREADMASK CACHE INTERNAL "") SET(HAVE_SIGWAIT CACHE INTERNAL "") -SET(HAVE_SIZEOF_BOOL FALSE CACHE INTERNAL "") -SET(HAVE_SIZEOF_CHAR TRUE CACHE INTERNAL "") -SET(SIZEOF_CHAR 1 CACHE INTERNAL "") SET(HAVE_SIZEOF_CHARP TRUE CACHE INTERNAL "") SET(SIZEOF_CHARP ${CMAKE_SIZEOF_VOID_P} CACHE INTERNAL "") SET(HAVE_SIZEOF_IN6_ADDR TRUE CACHE INTERNAL "") @@ -214,13 +173,10 @@ SET(SIZEOF_LONG_LONG 8 CACHE INTERNAL "") SET(HAVE_SIZEOF_MODE_T FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_OFF_T TRUE CACHE INTERNAL "") SET(SIZEOF_OFF_T 4 CACHE INTERNAL "") -SET(HAVE_SIZEOF_SHORT TRUE CACHE INTERNAL "") -SET(SIZEOF_SHORT 2 CACHE INTERNAL "") SET(HAVE_SIZEOF_SIGSET_T FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_SIZE_T TRUE CACHE INTERNAL "") SET(SIZEOF_SIZE_T ${CMAKE_SIZEOF_VOID_P} CACHE INTERNAL "") SET(HAVE_SIZEOF_SOCKADDR_IN6 TRUE CACHE INTERNAL "") -SET(HAVE_SIZEOF_SOCKLEN_T FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_UCHAR FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_UINT FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_UINT16 FALSE CACHE INTERNAL "") @@ -228,7 +184,6 @@ SET(HAVE_SIZEOF_UINT32 FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_UINT64 FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_UINT8 FALSE CACHE INTERNAL "") SET(HAVE_SIZEOF_ULONG FALSE CACHE INTERNAL "") -SET(HAVE_SIZEOF_U_INT32_T FALSE CACHE INTERNAL "") SET(HAVE_SIZE_OF_SSIZE_T FALSE CACHE INTERNAL "") SET(HAVE_SLEEP CACHE INTERNAL "") SET(HAVE_SOCKADDR_STORAGE_SS_FAMILY 1 CACHE INTERNAL "") @@ -241,30 +196,20 @@ SET(HAVE_STDLIB_H 1 CACHE INTERNAL "") SET(HAVE_STPCPY CACHE INTERNAL "") SET(HAVE_STRCASECMP CACHE INTERNAL "") SET(HAVE_STRCOLL 1 CACHE INTERNAL "") -SET(HAVE_STRDUP 1 CACHE INTERNAL "") SET(HAVE_STRERROR 1 CACHE INTERNAL "") SET(HAVE_STRINGS_H CACHE INTERNAL "") SET(HAVE_STRING_H 1 CACHE INTERNAL "") -SET(HAVE_STRLCAT CACHE INTERNAL "") -SET(HAVE_STRLCPY CACHE INTERNAL "") -SET(HAVE_STRNCASECMP CACHE INTERNAL "") SET(HAVE_STRNDUP CACHE INTERNAL "") IF(MSVC_VERSION GREATER 1310) SET(HAVE_STRNLEN 1 CACHE INTERNAL "") ENDIF() SET(HAVE_STRPBRK 1 CACHE INTERNAL "") -SET(HAVE_STRSEP CACHE INTERNAL "") -SET(HAVE_STRSIGNAL CACHE INTERNAL "") -SET(HAVE_STRSTR 1 CACHE INTERNAL "") SET(HAVE_STRTOK_R CACHE INTERNAL "") -SET(HAVE_STRTOL 1 CACHE INTERNAL "") SET(HAVE_STRTOLL CACHE INTERNAL "") SET(HAVE_STRTOUL 1 CACHE INTERNAL "") SET(HAVE_STRTOULL CACHE INTERNAL "") -SET(HAVE_SVR3_SIGNALS CACHE INTERNAL "") SET(HAVE_SYNCH_H CACHE INTERNAL "") SET(HAVE_SYSENT_H CACHE INTERNAL "") -SET(HAVE_SYS_CDEFS_H CACHE INTERNAL "") SET(HAVE_SYS_DIR_H CACHE INTERNAL "") SET(HAVE_SYS_EVENT_H CACHE INTERNAL "") SET(HAVE_SYS_ERRLIST CACHE INTERNAL "") @@ -285,7 +230,6 @@ SET(HAVE_SYS_SOCKIO_H CACHE INTERNAL "") SET(HAVE_SYS_SOCKET_H CACHE INTERNAL "") SET(HAVE_SYS_STAT_H 1 CACHE INTERNAL "") SET(HAVE_SYS_STREAM_H CACHE INTERNAL "") -SET(HAVE_SYS_TERMCAP_H CACHE INTERNAL "") SET(HAVE_SYS_TIMEB_H 1 CACHE INTERNAL "") SET(HAVE_SYS_TIMES_H CACHE INTERNAL "") SET(HAVE_SYS_TIME_H CACHE INTERNAL "") @@ -310,10 +254,8 @@ SET(HAVE_TIME_H 1 CACHE INTERNAL "") SET(HAVE_TZNAME 1 CACHE INTERNAL "") SET(HAVE_UNISTD_H CACHE INTERNAL "") SET(HAVE_UTIME_H CACHE INTERNAL "") -SET(HAVE_VALLOC CACHE INTERNAL "") SET(HAVE_VARARGS_H 1 CACHE INTERNAL "") SET(HAVE_VASPRINTF CACHE INTERNAL "") -SET(HAVE_VPRINTF 1 CACHE INTERNAL "") IF(MSVC_VERSION GREATER 1310) SET(HAVE_VSNPRINTF 1 CACHE INTERNAL "") ENDIF() @@ -334,9 +276,6 @@ IF(MSVC_VERSION GREATER 1310) SET(HAVE_strtok_s 1 CACHE INTERNAL "") ENDIF() SET(STDC_HEADERS CACHE 1 INTERNAL "") -SET(STRUCT_DIRENT_HAS_D_INO CACHE INTERNAL "") -SET(STRUCT_DIRENT_HAS_D_INO CACHE INTERNAL "") -SET(STRUCT_DIRENT_HAS_D_NAMLEN CACHE INTERNAL "") SET(TIME_WITH_SYS_TIME CACHE INTERNAL "") SET(TIME_T_UNSIGNED 1 CACHE INTERNAL "") SET(TIOCSTAT_IN_SYS_IOCTL CACHE INTERNAL "") @@ -354,18 +293,16 @@ SET(HAVE_SYS_NDIR_H CACHE INTERNAL "") SET(HAVE_SYS_NDIR_H CACHE INTERNAL "") SET(HAVE_ASM_TERMBITS_H CACHE INTERNAL "") SET(HAVE_TERMBITS_H CACHE INTERNAL "") -SET(HAVE_VIS_H CACHE INTERNAL "") SET(HAVE_WCHAR_H 1 CACHE INTERNAL "") SET(HAVE_WCTYPE_H 1 CACHE INTERNAL "") SET(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP CACHE INTERNAL "") SET(HAVE_SOCKADDR_IN_SIN_LEN CACHE INTERNAL "") SET(HAVE_SOCKADDR_IN6_SIN6_LEN CACHE INTERNAL "") -SET(HAVE_VALGRIND CACHE INTERNAL "") +SET(HAVE_VALGRIND_MEMCHECK_H CACHE INTERNAL "") SET(HAVE_EVENT_H CACHE INTERNAL "") SET(HAVE_LINUX_UNISTD_H CACHE INTERNAL "") SET(HAVE_SYS_UTSNAME_H CACHE INTERNAL "") SET(HAVE_PTHREAD_ATTR_GETGUARDSIZE CACHE INTERNAL "") -SET(HAVE_UCONTEXT_H CACHE INTERNAL "") SET(HAVE_SOCKPEERCRED CACHE INTERNAL "") SET(HAVE_ABI_CXA_DEMANGLE CACHE INTERNAL "") SET(HAVE_GCC_ATOMIC_BUILTINS CACHE INTERNAL "") diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 361cb597cac..c4edd585a8d 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -14,8 +14,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -GET_FILENAME_COMPONENT(MYSQL_CMAKE_SCRIPT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) -INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) +INCLUDE(CMakeParseArguments) # MYSQL_ADD_PLUGIN(plugin_name source1...sourceN # [STORAGE_ENGINE] @@ -29,9 +28,10 @@ INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/cmake_parse_arguments.cmake) # [DEPENDENCIES target1...targetN] MACRO(MYSQL_ADD_PLUGIN) - MYSQL_PARSE_ARGUMENTS(ARG - "LINK_LIBRARIES;DEPENDENCIES;MODULE_OUTPUT_NAME;STATIC_OUTPUT_NAME;COMPONENT;CONFIG" + CMAKE_PARSE_ARGUMENTS(ARG "STORAGE_ENGINE;STATIC_ONLY;MODULE_ONLY;MANDATORY;DEFAULT;DISABLED;RECOMPILE_FOR_EMBEDDED;CLIENT" + "MODULE_OUTPUT_NAME;STATIC_OUTPUT_NAME;COMPONENT;CONFIG" + "LINK_LIBRARIES;DEPENDENCIES" ${ARGN} ) IF(NOT WITHOUT_SERVER OR ARG_CLIENT) @@ -43,8 +43,8 @@ MACRO(MYSQL_ADD_PLUGIN) ${SSL_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}) - LIST(GET ARG_DEFAULT_ARGS 0 plugin) - SET(SOURCES ${ARG_DEFAULT_ARGS}) + LIST(GET ARG_UNPARSED_ARGUMENTS 0 plugin) + SET(SOURCES ${ARG_UNPARSED_ARGUMENTS}) LIST(REMOVE_AT SOURCES 0) STRING(TOUPPER ${plugin} plugin) STRING(TOLOWER ${plugin} target) diff --git a/cmake/readline.cmake b/cmake/readline.cmake index f570c91c1b5..1bd669fd605 100644 --- a/cmake/readline.cmake +++ b/cmake/readline.cmake @@ -27,25 +27,11 @@ MACRO (MYSQL_CHECK_MULTIBYTE) SET(HAVE_MBSTATE_T 1) ENDIF() ENDIF() - - CHECK_C_SOURCE_COMPILES(" - #include <langinfo.h> - int main(int ac, char **av) - { - char *cs = nl_langinfo(CODESET); - return 0; - }" - HAVE_LANGINFO_CODESET) CHECK_FUNCTION_EXISTS(mbrlen HAVE_MBRLEN) - CHECK_FUNCTION_EXISTS(mbscmp HAVE_MBSCMP) CHECK_FUNCTION_EXISTS(mbsrtowcs HAVE_MBSRTOWCS) - CHECK_FUNCTION_EXISTS(wcrtomb HAVE_WCRTOMB) CHECK_FUNCTION_EXISTS(mbrtowc HAVE_MBRTOWC) - CHECK_FUNCTION_EXISTS(wcscoll HAVE_WCSCOLL) - CHECK_FUNCTION_EXISTS(wcsdup HAVE_WCSDUP) CHECK_FUNCTION_EXISTS(wcwidth HAVE_WCWIDTH) - CHECK_FUNCTION_EXISTS(wctype HAVE_WCTYPE) CHECK_FUNCTION_EXISTS(iswlower HAVE_ISWLOWER) CHECK_FUNCTION_EXISTS(iswupper HAVE_ISWUPPER) CHECK_FUNCTION_EXISTS(towlower HAVE_TOWLOWER) @@ -60,13 +46,7 @@ MACRO (MYSQL_CHECK_MULTIBYTE) SET(CMAKE_EXTRA_INCLUDE_FILES wctype.h) CHECK_TYPE_SIZE(wctype_t SIZEOF_WCTYPE_T) - IF(SIZEOF_WCTYPE_T) - SET(HAVE_WCTYPE_T 1) - ENDIF() CHECK_TYPE_SIZE(wint_t SIZEOF_WINT_T) - IF(SIZEOF_WINT_T) - SET(HAVE_WINT_T 1) - ENDIF() SET(CMAKE_EXTRA_INCLUDE_FILES) ENDMACRO() @@ -87,15 +67,12 @@ MACRO (FIND_CURSES) IF(CURSES_HAVE_CURSES_H) SET(HAVE_CURSES_H 1 CACHE INTERNAL "") - ELSEIF(CURSES_HAVE_NCURSES_H) - SET(HAVE_NCURSES_H 1 CACHE INTERNAL "") ENDIF() IF(CMAKE_SYSTEM_NAME MATCHES "HP") # CMake uses full path to library /lib/libcurses.sl # On Itanium, it results into architecture mismatch+ # the library is for PA-RISC SET(CURSES_LIBRARY "curses" CACHE INTERNAL "" FORCE) - SET(CURSES_CURSES_LIBRARY "curses" CACHE INTERNAL "" FORCE) ENDIF() IF(CMAKE_SYSTEM_NAME MATCHES "Linux") diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index b699a3b493f..0173cf026f1 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -70,6 +70,7 @@ MACRO (MYSQL_USE_BUNDLED_SSL) SET(SSL_SOURCES ${SSL_SOURCES} ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/${file}) ENDFOREACH() + MESSAGE_ONCE(SSL_LIBRARIES "SSL_LIBRARIES = ${SSL_LIBRARIES}") ENDMACRO() # MYSQL_CHECK_SSL @@ -140,7 +141,7 @@ MACRO (MYSQL_CHECK_SSL) NAMES openssl/applink.c HINTS ${OPENSSL_ROOT_DIR}/include ) - MESSAGE(STATUS "OPENSSL_APPLINK_C ${OPENSSL_APPLINK_C}") + MESSAGE_ONCE(OPENSSL_APPLINK_C "OPENSSL_APPLINK_C ${OPENSSL_APPLINK_C}") ENDIF() # On mac this list is <.dylib;.so;.a> @@ -187,12 +188,11 @@ MACRO (MYSQL_CHECK_SSL) "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9]).*$" "\\1" OPENSSL_MAJOR_VERSION "${OPENSSL_VERSION_NUMBER}" ) - - MESSAGE(STATUS "OPENSSL_INCLUDE_DIR = ${OPENSSL_INCLUDE_DIR}") - MESSAGE(STATUS "OPENSSL_LIBRARIES = ${OPENSSL_LIBRARIES}") - MESSAGE(STATUS "CRYPTO_LIBRARY = ${CRYPTO_LIBRARY}") - MESSAGE(STATUS "OPENSSL_MAJOR_VERSION = ${OPENSSL_MAJOR_VERSION}") - MESSAGE(STATUS "SSL_LIBRARIES = ${SSL_LIBRARIES}") + MESSAGE_ONCE(OPENSSL_INCLUDE_DIR "OPENSSL_INCLUDE_DIR = ${OPENSSL_INCLUDE_DIR}") + MESSAGE_ONCE(OPENSSL_LIBRARIES "OPENSSL_LIBRARIES = ${OPENSSL_LIBRARIES}") + MESSAGE_ONCE(CRYPTO_LIBRARY "CRYPTO_LIBRARY = ${CRYPTO_LIBRARY}") + MESSAGE_ONCE(OPENSSL_MAJOR_VERSION "OPENSSL_MAJOR_VERSION = ${OPENSSL_MAJOR_VERSION}") + MESSAGE_ONCE(SSL_LIBRARIES "SSL_LIBRARIES = ${SSL_LIBRARIES}") SET(SSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR}) SET(SSL_INTERNAL_INCLUDE_DIRS "") SET(SSL_DEFINES "-DHAVE_OPENSSL") diff --git a/cmake/systemd.cmake b/cmake/systemd.cmake index b0161cf9114..e6094c7c5bc 100644 --- a/cmake/systemd.cmake +++ b/cmake/systemd.cmake @@ -65,7 +65,7 @@ MACRO(CHECK_SYSTEMD) SET(SYSTEMD_EXECSTARTPRE "ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld") SET(SYSTEMD_EXECSTARTPOST "ExecStartPost=/etc/mysql/debian-start") ENDIF() - MESSAGE(STATUS "Systemd features enabled") + MESSAGE_ONCE(systemd "Systemd features enabled") ELSE() UNSET(LIBSYSTEMD) UNSET(HAVE_SYSTEMD) @@ -73,7 +73,7 @@ MACRO(CHECK_SYSTEMD) UNSET(HAVE_SYSTEMD_SD_LISTEN_FDS) UNSET(HAVE_SYSTEMD_SD_NOTIFY) UNSET(HAVE_SYSTEMD_SD_NOTIFYF) - MESSAGE(STATUS "Systemd features not enabled") + MESSAGE_ONCE(systemd "Systemd features not enabled") IF(WITH_SYSTEMD STREQUAL "yes") MESSAGE(FATAL_ERROR "Requested WITH_SYSTEMD=YES however no dependencies installed/found") ENDIF() diff --git a/config.h.cmake b/config.h.cmake index ce6f14723b8..048ce816a43 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -20,15 +20,12 @@ #cmakedefine STDC_HEADERS 1 #cmakedefine _GNU_SOURCE 1 #cmakedefine HAVE_ALLOCA_H 1 -#cmakedefine HAVE_AIO_H 1 #cmakedefine HAVE_ARPA_INET_H 1 #cmakedefine HAVE_ASM_MSR_H 1 #cmakedefine HAVE_ASM_TERMBITS_H 1 -#cmakedefine HAVE_BSEARCH 1 #cmakedefine HAVE_CRYPT_H 1 #cmakedefine HAVE_CURSES_H 1 #cmakedefine HAVE_BFD_H 1 -#cmakedefine HAVE_NCURSES_H 1 #cmakedefine HAVE_NDIR_H 1 #cmakedefine HAVE_DIRENT_H 1 #cmakedefine HAVE_DLFCN_H 1 @@ -36,7 +33,6 @@ #cmakedefine HAVE_FCNTL_H 1 #cmakedefine HAVE_FENV_H 1 #cmakedefine HAVE_FLOAT_H 1 -#cmakedefine HAVE_FLOATINGPOINT_H 1 #cmakedefine HAVE_FNMATCH_H 1 #cmakedefine HAVE_FPU_CONTROL_H 1 #cmakedefine HAVE_GRP_H 1 @@ -53,7 +49,6 @@ #cmakedefine HAVE_NETINET_IN_H 1 #cmakedefine HAVE_PATHS_H 1 #cmakedefine HAVE_POLL_H 1 -#cmakedefine HAVE_PORT_H 1 #cmakedefine HAVE_PWD_H 1 #cmakedefine HAVE_SCHED_H 1 #cmakedefine HAVE_SELECT_H 1 @@ -64,11 +59,9 @@ #cmakedefine HAVE_STRINGS_H 1 #cmakedefine HAVE_STRING_H 1 #cmakedefine HAVE_STDINT_H 1 -#cmakedefine HAVE_SEMAPHORE_H 1 #cmakedefine HAVE_SYNCH_H 1 #cmakedefine HAVE_SYSENT_H 1 #cmakedefine HAVE_SYS_DIR_H 1 -#cmakedefine HAVE_SYS_CDEFS_H 1 #cmakedefine HAVE_SYS_FILE_H 1 #cmakedefine HAVE_SYS_FPU_H 1 #cmakedefine HAVE_SYS_IOCTL_H 1 @@ -88,7 +81,6 @@ #cmakedefine HAVE_SYS_STAT_H 1 #cmakedefine HAVE_SYS_STREAM_H 1 #cmakedefine HAVE_SYS_SYSCALL_H 1 -#cmakedefine HAVE_SYS_TERMCAP_H 1 #cmakedefine HAVE_SYS_TIMEB_H 1 #cmakedefine HAVE_SYS_TIMES_H 1 #cmakedefine HAVE_SYS_TIME_H 1 @@ -106,20 +98,11 @@ #cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_UTIME_H 1 #cmakedefine HAVE_VARARGS_H 1 -#cmakedefine HAVE_VIS_H 1 #cmakedefine HAVE_SYS_UTIME_H 1 #cmakedefine HAVE_SYS_WAIT_H 1 #cmakedefine HAVE_SYS_PARAM_H 1 /* Libraries */ -#cmakedefine HAVE_LIBPTHREAD 1 -#cmakedefine HAVE_LIBM 1 -#cmakedefine HAVE_LIBDL 1 -#cmakedefine HAVE_LIBRT 1 -#cmakedefine HAVE_LIBSOCKET 1 -#cmakedefine HAVE_LIBNSL 1 -#cmakedefine HAVE_LIBCRYPT 1 -#cmakedefine HAVE_LIBMTMALLOC 1 #cmakedefine HAVE_LIBWRAP 1 #cmakedefine HAVE_SYSTEMD 1 /* Does "struct timespec" have a "sec" and "nsec" field? */ @@ -136,43 +119,33 @@ #cmakedefine FIONREAD_IN_SYS_FILIO 1 /* Functions we may want to use. */ +#cmakedefine HAVE_ACCEPT4 1 #cmakedefine HAVE_ACCESS 1 #cmakedefine HAVE_AIOWAIT 1 #cmakedefine HAVE_ALARM 1 #cmakedefine HAVE_ALLOCA 1 #cmakedefine HAVE_BFILL 1 -#cmakedefine HAVE_BMOVE 1 -#cmakedefine HAVE_BZERO 1 #cmakedefine HAVE_INDEX 1 -#cmakedefine HAVE_CHOWN 1 #cmakedefine HAVE_CLOCK_GETTIME 1 #cmakedefine HAVE_CRYPT 1 #cmakedefine HAVE_CUSERID 1 -#cmakedefine HAVE_CXX_NEW 1 -#cmakedefine HAVE_DIRECTIO 1 #cmakedefine HAVE_DLERROR 1 #cmakedefine HAVE_DLOPEN 1 -#cmakedefine HAVE_DOPRNT 1 #cmakedefine HAVE_FCHMOD 1 #cmakedefine HAVE_FCNTL 1 -#cmakedefine HAVE_FCONVERT 1 #cmakedefine HAVE_FDATASYNC 1 #cmakedefine HAVE_DECL_FDATASYNC 1 #cmakedefine HAVE_FEDISABLEEXCEPT 1 #cmakedefine HAVE_FESETROUND 1 #cmakedefine HAVE_FINITE 1 #cmakedefine HAVE_FP_EXCEPT 1 -#cmakedefine HAVE_FPSETMASK 1 #cmakedefine HAVE_FSEEKO 1 #cmakedefine HAVE_FSYNC 1 #cmakedefine HAVE_FTIME 1 -#cmakedefine HAVE_GETADDRINFO 1 #cmakedefine HAVE_GETIFADDRS 1 #cmakedefine HAVE_GETCWD 1 #cmakedefine HAVE_GETHOSTBYADDR_R 1 #cmakedefine HAVE_GETHRTIME 1 -#cmakedefine HAVE_GETLINE 1 -#cmakedefine HAVE_GETNAMEINFO 1 #cmakedefine HAVE_GETPAGESIZE 1 #cmakedefine HAVE_GETPASS 1 #cmakedefine HAVE_GETPASSPHRASE 1 @@ -186,11 +159,6 @@ #cmakedefine gmtime_r @gmtime_r@ #cmakedefine HAVE_IN_ADDR_T 1 #cmakedefine HAVE_INITGROUPS 1 -#cmakedefine HAVE_ISSETUGID 1 -#cmakedefine HAVE_GETUID 1 -#cmakedefine HAVE_GETEUID 1 -#cmakedefine HAVE_GETGID 1 -#cmakedefine HAVE_GETEGID 1 #cmakedefine HAVE_ISNAN 1 #cmakedefine HAVE_ISINF 1 #cmakedefine HAVE_LARGE_PAGE_OPTION 1 @@ -198,7 +166,6 @@ #cmakedefine HAVE_LRAND48 1 #cmakedefine HAVE_LOCALTIME_R 1 #cmakedefine HAVE_LOG2 1 -#cmakedefine HAVE_LONGJMP 1 #cmakedefine HAVE_LSTAT 1 #cmakedefine HAVE_MEMALIGN 1 /* #cmakedefine HAVE_MLOCK 1 see Bug#54662 */ @@ -206,7 +173,6 @@ #cmakedefine HAVE_NL_LANGINFO 1 #cmakedefine HAVE_MADVISE 1 #cmakedefine HAVE_DECL_MADVISE 1 -#cmakedefine HAVE_DECL_TGOTO 1 #cmakedefine HAVE_DECL_MHA_MAPSIZE_VA 1 #cmakedefine HAVE_MALLINFO 1 #cmakedefine HAVE_MEMCPY 1 @@ -217,10 +183,8 @@ #cmakedefine HAVE_MMAP64 1 #cmakedefine HAVE_PERROR 1 #cmakedefine HAVE_POLL 1 -#cmakedefine HAVE_PORT_CREATE 1 #cmakedefine HAVE_POSIX_FALLOCATE 1 #cmakedefine HAVE_LINUX_FALLOC_H 1 -#cmakedefine HAVE_FALLOCATE 1 #cmakedefine HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE 1 #cmakedefine HAVE_PREAD 1 #cmakedefine HAVE_PAUSE_INSTRUCTION 1 @@ -230,26 +194,17 @@ #cmakedefine HAVE_PTHREAD_ATTR_CREATE 1 #cmakedefine HAVE_PTHREAD_ATTR_GETGUARDSIZE 1 #cmakedefine HAVE_PTHREAD_ATTR_GETSTACKSIZE 1 -#cmakedefine HAVE_PTHREAD_ATTR_SETPRIO 1 -#cmakedefine HAVE_PTHREAD_ATTR_SETSCHEDPARAM 1 #cmakedefine HAVE_PTHREAD_ATTR_SETSCOPE 1 #cmakedefine HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 #cmakedefine HAVE_PTHREAD_CONDATTR_CREATE 1 -#cmakedefine HAVE_PTHREAD_CONDATTR_SETCLOCK 1 -#cmakedefine HAVE_PTHREAD_KEY_DELETE 1 #cmakedefine HAVE_PTHREAD_KEY_DELETE 1 #cmakedefine HAVE_PTHREAD_KILL 1 #cmakedefine HAVE_PTHREAD_RWLOCK_RDLOCK 1 -#cmakedefine HAVE_PTHREAD_SETPRIO_NP 1 -#cmakedefine HAVE_PTHREAD_SETSCHEDPARAM 1 #cmakedefine HAVE_PTHREAD_SIGMASK 1 -#cmakedefine HAVE_PTHREAD_THREADMASK 1 #cmakedefine HAVE_PTHREAD_YIELD_NP 1 #cmakedefine HAVE_PTHREAD_YIELD_ZERO_ARG 1 #cmakedefine PTHREAD_ONCE_INITIALIZER @PTHREAD_ONCE_INITIALIZER@ #cmakedefine HAVE_PUTENV 1 -#cmakedefine HAVE_RE_COMP 1 -#cmakedefine HAVE_REGCOMP 1 #cmakedefine HAVE_READDIR_R 1 #cmakedefine HAVE_READLINK 1 #cmakedefine HAVE_REALPATH 1 @@ -258,15 +213,10 @@ #cmakedefine HAVE_RWLOCK_INIT 1 #cmakedefine HAVE_SCHED_YIELD 1 #cmakedefine HAVE_SELECT 1 -#cmakedefine HAVE_SETFD 1 #cmakedefine HAVE_SETENV 1 #cmakedefine HAVE_SETLOCALE 1 #cmakedefine HAVE_SETUPTERM 1 -#cmakedefine HAVE_SIGADDSET 1 -#cmakedefine HAVE_SIGEMPTYSET 1 -#cmakedefine HAVE_SIGHOLD 1 #cmakedefine HAVE_SIGSET 1 -#cmakedefine HAVE_SIGSET_T 1 #cmakedefine HAVE_SIGACTION 1 #cmakedefine HAVE_SIGTHREADMASK 1 #cmakedefine HAVE_SIGWAIT 1 @@ -275,38 +225,24 @@ #cmakedefine HAVE_STPCPY 1 #cmakedefine HAVE_STRERROR 1 #cmakedefine HAVE_STRCOLL 1 -#cmakedefine HAVE_STRSIGNAL 1 -#cmakedefine HAVE_STRLCPY 1 -#cmakedefine HAVE_STRLCAT 1 -#cmakedefine HAVE_FGETLN 1 #cmakedefine HAVE_STRNLEN 1 #cmakedefine HAVE_STRPBRK 1 -#cmakedefine HAVE_STRSEP 1 -#cmakedefine HAVE_STRSTR 1 #cmakedefine HAVE_STRTOK_R 1 -#cmakedefine HAVE_STRTOL 1 #cmakedefine HAVE_STRTOLL 1 #cmakedefine HAVE_STRTOUL 1 #cmakedefine HAVE_STRTOULL 1 -#cmakedefine HAVE_SHMAT 1 -#cmakedefine HAVE_SHMCTL 1 -#cmakedefine HAVE_SHMDT 1 -#cmakedefine HAVE_SHMGET 1 #cmakedefine HAVE_TELL 1 #cmakedefine HAVE_TEMPNAM 1 #cmakedefine HAVE_THR_SETCONCURRENCY 1 #cmakedefine HAVE_THR_YIELD 1 #cmakedefine HAVE_TIME 1 #cmakedefine HAVE_TIMES 1 -#cmakedefine HAVE_VALLOC 1 #cmakedefine HAVE_VIDATTR 1 #define HAVE_VIO_READ_BUFF 1 #cmakedefine HAVE_VASPRINTF 1 -#cmakedefine HAVE_VPRINTF 1 #cmakedefine HAVE_VSNPRINTF 1 #cmakedefine HAVE_FTRUNCATE 1 #cmakedefine HAVE_TZNAME 1 -#cmakedefine HAVE_AIO_READ 1 /* Symbols we may use */ #cmakedefine HAVE_SYS_ERRLIST 1 /* used by stacktrace functions */ @@ -315,25 +251,18 @@ #cmakedefine HAVE_BACKTRACE_SYMBOLS 1 #cmakedefine HAVE_BACKTRACE_SYMBOLS_FD 1 #cmakedefine HAVE_PRINTSTACK 1 -#cmakedefine HAVE_STRUCT_SOCKADDR_IN6 1 -#cmakedefine HAVE_STRUCT_IN6_ADDR 1 -#cmakedefine HAVE_NETINET_IN6_H 1 #cmakedefine HAVE_IPV6 1 #cmakedefine ss_family @ss_family@ #cmakedefine HAVE_SOCKADDR_IN_SIN_LEN 1 #cmakedefine HAVE_SOCKADDR_IN6_SIN6_LEN 1 -#cmakedefine HAVE_TIMESPEC_TS_SEC 1 -#cmakedefine STRUCT_DIRENT_HAS_D_INO 1 -#cmakedefine STRUCT_DIRENT_HAS_D_NAMLEN 1 #cmakedefine STRUCT_TIMESPEC_HAS_TV_SEC 1 #cmakedefine STRUCT_TIMESPEC_HAS_TV_NSEC 1 -#cmakedefine SPRINTF_RETURNS_INT 1 #define USE_MB 1 #define USE_MB_IDENT 1 /* this means that valgrind headers and macros are available */ -#cmakedefine HAVE_VALGRIND 1 +#cmakedefine HAVE_VALGRIND_MEMCHECK_H 1 /* this means WITH_VALGRIND - we change some code paths for valgrind */ #cmakedefine HAVE_valgrind 1 @@ -360,21 +289,14 @@ #cmakedefine SIZEOF_SIZE_T @SIZEOF_CHARP@ #endif -#cmakedefine SIZEOF_CHAR @SIZEOF_CHAR@ -#define HAVE_CHAR 1 #define HAVE_LONG 1 #define HAVE_CHARP 1 -#cmakedefine SIZEOF_SHORT @SIZEOF_SHORT@ -#define HAVE_SHORT 1 #cmakedefine SIZEOF_INT @SIZEOF_INT@ #define HAVE_INT 1 #cmakedefine SIZEOF_LONG_LONG @SIZEOF_LONG_LONG@ #cmakedefine HAVE_LONG_LONG 1 #cmakedefine SIZEOF_OFF_T @SIZEOF_OFF_T@ #cmakedefine HAVE_OFF_T 1 -#cmakedefine SIZEOF_SIGSET_T @SIZEOF_SIGSET_T@ -#cmakedefine HAVE_SIGSET_T 1 -#cmakedefine HAVE_SIZE_T 1 #cmakedefine SIZEOF_UCHAR @SIZEOF_UCHAR@ #cmakedefine HAVE_UCHAR 1 #cmakedefine SIZEOF_UINT @SIZEOF_UINT@ @@ -393,14 +315,10 @@ #cmakedefine HAVE_INT32 1 #cmakedefine SIZEOF_UINT32 @SIZEOF_UINT32@ #cmakedefine HAVE_UINT32 1 -#cmakedefine SIZEOF_U_INT32_T @SIZEOF_U_INT32_T@ -#cmakedefine HAVE_U_INT32_T 1 #cmakedefine SIZEOF_INT64 @SIZEOF_INT64@ #cmakedefine HAVE_INT64 1 #cmakedefine SIZEOF_UINT64 @SIZEOF_UINT64@ #cmakedefine HAVE_UINT64 1 -#cmakedefine SIZEOF_BOOL @SIZEOF_BOOL@ -#cmakedefine HAVE_BOOL 1 #cmakedefine SOCKET_SIZE_TYPE @SOCKET_SIZE_TYPE@ @@ -411,7 +329,6 @@ #cmakedefine QSORT_TYPE_IS_VOID 1 #cmakedefine RETQSORTTYPE @RETQSORTTYPE@ -#cmakedefine SIGNAL_RETURN_TYPE_IS_VOID 1 #cmakedefine RETSIGTYPE @RETSIGTYPE@ #cmakedefine VOID_SIGHANDLER 1 #cmakedefine HAVE_SIGHANDLER_T 1 @@ -441,30 +358,19 @@ #cmakedefine HAVE_WCHAR_H 1 #cmakedefine HAVE_LANGINFO_H 1 #cmakedefine HAVE_MBRLEN 1 -#cmakedefine HAVE_MBSCMP 1 #cmakedefine HAVE_MBSRTOWCS 1 -#cmakedefine HAVE_WCRTOMB 1 #cmakedefine HAVE_MBRTOWC 1 -#cmakedefine HAVE_WCSCOLL 1 -#cmakedefine HAVE_WCSDUP 1 #cmakedefine HAVE_WCWIDTH 1 -#cmakedefine HAVE_WCTYPE 1 #cmakedefine HAVE_ISWLOWER 1 #cmakedefine HAVE_ISWUPPER 1 #cmakedefine HAVE_TOWLOWER 1 #cmakedefine HAVE_TOWUPPER 1 #cmakedefine HAVE_ISWCTYPE 1 #cmakedefine HAVE_WCHAR_T 1 -#cmakedefine HAVE_WCTYPE_T 1 -#cmakedefine HAVE_WINT_T 1 #cmakedefine HAVE_STRCASECMP 1 -#cmakedefine HAVE_STRNCASECMP 1 -#cmakedefine HAVE_STRDUP 1 -#cmakedefine HAVE_LANGINFO_CODESET 1 #cmakedefine HAVE_TCGETATTR 1 -#cmakedefine HAVE_FLOCKFILE 1 #cmakedefine HAVE_WEAK_SYMBOL 1 #cmakedefine HAVE_ABI_CXA_DEMANGLE 1 @@ -472,6 +378,7 @@ #cmakedefine HAVE_POSIX_SIGNALS 1 #cmakedefine HAVE_BSD_SIGNALS 1 + #cmakedefine HAVE_SVR3_SIGNALS 1 #cmakedefine HAVE_V7_SIGNALS 1 #cmakedefine HAVE_ERR_remove_thread_state 1 @@ -546,7 +453,6 @@ #cmakedefine ENABLED_LOCAL_INFILE 1 #cmakedefine ENABLED_PROFILING 1 #cmakedefine EXTRA_DEBUG 1 -#cmakedefine CYBOZU 1 #cmakedefine USE_SYMDIR 1 /* Character sets and collations */ @@ -555,7 +461,6 @@ #cmakedefine USE_MB 1 #cmakedefine USE_MB_IDENT 1 -#cmakedefine USE_STRCOLL 1 /* This should mean case insensitive file system */ #cmakedefine FN_NO_CASE_SENSE 1 @@ -616,12 +521,8 @@ Important storage engines (those that really need define WITH_<ENGINE>_STORAGE_ENGINE for the whole server) */ -#cmakedefine WITH_MYISAM_STORAGE_ENGINE 1 -#cmakedefine WITH_MYISAMMRG_STORAGE_ENGINE 1 -#cmakedefine WITH_HEAP_STORAGE_ENGINE 1 #cmakedefine WITH_INNOBASE_STORAGE_ENGINE 1 #cmakedefine WITH_XTRADB_STORAGE_ENGINE 1 -#cmakedefine WITH_CSV_STORAGE_ENGINE 1 #cmakedefine WITH_PARTITION_STORAGE_ENGINE 1 #cmakedefine WITH_PERFSCHEMA_STORAGE_ENGINE 1 #cmakedefine WITH_ARIA_STORAGE_ENGINE 1 diff --git a/configure.cmake b/configure.cmake index a1fdb98389d..294c5e24ca8 100644 --- a/configure.cmake +++ b/configure.cmake @@ -172,7 +172,6 @@ INCLUDE (CheckIncludeFileCXX) CHECK_INCLUDE_FILES ("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS) CHECK_INCLUDE_FILES (sys/types.h HAVE_SYS_TYPES_H) CHECK_INCLUDE_FILES (alloca.h HAVE_ALLOCA_H) -CHECK_INCLUDE_FILES (aio.h HAVE_AIO_H) CHECK_INCLUDE_FILES (arpa/inet.h HAVE_ARPA_INET_H) CHECK_INCLUDE_FILES (crypt.h HAVE_CRYPT_H) CHECK_INCLUDE_FILES (dirent.h HAVE_DIRENT_H) @@ -181,7 +180,6 @@ CHECK_INCLUDE_FILES (execinfo.h HAVE_EXECINFO_H) CHECK_INCLUDE_FILES (fcntl.h HAVE_FCNTL_H) CHECK_INCLUDE_FILES (fenv.h HAVE_FENV_H) CHECK_INCLUDE_FILES (float.h HAVE_FLOAT_H) -CHECK_INCLUDE_FILES (floatingpoint.h HAVE_FLOATINGPOINT_H) CHECK_INCLUDE_FILES (fpu_control.h HAVE_FPU_CONTROL_H) CHECK_INCLUDE_FILES (grp.h HAVE_GRP_H) CHECK_INCLUDE_FILES (ieeefp.h HAVE_IEEEFP_H) @@ -197,13 +195,11 @@ CHECK_INCLUDE_FILES (memory.h HAVE_MEMORY_H) CHECK_INCLUDE_FILES (ndir.h HAVE_NDIR_H) CHECK_INCLUDE_FILES (netinet/in.h HAVE_NETINET_IN_H) CHECK_INCLUDE_FILES (paths.h HAVE_PATHS_H) -CHECK_INCLUDE_FILES (port.h HAVE_PORT_H) CHECK_INCLUDE_FILES (poll.h HAVE_POLL_H) CHECK_INCLUDE_FILES (sys/poll.h HAVE_SYS_POLL_H) CHECK_INCLUDE_FILES (pwd.h HAVE_PWD_H) CHECK_INCLUDE_FILES (sched.h HAVE_SCHED_H) CHECK_INCLUDE_FILES (select.h HAVE_SELECT_H) -CHECK_INCLUDE_FILES (semaphore.h HAVE_SEMAPHORE_H) CHECK_INCLUDE_FILES ("sys/types.h;sys/dir.h" HAVE_SYS_DIR_H) CHECK_INCLUDE_FILES ("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H) CHECK_INCLUDE_FILES (sys/ndir.h HAVE_SYS_NDIR_H) @@ -215,7 +211,6 @@ CHECK_INCLUDE_FILES (strings.h HAVE_STRINGS_H) CHECK_INCLUDE_FILES (string.h HAVE_STRING_H) CHECK_INCLUDE_FILES (synch.h HAVE_SYNCH_H) CHECK_INCLUDE_FILES (sysent.h HAVE_SYSENT_H) -CHECK_INCLUDE_FILES (sys/cdefs.h HAVE_SYS_CDEFS_H) CHECK_INCLUDE_FILES (sys/file.h HAVE_SYS_FILE_H) CHECK_INCLUDE_FILES (sys/fpu.h HAVE_SYS_FPU_H) CHECK_INCLUDE_FILES (sys/ioctl.h HAVE_SYS_IOCTL_H) @@ -230,7 +225,6 @@ CHECK_INCLUDE_FILES (sys/socket.h HAVE_SYS_SOCKET_H) CHECK_INCLUDE_FILES (sys/stat.h HAVE_SYS_STAT_H) CHECK_INCLUDE_FILES (sys/stream.h HAVE_SYS_STREAM_H) CHECK_INCLUDE_FILES (sys/syscall.h HAVE_SYS_SYSCALL_H) -CHECK_INCLUDE_FILES (sys/termcap.h HAVE_SYS_TERMCAP_H) CHECK_INCLUDE_FILES ("curses.h;term.h" HAVE_TERM_H) CHECK_INCLUDE_FILES (asm/termbits.h HAVE_ASM_TERMBITS_H) CHECK_INCLUDE_FILES (termbits.h HAVE_TERMBITS_H) @@ -248,7 +242,6 @@ CHECK_INCLUDE_FILES (sys/vadvise.h HAVE_SYS_VADVISE_H) CHECK_INCLUDE_FILES (fnmatch.h HAVE_FNMATCH_H) CHECK_INCLUDE_FILES (stdarg.h HAVE_STDARG_H) CHECK_INCLUDE_FILES ("stdlib.h;sys/un.h" HAVE_SYS_UN_H) -CHECK_INCLUDE_FILES (vis.h HAVE_VIS_H) CHECK_INCLUDE_FILES (wchar.h HAVE_WCHAR_H) CHECK_INCLUDE_FILES (wctype.h HAVE_WCTYPE_H) CHECK_INCLUDE_FILES (sys/sockio.h HAVE_SYS_SOCKIO_H) @@ -277,7 +270,7 @@ FIND_PACKAGE (Threads) FUNCTION(MY_CHECK_PTHREAD_ONCE_INIT) MY_CHECK_C_COMPILER_FLAG("-Werror") - IF(NOT HAVE_C__Werror) + IF(NOT have_C__Werror) RETURN() ENDIF() SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror") @@ -324,7 +317,6 @@ ENDIF() CHECK_FUNCTION_EXISTS (accept4 HAVE_ACCEPT4) CHECK_FUNCTION_EXISTS (access HAVE_ACCESS) #CHECK_FUNCTION_EXISTS (aiowait HAVE_AIOWAIT) -CHECK_FUNCTION_EXISTS (aio_read HAVE_AIO_READ) CHECK_FUNCTION_EXISTS (alarm HAVE_ALARM) SET(HAVE_ALLOCA 1) CHECK_FUNCTION_EXISTS (backtrace HAVE_BACKTRACE) @@ -332,35 +324,25 @@ CHECK_FUNCTION_EXISTS (backtrace_symbols HAVE_BACKTRACE_SYMBOLS) CHECK_FUNCTION_EXISTS (backtrace_symbols_fd HAVE_BACKTRACE_SYMBOLS_FD) CHECK_FUNCTION_EXISTS (printstack HAVE_PRINTSTACK) CHECK_FUNCTION_EXISTS (bfill HAVE_BFILL) -CHECK_FUNCTION_EXISTS (bmove HAVE_BMOVE) -CHECK_FUNCTION_EXISTS (bsearch HAVE_BSEARCH) CHECK_FUNCTION_EXISTS (index HAVE_INDEX) -CHECK_FUNCTION_EXISTS (bzero HAVE_BZERO) CHECK_FUNCTION_EXISTS (clock_gettime HAVE_CLOCK_GETTIME) CHECK_FUNCTION_EXISTS (cuserid HAVE_CUSERID) -CHECK_FUNCTION_EXISTS (directio HAVE_DIRECTIO) -CHECK_FUNCTION_EXISTS (_doprnt HAVE_DOPRNT) -CHECK_FUNCTION_EXISTS (flockfile HAVE_FLOCKFILE) CHECK_FUNCTION_EXISTS (ftruncate HAVE_FTRUNCATE) -CHECK_FUNCTION_EXISTS (getline HAVE_GETLINE) CHECK_FUNCTION_EXISTS (compress HAVE_COMPRESS) CHECK_FUNCTION_EXISTS (crypt HAVE_CRYPT) CHECK_FUNCTION_EXISTS (dlerror HAVE_DLERROR) CHECK_FUNCTION_EXISTS (dlopen HAVE_DLOPEN) CHECK_FUNCTION_EXISTS (fchmod HAVE_FCHMOD) CHECK_FUNCTION_EXISTS (fcntl HAVE_FCNTL) -CHECK_FUNCTION_EXISTS (fconvert HAVE_FCONVERT) CHECK_FUNCTION_EXISTS (fdatasync HAVE_FDATASYNC) CHECK_SYMBOL_EXISTS(fdatasync "unistd.h" HAVE_DECL_FDATASYNC) CHECK_FUNCTION_EXISTS (fesetround HAVE_FESETROUND) CHECK_FUNCTION_EXISTS (fedisableexcept HAVE_FEDISABLEEXCEPT) -CHECK_FUNCTION_EXISTS (fpsetmask HAVE_FPSETMASK) CHECK_FUNCTION_EXISTS (fseeko HAVE_FSEEKO) CHECK_FUNCTION_EXISTS (fsync HAVE_FSYNC) CHECK_FUNCTION_EXISTS (getcwd HAVE_GETCWD) CHECK_FUNCTION_EXISTS (gethostbyaddr_r HAVE_GETHOSTBYADDR_R) CHECK_FUNCTION_EXISTS (gethrtime HAVE_GETHRTIME) -CHECK_FUNCTION_EXISTS (getnameinfo HAVE_GETNAMEINFO) CHECK_FUNCTION_EXISTS (getpass HAVE_GETPASS) CHECK_FUNCTION_EXISTS (getpassphrase HAVE_GETPASSPHRASE) CHECK_FUNCTION_EXISTS (getpwnam HAVE_GETPWNAM) @@ -371,14 +353,8 @@ CHECK_FUNCTION_EXISTS (getrusage HAVE_GETRUSAGE) CHECK_FUNCTION_EXISTS (getwd HAVE_GETWD) CHECK_FUNCTION_EXISTS (gmtime_r HAVE_GMTIME_R) CHECK_FUNCTION_EXISTS (initgroups HAVE_INITGROUPS) -CHECK_FUNCTION_EXISTS (issetugid HAVE_ISSETUGID) -CHECK_FUNCTION_EXISTS (getuid HAVE_GETUID) -CHECK_FUNCTION_EXISTS (geteuid HAVE_GETEUID) -CHECK_FUNCTION_EXISTS (getgid HAVE_GETGID) -CHECK_FUNCTION_EXISTS (getegid HAVE_GETEGID) CHECK_FUNCTION_EXISTS (ldiv HAVE_LDIV) CHECK_FUNCTION_EXISTS (localtime_r HAVE_LOCALTIME_R) -CHECK_FUNCTION_EXISTS (longjmp HAVE_LONGJMP) CHECK_FUNCTION_EXISTS (lstat HAVE_LSTAT) CHECK_FUNCTION_EXISTS (madvise HAVE_MADVISE) CHECK_FUNCTION_EXISTS (mallinfo HAVE_MALLINFO) @@ -391,9 +367,7 @@ CHECK_FUNCTION_EXISTS (mmap HAVE_MMAP) CHECK_FUNCTION_EXISTS (mmap64 HAVE_MMAP64) CHECK_FUNCTION_EXISTS (perror HAVE_PERROR) CHECK_FUNCTION_EXISTS (poll HAVE_POLL) -CHECK_FUNCTION_EXISTS (port_create HAVE_PORT_CREATE) CHECK_FUNCTION_EXISTS (posix_fallocate HAVE_POSIX_FALLOCATE) -CHECK_FUNCTION_EXISTS (fallocate HAVE_FALLOCATE) CHECK_FUNCTION_EXISTS (pread HAVE_PREAD) CHECK_FUNCTION_EXISTS (pthread_attr_create HAVE_PTHREAD_ATTR_CREATE) CHECK_FUNCTION_EXISTS (pthread_attr_getstacksize HAVE_PTHREAD_ATTR_GETSTACKSIZE) @@ -401,65 +375,42 @@ CHECK_FUNCTION_EXISTS (pthread_attr_setscope HAVE_PTHREAD_ATTR_SETSCOPE) CHECK_FUNCTION_EXISTS (pthread_attr_getguardsize HAVE_PTHREAD_ATTR_GETGUARDSIZE) CHECK_FUNCTION_EXISTS (pthread_attr_setstacksize HAVE_PTHREAD_ATTR_SETSTACKSIZE) CHECK_FUNCTION_EXISTS (pthread_condattr_create HAVE_PTHREAD_CONDATTR_CREATE) -CHECK_FUNCTION_EXISTS (pthread_condattr_setclock HAVE_PTHREAD_CONDATTR_SETCLOCK) CHECK_FUNCTION_EXISTS (pthread_key_delete HAVE_PTHREAD_KEY_DELETE) CHECK_FUNCTION_EXISTS (pthread_rwlock_rdlock HAVE_PTHREAD_RWLOCK_RDLOCK) CHECK_FUNCTION_EXISTS (pthread_sigmask HAVE_PTHREAD_SIGMASK) -CHECK_FUNCTION_EXISTS (pthread_threadmask HAVE_PTHREAD_THREADMASK) CHECK_FUNCTION_EXISTS (pthread_yield_np HAVE_PTHREAD_YIELD_NP) CHECK_FUNCTION_EXISTS (putenv HAVE_PUTENV) CHECK_FUNCTION_EXISTS (readdir_r HAVE_READDIR_R) CHECK_FUNCTION_EXISTS (readlink HAVE_READLINK) -CHECK_FUNCTION_EXISTS (re_comp HAVE_RE_COMP) -CHECK_FUNCTION_EXISTS (regcomp HAVE_REGCOMP) CHECK_FUNCTION_EXISTS (realpath HAVE_REALPATH) CHECK_FUNCTION_EXISTS (rename HAVE_RENAME) CHECK_FUNCTION_EXISTS (rwlock_init HAVE_RWLOCK_INIT) CHECK_FUNCTION_EXISTS (sched_yield HAVE_SCHED_YIELD) CHECK_FUNCTION_EXISTS (setenv HAVE_SETENV) CHECK_FUNCTION_EXISTS (setlocale HAVE_SETLOCALE) -CHECK_FUNCTION_EXISTS (setfd HAVE_SETFD) CHECK_FUNCTION_EXISTS (sigaction HAVE_SIGACTION) CHECK_FUNCTION_EXISTS (sigthreadmask HAVE_SIGTHREADMASK) CHECK_FUNCTION_EXISTS (sigwait HAVE_SIGWAIT) -CHECK_FUNCTION_EXISTS (sigaddset HAVE_SIGADDSET) -CHECK_FUNCTION_EXISTS (sigemptyset HAVE_SIGEMPTYSET) -CHECK_FUNCTION_EXISTS (sighold HAVE_SIGHOLD) CHECK_FUNCTION_EXISTS (sigset HAVE_SIGSET) CHECK_FUNCTION_EXISTS (sleep HAVE_SLEEP) CHECK_FUNCTION_EXISTS (snprintf HAVE_SNPRINTF) CHECK_FUNCTION_EXISTS (stpcpy HAVE_STPCPY) CHECK_FUNCTION_EXISTS (strcoll HAVE_STRCOLL) CHECK_FUNCTION_EXISTS (strerror HAVE_STRERROR) -CHECK_FUNCTION_EXISTS (strlcpy HAVE_STRLCPY) CHECK_FUNCTION_EXISTS (strnlen HAVE_STRNLEN) -CHECK_FUNCTION_EXISTS (strlcat HAVE_STRLCAT) -CHECK_FUNCTION_EXISTS (strsignal HAVE_STRSIGNAL) -CHECK_FUNCTION_EXISTS (fgetln HAVE_FGETLN) CHECK_FUNCTION_EXISTS (strpbrk HAVE_STRPBRK) -CHECK_FUNCTION_EXISTS (strstr HAVE_STRSTR) CHECK_FUNCTION_EXISTS (strtok_r HAVE_STRTOK_R) -CHECK_FUNCTION_EXISTS (strtol HAVE_STRTOL) CHECK_FUNCTION_EXISTS (strtoll HAVE_STRTOLL) CHECK_FUNCTION_EXISTS (strtoul HAVE_STRTOUL) CHECK_FUNCTION_EXISTS (strtoull HAVE_STRTOULL) CHECK_FUNCTION_EXISTS (strcasecmp HAVE_STRCASECMP) -CHECK_FUNCTION_EXISTS (strncasecmp HAVE_STRNCASECMP) -CHECK_FUNCTION_EXISTS (strdup HAVE_STRDUP) -CHECK_FUNCTION_EXISTS (shmat HAVE_SHMAT) -CHECK_FUNCTION_EXISTS (shmctl HAVE_SHMCTL) -CHECK_FUNCTION_EXISTS (shmdt HAVE_SHMDT) -CHECK_FUNCTION_EXISTS (shmget HAVE_SHMGET) CHECK_FUNCTION_EXISTS (tell HAVE_TELL) CHECK_FUNCTION_EXISTS (tempnam HAVE_TEMPNAM) CHECK_FUNCTION_EXISTS (thr_setconcurrency HAVE_THR_SETCONCURRENCY) CHECK_FUNCTION_EXISTS (thr_yield HAVE_THR_YIELD) CHECK_FUNCTION_EXISTS (vasprintf HAVE_VASPRINTF) CHECK_FUNCTION_EXISTS (vsnprintf HAVE_VSNPRINTF) -CHECK_FUNCTION_EXISTS (vprintf HAVE_VPRINTF) -CHECK_FUNCTION_EXISTS (valloc HAVE_VALLOC) CHECK_FUNCTION_EXISTS (memalign HAVE_MEMALIGN) -CHECK_FUNCTION_EXISTS (chown HAVE_CHOWN) CHECK_FUNCTION_EXISTS (nl_langinfo HAVE_NL_LANGINFO) IF(HAVE_SYS_EVENT_H) @@ -570,7 +521,6 @@ ENDIF(HAVE_STDINT_H) SET(HAVE_VOIDP 1) SET(HAVE_CHARP 1) SET(HAVE_LONG 1) -SET(HAVE_SIZE_T 1) IF(NOT APPLE) MY_CHECK_TYPE_SIZE("void *" VOIDP) @@ -579,7 +529,6 @@ MY_CHECK_TYPE_SIZE(long LONG) MY_CHECK_TYPE_SIZE(size_t SIZE_T) ENDIF() -MY_CHECK_TYPE_SIZE(char CHAR) MY_CHECK_TYPE_SIZE(short SHORT) MY_CHECK_TYPE_SIZE(int INT) MY_CHECK_TYPE_SIZE("long long" LONG_LONG) @@ -594,17 +543,14 @@ MY_CHECK_TYPE_SIZE(int16 INT16) MY_CHECK_TYPE_SIZE(uint16 UINT16) MY_CHECK_TYPE_SIZE(int32 INT32) MY_CHECK_TYPE_SIZE(uint32 UINT32) -MY_CHECK_TYPE_SIZE(u_int32_t U_INT32_T) MY_CHECK_TYPE_SIZE(int64 INT64) MY_CHECK_TYPE_SIZE(uint64 UINT64) MY_CHECK_TYPE_SIZE(time_t TIME_T) SET (CMAKE_EXTRA_INCLUDE_FILES sys/types.h) -MY_CHECK_TYPE_SIZE(bool BOOL) SET(CMAKE_EXTRA_INCLUDE_FILES) IF(HAVE_SYS_SOCKET_H) SET(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h) ENDIF(HAVE_SYS_SOCKET_H) -MY_CHECK_TYPE_SIZE(socklen_t SOCKLEN_T) SET(CMAKE_EXTRA_INCLUDE_FILES) IF(HAVE_IEEEFP_H) @@ -627,23 +573,6 @@ int main() }" TIME_T_UNSIGNED) - -CHECK_C_SOURCE_COMPILES(" -#ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#else -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#endif -int main() -{ - getaddrinfo( 0, 0, 0, 0); - return 0; -}" -HAVE_GETADDRINFO) - CHECK_C_SOURCE_COMPILES(" #ifdef _WIN32 #include <winsock2.h> @@ -883,21 +812,6 @@ IF(NOT HAVE_POSIX_SIGNALS) sigsetmask(mask); sigblock(mask); sigpause(mask); }" HAVE_BSD_SIGNALS) - IF (NOT HAVE_BSD_SIGNALS) - CHECK_C_SOURCE_COMPILES(" - #include <signal.h> - void foo() { } - int main(int ac, char **av) - { - int mask = sigmask(SIGINT); - sigset(SIGINT, foo); sigrelse(SIGINT); - sighold(SIGINT); sigpause(SIGINT); - }" - HAVE_SVR3_SIGNALS) - IF (NOT HAVE_SVR3_SIGNALS) - SET(HAVE_V7_SIGNALS 1) - ENDIF(NOT HAVE_SVR3_SIGNALS) - ENDIF(NOT HAVE_BSD_SIGNALS) ENDIF(NOT HAVE_POSIX_SIGNALS) # Assume regular sprintf @@ -945,8 +859,8 @@ CHECK_CXX_SOURCE_COMPILES(" #include <new> int main() { - char *c = new char; - return 0; + char *c = new char; + return 0; }" HAVE_CXX_NEW ) @@ -1031,7 +945,7 @@ IF(WITH_VALGRIND) ENDIF() CHECK_INCLUDE_FILES("valgrind/memcheck.h;valgrind/valgrind.h" - HAVE_VALGRIND) + HAVE_VALGRIND_MEMCHECK_H) #-------------------------------------------------------------------- # Check for IPv6 support @@ -1084,9 +998,6 @@ CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin6_len SET(CMAKE_EXTRA_INCLUDE_FILES) -CHECK_STRUCT_HAS_MEMBER("struct dirent" d_ino "dirent.h" STRUCT_DIRENT_HAS_D_INO) -CHECK_STRUCT_HAS_MEMBER("struct dirent" d_namlen "dirent.h" STRUCT_DIRENT_HAS_D_NAMLEN) -SET(SPRINTF_RETURNS_INT 1) CHECK_INCLUDE_FILE(ucontext.h HAVE_UCONTEXT_H) IF(NOT HAVE_UCONTEXT_H) CHECK_INCLUDE_FILE(sys/ucontext.h HAVE_UCONTEXT_H) diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index f304e984b54..6f4109515e6 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -37,8 +37,11 @@ if apt-cache madison cracklib2|grep 'cracklib2 *| *2\.[0-8]\.' >/dev/null 2>&1 then # Anything in MARIADB_OPTIONAL_DEBS is omitted from the resulting # packages by snipped in rules file - MARIADB_OPTIONAL_DEBS="${MARIADB_OPTIONAL_DEBS} cracklib-password-check-10.1" + MARIADB_OPTIONAL_DEBS="${MARIADB_OPTIONAL_DEBS} cracklib-password-check-10.2" sed -i -e "/\\\${MAYBE_LIBCRACK}/d" debian/control + # Remove package entry from control file completely so that + # resulting Debian source package will actually be buildable + sed -i -e "/Package: mariadb-cracklib-password-check/,+6d" debian/control else MAYBE_LIBCRACK='libcrack2-dev (>= 2.9.0),' sed -i -e "s/\\\${MAYBE_LIBCRACK}/${MAYBE_LIBCRACK}/g" debian/control diff --git a/debian/changelog b/debian/changelog index 4d0d74b12c4..31ba0ab81cc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +mariadb-10.2 (10.2.0) unstable; urgency=low + + * Initial release. + + -- Otto Kekäläinen <otto@mariadb.org> Sat, 14 Nov 2015 21:26:45 +0200 + mariadb-10.1 (10.1.0) unstable; urgency=low * Initial release. diff --git a/debian/control b/debian/control index 218f9544e46..e88325b49a6 100644 --- a/debian/control +++ b/debian/control @@ -1,4 +1,4 @@ -Source: mariadb-10.1 +Source: mariadb-10.2 Section: database Priority: optional Maintainer: MariaDB Developers <maria-developers@lists.launchpad.net> @@ -129,7 +129,7 @@ Description: MariaDB database common files (e.g. /etc/mysql/conf.d/mariadb.cnf) This package includes files needed by all versions of the client library (e.g. /etc/mysql/conf.d/mariadb.cnf). -Package: mariadb-client-core-10.1 +Package: mariadb-client-core-10.2 Architecture: any Depends: libmariadbclient18 (>= ${source:Version}), mariadb-common (>= ${source:Version}), @@ -140,11 +140,13 @@ Provides: mysql-client-core, mysql-client-core-5.5, mysql-client-core-5.6, virtual-mysql-client-core -Conflicts: mariadb-client-10.0, +Conflicts: mariadb-client-10.1, + mariadb-client-10.0, mariadb-client-5.1, mariadb-client-5.2, mariadb-client-5.3, mariadb-client-5.5, + mariadb-client-core-10.1, mariadb-client-core-10.0, mariadb-client-core-5.1, mariadb-client-core-5.2, @@ -158,11 +160,13 @@ Conflicts: mariadb-client-10.0, mysql-client-core-5.5, mysql-client-core-5.6, virtual-mysql-client-core -Replaces: mariadb-client-10.0, +Replaces: mariadb-client-10.1, + mariadb-client-10.0, mariadb-client-5.1, mariadb-client-5.2, mariadb-client-5.3, mariadb-client-5.5, + mariadb-client-core-10.1, mariadb-client-core-10.0, mariadb-client-core-5.1, mariadb-client-core-5.2, @@ -184,13 +188,13 @@ Description: MariaDB database core client binaries . This package includes the core client files, as used by Akonadi. -Package: mariadb-client-10.1 +Package: mariadb-client-10.2 Architecture: any Depends: debianutils (>=1.6), libdbd-mysql-perl (>= 1.2202), libdbi-perl, libmariadbclient18 (>= ${source:Version}), - mariadb-client-core-10.1 (>= ${source:Version}), + mariadb-client-core-10.2 (>= ${source:Version}), mariadb-common, ${misc:Depends}, ${perl:Depends}, @@ -203,6 +207,7 @@ Provides: mysql-client, mysql-client-5.6, virtual-mysql-client Conflicts: mariadb-client (<< ${source:Version}), + mariadb-client-10.1, mariadb-client-10.0, mariadb-client-5.1, mariadb-client-5.2, @@ -215,6 +220,7 @@ Conflicts: mariadb-client (<< ${source:Version}), mysql-client-5.6, virtual-mysql-client Replaces: mariadb-client (<< ${source:Version}), + mariadb-client-10.1, mariadb-client-10.0, mariadb-client-5.1, mariadb-client-5.2, @@ -235,7 +241,7 @@ Description: MariaDB database client binaries This package includes the client binaries and the additional tools innotop and mysqlreport. -Package: mariadb-server-core-10.1 +Package: mariadb-server-core-10.2 Architecture: any Depends: libmariadbclient18 (>= ${binary:Version}), mariadb-common (>= ${source:Version}), @@ -246,7 +252,8 @@ Provides: mysql-server-core, mysql-server-core-5.5, mysql-server-core-5.6, virtual-mysql-server-core -Conflicts: mariadb-server-core-10.0, +Conflicts: mariadb-server-core-10.1, + mariadb-server-core-10.0, mariadb-server-core-5.1, mariadb-server-core-5.2, mariadb-server-core-5.3, @@ -257,7 +264,8 @@ Conflicts: mariadb-server-core-10.0, mysql-server-core-5.5, mysql-server-core-5.6, virtual-mysql-server-core -Replaces: mariadb-server-core-10.0, +Replaces: mariadb-server-core-10.1, + mariadb-server-core-10.0, mariadb-server-core-5.1, mariadb-server-core-5.2, mariadb-server-core-5.3, @@ -276,20 +284,22 @@ Description: MariaDB database core server files . This package includes the core server files, as used by Akonadi. -Package: mariadb-test-10.1 +Package: mariadb-test-10.2 Architecture: any -Depends: mariadb-client-10.1 (= ${binary:Version}), - mariadb-server-10.1 (= ${binary:Version}) +Depends: mariadb-client-10.2 (= ${binary:Version}), + mariadb-server-10.2 (= ${binary:Version}) Suggests: patch Conflicts: mariadb-galera-server-5.5 (<< 5.5.33), mariadb-server-5.5 (<< 5.5.33), mariadb-test (<< ${source:Version}), + mariadb-test-10.1, mariadb-test-10.0, mariadb-test-5.1, mariadb-test-5.2, mariadb-test-5.3, virtual-mysql-testsuite Replaces: mariadb-test (<< ${source:Version}), + mariadb-test-10.1, mariadb-test-10.0, mariadb-test-5.1, mariadb-test-5.2, @@ -304,7 +314,7 @@ Description: MariaDB database regression test suite . This package includes the regression test suite. -Package: mariadb-server-10.1 +Package: mariadb-server-10.2 Architecture: any Suggests: mailx, mariadb-test, netcat-openbsd, socat, tinyca Recommends: libhtml-template-perl @@ -319,8 +329,8 @@ Depends: bsdutils, libdbi-perl, lsb-base (>= 3.0-10), lsof, - mariadb-client-10.1 (>= ${source:Version}), - mariadb-server-core-10.1 (>= ${binary:Version}), + mariadb-client-10.2 (>= ${source:Version}), + mariadb-server-core-10.2 (>= ${binary:Version}), passwd, perl (>= 5.6), psmisc, @@ -330,6 +340,7 @@ Depends: bsdutils, ${shlibs:Depends} Provides: mariadb-server, mysql-server, virtual-mysql-server Conflicts: mariadb-server (<< ${source:Version}), + mariadb-server-10.1, mariadb-server-10.0, mariadb-server-5.1, mariadb-server-5.2, @@ -347,6 +358,7 @@ Conflicts: mariadb-server (<< ${source:Version}), Replaces: libmariadbclient-dev (<< 5.5.0), libmariadbclient16 (<< 5.3.4), mariadb-server (<< ${source:Version}), + mariadb-server-10.1, mariadb-server-10.0, mariadb-server-5.1, mariadb-server-5.2, @@ -371,10 +383,10 @@ Description: MariaDB database server binaries Package: mariadb-server Architecture: all -Depends: mariadb-server-10.1 (= ${source:Version}), ${misc:Depends} +Depends: mariadb-server-10.2 (= ${source:Version}), ${misc:Depends} Description: MariaDB database server (metapackage depending on the latest version) This is an empty package that depends on the current "best" version of - mariadb-server (currently mariadb-server-10.1), as determined by the MariaDB + mariadb-server (currently mariadb-server-10.2), as determined by the MariaDB maintainers. Install this package if in doubt about which MariaDB version you need. That will install the version recommended by the package maintainers. @@ -386,26 +398,26 @@ Description: MariaDB database server (metapackage depending on the latest versio Package: mariadb-client Architecture: all -Depends: mariadb-client-10.1 (= ${source:Version}), ${misc:Depends} +Depends: mariadb-client-10.2 (= ${source:Version}), ${misc:Depends} Description: MariaDB database client (metapackage depending on the latest version) This is an empty package that depends on the current "best" version of - mariadb-client (currently mariadb-client-10.1), as determined by the MariaDB + mariadb-client (currently mariadb-client-10.2), as determined by the MariaDB maintainers. Install this package if in doubt about which MariaDB version you want, as this is the one considered to be in the best shape. Package: mariadb-test Architecture: all -Depends: mariadb-test-10.1 (= ${source:Version}), ${misc:Depends} +Depends: mariadb-test-10.2 (= ${source:Version}), ${misc:Depends} Description: MariaDB database regression test suite (metapackage for the latest version) This is an empty package that depends on the current "best" version of - mariadb-test (currently mariadb-test-10.1), as determined by the MariaDB + mariadb-test (currently mariadb-test-10.2), as determined by the MariaDB maintainers. -Package: mariadb-connect-engine-10.1 +Package: mariadb-connect-engine-10.2 Architecture: any -Depends: libxml2, mariadb-server-10.1, unixODBC +Depends: libxml2, mariadb-server-10.2, unixODBC Build-Depends: libxml2-dev, - mariadb-server-10.1, + mariadb-server-10.2, unixODBC-dev, ${misc:Depends}, ${shlibs:Depends} @@ -415,18 +427,18 @@ Description: Connect storage engine for MariaDB other interesting features. This package contains the Connect plugin for MariaDB. -Package: mariadb-oqgraph-engine-10.1 +Package: mariadb-oqgraph-engine-10.2 Architecture: any -Depends: libjudydebian1, mariadb-server-10.1, ${misc:Depends}, ${shlibs:Depends} +Depends: libjudydebian1, mariadb-server-10.2, ${misc:Depends}, ${shlibs:Depends} Description: OQGraph storage engine for MariaDB The OQGraph engine is a computation engine plugin for handling hierarchies (trees) and graphs (friend-of-a-friend, etc) cleanly through standard SQL. This package contains the OQGraph plugin for MariaDB. -Package: mariadb-cracklib-password-check-10.1 +Package: mariadb-cracklib-password-check-10.2 Section: database Architecture: any -Depends: libcrack2 (>= 2.9.0), mariadb-server-10.1 +Depends: libcrack2 (>= 2.9.0), mariadb-server-10.2 Description: CrackLib Password Validation Plugin for MariaDB This password validation plugin uses cracklib to allow only sufficiently secure (as defined by cracklib) user passwords in MariaDB. diff --git a/debian/mariadb-client-10.1.README.Debian b/debian/mariadb-client-10.2.README.Debian index 64f0f509951..64f0f509951 100644 --- a/debian/mariadb-client-10.1.README.Debian +++ b/debian/mariadb-client-10.2.README.Debian diff --git a/debian/mariadb-client-10.1.dirs b/debian/mariadb-client-10.2.dirs index ceda5922c5d..ceda5922c5d 100644 --- a/debian/mariadb-client-10.1.dirs +++ b/debian/mariadb-client-10.2.dirs diff --git a/debian/mariadb-client-10.1.docs b/debian/mariadb-client-10.2.docs index 21446855f51..21446855f51 100644 --- a/debian/mariadb-client-10.1.docs +++ b/debian/mariadb-client-10.2.docs diff --git a/debian/mariadb-client-10.1.files b/debian/mariadb-client-10.2.files index e6033952c26..95e788dc8d8 100644 --- a/debian/mariadb-client-10.1.files +++ b/debian/mariadb-client-10.2.files @@ -2,7 +2,6 @@ usr/bin/innochecksum usr/bin/innotop usr/bin/mysqlaccess usr/bin/mysqladmin -usr/bin/mysqlbug usr/bin/mysqldump usr/bin/mysqldumpslow usr/bin/mysql_find_rows @@ -15,7 +14,6 @@ usr/bin/mysql_waitpid usr/share/man/man1/innotop.1 usr/share/man/man1/mysqlaccess.1 usr/share/man/man1/mysqladmin.1 -usr/share/man/man1/mysqlbug.1 usr/share/man/man1/mysqldump.1 usr/share/man/man1/mysqldumpslow.1 usr/share/man/man1/mysql_find_rows.1 diff --git a/debian/mariadb-client-10.1.links b/debian/mariadb-client-10.2.links index 0b86e87f2e9..0b86e87f2e9 100644 --- a/debian/mariadb-client-10.1.links +++ b/debian/mariadb-client-10.2.links diff --git a/debian/mariadb-client-10.1.menu b/debian/mariadb-client-10.2.menu index 1378555c423..1378555c423 100644 --- a/debian/mariadb-client-10.1.menu +++ b/debian/mariadb-client-10.2.menu diff --git a/debian/mariadb-client-core-10.1.files b/debian/mariadb-client-core-10.2.files index a2781309439..a2781309439 100644 --- a/debian/mariadb-client-core-10.1.files +++ b/debian/mariadb-client-core-10.2.files diff --git a/debian/mariadb-connect-engine-10.1.files b/debian/mariadb-connect-engine-10.2.files index 0b042607c36..0b042607c36 100644 --- a/debian/mariadb-connect-engine-10.1.files +++ b/debian/mariadb-connect-engine-10.2.files diff --git a/debian/mariadb-cracklib-password-check-10.1.files b/debian/mariadb-cracklib-password-check-10.2.files index 3fe06639703..3fe06639703 100644 --- a/debian/mariadb-cracklib-password-check-10.1.files +++ b/debian/mariadb-cracklib-password-check-10.2.files diff --git a/debian/mariadb-oqgraph-engine-10.1.files b/debian/mariadb-oqgraph-engine-10.2.files index f67b0cd9d13..f67b0cd9d13 100644 --- a/debian/mariadb-oqgraph-engine-10.1.files +++ b/debian/mariadb-oqgraph-engine-10.2.files diff --git a/debian/mariadb-server-10.1.README.Debian b/debian/mariadb-server-10.2.README.Debian index be2e33d705d..be2e33d705d 100644 --- a/debian/mariadb-server-10.1.README.Debian +++ b/debian/mariadb-server-10.2.README.Debian diff --git a/debian/mariadb-server-10.1.config b/debian/mariadb-server-10.2.config index 162017caf71..162017caf71 100644 --- a/debian/mariadb-server-10.1.config +++ b/debian/mariadb-server-10.2.config diff --git a/debian/mariadb-server-10.1.dirs b/debian/mariadb-server-10.2.dirs index 64b49db4af9..037d669e833 100644 --- a/debian/mariadb-server-10.1.dirs +++ b/debian/mariadb-server-10.2.dirs @@ -5,6 +5,6 @@ usr/bin usr/sbin usr/share/man/man8 usr/share/mysql -usr/share/doc/mariadb-server-10.1 +usr/share/doc/mariadb-server-10.2 var/run/mysqld var/lib/mysql-upgrade diff --git a/debian/mariadb-server-10.1.files.in b/debian/mariadb-server-10.2.files.in index 3b143c5c9cf..d562d285994 100644 --- a/debian/mariadb-server-10.1.files.in +++ b/debian/mariadb-server-10.2.files.in @@ -19,9 +19,10 @@ usr/lib/mysql/plugin/server_audit.so usr/lib/mysql/plugin/simple_password_check.so usr/lib/mysql/plugin/sql_errlog.so usr/lib/mysql/plugin/wsrep_info.so +usr/lib/mysql/plugin/user_variables.so usr/lib/libhsclient.so.* etc/apparmor.d/usr.sbin.mysqld -usr/share/apport/package-hooks/source_mariadb-10.1.py +usr/share/apport/package-hooks/source_mariadb-10.2.py etc/mysql/debian-start etc/mysql/conf.d/mysqld_safe_syslog.cnf usr/bin/msql2mysql @@ -42,7 +43,6 @@ usr/bin/mysql_secure_installation usr/bin/mysql_setpermission usr/bin/mysql_tzinfo_to_sql usr/bin/mysql_upgrade -usr/bin/mysql_zap usr/bin/mysqlbinlog usr/bin/mysqld_multi usr/bin/mysqld_safe @@ -56,9 +56,9 @@ usr/bin/wsrep_sst_mysqldump usr/bin/wsrep_sst_rsync usr/bin/wsrep_sst_xtrabackup usr/bin/wsrep_sst_xtrabackup-v2 -usr/share/doc/mariadb-server-10.1/mysqld.sym.gz -usr/share/doc/mariadb-server-10.1/INFO_SRC -usr/share/doc/mariadb-server-10.1/INFO_BIN +usr/share/doc/mariadb-server-10.2/mysqld.sym.gz +usr/share/doc/mariadb-server-10.2/INFO_SRC +usr/share/doc/mariadb-server-10.2/INFO_BIN usr/share/man/man1/msql2mysql.1 usr/share/man/man1/myisamchk.1 usr/share/man/man1/myisam_ftdump.1 @@ -74,7 +74,6 @@ usr/share/man/man1/mysql_install_db.1 usr/share/man/man1/mysql_secure_installation.1 usr/share/man/man1/mysql_setpermission.1 usr/share/man/man1/mysql_upgrade.1 -usr/share/man/man1/mysql_zap.1 usr/share/man/man1/perror.1 usr/share/man/man1/replace.1 usr/share/man/man1/resolveip.1 diff --git a/debian/mariadb-server-10.1.logcheck.ignore.paranoid b/debian/mariadb-server-10.2.logcheck.ignore.paranoid index 00cc5c3e29d..00cc5c3e29d 100644 --- a/debian/mariadb-server-10.1.logcheck.ignore.paranoid +++ b/debian/mariadb-server-10.2.logcheck.ignore.paranoid diff --git a/debian/mariadb-server-10.1.logcheck.ignore.server b/debian/mariadb-server-10.2.logcheck.ignore.server index 37f25cb01ea..a0b4792ecda 100644 --- a/debian/mariadb-server-10.1.logcheck.ignore.server +++ b/debian/mariadb-server-10.2.logcheck.ignore.server @@ -19,7 +19,7 @@ mysqld_safe\[[0-9]+\]: ended$ mysqld_safe\[[0-9]+\]: http://www.mysql.com$ mysqld_safe\[[0-9]+\]: NOTE: If you are upgrading from a MySQL <= 3.22.10 you should run$ mysqld_safe\[[0-9]+\]: PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !$ -mysqld_safe\[[0-9]+\]: Please report any problems with the /usr/bin/mysqlbug script!$ +mysqld_safe\[[0-9]+\]: Please report any problems at http://mariadb.org/jira$ mysqld_safe\[[0-9]+\]: See the manual for more instructions.$ mysqld_safe\[[0-9]+\]: started$ mysqld_safe\[[0-9]+\]: Support MySQL by buying support/licenses at https://order.mysql.com$ diff --git a/debian/mariadb-server-10.1.logcheck.ignore.workstation b/debian/mariadb-server-10.2.logcheck.ignore.workstation index 37f25cb01ea..a0b4792ecda 100644 --- a/debian/mariadb-server-10.1.logcheck.ignore.workstation +++ b/debian/mariadb-server-10.2.logcheck.ignore.workstation @@ -19,7 +19,7 @@ mysqld_safe\[[0-9]+\]: ended$ mysqld_safe\[[0-9]+\]: http://www.mysql.com$ mysqld_safe\[[0-9]+\]: NOTE: If you are upgrading from a MySQL <= 3.22.10 you should run$ mysqld_safe\[[0-9]+\]: PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !$ -mysqld_safe\[[0-9]+\]: Please report any problems with the /usr/bin/mysqlbug script!$ +mysqld_safe\[[0-9]+\]: Please report any problems at http://mariadb.org/jira$ mysqld_safe\[[0-9]+\]: See the manual for more instructions.$ mysqld_safe\[[0-9]+\]: started$ mysqld_safe\[[0-9]+\]: Support MySQL by buying support/licenses at https://order.mysql.com$ diff --git a/debian/mariadb-server-10.1.mysql-server.logrotate b/debian/mariadb-server-10.2.mysql-server.logrotate index a19e9ec46a2..a19e9ec46a2 100644 --- a/debian/mariadb-server-10.1.mysql-server.logrotate +++ b/debian/mariadb-server-10.2.mysql-server.logrotate diff --git a/debian/mariadb-server-10.1.mysql.init b/debian/mariadb-server-10.2.mysql.init index 91d07e8de3e..d5d0ab4ba93 100644 --- a/debian/mariadb-server-10.1.mysql.init +++ b/debian/mariadb-server-10.2.mysql.init @@ -155,7 +155,7 @@ case "${1:-''}" in if ! mysqld_status check_dead warn; then log_end_msg 1 - log_failure_msg "Please stop MariaDB manually and read /usr/share/doc/mariadb-server-10.1/README.Debian.gz!" + log_failure_msg "Please stop MariaDB manually and read /usr/share/doc/mariadb-server-10.2/README.Debian.gz!" exit -1 else log_end_msg 0 diff --git a/debian/mariadb-server-10.1.postinst b/debian/mariadb-server-10.2.postinst index ccf7d5c88ca..83f5d5e3cd0 100644 --- a/debian/mariadb-server-10.1.postinst +++ b/debian/mariadb-server-10.2.postinst @@ -131,7 +131,7 @@ EOF db_set mysql-server/postrm_remove_database false || true # To avoid downgrades. - touch $mysql_statedir/debian-10.1.flag + touch $mysql_statedir/debian-10.2.flag ## On every reconfiguration the maintenance user is recreated. # diff --git a/debian/mariadb-server-10.1.postrm b/debian/mariadb-server-10.2.postrm index 7cee5150ef9..7cee5150ef9 100644 --- a/debian/mariadb-server-10.1.postrm +++ b/debian/mariadb-server-10.2.postrm diff --git a/debian/mariadb-server-10.1.preinst b/debian/mariadb-server-10.2.preinst index 1df01b2dcee..ee0723ea85d 100644 --- a/debian/mariadb-server-10.1.preinst +++ b/debian/mariadb-server-10.2.preinst @@ -46,7 +46,7 @@ stop_server() { ################################ main() ########################## -this_version=10.1 +this_version=10.2 # Safe the user from stupidities. show_downgrade_warning=0 diff --git a/debian/mariadb-server-10.1.prerm b/debian/mariadb-server-10.2.prerm index 03e9ea37420..03e9ea37420 100644 --- a/debian/mariadb-server-10.1.prerm +++ b/debian/mariadb-server-10.2.prerm diff --git a/debian/mariadb-server-10.1.py b/debian/mariadb-server-10.2.py index fe5029d056c..7881029a24c 100644 --- a/debian/mariadb-server-10.1.py +++ b/debian/mariadb-server-10.2.py @@ -1,4 +1,4 @@ -'''apport package hook for mariadb-10.1 +'''apport package hook for mariadb-10.2 (c) 2009 Canonical Ltd. Author: Mathias Gug <mathias.gug@canonical.com> @@ -20,7 +20,7 @@ def _add_my_conf_files(report, filename): continue def add_info(report): - attach_conffiles(report, 'mariadb-server-10.1', conffiles=None) + attach_conffiles(report, 'mariadb-server-10.2', conffiles=None) key = 'Logs' + path_to_key('/var/log/daemon.log') report[key] = "" for line in read_file('/var/log/daemon.log').split('\n'): diff --git a/debian/mariadb-server-10.1.templates b/debian/mariadb-server-10.2.templates index f64dd02d7bd..50eee893659 100644 --- a/debian/mariadb-server-10.1.templates +++ b/debian/mariadb-server-10.2.templates @@ -7,7 +7,7 @@ # Even minor modifications require translation updates and such # changes should be coordinated with translators and reviewers. -Template: mariadb-server-10.1/really_downgrade +Template: mariadb-server-10.2/really_downgrade Type: boolean Default: false _Description: Really proceed with downgrade? @@ -73,7 +73,7 @@ _Description: Unable to set password for the MariaDB "root" user . You should check the account's password after the package installation. . - Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file + Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for more information. Template: mysql-server/password_mismatch diff --git a/debian/mariadb-server-core-10.1.files b/debian/mariadb-server-core-10.2.files index 5c60ca5ec67..5c60ca5ec67 100644 --- a/debian/mariadb-server-core-10.1.files +++ b/debian/mariadb-server-core-10.2.files diff --git a/debian/mariadb-test-10.1.dirs b/debian/mariadb-test-10.2.dirs index 1a488d98195..1a488d98195 100644 --- a/debian/mariadb-test-10.1.dirs +++ b/debian/mariadb-test-10.2.dirs diff --git a/debian/mariadb-test-10.1.files b/debian/mariadb-test-10.2.files index dbb551a9407..dbb551a9407 100644 --- a/debian/mariadb-test-10.1.files +++ b/debian/mariadb-test-10.2.files diff --git a/debian/mariadb-test-10.1.links b/debian/mariadb-test-10.2.links index 082680fe5ed..082680fe5ed 100644 --- a/debian/mariadb-test-10.1.links +++ b/debian/mariadb-test-10.2.links diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in index 029c650fe7a..be16669a512 100644 --- a/debian/po/POTFILES.in +++ b/debian/po/POTFILES.in @@ -1 +1 @@ -[type: gettext/rfc822deb] mariadb-server-10.1.templates +[type: gettext/rfc822deb] mariadb-server-10.2.templates diff --git a/debian/po/ar.po b/debian/po/ar.po index c9009069ee5..387086d51ca 100644 --- a/debian/po/ar.po +++ b/debian/po/ar.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: templates\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2007-05-01 13:04+0300\n" "Last-Translator: Ossama M. Khayat <okhayat@yahoo.com>\n" @@ -27,19 +27,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "هل ÙØ¹Ù„اً تريد التثبيط؟" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "هناك مل٠مسمى /var/lib/mysql/debian-*.flag موجود على هذا النظام." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "Such file is an indication that a mariadb-server package with a higher " @@ -52,7 +52,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -62,13 +62,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Ù…Ù„Ø§ØØ¸Ø© هامة لمستخدمي NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -76,7 +76,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "" #| "You should also check the permissions and the owner of the /var/lib/mysql " @@ -88,13 +88,13 @@ msgstr "عليك أيضاً أن تقوم بالتأكد من صلاØÙŠØ§Øª Ù…Ø #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "إزالة جميع قواعد بيانات MariaDBØŸ" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -102,7 +102,7 @@ msgstr "الدليل /var/lib/mysql الذي ÙŠØØªÙˆÙŠ Ù‚ÙˆØ§Ø¹Ø¯ بيانات #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -113,13 +113,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "تشغيل خادم MariaDB عند الإقلاع؟" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -129,13 +129,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "كلمة المرور الجديدة لمستخد \"root\" الخاص بـMariaDB:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -145,7 +145,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "If that field is left blank, the password will not be changed." msgid "If this field is left blank, the password will not be changed." @@ -153,7 +153,7 @@ msgstr "إن ترك الØÙ‚Ù„ ÙØ§Ø±ØºØ§Ù‹ØŒ Ùلن يتم تغيير كلمة #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for the MariaDB \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -161,13 +161,13 @@ msgstr "كلمة المرور الجديدة لمستخد \"root\" الخاص ب #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "تعذر تعيين كلمة مرور للمستخدم \"root\" الخاص بـMariaDB." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -179,7 +179,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "You should check the account's password after tha package installation." @@ -188,27 +188,27 @@ msgstr "يجب عليك التØÙ‚Ù‚ من كلمة مرور Ø§Ù„ØØ³Ø§Ø¨ عقب #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "Please read the /usr/share/doc/mysql-server-5.1/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"الرجاء قراءة المل٠/usr/share/doc/mariadb-server-10.1/README.Debian للمزيد من " +"الرجاء قراءة المل٠/usr/share/doc/mariadb-server-10.2/README.Debian للمزيد من " "المعلومات." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" diff --git a/debian/po/ca.po b/debian/po/ca.po index 7c7d2210834..6f82d771279 100644 --- a/debian/po/ca.po +++ b/debian/po/ca.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-4.1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2004-01-31 19:20GMT\n" "Last-Translator: Aleix Badia i Bosch <abadia@ica.es>\n" @@ -17,19 +17,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -37,7 +37,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -45,7 +45,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "Important note for NIS/YP users!" msgid "Important note for NIS/YP users" @@ -53,7 +53,7 @@ msgstr "Nota important pels usuaris de NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -61,7 +61,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -69,13 +69,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -83,7 +83,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -92,7 +92,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy #| msgid "Should MySQL start on boot?" msgid "Start the MariaDB server on boot?" @@ -100,7 +100,7 @@ msgstr "Voleu que el MariaDB s'iniciï a l'arrencada ?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy msgid "" "The MariaDB server can be launched automatically at boot time or manually " @@ -112,13 +112,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -126,25 +126,25 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -153,27 +153,27 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" @@ -207,13 +207,13 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.2.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "El MySQL només s'instal·la en cas de tenir un nom d'ordinador central que " #~ "no sigui numèric i que es pugui resoldre a través del fitxer /etc/hosts. " #~ "Ex. si l'ordre \"hostname\" retorna \"myhostname\", llavors hi ha d'haver " -#~ "una línia com la següent \"10.1.0.1 myhostname\"." +#~ "una línia com la següent \"10.2.0.1 myhostname\"." #, fuzzy #~ msgid "" diff --git a/debian/po/cs.po b/debian/po/cs.po index f3ae24b1e8c..cf30159d179 100644 --- a/debian/po/cs.po +++ b/debian/po/cs.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2007-05-01 13:01+0200\n" "Last-Translator: Miroslav Kure <kurem@debian.cz>\n" @@ -26,19 +26,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Opravdu pokraÄovat v degradaci?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "V systému existuje soubor /var/lib/mysql/debian-*.flag." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "Such file is an indication that a mariadb-server package with a higher " @@ -51,7 +51,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -61,13 +61,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Důležitá poznámka pro uživatele NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -75,7 +75,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "" #| "You should also check the permissions and the owner of the /var/lib/mysql " @@ -88,13 +88,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Odstranit vÅ¡echny MariaDB databáze?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -104,7 +104,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -116,13 +116,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Spustit MariaDB server pÅ™i startu systému?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -132,13 +132,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Nové heslo MariaDB uživatele \"root\":" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -148,7 +148,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "If that field is left blank, the password will not be changed." msgid "If this field is left blank, the password will not be changed." @@ -156,7 +156,7 @@ msgstr "Ponecháte-li pole prázdné, heslo se nezmÄ›nÃ." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for the MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -164,13 +164,13 @@ msgstr "Nové heslo MariaDB uživatele \"root\":" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "Nelze nastavit heslo MariaDB uživatele \"root\"" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -182,7 +182,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "You should check the account's password after tha package installation." @@ -191,26 +191,26 @@ msgstr "Po instalaci balÃku byste mÄ›li heslo ověřit." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "Please read the /usr/share/doc/mysql-server-5.1/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"VÃce informacà naleznete v /usr/share/doc/mariadb-server-10.1/README.Debian." +"VÃce informacà naleznete v /usr/share/doc/mariadb-server-10.2/README.Debian." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" @@ -298,13 +298,13 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.2.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "MySQL se nainstaluje pouze v pÅ™ÃpadÄ›, že použÃváte nenumerické jméno " #~ "poÄÃtaÄe, které se dá pÅ™eložit pÅ™es soubor /etc/hosts. NapÅ™. když pÅ™Ãkaz " #~ "\"hostname\" vrátà \"diamond\", tak v /etc/hosts musà existovat obdobný " -#~ "řádek jako \"10.1.0.1 diamond\"." +#~ "řádek jako \"10.2.0.1 diamond\"." #~ msgid "" #~ "A new mysql user \"debian-sys-maint\" will be created. This mysql account " diff --git a/debian/po/da.po b/debian/po/da.po index d68b8575d72..917465943af 100644 --- a/debian/po/da.po +++ b/debian/po/da.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-4.1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2007-05-30 22:41+0200\n" "Last-Translator: Claus Hindsgaul <claus.hindsgaul@gmail.com>\n" @@ -27,20 +27,20 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Ønsker du virkelig at fortsætte nedgraderingen?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" "Der er en fil med navnet /var/lib/mysql/debian-*.flag på dette system." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "Such file is an indication that a mariadb-server package with a higher " @@ -54,7 +54,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -64,13 +64,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Vigtig oplysning til NIS/YP-brugere" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -78,7 +78,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "" #| "You should also check the permissions and the owner of the /var/lib/mysql " @@ -91,13 +91,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Fjern alle MariaDB-databaser?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -107,7 +107,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -119,13 +119,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Start MariaDB-serveren under systemopstart?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -135,13 +135,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Ny adgangskode for MariaDB's \"root\"-bruger:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -151,7 +151,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "If that field is left blank, the password will not be changed." msgid "If this field is left blank, the password will not be changed." @@ -159,7 +159,7 @@ msgstr "Hvis du lader dette felt stå tomt, vil adgangskoden ikke blive ændret." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for the MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -167,13 +167,13 @@ msgstr "Ny adgangskode for MariaDB's \"root\"-bruger:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "Kunne ikke sætte adgangskoden for MariaDB's \"root\"-bruger" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -186,33 +186,33 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "Du bør tjekke kontoens adgangskode efter pakkeinstallationen." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "Please read the /usr/share/doc/mysql-server-5.1/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"Se filen /usr/share/doc/mariadb-server-10.1/README.Debian for yderligere " +"Se filen /usr/share/doc/mariadb-server-10.2/README.Debian for yderligere " "oplysninger." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" @@ -324,12 +324,12 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.2.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "MySQL vil kun blive installeret, hvis du har et ikke-numerisk værtsnavn, " #~ "som kan slås op i filen /ets/hosts. Hvis f.eks. kommandoen \"hostname\" " -#~ "svarer med \"mitvaertsnavn\", skal du have en linje a'la \"10.1.0.1 " +#~ "svarer med \"mitvaertsnavn\", skal du have en linje a'la \"10.2.0.1 " #~ "mitvaertsnavn\" i /etc/hosts." #~ msgid "" diff --git a/debian/po/de.po b/debian/po/de.po index 6147b55903e..c39c1abeb8f 100644 --- a/debian/po/de.po +++ b/debian/po/de.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1_5.1.37-1_de\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2009-08-27 22:41+0200\n" "Last-Translator: Thomas Mueller <thomas.mueller@tmit.eu>\n" @@ -29,13 +29,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Möchten Sie wirklich eine ältere Version einspielen?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" "Auf diesem System existiert eine Datei mit dem Namen /var/lib/mysql/debian-*." @@ -43,7 +43,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -53,7 +53,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -63,13 +63,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Wichtige Anmerkung für NIS/YP-Benutzer!" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -79,7 +79,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -89,13 +89,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Alle MariaDB-Datenbanken entfernen?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -105,7 +105,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -117,13 +117,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Soll der MariaDB-Server automatisch beim Booten starten?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -133,13 +133,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Neues Passwort für den MariaDB »root«-Benutzer:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -149,25 +149,25 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "Wenn dieses Feld freigelassen wird, wird das Passwort nicht geändert." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "Wiederholen Sie das Passwort für den MariaDB-»root«-Benutzer:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "Konnte für den MariaDB-»root«-Benutzer kein Passwort setzen" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -180,7 +180,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" "Sie sollten das Passwort des administrativen Benutzers nach der " @@ -188,13 +188,13 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "Please read the /usr/share/doc/mariadb-server-5.1/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" "Für weitere Informationen lesen Sie /usr/share/doc/mariadb-server-5.1/README." @@ -202,13 +202,13 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "Passwort-Eingabefehler" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" "Die beiden von Ihnen eingegebenen Passwörter sind nicht identisch. Bitte " diff --git a/debian/po/es.po b/debian/po/es.po index e76c173a9f5..cb3d101460b 100644 --- a/debian/po/es.po +++ b/debian/po/es.po @@ -40,7 +40,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1_5.0.24-3\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2007-05-28 22:21+0200\n" "Last-Translator: Javier Fernández-Sanguino <jfs@debian.org>\n" @@ -52,20 +52,20 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "¿Desea realmente continuar con la desactualización?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" "Existe un archivo con el nombre /var/lib/mysql/debian-*.flag en este sistema." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "Such file is an indication that a mariadb-server package with a higher " @@ -79,7 +79,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -89,13 +89,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Nota importante para los usuarios de NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -103,7 +103,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "" #| "You should also check the permissions and the owner of the /var/lib/mysql " @@ -117,13 +117,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "¿Desea eliminar todas las bases de datos MariaDB?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -133,7 +133,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -145,13 +145,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "¿DeberÃa ejecutarse el servidor MariaDB al iniciarse el sistema?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -161,13 +161,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Nueva contraseña para el usuario «root» de MariaDB:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -177,7 +177,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "If that field is left blank, the password will not be changed." msgid "If this field is left blank, the password will not be changed." @@ -185,7 +185,7 @@ msgstr "No se modificará la contraseña si deja el espacio en blanco." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for the MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -193,13 +193,13 @@ msgstr "Nueva contraseña para el usuario «root» de MariaDB:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "No se pudo fijar la contraseña para el usuario «root» de MariaDB" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -212,7 +212,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" "DeberÃa comprobar la contraseña de la cuenta después de la instalación del " @@ -220,27 +220,27 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "Please read the /usr/share/doc/mysql-server-5.1/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"Consulte /usr/share/doc/mariadb-server-10.1/README.Debian para más " +"Consulte /usr/share/doc/mariadb-server-10.2/README.Debian para más " "información." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" @@ -341,13 +341,13 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.2.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "Sólo se instalará MySQL si tiene un nombre de equipo que no sea una " #~ "dirección IP y pueda resolverse a través del archivo /etc/hosts. Por " #~ "ejemplo, si la orden «hostname» devuelve «MiNombreEquipo» entonces deberá " -#~ "existir una lÃnea «10.1.0.1 MiNombreEquipo» en dicho archivo." +#~ "existir una lÃnea «10.2.0.1 MiNombreEquipo» en dicho archivo." #~ msgid "" #~ "A new mysql user \"debian-sys-maint\" will be created. This mysql account " diff --git a/debian/po/eu.po b/debian/po/eu.po index 8f1ae0c8ecd..3b538bb074e 100644 --- a/debian/po/eu.po +++ b/debian/po/eu.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: eu\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2009-07-29 11:59+0200\n" "Last-Translator: Piarres Beobide <pi@beobide.net>\n" @@ -20,19 +20,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Benetan bertsio zaharragora itzuli nahi duzu?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "Sisteman badago /var/lib/mysql/debian-*.flag izeneko fitxategi bat." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "Such file is an indication that a mariadb-server package with a higher " @@ -46,7 +46,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -56,13 +56,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "NIS/YP erabiltzaileentzat ohar garrantzitsua" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -70,7 +70,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "" #| "You should also check the permissions and the owner of the /var/lib/mysql " @@ -84,13 +84,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Ezabatu MariaDB datubase guztiak?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -99,7 +99,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -111,13 +111,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Abioan MariaDB zerbitzaria abiarazi?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -127,13 +127,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "MariaDB \"root\" erabiltzailearen pasahitz berria:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -143,7 +143,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "If that field is left blank, the password will not be changed." msgid "If this field is left blank, the password will not be changed." @@ -151,19 +151,19 @@ msgstr "Eremua hau zurian utziaz gero ez da pasahitza aldatuko." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "Errepikatu MariaDB \"root\" erabiltzailearen pasahitza:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "Ezin da MariaDB \"root\" erabiltzailearen pasahitza ezarri" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -175,34 +175,34 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" "Kontuaren pasahitza egiaztatu beharko zenuke paketea instalatu aurretik." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" -#| "Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +#| "Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"Mesedez irakurri /usr/share/doc/mariadb-server-10.1/README.Debian fitxategia " +"Mesedez irakurri /usr/share/doc/mariadb-server-10.2/README.Debian fitxategia " "xehetasun gehiagorako." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "Pasahitz sarrera errorea" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Idatzi dituzun bi pasahitzak ez dira berdina. Mesedez saiatu berriz." diff --git a/debian/po/fr.po b/debian/po/fr.po index 98d6740b7e2..2c29513ac0a 100644 --- a/debian/po/fr.po +++ b/debian/po/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: fr\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2009-08-08 14:56+0200\n" "Last-Translator: Christian Perrier <bubulle@debian.org>\n" @@ -22,19 +22,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Faut-il vraiment revenir à la version précédente ?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "Un fichier /var/lib/mysql/debian-*.flag est présent sur ce système." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -44,7 +44,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -52,13 +52,13 @@ msgstr "Il n'est pas garanti que cette version puisse en utiliser les données." #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Note importante pour les utilisateurs NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -68,7 +68,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -78,13 +78,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Faut-il supprimer toutes les bases de données MariaDB ?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -94,7 +94,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -105,13 +105,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Faut-il lancer MariaDB au démarrage ?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -121,13 +121,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Nouveau mot de passe du superutilisateur de MariaDB :" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -137,26 +137,26 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "Si ce champ est laissé vide, le mot de passe ne sera pas changé." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "Confirmation du mot de passe du superutilisateur de MariaDB :" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "" "Impossible de changer le mot de passe de l'utilisateur « root » de MariaDB" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -168,7 +168,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" "Vous devriez vérifier le mot de passe de ce compte après l'installation du " @@ -176,27 +176,27 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" -#| "Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +#| "Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"Veuillez consulter le fichier /usr/share/doc/mysql-server-10.1/README.Debian " +"Veuillez consulter le fichier /usr/share/doc/mysql-server-10.2/README.Debian " "pour plus d'informations." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "Erreur de saisie du mot de passe" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" "Le mot de passe et sa confirmation ne sont pas identiques. Veuillez " diff --git a/debian/po/gl.po b/debian/po/gl.po index 122e4091c16..8b0dca67223 100644 --- a/debian/po/gl.po +++ b/debian/po/gl.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2007-04-20 09:44+0200\n" "Last-Translator: Jacobo Tarrio <jtarrio@debian.org>\n" @@ -17,19 +17,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "¿Quere pasar a unha versión anterior?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "Neste sistema hai un ficheiro chamado /var/lib/mysql/debian-*.flag." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "Such file is an indication that a mariadb-server package with a higher " @@ -43,7 +43,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -53,13 +53,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Nota importante para os usuarios de NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -67,7 +67,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "" #| "You should also check the permissions and the owner of the /var/lib/mysql " @@ -81,13 +81,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "¿Eliminar tódalas bases de datos de MariaDB?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -97,7 +97,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -109,13 +109,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "¿Iniciar o servidor MariaDB co ordenador?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -125,13 +125,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Novo contrasinal para o usuario \"root\" de MariaDB:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -141,7 +141,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "If that field is left blank, the password will not be changed." msgid "If this field is left blank, the password will not be changed." @@ -149,7 +149,7 @@ msgstr "Se deixa o campo en branco, non se ha cambiar o contrasinal." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for the MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -157,13 +157,13 @@ msgstr "Novo contrasinal para o usuario \"root\" de MariaDB:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "Non se puido establecer o contrasinal do usuario \"root\" de MariaDB" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -175,7 +175,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "You should check the account's password after tha package installation." @@ -184,27 +184,27 @@ msgstr "DeberÃa comprobar o contrasinal da conta trala instalación do paquete. #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "Please read the /usr/share/doc/mysql-server-5.1/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"Consulte o ficheiro /usr/share/doc/mariadb-server-10.1/README.Debian para " +"Consulte o ficheiro /usr/share/doc/mariadb-server-10.2/README.Debian para " "máis información." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" diff --git a/debian/po/it.po b/debian/po/it.po index 459099cbc6a..076f03c9b75 100644 --- a/debian/po/it.po +++ b/debian/po/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1 5.1.37 italian debconf templates\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2009-08-08 11:03+0200\n" "Last-Translator: Luca Monducci <luca.mo@tiscali.it>\n" @@ -18,20 +18,20 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Procedere realmente con l'abbassamento di versione?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" "Su questo sistema esiste un file con nome /var/lib/mysql/debian-*.flag." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -41,7 +41,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -51,13 +51,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Nota importante per gli utenti NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -67,7 +67,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -77,13 +77,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Eliminare tutti i database MariaDB?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -93,7 +93,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -105,13 +105,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Lanciare il server MariaDB all'avvio?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -121,13 +121,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Nuova password per l'utente «root» di MariaDB:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -137,25 +137,25 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "Se questo campo è lasciato vuoto, la password non viene cambiata." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "Ripetere la password per l'utente «root» di MariaDB:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "Impossibile impostare la password per l'utente «root» di MariaDB" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -168,34 +168,34 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" "Al termine dell'installazione si deve verificare la password dell'account." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" -#| "Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +#| "Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" "Per maggiori informazioni si consulti il file /usr/share/doc/mariadb-" -"server-10.1/README.Debian." +"server-10.2/README.Debian." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "Errore di inserimento della password" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Le due password inserite sono diverse. Riprovare." diff --git a/debian/po/ja.po b/debian/po/ja.po index c1087266eaf..30b54ff447d 100644 --- a/debian/po/ja.po +++ b/debian/po/ja.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1 5.1.37-1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2009-09-01 08:25+0900\n" "Last-Translator: Hideki Yamane (Debian-JP) <henrich@debian.or.jp>\n" @@ -27,13 +27,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "本当ã«ãƒ€ã‚¦ãƒ³ã‚°ãƒ¬ãƒ¼ãƒ‰ã‚’実行ã—ã¾ã™ã‹?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" "ã“ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã¯ /var/lib/mysql/debian-*.flag ã¨ã„ã†åå‰ã®ãƒ•ァイルãŒå˜åœ¨ã—ã¦" @@ -41,7 +41,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -51,7 +51,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -61,13 +61,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "NIS/YP ユーザã¸ã®é‡è¦ãªæ³¨æ„" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -77,7 +77,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -85,13 +85,13 @@ msgstr "/var/lib/mysql ã®æ‰€æœ‰è€…権é™ã‚’ãƒã‚§ãƒƒã‚¯ã™ã‚‹å¿…è¦ã‚‚ã‚り㾠#. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "ã™ã¹ã¦ã® MariaDB データベースを削除ã—ã¾ã™ã‹?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -101,7 +101,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -113,13 +113,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "MariaDB をシステム起動時ã«é–‹å§‹ã—ã¾ã™ã‹?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -129,13 +129,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "MariaDB ã® \"root\" ユーザã«å¯¾ã™ã‚‹æ–°ã—ã„パスワード:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -145,25 +145,25 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "ã“ã®å€¤ã‚’空ã®ã¾ã¾ã«ã—ã¦ãŠã„ãŸå ´åˆã¯ã€ãƒ‘スワードã¯å¤‰æ›´ã•れã¾ã›ã‚“。" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "MariaDB ã® \"root\" ユーザã«å¯¾ã™ã‚‹æ–°ã—ã„パスワード:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "MariaDB ã® \"root\" ユーザã®ãƒ‘スワードをè¨å®šã§ãã¾ã›ã‚“" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -175,33 +175,33 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" "パッケージã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«å¾Œã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒ‘スワードを確èªã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" -#| "Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +#| "Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"詳細㯠/usr/share/doc/mariadb-server-10.1/README.Debian ã‚’å‚ç…§ã—ã¦ãã ã•ã„。" +"詳細㯠/usr/share/doc/mariadb-server-10.2/README.Debian ã‚’å‚ç…§ã—ã¦ãã ã•ã„。" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "パスワード入力エラー" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "入力ã•れãŸäºŒã¤ã®ãƒ‘スワードãŒä¸€è‡´ã—ã¾ã›ã‚“。å†å…¥åŠ›ã—ã¦ãã ã•ã„。" diff --git a/debian/po/nb.po b/debian/po/nb.po index 992684fa3e1..c3230913e01 100644 --- a/debian/po/nb.po +++ b/debian/po/nb.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql_nb\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2007-02-18 12:13+0100\n" "Last-Translator: Bjørn Steensrud <bjornst@powertech.no>\n" @@ -19,7 +19,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "Do you really want to downgrade?" msgid "Really proceed with downgrade?" @@ -27,13 +27,13 @@ msgstr "Er du sikker pÃ¥ at du vil nedgradere?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "WARNING: The file /var/lib/mysql/debian-*.flag exists. This indicates " @@ -50,7 +50,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -58,7 +58,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "Important note for NIS/YP users!" msgid "Important note for NIS/YP users" @@ -66,7 +66,7 @@ msgstr "Viktig merknad for NIS/YP-brukere!" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -74,7 +74,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -82,13 +82,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -96,7 +96,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 #, fuzzy #| msgid "" #| "The script is about to remove the data directory /var/lib/mysql. If it is " @@ -113,7 +113,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy #| msgid "Should MySQL start on boot?" msgid "Start the MariaDB server on boot?" @@ -121,7 +121,7 @@ msgstr "Skal MariaDB startes ved maskinoppstart?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy #| msgid "" #| "The MySQL can start automatically on boot time or only if you manually " @@ -135,7 +135,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "New password for MySQL \"root\" user:" msgid "New password for the MariaDB \"root\" user:" @@ -143,7 +143,7 @@ msgstr "Nytt passord for MariaDBs «root»-bruker:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "" #| "It is highly recommended that you set a password for the MySQL " @@ -157,13 +157,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -171,7 +171,7 @@ msgstr "Nytt passord for MariaDBs «root»-bruker:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "Unable to set password for MySQL \"root\" user" msgid "Unable to set password for the MariaDB \"root\" user" @@ -179,7 +179,7 @@ msgstr "Klarer ikke angi passord for MariaDBs «root»-bruker" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "It seems an error occurred while setting the password for the MySQL " @@ -198,27 +198,27 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" diff --git a/debian/po/nl.po b/debian/po/nl.po index 82864ed8456..900fcaa5822 100644 --- a/debian/po/nl.po +++ b/debian/po/nl.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1 5.0.30-1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2006-02-19 10:20+0100\n" "Last-Translator: Thijs Kinkhorst <thijs@debian.org>\n" @@ -18,7 +18,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "Do you really want to downgrade?" msgid "Really proceed with downgrade?" @@ -26,13 +26,13 @@ msgstr "Wilt u echt een oude versie herstellen?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "WARNING: The file /var/lib/mysql/debian-*.flag exists. This indicates " @@ -50,7 +50,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -58,7 +58,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "Important note for NIS/YP users!" msgid "Important note for NIS/YP users" @@ -66,7 +66,7 @@ msgstr "Belangrijke opmerking voor gebruikers van NIS/YP!" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -74,7 +74,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -82,13 +82,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -96,7 +96,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 #, fuzzy #| msgid "" #| "The script is about to remove the data directory /var/lib/mysql. If it is " @@ -114,7 +114,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy #| msgid "Should MySQL start on boot?" msgid "Start the MariaDB server on boot?" @@ -122,7 +122,7 @@ msgstr "Moet MariaDB starten als de computer start?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy #| msgid "" #| "The MySQL can start automatically on boot time or only if you manually " @@ -136,7 +136,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "New password for MySQL \"root\" user:" msgid "New password for the MariaDB \"root\" user:" @@ -144,7 +144,7 @@ msgstr "Nieuw wachtwoord voor de MariaDB \"root\"-gebruiker:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "" #| "It is highly recommended that you set a password for the MySQL " @@ -158,13 +158,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -172,7 +172,7 @@ msgstr "Nieuw wachtwoord voor de MariaDB \"root\"-gebruiker:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "Unable to set password for MySQL \"root\" user" msgid "Unable to set password for the MariaDB \"root\" user" @@ -180,7 +180,7 @@ msgstr "Kan het wachtwoord voor de MariaDB \"root\"-gebruiker niet instellen" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "It seems an error occurred while setting the password for the MySQL " @@ -199,27 +199,27 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" diff --git a/debian/po/pt.po b/debian/po/pt.po index 0c35c038b70..d612b83f943 100644 --- a/debian/po/pt.po +++ b/debian/po/pt.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2007-05-05 21:01+0100\n" "Last-Translator: Miguel Figueiredo <elmig@debianpt.org>\n" @@ -18,19 +18,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Deseja mesmo fazer downgrade?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "Existe um ficheiro chamado /var/lib/mysql/debian-*.flag neste sistema." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "Such file is an indication that a mariadb-server package with a higher " @@ -44,7 +44,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -54,13 +54,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Nota importante para utilizadores de NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -68,7 +68,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "" #| "You should also check the permissions and the owner of the /var/lib/mysql " @@ -81,13 +81,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Remover todas as bases de dados MariaDB?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -97,7 +97,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -109,13 +109,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Iniciar o servidor MariaDB no arranque?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -125,13 +125,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Nova palavra-passe para o utilizador \"root\" do MariaDB:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -141,7 +141,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "If that field is left blank, the password will not be changed." msgid "If this field is left blank, the password will not be changed." @@ -150,7 +150,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for the MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -158,7 +158,7 @@ msgstr "Nova palavra-passe para o utilizador \"root\" do MariaDB:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "" "Não foi possÃvel definir a palavra-passe para o utilizador \"root\" do " @@ -166,7 +166,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -179,7 +179,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "You should check the account's password after tha package installation." @@ -189,27 +189,27 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "Please read the /usr/share/doc/mysql-server-5.1/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" "Para mais informação por favor leia o ficheiro /usr/share/doc/mariadb-" -"server-10.1/README.Debian." +"server-10.2/README.Debian." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" diff --git a/debian/po/pt_BR.po b/debian/po/pt_BR.po index a0b4cdbfbfb..46ffefb8259 100644 --- a/debian/po/pt_BR.po +++ b/debian/po/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2007-04-21 15:59-0300\n" "Last-Translator: André LuÃs Lopes <andrelop@debian.org>\n" @@ -21,19 +21,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Realmente proceder com o rebaixamento de versão?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "Um arquivo de nome /var/lib/mysql/debian-*.flag existe no sistema." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "Such file is an indication that a mariadb-server package with a higher " @@ -47,7 +47,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -57,13 +57,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Aviso importante para usuários NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -71,7 +71,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "" #| "You should also check the permissions and the owner of the /var/lib/mysql " @@ -84,13 +84,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Remover todas as bases de dados do MariaDB?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -100,7 +100,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -112,13 +112,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Iniciar o servidor MariaDB junto a inicialização da máquina?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -128,13 +128,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Nova senha para o usuário \"root\" do MariaDB:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -144,7 +144,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "If that field is left blank, the password will not be changed." msgid "If this field is left blank, the password will not be changed." @@ -152,7 +152,7 @@ msgstr "Caso este campo seja deixado em branco, a senha não sera mudada." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for the MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -160,13 +160,13 @@ msgstr "Nova senha para o usuário \"root\" do MariaDB:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "ImpossÃvel definir senha para o usuário \"root\" do MariaDB" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -179,7 +179,7 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "You should check the account's password after tha package installation." @@ -188,27 +188,27 @@ msgstr "Você deverá checar a senha dessa conta após a instalação deste paco #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "Please read the /usr/share/doc/mysql-server-5.1/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"Por favor, leia o arquivo /usr/share/doc/mariadb-server-10.1/README.Debian " +"Por favor, leia o arquivo /usr/share/doc/mariadb-server-10.2/README.Debian " "para maiores informações." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" @@ -308,13 +308,13 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.2.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "O MySQL será instalado somente caso você possua um nome de host NÃO " #~ "NUMÉRICO que possa ser resolvido através do arquivo /etc/hosts, ou seja, " #~ "caso o comando \"hostname\" retorne \"myhostname\", uma linha como " -#~ "\"10.1.0.1 myhostname\" deverá existir no arquivo /etc/hosts." +#~ "\"10.2.0.1 myhostname\" deverá existir no arquivo /etc/hosts." #~ msgid "" #~ "A new mysql user \"debian-sys-maint\" will be created. This mysql account " diff --git a/debian/po/ro.po b/debian/po/ro.po index ceefecc8a1b..c960e3d2eb4 100644 --- a/debian/po/ro.po +++ b/debian/po/ro.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: po-debconf://mysql-dfsg\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2006-12-20 21:27+0200\n" "Last-Translator: stan ioan-eugen <stan.ieugen@gmail.com>\n" @@ -19,7 +19,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "Do you really want to downgrade?" msgid "Really proceed with downgrade?" @@ -27,13 +27,13 @@ msgstr "SunteÅ£i sigur că doriÅ£i să instalaÅ£i o versiune mai veche?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 #, fuzzy #| msgid "" #| "WARNING: The file /var/lib/mysql/debian-*.flag exists. This indicates " @@ -50,7 +50,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -58,7 +58,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "Important note for NIS/YP users!" msgid "Important note for NIS/YP users" @@ -66,7 +66,7 @@ msgstr "Notă importantă pentru utilizatorii NIS/YP!" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -74,7 +74,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -82,13 +82,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -96,7 +96,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 #, fuzzy #| msgid "" #| "The script is about to remove the data directory /var/lib/mysql. If it is " @@ -113,7 +113,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy #| msgid "Should MySQL start on boot?" msgid "Start the MariaDB server on boot?" @@ -121,7 +121,7 @@ msgstr "DoriÅ£i ca MariaDB să pornească la initializarea sistemului?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy #| msgid "" #| "The MySQL can start automatically on boot time or only if you manually " @@ -135,7 +135,7 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "New password for MySQL \"root\" user:" msgid "New password for the MariaDB \"root\" user:" @@ -143,7 +143,7 @@ msgstr "Noua parolă pentru utilizatorul „root†al MariaDB:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 #, fuzzy #| msgid "" #| "It is highly recommended that you set a password for the MySQL " @@ -157,13 +157,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 #, fuzzy #| msgid "New password for MySQL \"root\" user:" msgid "Repeat password for the MariaDB \"root\" user:" @@ -171,7 +171,7 @@ msgstr "Noua parolă pentru utilizatorul „root†al MariaDB:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "Unable to set password for MySQL \"root\" user" msgid "Unable to set password for the MariaDB \"root\" user" @@ -179,7 +179,7 @@ msgstr "Nu s-a putut stabili parola pentru utilizatorul „root†al MariaDB" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" #| "It seems an error occurred while setting the password for the MySQL " @@ -198,27 +198,27 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" diff --git a/debian/po/ru.po b/debian/po/ru.po index 5136933159b..096e9babe09 100644 --- a/debian/po/ru.po +++ b/debian/po/ru.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1 5.1.37-1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2009-08-06 20:27+0400\n" "Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n" @@ -32,19 +32,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "ДейÑтвительно уÑтановить более Ñтарую верÑию?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "Ð’ ÑиÑтеме найден файл /var/lib/mysql/debian-*.flag." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -54,7 +54,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -64,13 +64,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Важное замечание Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹ NIS/YP" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -80,7 +80,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -88,13 +88,13 @@ msgstr "Также проверьте права доÑтупа и Ð²Ð»Ð°Ð´ÐµÐ»Ñ #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Удалить вÑе базы данных MariaDB?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -103,7 +103,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -115,13 +115,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "ЗапуÑкать MariaDB при загрузке ÑиÑтемы?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -131,13 +131,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Ðовый пароль Ð´Ð»Ñ MariaDB Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"root\":" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -147,25 +147,25 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "ЕÑли оÑтавить поле пуÑтым, то пароль изменён не будет." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "Повторите ввод Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð´Ð»Ñ MariaDB Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"root\":" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "Ðевозможно задать пароль MariaDB пользователю \"root\"" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -177,32 +177,32 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "Проверьте пароль учётной запиÑи поÑле уÑтановки пакета." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" -#| "Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +#| "Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"ПодробноÑти Ñм. в файле /usr/share/doc/mariadb-server-10.1/README.Debian." +"ПодробноÑти Ñм. в файле /usr/share/doc/mariadb-server-10.2/README.Debian." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "Ошибка ввода паролÑ" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "Два введённых Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½Ðµ одинаковы. Повторите ввод." diff --git a/debian/po/sv.po b/debian/po/sv.po index 0cd512a252b..522403a049e 100644 --- a/debian/po/sv.po +++ b/debian/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-5.1 5.0.21-3\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2009-09-08 21:42+0100\n" "Last-Translator: Martin Bagge <brother@bsnet.se>\n" @@ -21,19 +21,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "Vill du verkligen genomföra nedgraderingen?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "En fil med namnet /var/lib/mysql/debian-*.flag hittades i systemet." #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -43,7 +43,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -53,13 +53,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "Viktig information för NIS/YP-användare" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -69,7 +69,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -79,13 +79,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "Ta bort alla MariaDB-databaser?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -95,7 +95,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -107,13 +107,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "Ska MariaDB startas vid systemets uppstart?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -123,13 +123,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "Nytt lösenord för MariaDBs \"root\"-användare:" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -139,25 +139,25 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "Om detta fält lämnas tom kommer lösenordet inte att ändras." #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "Repetera lösenordet för MariaDBs \"root\"-användare:" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "Kunde inte sätta lösenord för MariaDBs \"root\"-användare" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -170,33 +170,33 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "Du bör kontrollera kontots lösenord efter installationen av paketet." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 #, fuzzy #| msgid "" -#| "Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +#| "Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " #| "more information." msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" -"Läs filen /usr/share/doc/mariadb-server-10.1/README.Debian för mer " +"Läs filen /usr/share/doc/mariadb-server-10.2/README.Debian för mer " "information." #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "Fel vid inmatning av lösenord" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "De tvÃ¥ lösenorden du angav stämde inte överrens. Prova igen." diff --git a/debian/po/templates.pot b/debian/po/templates.pot index c164f1f4811..7032c34bc20 100644 --- a/debian/po/templates.pot +++ b/debian/po/templates.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" @@ -19,19 +19,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -39,7 +39,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -47,13 +47,13 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "Important note for NIS/YP users" msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -61,7 +61,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -69,13 +69,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -83,7 +83,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -92,13 +92,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "Start the MariaDB server on boot?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 msgid "" "The MariaDB server can be launched automatically at boot time or manually " "with the '/etc/init.d/mysql start' command." @@ -106,13 +106,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -120,25 +120,25 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -147,26 +147,26 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" diff --git a/debian/po/tr.po b/debian/po/tr.po index 814341a6bc2..81c20ba3b3e 100644 --- a/debian/po/tr.po +++ b/debian/po/tr.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: mysql-dfsg-4.1\n" -"Report-Msgid-Bugs-To: mariadb-10.1@packages.debian.org\n" +"Report-Msgid-Bugs-To: mariadb-10.2@packages.debian.org\n" "POT-Creation-Date: 2012-01-12 13:08+0100\n" "PO-Revision-Date: 2004-06-05 08:53+0300\n" "Last-Translator: Gürkan Aslan <gurkan@iaslan.com>\n" @@ -18,19 +18,19 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "Really proceed with downgrade?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "A file named /var/lib/mysql/debian-*.flag exists on this system." msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "Such a file is an indication that a mariadb-server package with a higher " "version has been installed previously." @@ -38,7 +38,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:2001 +#: ../mariadb-server-10.2.templates:2001 msgid "" "There is no guarantee that the version you're currently installing will be " "able to use the current databases." @@ -46,7 +46,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 #, fuzzy #| msgid "Important note for NIS/YP users!" msgid "Important note for NIS/YP users" @@ -54,7 +54,7 @@ msgstr "NIS/YP kullanıcıları için önemli not!" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "Using MariaDB under NIS/YP requires a mysql user account to be added on the " "local system with:" @@ -62,7 +62,7 @@ msgstr "" #. Type: note #. Description -#: ../mariadb-server-10.1.templates:3001 +#: ../mariadb-server-10.2.templates:3001 msgid "" "You should also check the permissions and ownership of the /var/lib/mysql " "directory:" @@ -70,13 +70,13 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "Remove all MariaDB databases?" msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "The /var/lib/mysql directory which contains the MariaDB databases is about " "to be removed." @@ -84,7 +84,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:4001 +#: ../mariadb-server-10.2.templates:4001 msgid "" "If you're removing the MariaDB package in order to later install a more " "recent version or if a different mariadb-server package is already using it, " @@ -93,7 +93,7 @@ msgstr "" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy #| msgid "Should MySQL start on boot?" msgid "Start the MariaDB server on boot?" @@ -101,7 +101,7 @@ msgstr "MariaDB açılış sırasında baÅŸlatılsın mı?" #. Type: boolean #. Description -#: ../mariadb-server-10.1.templates:5001 +#: ../mariadb-server-10.2.templates:5001 #, fuzzy msgid "" "The MariaDB server can be launched automatically at boot time or manually " @@ -113,13 +113,13 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "New password for the MariaDB \"root\" user:" msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "" "While not mandatory, it is highly recommended that you set a password for " "the MariaDB administrative \"root\" user." @@ -127,25 +127,25 @@ msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:6001 +#: ../mariadb-server-10.2.templates:6001 msgid "If this field is left blank, the password will not be changed." msgstr "" #. Type: password #. Description -#: ../mariadb-server-10.1.templates:7001 +#: ../mariadb-server-10.2.templates:7001 msgid "Repeat password for the MariaDB \"root\" user:" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "Unable to set password for the MariaDB \"root\" user" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" "An error occurred while setting the password for the MariaDB administrative " "user. This may have happened because the account already has a password, or " @@ -154,27 +154,27 @@ msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "You should check the account's password after the package installation." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:8001 +#: ../mariadb-server-10.2.templates:8001 msgid "" -"Please read the /usr/share/doc/mariadb-server-10.1/README.Debian file for " +"Please read the /usr/share/doc/mariadb-server-10.2/README.Debian file for " "more information." msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "Password input error" msgstr "" #. Type: error #. Description -#: ../mariadb-server-10.1.templates:9001 +#: ../mariadb-server-10.2.templates:9001 msgid "The two passwords you entered were not the same. Please try again." msgstr "" @@ -206,12 +206,12 @@ msgstr "" #~ msgid "" #~ "MySQL will only install if you have a non-numeric hostname that is " #~ "resolvable via the /etc/hosts file. E.g. if the \"hostname\" command " -#~ "returns \"myhostname\" then there must be a line like \"10.1.0.1 " +#~ "returns \"myhostname\" then there must be a line like \"10.2.0.1 " #~ "myhostname\"." #~ msgstr "" #~ "MySQL sadece /etc/hosts dosyası yoluyla çözülebilir NUMERİK OLMAYAN bir " #~ "makine adına sahipseniz kurulacaktır. ÖrneÄŸin, eÄŸer \"hostname\" komutu " -#~ "\"makinem\" ismini döndürüyorsa, bu dosya içinde \"10.1.0.1 makinem\" " +#~ "\"makinem\" ismini döndürüyorsa, bu dosya içinde \"10.2.0.1 makinem\" " #~ "gibi bir satır olmalıdır." #, fuzzy diff --git a/debian/rules b/debian/rules index 1c824626dca..7f134af24a8 100755 --- a/debian/rules +++ b/debian/rules @@ -3,7 +3,7 @@ export DH_VERBOSE=1 export DEB_BUILD_HARDENING=1 -PACKAGE=mariadb-10.1 +PACKAGE=mariadb-10.2 include /usr/share/dpatch/dpatch.make @@ -163,37 +163,37 @@ install: build # mariadb-server install -m 0755 $(BUILDDIR)/scripts/mysqld_safe $(TMP)/usr/bin/mysqld_safe - mkdir -p $(TMP)/usr/share/doc/mariadb-server-10.1/examples + mkdir -p $(TMP)/usr/share/doc/mariadb-server-10.2/examples # We have a sane my.cnf, cruft not needed (remove my-*.cnf and config-*.cnf) - # $(TMP)/usr/share/mysql/*cnf $(TMP)/usr/share/doc/mariadb-server-10.1/examples/ + # $(TMP)/usr/share/mysql/*cnf $(TMP)/usr/share/doc/mariadb-server-10.2/examples/ rm -vf $(TMP)/usr/share/mysql/my-*.cnf \ $(TMP)/usr/share/mysql/config-*.cnf \ $(TMP)/usr/share/mysql/mi_test_all* \ $(TMP)/usr/share/mysql/mysql-log-rotate \ $(TMP)/usr/share/mysql/mysql.server \ $(TMP)/usr/share/mysql/binary-configure - nm -n $(BUILDDIR)/sql/mysqld |gzip -9 > $(TMP)/usr/share/doc/mariadb-server-10.1/mysqld.sym.gz + nm -n $(BUILDDIR)/sql/mysqld |gzip -9 > $(TMP)/usr/share/doc/mariadb-server-10.2/mysqld.sym.gz install -m 0755 debian/additions/echo_stderr $(TMP)/usr/share/mysql/ install -m 0755 debian/additions/debian-start $(TMP)/etc/mysql/ install -m 0755 debian/additions/debian-start.inc.sh $(TMP)/usr/share/mysql/ - install -m 0644 $(builddir)/Docs/INFO_SRC $(TMP)/usr/share/doc/mariadb-server-10.1/INFO_SRC - install -m 0644 $(builddir)/Docs/INFO_BIN $(TMP)/usr/share/doc/mariadb-server-10.1/INFO_BIN + install -m 0644 $(builddir)/Docs/INFO_SRC $(TMP)/usr/share/doc/mariadb-server-10.2/INFO_SRC + install -m 0644 $(builddir)/Docs/INFO_BIN $(TMP)/usr/share/doc/mariadb-server-10.2/INFO_BIN # mariadb-test mv $(TMP)/usr/mysql-test $(TMP)/usr/share/mysql - # For 5.0 -> 10.1 transition + # For 5.0 -> 10.2 transition d=$(TMP)/usr/share/mysql-common/internal-use-only/; \ mkdir -p $$d; \ - cp debian/mariadb-server-10.1.mysql.init $$d/_etc_init.d_mysql; \ - cp debian/mariadb-server-10.1.mysql-server.logrotate $$d/_etc_logrotate.d_mysql-server; \ + cp debian/mariadb-server-10.2.mysql.init $$d/_etc_init.d_mysql; \ + cp debian/mariadb-server-10.2.mysql-server.logrotate $$d/_etc_logrotate.d_mysql-server; \ cp debian/additions/debian-start $$d/_etc_mysql_debian-start; # install AppArmor profile install -D -m 644 debian/apparmor-profile $(TMP)/etc/apparmor.d/usr.sbin.mysqld # install Apport hook - install -D -m 644 debian/mariadb-server-10.1.py $(TMP)/usr/share/apport/package-hooks/source_mariadb-10.1.py + install -D -m 644 debian/mariadb-server-10.2.py $(TMP)/usr/share/apport/package-hooks/source_mariadb-10.2.py autorm=debian/autorm-file; \ rm -f $$autorm; \ @@ -241,12 +241,12 @@ binary-arch: build install dh_installexamples -a dh_installmenu -a dh_installlogrotate -a --name mysql-server - if [ -x /usr/bin/dh_systemd_enable -a -f debian/mariadb-server-10.1/lib/systemd/system/mariadb.service ]; then dh_systemd_enable -pmariadb-server-10.1 mariadb.service; fi - if [ -x /usr/bin/dh_systemd_enable -a -f debian/mariadb-server-10.1/lib/systemd/system/mariadb@.service ]; then dh_systemd_enable --no-enable -pmariadb-server-10.1 mariadb@.service; fi + if [ -x /usr/bin/dh_systemd_enable -a -f debian/mariadb-server-10.2/lib/systemd/system/mariadb.service ]; then dh_systemd_enable -pmariadb-server-10.2 mariadb.service; fi + if [ -x /usr/bin/dh_systemd_enable -a -f debian/mariadb-server-10.2/lib/systemd/system/mariadb@.service ]; then dh_systemd_enable --no-enable -pmariadb-server-10.2 mariadb@.service; fi # Start mysql in runlevel 19 before 20 where apache, proftpd etc gets # started which might depend on a running database server. dh_installinit -a --name=mysql -- defaults 19 21 - if [ -x /usr/bin/dh_systemd_start -a -f debian/mariadb-server-10.1/lib/systemd/system/mariadb.service ]; then dh_systemd_start -pmariadb-server-10.1 --restart-after-upgrade mariadb.service; fi + if [ -x /usr/bin/dh_systemd_start -a -f debian/mariadb-server-10.2/lib/systemd/system/mariadb.service ]; then dh_systemd_start -pmariadb-server-10.2 --restart-after-upgrade mariadb.service; fi dh_installcron -a --name mysql-server dh_installman -a dh_installinfo -a diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 269976a6eaa..55b4b34f9c6 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -342,6 +342,7 @@ private: Sessions& GetSessions(); // forward singletons sslFactory& GetSSL_Factory(); Errors& GetErrors(); +bool HasErrors(); // openSSL method and context types diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index ccc1ad24b39..5603430a677 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -1493,7 +1493,8 @@ int SSLeay_add_ssl_algorithms() // compatibility only void ERR_remove_state(unsigned long) { - GetErrors().Remove(); + if (HasErrors()) + GetErrors().Remove(); } diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index a38b7a5c81f..9b447547c56 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -1688,6 +1688,11 @@ Errors& GetErrors() return *errorsInstance; } +bool HasErrors() +{ + return (errorsInstance != 0); +} + typedef Mutex::Lock Lock; diff --git a/include/byte_order_generic_x86_64.h b/include/byte_order_generic_x86_64.h index b6b0c5d8ea5..05c144f83cb 100644 --- a/include/byte_order_generic_x86_64.h +++ b/include/byte_order_generic_x86_64.h @@ -16,6 +16,7 @@ /* Optimized function-like macros for the x86 architecture (_WIN32 included). */ + #define sint2korr(A) (int16) (*((int16 *) (A))) #define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \ (((uint32) 255L << 24) | \ @@ -39,17 +40,21 @@ #define uint3korr(A) (uint32) (*((unsigned int *) (A)) & 0xFFFFFF) #endif #define uint4korr(A) (uint32) (*((uint32 *) (A))) -#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\ - (((uint32) ((uchar) (A)[1])) << 8) +\ - (((uint32) ((uchar) (A)[2])) << 16) +\ - (((uint32) ((uchar) (A)[3])) << 24)) +\ - (((ulonglong) ((uchar) (A)[4])) << 32)) -#define uint6korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) + \ - (((uint32) ((uchar) (A)[1])) << 8) + \ - (((uint32) ((uchar) (A)[2])) << 16) + \ - (((uint32) ((uchar) (A)[3])) << 24)) + \ - (((ulonglong) ((uchar) (A)[4])) << 32) + \ - (((ulonglong) ((uchar) (A)[5])) << 40)) + + +static inline ulonglong uint5korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(4 + (uchar *) p); + return a | (b << 32); +} +static inline ulonglong uint6korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(uint16 *) (4 + (char *) p); + return a | (b << 32); +} + #define uint8korr(A) (ulonglong) (*((ulonglong *) (A))) #define sint8korr(A) (longlong) (*((longlong *) (A))) @@ -61,23 +66,67 @@ *(T+1)=(uchar) (((uint) (A) >> 8));\ *(T+2)=(uchar) (((A) >> 16));\ } while (0) + #define int4store(T,A) do { uchar *pT= (uchar*)(T);\ *((uint32 *) (pT))= (uint32) (A); \ } while (0) -#define int5store(T,A) do { *(T)= (uchar)((A));\ - *((T)+1)=(uchar) (((A) >> 8));\ - *((T)+2)=(uchar) (((A) >> 16));\ - *((T)+3)=(uchar) (((A) >> 24));\ - *((T)+4)=(uchar) (((A) >> 32));\ - } while(0) -#define int6store(T,A) do { *(T)= (uchar)((A)); \ - *((T)+1)=(uchar) (((A) >> 8)); \ - *((T)+2)=(uchar) (((A) >> 16)); \ - *((T)+3)=(uchar) (((A) >> 24)); \ - *((T)+4)=(uchar) (((A) >> 32)); \ - *((T)+5)=(uchar) (((A) >> 40)); \ - } while(0) +#define int5store(T,A) do { uchar *pT= (uchar*)(T);\ + *((uint32 *) (pT))= (uint32) (A); \ + *((pT)+4)=(uchar) (((A) >> 32));\ + } while (0) + +#define int6store(T,A) do { uchar *pT= (uchar*)(T);\ + *((uint32 *) (pT))= (uint32) (A); \ + *((uint16*)(pT+4))= (uint16) (A >> 32);\ + } while (0) + #define int8store(T,A) do { uchar *pT= (uchar*)(T);\ *((ulonglong *) (pT))= (ulonglong) (A);\ } while(0) + +#if defined(__GNUC__) + +#define HAVE_mi_uint5korr +#define HAVE_mi_uint6korr +#define HAVE_mi_uint7korr +#define HAVE_mi_uint78orr + +/* Read numbers stored in high-bytes-first order */ + +static inline ulonglong mi_uint5korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(4 + (uchar *) p); + ulonglong v= (a | (b << 32)) << 24; + asm ("bswapq %0" : "=r" (v) : "0" (v)); + return v; +} + +static inline ulonglong mi_uint6korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(uint16 *) (4 + (char *) p); + ulonglong v= (a | (b << 32)) << 16; + asm ("bswapq %0" : "=r" (v) : "0" (v)); + return v; +} + +static inline ulonglong mi_uint7korr(const void *p) +{ + ulonglong a= *(uint32 *) p; + ulonglong b= *(uint16 *) (4 + (char *) p); + ulonglong c= *(6 + (uchar *) p); + ulonglong v= (a | (b << 32) | (c << 48)) << 8; + asm ("bswapq %0" : "=r" (v) : "0" (v)); + return v; +} + +static inline ulonglong mi_uint8korr(const void *p) +{ + ulonglong v= *(ulonglong *) p; + asm ("bswapq %0" : "=r" (v) : "0" (v)); + return v; +} + +#endif diff --git a/include/decimal.h b/include/decimal.h index 2adeb824318..39d617ae08d 100644 --- a/include/decimal.h +++ b/include/decimal.h @@ -51,7 +51,7 @@ int decimal2longlong(const decimal_t *from, longlong *to); int longlong2decimal(longlong from, decimal_t *to); int decimal2double(const decimal_t *from, double *to); int double2decimal(double from, decimal_t *to); -int decimal_actual_fraction(decimal_t *from); +int decimal_actual_fraction(const decimal_t *from); int decimal2bin(const decimal_t *from, uchar *to, int precision, int scale); int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale); diff --git a/include/m_ctype.h b/include/m_ctype.h index ee49e94ef99..b891e89d00d 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -400,7 +400,6 @@ struct my_charset_handler_st { my_bool (*init)(struct charset_info_st *, MY_CHARSET_LOADER *loader); /* Multibyte routines */ - uint (*ismbchar)(CHARSET_INFO *, const char *, const char *); uint (*mbcharlen)(CHARSET_INFO *, uint c); size_t (*numchars)(CHARSET_INFO *, const char *b, const char *e); size_t (*charpos)(CHARSET_INFO *, const char *b, const char *e, @@ -972,8 +971,42 @@ size_t my_convert_fix(CHARSET_INFO *dstcs, char *dst, size_t dst_length, #define my_strcasecmp(s, a, b) ((s)->coll->strcasecmp((s), (a), (b))) #define my_charpos(cs, b, e, num) (cs)->cset->charpos((cs), (const char*) (b), (const char *)(e), (num)) -#define use_mb(s) ((s)->cset->ismbchar != NULL) -#define my_ismbchar(s, a, b) ((s)->cset->ismbchar((s), (a), (b))) +#define use_mb(s) ((s)->mbmaxlen > 1) +/** + Detect if the leftmost character in a string is a valid multi-byte character + and return its length, or return 0 otherwise. + @param cs - character set + @param str - the beginning of the string + @param end - the string end (the next byte after the string) + @return >0, for a multi-byte character + @rerurn 0, for a single byte character, broken sequence, empty string. +*/ +static inline +uint my_ismbchar(CHARSET_INFO *cs, const char *str, const char *end) +{ + int char_length= (cs->cset->charlen)(cs, (const uchar *) str, + (const uchar *) end); + return char_length > 1 ? (uint) char_length : 0U; +} + + +/** + Return length of the leftmost character in a string. + @param cs - character set + @param str - the beginning of the string + @param end - the string end (the next byte after the string) + @return <=0 on errors (EOL, wrong byte sequence) + @return 1 on a single byte character + @return >1 on a multi-byte character + + Note, inlike my_ismbchar(), 1 is returned for a single byte character. +*/ +static inline +uint my_charlen(CHARSET_INFO *cs, const char *str, const char *end) +{ + return (cs->cset->charlen)(cs, (const uchar *) str, + (const uchar *) end); +} #ifdef USE_MB #define my_mbcharlen(s, a) ((s)->cset->mbcharlen((s),(a))) #else diff --git a/include/my_atomic.h b/include/my_atomic.h index c75b65db38d..2034bf48987 100644 --- a/include/my_atomic.h +++ b/include/my_atomic.h @@ -280,6 +280,12 @@ make_atomic_store(32) make_atomic_store(64) make_atomic_store(ptr) +#if SIZEOF_LONG == 4 +#define my_atomic_addlong(A,B) my_atomic_add32((int32*) (A), (B)) +#else +#define my_atomic_addlong(A,B) my_atomic_add64((int64*) (A), (B)) +#endif + #ifdef _atomic_h_cleanup_ #include _atomic_h_cleanup_ #undef _atomic_h_cleanup_ diff --git a/include/my_context.h b/include/my_context.h index c59d6ce3577..ea0e3496887 100644 --- a/include/my_context.h +++ b/include/my_context.h @@ -62,7 +62,7 @@ struct my_context { ucontext_t base_context; ucontext_t spawned_context; int active; -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H unsigned int valgrind_stack_id; #endif #ifndef DBUG_OFF @@ -79,7 +79,7 @@ struct my_context { uint64_t save[9]; void *stack_top; void *stack_bot; -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H unsigned int valgrind_stack_id; #endif #ifndef DBUG_OFF @@ -96,7 +96,7 @@ struct my_context { uint64_t save[7]; void *stack_top; void *stack_bot; -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H unsigned int valgrind_stack_id; #endif #ifndef DBUG_OFF diff --git a/include/my_global.h b/include/my_global.h index f5af8083cdc..7ed306b8b56 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -153,13 +153,11 @@ */ #if defined(__APPLE__) && defined(__MACH__) # undef SIZEOF_CHARP -# undef SIZEOF_SHORT # undef SIZEOF_INT # undef SIZEOF_LONG # undef SIZEOF_LONG_LONG # undef SIZEOF_OFF_T # undef WORDS_BIGENDIAN -# define SIZEOF_SHORT 2 # define SIZEOF_INT 4 # define SIZEOF_LONG_LONG 8 # define SIZEOF_OFF_T 8 diff --git a/include/my_pthread.h b/include/my_pthread.h index 37576ac3cb4..991bc76c1ec 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -445,30 +445,10 @@ void safe_mutex_free_deadlock_data(safe_mutex_t *mp); #define safe_mutex_assert_not_owner(mp) do {} while (0) #define safe_mutex_setflags(mp, F) do {} while (0) -#if defined(MY_PTHREAD_FASTMUTEX) -#define my_cond_timedwait(A,B,C) pthread_cond_timedwait((A), &(B)->mutex, (C)) -#define my_cond_wait(A,B) pthread_cond_wait((A), &(B)->mutex) -#else #define my_cond_timedwait(A,B,C) pthread_cond_timedwait((A),(B),(C)) #define my_cond_wait(A,B) pthread_cond_wait((A), (B)) -#endif /* MY_PTHREAD_FASTMUTEX */ #endif /* !SAFE_MUTEX */ -#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) -typedef struct st_my_pthread_fastmutex_t -{ - pthread_mutex_t mutex; - uint spins; - uint rng_state; -} my_pthread_fastmutex_t; -void fastmutex_global_init(void); - -int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, - const pthread_mutexattr_t *attr); -int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp); - -#endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */ - /* READ-WRITE thread locking */ #if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS) @@ -692,7 +672,7 @@ extern pthread_mutexattr_t my_errorcheck_mutexattr; #define ESRCH 1 #endif -typedef ulong my_thread_id; +typedef int64 my_thread_id; extern void my_threadattr_global_init(void); extern my_bool my_thread_global_init(void); @@ -714,7 +694,7 @@ extern void my_mutex_end(void); We need to have at least 256K stack to handle calls to myisamchk_init() with the current number of keys and key parts. */ -#define DEFAULT_THREAD_STACK (289*1024L) +#define DEFAULT_THREAD_STACK (290*1024L) #endif #define MY_PTHREAD_LOCK_READ 0 diff --git a/include/my_valgrind.h b/include/my_valgrind.h index 4531ec78f9a..0662f5dce71 100644 --- a/include/my_valgrind.h +++ b/include/my_valgrind.h @@ -19,18 +19,18 @@ #define IF_VALGRIND(A,B) B #endif -#if defined(HAVE_VALGRIND) && defined(HAVE_valgrind) +#if defined(HAVE_VALGRIND_MEMCHECK_H) && defined(HAVE_valgrind) # include <valgrind/memcheck.h> # define MEM_UNDEFINED(a,len) VALGRIND_MAKE_MEM_UNDEFINED(a,len) # define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len) # define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len) # define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len) -#else /* HAVE_VALGRIND */ +#else /* HAVE_VALGRIND_MEMCHECK_H */ # define MEM_UNDEFINED(a,len) ((void) 0) # define MEM_NOACCESS(a,len) ((void) 0) # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) # define MEM_CHECK_DEFINED(a,len) ((void) 0) -#endif /* HAVE_VALGRIND */ +#endif /* HAVE_VALGRIND_MEMCHECK_H */ #ifndef DBUG_OFF #define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); memset(A, C, trash_tmp); MEM_UNDEFINED(A, trash_tmp); } while (0) diff --git a/include/myisampack.h b/include/myisampack.h index 0795455dc3e..cfe1fcbc24a 100644 --- a/include/myisampack.h +++ b/include/myisampack.h @@ -52,11 +52,16 @@ (((uint32) (((const uchar*) (A))[2])) << 8) +\ (((uint32) (((const uchar*) (A))[1])) << 16) +\ (((uint32) (((const uchar*) (A))[0])) << 24))) + +#ifndef HAVE_mi_uint5korr #define mi_uint5korr(A) ((ulonglong)(((uint32) (((const uchar*) (A))[4])) +\ (((uint32) (((const uchar*) (A))[3])) << 8) +\ (((uint32) (((const uchar*) (A))[2])) << 16) +\ (((uint32) (((const uchar*) (A))[1])) << 24)) +\ (((ulonglong) (((const uchar*) (A))[0])) << 32)) +#endif /* HAVE_mi_uint5korr */ + +#ifndef HAVE_mi_uint6korr #define mi_uint6korr(A) ((ulonglong)(((uint32) (((const uchar*) (A))[5])) +\ (((uint32) (((const uchar*) (A))[4])) << 8) +\ (((uint32) (((const uchar*) (A))[3])) << 16) +\ @@ -64,6 +69,9 @@ (((ulonglong) (((uint32) (((const uchar*) (A))[1])) +\ (((uint32) (((const uchar*) (A))[0]) << 8)))) <<\ 32)) +#endif /* HAVE_mi_uint6korr */ + +#ifndef HAVE_mi_uint7korr #define mi_uint7korr(A) ((ulonglong)(((uint32) (((const uchar*) (A))[6])) +\ (((uint32) (((const uchar*) (A))[5])) << 8) +\ (((uint32) (((const uchar*) (A))[4])) << 16) +\ @@ -72,6 +80,9 @@ (((uint32) (((const uchar*) (A))[1])) << 8) +\ (((uint32) (((const uchar*) (A))[0])) << 16))) <<\ 32)) +#endif /* HAVE_mi_uint7korr */ + +#ifndef HAVE_mi_uint8korr #define mi_uint8korr(A) ((ulonglong)(((uint32) (((const uchar*) (A))[7])) +\ (((uint32) (((const uchar*) (A))[6])) << 8) +\ (((uint32) (((const uchar*) (A))[5])) << 16) +\ @@ -81,6 +92,7 @@ (((uint32) (((const uchar*) (A))[1])) << 16) +\ (((uint32) (((const uchar*) (A))[0])) << 24))) <<\ 32)) +#endif /* HAVE_mi_uint8korr */ /* This one is for uniformity */ #define mi_int1store(T,A) *((uchar*)(T))= (uchar) (A) diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 5c3a9210ce8..0c06141df6c 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -9,6 +9,9 @@ enum enum_server_command COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE, COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON, + COM_MDB_GAP_BEG, + COM_MDB_GAP_END=253, + COM_MULTI, COM_END }; struct st_vio; diff --git a/include/mysql/plugin_audit.h b/include/mysql/plugin_audit.h index 31589f071f0..7fb6e816181 100644 --- a/include/mysql/plugin_audit.h +++ b/include/mysql/plugin_audit.h @@ -56,7 +56,7 @@ struct mysql_event_general unsigned int general_command_length; const char *general_query; unsigned int general_query_length; - struct charset_info_st *general_charset; + const struct charset_info_st *general_charset; unsigned long long general_time; unsigned long long general_rows; /* Added in version 0x302 */ diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index f4df16afa67..8fc935262e2 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -422,7 +422,7 @@ struct mysql_event_general unsigned int general_command_length; const char *general_query; unsigned int general_query_length; - struct charset_info_st *general_charset; + const struct charset_info_st *general_charset; unsigned long long general_time; unsigned long long general_rows; unsigned long long query_id; diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h index 1dbe8c7eb22..619f600a776 100644 --- a/include/mysql/psi/mysql_socket.h +++ b/include/mysql/psi/mysql_socket.h @@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA #ifndef MYSQL_SOCKET_H #define MYSQL_SOCKET_H -/* For strlen() */ -#include <string.h> /* For MY_STAT */ #include <my_dir.h> /* For my_chsize */ @@ -1014,7 +1012,7 @@ inline_mysql_socket_accept MYSQL_SOCKET socket_listen, struct sockaddr *addr, socklen_t *addr_len) { #ifdef FD_CLOEXEC - int flags; + int flags __attribute__ ((unused)); #endif MYSQL_SOCKET socket_accept= MYSQL_INVALID_SOCKET; diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h index 08dfeac37f1..54a0eaabef7 100644 --- a/include/mysql/psi/mysql_thread.h +++ b/include/mysql/psi/mysql_thread.h @@ -71,8 +71,6 @@ struct st_mysql_mutex /** The real mutex. */ #ifdef SAFE_MUTEX safe_mutex_t m_mutex; -#elif defined(MY_PTHREAD_FASTMUTEX) - my_pthread_fastmutex_t m_mutex; #else pthread_mutex_t m_mutex; #endif @@ -619,8 +617,6 @@ static inline int inline_mysql_mutex_init( #endif #ifdef SAFE_MUTEX return safe_mutex_init(&that->m_mutex, attr, src_name, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - return my_pthread_fastmutex_init(&that->m_mutex, attr); #else return pthread_mutex_init(&that->m_mutex, attr); #endif @@ -642,8 +638,6 @@ static inline int inline_mysql_mutex_destroy( #endif #ifdef SAFE_MUTEX return safe_mutex_destroy(&that->m_mutex, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - return pthread_mutex_destroy(&that->m_mutex.mutex); #else return pthread_mutex_destroy(&that->m_mutex); #endif @@ -670,8 +664,6 @@ static inline int inline_mysql_mutex_lock( /* Instrumented code */ #ifdef SAFE_MUTEX result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= my_pthread_fastmutex_lock(&that->m_mutex); #else result= pthread_mutex_lock(&that->m_mutex); #endif @@ -687,8 +679,6 @@ static inline int inline_mysql_mutex_lock( /* Non instrumented code */ #ifdef SAFE_MUTEX result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= my_pthread_fastmutex_lock(&that->m_mutex); #else result= pthread_mutex_lock(&that->m_mutex); #endif @@ -717,8 +707,6 @@ static inline int inline_mysql_mutex_trylock( /* Instrumented code */ #ifdef SAFE_MUTEX result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= pthread_mutex_trylock(&that->m_mutex.mutex); #else result= pthread_mutex_trylock(&that->m_mutex); #endif @@ -734,8 +722,6 @@ static inline int inline_mysql_mutex_trylock( /* Non instrumented code */ #ifdef SAFE_MUTEX result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= pthread_mutex_trylock(&that->m_mutex.mutex); #else result= pthread_mutex_trylock(&that->m_mutex); #endif @@ -759,8 +745,6 @@ static inline int inline_mysql_mutex_unlock( #ifdef SAFE_MUTEX result= safe_mutex_unlock(&that->m_mutex, src_file, src_line); -#elif defined(MY_PTHREAD_FASTMUTEX) - result= pthread_mutex_unlock(&that->m_mutex.mutex); #else result= pthread_mutex_unlock(&that->m_mutex); #endif @@ -1256,7 +1240,7 @@ static inline int inline_mysql_thread_create( return result; } -static inline void inline_mysql_thread_set_psi_id(ulong id) +static inline void inline_mysql_thread_set_psi_id(my_thread_id id) { struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)(); PSI_THREAD_CALL(set_thread_id)(psi, id); diff --git a/include/mysql_com.h b/include/mysql_com.h index a3790a44c1d..c13999a1028 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -102,7 +102,9 @@ enum enum_server_command COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE, COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON, /* don't forget to update const char *command_name[] in sql_parse.cc */ - + COM_MDB_GAP_BEG, + COM_MDB_GAP_END=253, + COM_MULTI, /* Must be last */ COM_END }; @@ -139,7 +141,6 @@ enum enum_server_command #define NUM_FLAG 32768 /* Field is num (for clients) */ #define PART_KEY_FLAG 16384 /* Intern; Part of some key */ #define GROUP_FLAG 32768 /* Intern: Group field */ -#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */ #define BINCMP_FLAG 131072 /* Intern: Used by sql_yacc */ #define GET_FIXED_FIELDS_FLAG (1 << 18) /* Used to get fields in item tree */ #define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */ @@ -189,7 +190,8 @@ enum enum_server_command #define REFRESH_GENERIC (1ULL << 30) #define REFRESH_FAST (1ULL << 31) /* Intern flag */ -#define CLIENT_LONG_PASSWORD 1 /* new more secure passwords */ +#define CLIENT_LONG_PASSWORD 0 /* obsolete flag */ +#define CLIENT_MYSQL 1 /* mysql/old mariadb server/client */ #define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ #define CLIENT_LONG_FLAG 4 /* Get all column flags */ #define CLIENT_CONNECT_WITH_DB 8 /* One can specify db on connect */ @@ -216,7 +218,7 @@ enum enum_server_command /* Don't close the connection for a connection with expired password. */ #define CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS (1UL << 22) -#define CLIENT_PROGRESS (1UL << 29) /* Client support progress indicator */ +#define CLIENT_PROGRESS_OBSOLETE (1UL << 29) #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) /* It used to be that if mysql_real_connect() failed, it would delete any @@ -229,14 +231,25 @@ enum enum_server_command */ #define CLIENT_REMEMBER_OPTIONS (1UL << 31) +/* MariaDB extended capability flags */ +#define MARIADB_CLIENT_FLAGS_MASK 0xffffffff00000000ULL +/* Client support progress indicator */ +#define MARIADB_CLIENT_PROGRESS (1ULL << 32) +/* support COM_MULTI */ +#define MARIADB_CLIENT_COM_MULTI (1ULL << 33) + #ifdef HAVE_COMPRESS #define CAN_CLIENT_COMPRESS CLIENT_COMPRESS #else #define CAN_CLIENT_COMPRESS 0 #endif -/* Gather all possible capabilites (flags) supported by the server */ -#define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD | \ +/* + Gather all possible capabilites (flags) supported by the server + + MARIADB_* flags supported only by MariaDB connector(s). +*/ +#define CLIENT_ALL_FLAGS (\ CLIENT_FOUND_ROWS | \ CLIENT_LONG_FLAG | \ CLIENT_CONNECT_WITH_DB | \ @@ -257,10 +270,11 @@ enum enum_server_command CLIENT_PS_MULTI_RESULTS | \ CLIENT_SSL_VERIFY_SERVER_CERT | \ CLIENT_REMEMBER_OPTIONS | \ - CLIENT_PROGRESS | \ + MARIADB_CLIENT_PROGRESS | \ CLIENT_PLUGIN_AUTH | \ CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | \ - CLIENT_CONNECT_ATTRS) + CLIENT_CONNECT_ATTRS |\ + MARIADB_CLIENT_COM_MULTI) /* To be added later: diff --git a/include/thread_pool_priv.h b/include/thread_pool_priv.h index 4270c32c826..afa2848ae88 100644 --- a/include/thread_pool_priv.h +++ b/include/thread_pool_priv.h @@ -100,8 +100,6 @@ bool thd_is_connection_alive(THD *thd); void close_connection(THD *thd, uint errcode); /* End the connection before closing it */ void end_connection(THD *thd); -/* Cleanup the THD object */ -void thd_cleanup(THD *thd); /* Decrement connection counter */ void dec_connection_count(); /* Destroy THD object */ diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index b233614fa1e..2577870bfa3 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -27,7 +27,7 @@ extern char * mysql_unix_port; When adding capabilities here, consider if they should be also added to the server's version. */ -#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | \ +#define CLIENT_CAPABILITIES (CLIENT_MYSQL | \ CLIENT_LONG_FLAG | \ CLIENT_TRANSACTIONS | \ CLIENT_PROTOCOL_41 | \ diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index d4df327930d..2081e7558d5 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -109,6 +109,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/table_cache.cc ../sql/mf_iocache_encr.cc ../sql/item_inetfunc.cc ../sql/wsrep_dummy.cc ../sql/encryption.cc + ../sql/sql_cte.cc ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 86a0676d97e..476981023fd 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -165,7 +165,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, arg_length= header_length; } - result= dispatch_command(command, thd, (char *) arg, arg_length); + result= dispatch_command(command, thd, (char *) arg, arg_length, FALSE, + FALSE); thd->cur_data= 0; thd->mysys_var= NULL; @@ -428,8 +429,8 @@ static void emb_free_embedded_thd(MYSQL *mysql) thread_count--; thd->store_globals(); thd->unlink(); - delete thd; mysql_mutex_unlock(&LOCK_thread_count); + delete thd; my_pthread_setspecific_ptr(THR_THD, 0); mysql->thd=0; } @@ -664,7 +665,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag) void *create_embedded_thd(int client_flag) { THD * thd= new THD; - thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; + thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id(); thd->thread_stack= (char*) &thd; if (thd->store_globals()) @@ -1029,7 +1030,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags) while ((item= it++)) { Send_field server_field; - item->make_field(&server_field); + item->make_field(thd, &server_field); /* Keep things compatible for old clients */ if (server_field.type == MYSQL_TYPE_VARCHAR) diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt index c4383b31a17..b99ea688d21 100644 --- a/man/CMakeLists.txt +++ b/man/CMakeLists.txt @@ -19,10 +19,10 @@ SET(MAN1_SERVER innochecksum.1 my_print_defaults.1 myisam_ftdump.1 myisamchk.1 mysql_convert_table_format.1 mysql_fix_extensions.1 mysql_install_db.1 mysql_secure_installation.1 mysql_setpermission.1 - mysql_tzinfo_to_sql.1 mysql_upgrade.1 mysql_zap.1 + mysql_tzinfo_to_sql.1 mysql_upgrade.1 mysqld_multi.1 mysqld_safe.1 mysqldumpslow.1 mysqlhotcopy.1 mysqltest.1 perror.1 replace.1 resolve_stack_dump.1 - resolveip.1 mysqlbug.1) + resolveip.1) SET(MAN8_SERVER mysqld.8) SET(MAN1_CLIENT msql2mysql.1 mysql.1 mysql_find_rows.1 mysql_waitpid.1 mysqlaccess.1 mysqladmin.1 mysqlbinlog.1 mysqlcheck.1 diff --git a/man/mysql_zap.1 b/man/mysql_zap.1 deleted file mode 100644 index ed9596cea45..00000000000 --- a/man/mysql_zap.1 +++ /dev/null @@ -1,123 +0,0 @@ -'\" t -.\" -.TH "\FBMYSQL_ZAP\FR" "1" "14/12/2015" "MariaDB 10\&.1" "MariaDB Database System" -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.\" mysql_zap -.SH "NAME" -mysql_zap \- kill processes that match a pattern -.SH "SYNOPSIS" -.HP \w'\fBmysql_zap\ [\-\fR\fB\fIsignal\fR\fR\fB]\ [\-?Ift]\ \fR\fB\fIpattern\fR\fR\ 'u -\fBmysql_zap [\-\fR\fB\fIsignal\fR\fR\fB] [\-?Ift] \fR\fB\fIpattern\fR\fR -.SH "DESCRIPTION" -.PP -\fBmysql_zap\fR -kills processes that match a pattern\&. It uses the -\fBps\fR -command and Unix signals, so it runs on Unix and Unix\-like systems\&. -.PP -Invoke -\fBmysql_zap\fR -like this: -.sp -.if n \{\ -.RS 4 -.\} -.nf -shell> \fBmysql_zap [\-\fR\fB\fIsignal\fR\fR\fB] [\-?Ift] \fR\fB\fIpattern\fR\fR -.fi -.if n \{\ -.RE -.\} -.PP -A process matches if its output line from the -\fBps\fR -command contains the pattern\&. By default, -\fBmysql_zap\fR -asks for confirmation for each process\&. Respond -y -to kill the process, or -q -to exit -\fBmysql_zap\fR\&. For any other response, -\fBmysql_zap\fR -does not attempt to kill the process\&. -.PP -If the -\fB\-\fR\fB\fIsignal\fR\fR -option is given, it specifies the name or number of the signal to send to each process\&. Otherwise, -\fBmysql_zap\fR -tries first with -TERM -(signal 15) and then with -KILL -(signal 9)\&. -.PP -\fBmysql_zap\fR -supports the following additional options: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -\fB\-\-help\fR, -\fB\-?\fR, -\fB\-I\fR -.sp -Display a help message and exit\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -\fB\-f\fR -.sp -Force mode\&. -\fBmysql_zap\fR -attempts to kill each process without confirmation\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -\fB\-t\fR -.sp -Test mode\&. Display information about each process but do not kill it\&. -.RE -.SH "COPYRIGHT" -.br -.PP -Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2015 MariaDB Foundation -.PP -This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. -.PP -This documentation 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. -.PP -You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or see http://www.gnu.org/licenses/. -.sp -.SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ -.SH AUTHOR -MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysqlbug.1 b/man/mysqlbug.1 deleted file mode 100644 index 76572150ac2..00000000000 --- a/man/mysqlbug.1 +++ /dev/null @@ -1,71 +0,0 @@ -'\" t -.\" -.TH "\FBMYSQLBUG\FR" "1" "14/12/2015" "MariaDB 10\&.1" "MariaDB Database System" -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.\" mysqlbug -.SH "NAME" -mysqlbug \- generate bug report -.SH "SYNOPSIS" -.HP \w'\fBmysqlbug\fR\ 'u -\fBmysqlbug\fR -.SH "DESCRIPTION" -.PP -To report MariaDB bugs, see https://mariadb.com/kb/en/mariadb/reporting-bugs/ - the mysqlbug program has now been deprecated by Oracle, and was never useful for MariaDB. - -Originally, the program enabled you to generate a bug report and send it to Oracle Corporation\&. It is a shell script and runs on Unix\&. -.PP -The normal way to report MySQL bugs is to visit -\m[blue]\fB\%http://bugs.mysql.com/\fR\m[], which is the address for MySQL's bugs database\&. This database is public and can be browsed and searched by anyone\&. If you log in to the system, you can enter new reports\&. If you have no Web access, you can generate a bug report by using the -\fBmysqlbug\fR -script\&. -.PP -\fBmysqlbug\fR -helps you generate a report by determining much of the following information automatically, but if something important is missing, please include it with your message\&. -\fBmysqlbug\fR -can be found in the -scripts -directory (source distribution) and in the -bin -directory under your MySQL installation directory (binary distribution)\&. -.PP -Invoke -\fBmysqlbug\fR -without arguments: -.sp -.if n \{\ -.RS 4 -.\} -.nf -shell> \fBmysqlbug\fR -.fi -.if n \{\ -.RE -.\} -.PP -The script will place you in an editor with a copy of the report to be sent\&. Edit the lines near the beginning that indicate the nature of the problem\&. Then write the file to save your changes, quit the editor, and -\fBmysqlbug\fR -will send the report by email\&. -.SH "COPYRIGHT" -.br -.PP -Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2015 MariaDB Foundation -.PP -This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. -.PP -This documentation 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. -.PP -You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or see http://www.gnu.org/licenses/. -.sp -.SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ -.SH AUTHOR -MariaDB Foundation (http://www.mariadb.org/). diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 8ccafec342b..7e5292c1a8e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2131,7 +2131,7 @@ sub mysqld_client_arguments () { sub have_maria_support () { - my $maria_var= $mysqld_variables{'aria-recover'}; + my $maria_var= $mysqld_variables{'aria-recover-options'}; return defined $maria_var; } diff --git a/mysql-test/r/alter_user.result b/mysql-test/r/alter_user.result new file mode 100644 index 00000000000..ac668bba8fa --- /dev/null +++ b/mysql-test/r/alter_user.result @@ -0,0 +1,93 @@ +select * from mysql.user where user = 'root' and host = 'localhost'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000 +# Test syntax +# +# These 2 selects should have no changes from the first one. +alter user CURRENT_USER; +select * from mysql.user where user = 'root' and host = 'localhost'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000 +alter user CURRENT_USER(); +select * from mysql.user where user = 'root' and host = 'localhost'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000 +create user foo; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo 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 N N 0.000000 +alter user foo; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo 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 N N 0.000000 +# Test super privilege works correctly with a read only database. +SET @start_read_only = @@global.read_only; +SET GLOBAL read_only=1; +grant create user on *.* to foo; +# Currently no super privileges. +connect a, localhost, foo; +select @@global.read_only; +@@global.read_only +1 +alter user foo; +ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement +# Grant super privilege to the user. +connection default; +grant super on *.* to foo; +# We now have super privilege. We should be able to run alter user. +connect b, localhost, foo; +alter user foo; +connection default; +SET GLOBAL read_only = @start_read_only; +# Test inexistant user. +alter user boo; +ERROR HY000: Operation ALTER USER failed for 'boo' +#--warning ER_CANNOT_USER +alter if exists user boo; +Warnings: +Error 1133 Can't find any matching row in the user table +Note 1396 Operation ALTER USER failed for 'boo' +# Test password related altering. +alter user foo identified by 'something'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 N N 0.000000 +alter user foo identified by 'something2'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *9CD58369E930E28C8996A89DB18B63294E6DC10C N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 N N 0.000000 +alter user foo identified by password '*88C89BE093D4ECF72D039F62EBB7477EA1FD4D63'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 N N 0.000000 +alter user foo identified with 'somecoolplugin'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 somecoolplugin N N 0.000000 +alter user foo identified with 'somecoolplugin' using 'somecoolpassphrase'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N 0 0 0 0 somecoolplugin somecoolpassphrase N N 0.000000 +# Test ssl related altering. +alter user foo identified by 'something' require SSL; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N ANY 0 0 0 0 N N 0.000000 +alter user foo identified by 'something' require X509; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N X509 0 0 0 0 N N 0.000000 +alter user foo identified by 'something' +require cipher 'text' issuer 'foo_issuer' subject 'foo_subject'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N SPECIFIED text foo_issuer foo_subject 0 0 0 0 N N 0.000000 +# Test resource limits altering. +alter user foo with MAX_QUERIES_PER_HOUR 10 +MAX_UPDATES_PER_HOUR 20 +MAX_CONNECTIONS_PER_HOUR 30 +MAX_USER_CONNECTIONS 40; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N SPECIFIED text foo_issuer foo_subject 10 20 30 40 N N 0.000000 +drop user foo; diff --git a/mysql-test/r/connect2.result b/mysql-test/r/connect2.result new file mode 100644 index 00000000000..eecb6455162 --- /dev/null +++ b/mysql-test/r/connect2.result @@ -0,0 +1,46 @@ +call mtr.add_suppression("Allocation failed"); +SET @old_debug= @@session.debug; +set @old_thread_cache_size=@@global.thread_cache_size; +select 1; +1 +1 +set global debug_dbug='+d,simulate_failed_connection_1'; +connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); +Got one of the listed errors +set global debug_dbug=@old_debug; +set global debug_dbug='+d,simulate_failed_connection_2'; +connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); +Got one of the listed errors +set global debug_dbug=@old_debug; +select 1; +1 +1 +select 1; +1 +1 +set global debug_dbug='+d,simulate_failed_connection_1'; +connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); +Got one of the listed errors +set global debug_dbug=@old_debug; +set global debug_dbug='+d,simulate_failed_connection_2'; +connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); +Got one of the listed errors +set global debug_dbug=@old_debug; +select 1; +1 +1 +set @@global.thread_cache_size=2; +select 1; +1 +1 +select 1; +1 +1 +set global debug_dbug='+d,simulate_failed_connection_2'; +connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); +Got one of the listed errors +show status like "Threads_connected"; +Variable_name Value +Threads_connected 1 +set global debug_dbug=@old_debug; +set global thread_cache_size=@old_thread_cache_size; diff --git a/mysql-test/r/create_user.result b/mysql-test/r/create_user.result new file mode 100644 index 00000000000..1411f2e8792 --- /dev/null +++ b/mysql-test/r/create_user.result @@ -0,0 +1,72 @@ +create user foo; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo 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 N N 0.000000 +drop user foo; +create user foo identified by 'password'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 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 N N 0.000000 +drop user foo; +create user foo identified by 'password' require SSL; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 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 ANY 0 0 0 0 N N 0.000000 +drop user foo; +create user foo identified by 'password' require X509; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 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 X509 0 0 0 0 N N 0.000000 +drop user foo; +create user foo identified by 'password' require CIPHER 'cipher'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 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 cipher 0 0 0 0 N N 0.000000 +drop user foo; +create user foo identified by 'password' require ISSUER 'issuer'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 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 issuer 0 0 0 0 N N 0.000000 +drop user foo; +create user foo identified by 'password' require SUBJECT 'subject'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 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 subject 0 0 0 0 N N 0.000000 +drop user foo; +create user foo identified by 'password' require CIPHER 'cipher' + SUBJECT 'subject'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 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 cipher subject 0 0 0 0 N N 0.000000 +drop user foo; +create user foo identified by 'password' require CIPHER 'cipher' +AND SUBJECT 'subject' + AND ISSUER 'issuer'; +select * from mysql.user where user = 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 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 cipher issuer subject 0 0 0 0 N N 0.000000 +drop user foo; +create user foo, foo2 identified by 'password' require CIPHER 'cipher' +AND SUBJECT 'subject' + AND ISSUER 'issuer'; +select * from mysql.user where user like 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo 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 cipher issuer subject 0 0 0 0 N N 0.000000 +#--warning ER_USER_CREATE_EXISTS +create user if not exists foo, foo2 identified by 'password2' + require CIPHER 'cipher2' AND SUBJECT 'subject2' AND ISSUER 'issuer2'; +Warnings: +Note 1973 Can't create user 'foo'@'%'; it already exists +Note 1973 Can't create user 'foo2'@'%'; it already exists +select * from mysql.user where user like 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo 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 cipher issuer subject 0 0 0 0 N N 0.000000 +drop user foo, foo2; +create user foo with MAX_QUERIES_PER_HOUR 10 +MAX_UPDATES_PER_HOUR 20 +MAX_CONNECTIONS_PER_HOUR 30 +MAX_USER_CONNECTIONS 40; +select * from mysql.user where user like 'foo'; +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 plugin authentication_string password_expired is_role default_role max_statement_time +% foo 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 40 N N 0.000000 +drop user foo; diff --git a/mysql-test/r/cte_grant.result b/mysql-test/r/cte_grant.result new file mode 100644 index 00000000000..4b067f42ff2 --- /dev/null +++ b/mysql-test/r/cte_grant.result @@ -0,0 +1,54 @@ +create database mysqltest; +create user mysqltest_1@localhost; +create table mysqltest.t1 (a int, b int); +insert into mysqltest.t1 values (2,10), (1,30); +create table mysqltest.t2 (c int, d char(32)); +insert into mysqltest.t2 values (1,'xxx'), (1,'zzz'); +grant select on mysqltest.t1 to mysqltest_1@localhost; +grant select (c) on mysqltest.t2 to mysqltest_1@localhost; +with t as (select c from mysqltest.t2 where c < 2) +select t.c,t1.b from t,mysqltest.t1 where t.c=t1.a; +c b +1 30 +1 30 +select t.c,t.d,t1.b +from (select c,d from mysqltest.t2 where c < 2) as t, mysqltest.t1 +where t.c=t1.a; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 't2' +with t as (select c,d from mysqltest.t2 where c < 2) +select t.c,t.d,t1.b from t,mysqltest.t1 where t.c=t1.a; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 't2' +create view mysqltest.v1(f1,f2) as +with t as (select c from mysqltest.t2 where c < 2) +select t.c,t1.b from t,mysqltest.t1 where t.c=t1.a; +create view mysqltest.v2(c,d) as +with t as (select a from mysqltest.t1 where a>=3) +select t.a,b from t,mysqltest.t1 where mysqltest.t1.a = t.a; +grant select on mysqltest.v1 to mysqltest_1@localhost; +grant select (c) on mysqltest.v2 to mysqltest_1@localhost; +grant create view on mysqltest.* to mysqltest_1@localhost; +create view mysqltest.v3(c,d) as +with t as (select c from mysqltest.t2 where c < 2) +select t.c,t1.b from t,mysqltest.t1 where t.c=t1.a; +create view mysqltest.v4(f1,f2,f3) as +with t as (select c,d from mysqltest.t2 where c < 2) +select t.c,t.d,t1.b from t,mysqltest.t1 where t.c=t1.a; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 't2' +select * from mysqltest.v1; +f1 f2 +1 30 +1 30 +select c from mysqltest.v2; +c +select d from mysqltest.v2; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'd' in table 'v2' +select * from mysqltest.v3; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v3' +grant select on mysqltest.v3 to mysqltest_1@localhost; +select * from mysqltest.v3; +c d +1 30 +1 30 +revoke all privileges on mysqltest.v1 from mysqltest_1@localhost; +drop user mysqltest_1@localhost; +drop database mysqltest; diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result new file mode 100644 index 00000000000..df641156e61 --- /dev/null +++ b/mysql-test/r/cte_nonrecursive.result @@ -0,0 +1,748 @@ +create table t1 (a int, b varchar(32)); +insert into t1 values +(4,'aaaa' ), (7,'bb'), (1,'ccc'), (4,'dd'); +insert into t1 values +(3,'eee'), (7,'bb'), (1,'fff'), (4,'ggg'); +create table t2 (c int); +insert into t2 values +(2), (4), (5), (3); +# select certain field in the specification of t +with t as (select a from t1 where b >= 'c') +select * from t2,t where t2.c=t.a; +c a +4 4 +3 3 +4 4 +select * from t2, (select a from t1 where b >= 'c') as t +where t2.c=t.a; +c a +4 4 +3 3 +4 4 +explain +with t as (select a from t1 where b >= 'c') +select * from t2,t where t2.c=t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +explain +select * from t2, (select a from t1 where b >= 'c') as t +where t2.c=t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# select '*' in the specification of t +with t as (select * from t1 where b >= 'c') +select * from t2,t where t2.c=t.a; +c a b +4 4 dd +3 3 eee +4 4 ggg +select * from t2, (select * from t1 where b >= 'c') as t +where t2.c=t.a; +c a b +4 4 dd +3 3 eee +4 4 ggg +explain +with t as (select * from t1 where b >= 'c') +select * from t2,t where t2.c=t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +explain +select * from t2, (select * from t1 where b >= 'c') as t +where t2.c=t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# rename fields returned by the specication when defining t +with t(f1,f2) as (select * from t1 where b >= 'c') +select * from t2,t where t2.c=t.f1; +c f1 f2 +4 4 dd +3 3 eee +4 4 ggg +explain +with t(f1,f2) as (select * from t1 where b >= 'c') +select * from t2,t where t2.c=t.f1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# materialized query specifying t +with t as (select a, count(*) from t1 where b >= 'c' group by a) +select * from t2,t where t2.c=t.a; +c a count(*) +4 4 2 +3 3 1 +select * from t2, (select a, count(*) from t1 where b >= 'c' group by a) as t +where t2.c=t.a; +c a count(*) +4 4 2 +3 3 1 +explain +with t as (select a, count(*) from t1 where b >= 'c' group by a) +select * from t2,t where t2.c=t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort +explain +select * from t2, (select a, count(*) from t1 where b >= 'c' group by a) as t +where t2.c=t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort +# specivication of t contains having +with t as (select a, count(*) from t1 where b >= 'c' + group by a having count(*)=1 ) +select * from t2,t where t2.c=t.a; +c a count(*) +3 3 1 +select * from t2, (select a, count(*) from t1 where b >= 'c' + group by a having count(*)=1) t +where t2.c=t.a; +c a count(*) +3 3 1 +# main query contains having +with t as (select * from t2 where c <= 4) +select a, count(*) from t1,t where t1.a=t.c group by a having count(*)=1; +a count(*) +3 1 +select a, count(*) from t1, (select * from t2 where c <= 4) t +where t1.a=t.c group by a having count(*)=1; +a count(*) +3 1 +# main query contains group by + order by +with t as (select * from t2 where c <= 4 ) +select a, count(*) from t1,t where t1.a=t.c group by a order by count(*); +a count(*) +3 1 +4 3 +select a, count(*) from t1, (select * from t2 where c <= 4 ) t +where t1.a=t.c group by a order by count(*); +a count(*) +3 1 +4 3 +# main query contains group by + order by + limit +with t as (select * from t2 where c <= 4 ) +select a, count(*) from t1,t +where t1.a=t.c group by a order by count(*) desc limit 1; +a count(*) +4 3 +select a, count(*) from t1, (select * from t2 where c <= 4 ) t +where t1.a=t.c group by a order by count(*) desc limit 1; +a count(*) +4 3 +# t is used in a subquery +with t as (select a from t1 where a<5) +select * from t2 where c in (select a from t); +c +4 +3 +select * from t2 +where c in (select a from (select a from t1 where a<5) as t); +c +4 +3 +explain +with t as (select a from t1 where a<5) +select * from t2 where c in (select a from t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +explain +select * from t2 +where c in (select a from (select a from t1 where a<5) as t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where +# materialized t is used in a subquery +with t as (select count(*) as c from t1 where b >= 'c' group by a) +select * from t2 where c in (select c from t); +c +2 +select * from t2 +where c in (select c from (select count(*) as c from t1 +where b >= 'c' group by a) as t); +c +2 +explain +with t as (select count(*) as c from t1 where b >= 'c' group by a) +select * from t2 where c in (select c from t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY <derived2> ref key0 key0 8 test.t2.c 2 Using where; FirstMatch(t2) +2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort +explain +select * from t2 +where c in (select c from (select count(*) as c from t1 +where b >= 'c' group by a) as t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY <derived3> ref key0 key0 8 test.t2.c 2 Using where; FirstMatch(t2) +3 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort +# two references to t specified by a query +# selecting a field: both in main query +with t as (select a from t1 where b >= 'c') +select * from t as r1, t as r2 where r1.a=r2.a; +a a +1 1 +1 1 +4 4 +4 4 +3 3 +1 1 +1 1 +4 4 +4 4 +select * from (select a from t1 where b >= 'c') as r1, +(select a from t1 where b >= 'c') as r2 +where r1.a=r2.a; +a a +1 1 +1 1 +4 4 +4 4 +3 3 +1 1 +1 1 +4 4 +4 4 +explain +with t as (select a from t1 where b >= 'c') +select * from t as r1, t as r2 where r1.a=r2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +explain +select * from (select a from t1 where b >= 'c') as r1, +(select a from t1 where b >= 'c') as r2 +where r1.a=r2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# two references to materialized t: both in main query +with t as (select distinct a from t1 where b >= 'c') +select * from t as r1, t as r2 where r1.a=r2.a; +a a +1 1 +4 4 +3 3 +select * from (select distinct a from t1 where b >= 'c') as r1, +(select distinct a from t1 where b >= 'c') as r2 +where r1.a=r2.a; +a a +1 1 +4 4 +3 3 +explain +with t as (select distinct a from t1 where b >= 'c') +select * from t as r1, t as r2 where r1.a=r2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <derived3> ref key0 key0 5 r1.a 2 +3 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary +2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary +explain +select * from (select distinct a from t1 where b >= 'c') as r1, +(select distinct a from t1 where b >= 'c') as r2 +where r1.a=r2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY <derived3> ref key0 key0 5 r1.a 2 +3 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary +2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary +# two references to t specified by a query +# selecting all fields: both in main query +with t as (select * from t1 where b >= 'c') +select * from t as r1, t as r2 where r1.a=r2.a; +a b a b +1 ccc 1 ccc +1 fff 1 ccc +4 dd 4 dd +4 ggg 4 dd +3 eee 3 eee +1 ccc 1 fff +1 fff 1 fff +4 dd 4 ggg +4 ggg 4 ggg +select * from (select * from t1 where b >= 'c') as r1, +(select * from t1 where b >= 'c') as r2 +where r1.a=r2.a; +a b a b +1 ccc 1 ccc +1 fff 1 ccc +4 dd 4 dd +4 ggg 4 dd +3 eee 3 eee +1 ccc 1 fff +1 fff 1 fff +4 dd 4 ggg +4 ggg 4 ggg +explain +with t as (select * from t1 where b >= 'c') +select * from t as r1, t as r2 where r1.a=r2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +explain +select * from (select * from t1 where b >= 'c') as r1, +(select * from t1 where b >= 'c') as r2 +where r1.a=r2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# two references to t specifying explicitly column names +with t(c) as (select a from t1 where b >= 'c') +select * from t r1, t r2 where r1.c=r2.c; +c c +1 1 +1 1 +4 4 +4 4 +3 3 +1 1 +1 1 +4 4 +4 4 +# specification of t contains union +with t as (select a from t1 where b >= 'f' +union +select c as a from t2 where c < 4) +select * from t2,t where t2.c=t.a; +c a +2 2 +4 4 +3 3 +select * from t2, +(select a from t1 where b >= 'f' +union +select c as a from t2 where c < 4) as t +where t2.c=t.a; +c a +2 2 +4 4 +3 3 +explain +with t as (select a from t1 where b >= 'f' +union +select c as a from t2 where c < 4) +select * from t2,t where t2.c=t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where +3 UNION t2 ALL NULL NULL NULL NULL 4 Using where +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +explain +select * from t2, +(select a from t1 where b >= 'f' +union +select c as a from t2 where c < 4) as t +where t2.c=t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where +3 UNION t2 ALL NULL NULL NULL NULL 4 Using where +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +# t is defined in the with clause of a subquery +select t1.a,t1.b from t1,t2 +where t1.a>t2.c and +t2.c in (with t as (select * from t1 where t1.a<5) +select t2.c from t2,t where t2.c=t.a); +a b +4 aaaa +7 bb +7 bb +4 dd +7 bb +7 bb +4 ggg +select t1.a,t1.b from t1,t2 +where t1.a>t2.c and +t2.c in (select t2.c +from t2,(select * from t1 where t1.a<5) as t +where t2.c=t.a); +a b +4 aaaa +7 bb +7 bb +4 dd +7 bb +7 bb +4 ggg +explain +select t1.a,t1.b from t1,t2 +where t1.a>t2.c and +t2.c in (with t as (select * from t1 where t1.a<5) +select t2.c from t2,t where t2.c=t.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +explain +select t1.a,t1.b from t1,t2 +where t1.a>t2.c and +t2.c in (select t2.c +from t2,(select * from t1 where t1.a<5) as t +where t2.c=t.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# two different definitions of t: one in the with clause of the main query, +# the other in the with clause of a subquery +with t as (select c from t2 where c >= 4) +select t1.a,t1.b from t1,t +where t1.a=t.c and +t.c in (with t as (select * from t1 where t1.a<5) +select t2.c from t2,t where t2.c=t.a); +a b +4 aaaa +4 dd +4 ggg +select t1.a,t1.b from t1, (select c from t2 where c >= 4) as t +where t1.a=t.c and +t.c in (select t2.c from t2, (select * from t1 where t1.a<5) as t +where t2.c=t.a); +a b +4 aaaa +4 dd +4 ggg +explain +with t as (select c from t2 where c >= 4) +select t1.a,t1.b from t1,t +where t1.a=t.c and +t.c in (with t as (select * from t1 where t1.a<5) +select t2.c from t2,t where t2.c=t.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +explain +select t1.a,t1.b from t1, (select c from t2 where c >= 4) as t +where t1.a=t.c and +t.c in (select t2.c from t2, (select * from t1 where t1.a<5) as t +where t2.c=t.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where +1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# another with table tt is defined in the with clause of a subquery +# from the specification of t +with t as (select * from t1 +where a>2 and +b in (with tt as (select * from t2 where t2.c<5) +select t1.b from t1,tt where t1.a=tt.c)) +select t.a, count(*) from t1,t where t1.a=t.a group by t.a; +a count(*) +3 1 +4 9 +select t.a, count(*) +from t1, +(select * from t1 +where a>2 and +b in (select t1.b +from t1, +(select * from t2 where t2.c<5) as tt +where t1.a=tt.c)) as t +where t1.a=t.a group by t.a; +a count(*) +3 1 +4 9 +explain +with t as (select * from t1 +where a>2 and +b in (with tt as (select * from t2 where t2.c<5) +select t1.b from t1,tt where t1.a=tt.c)) +select t.a, count(*) from t1,t where t1.a=t.a group by t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +explain +select t.a, count(*) +from t1, +(select * from t1 +where a>2 and +b in (select t1.b +from t1, +(select * from t2 where t2.c<5) as tt +where t1.a=tt.c)) as t +where t1.a=t.a group by t.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort +1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where +3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# with clause in the specification of a derived table +select * +from t1, +(with t as (select a from t1 where b >= 'c') +select * from t2,t where t2.c=t.a) as tt +where t1.b > 'f' and tt.a=t1.a; +a b c a +4 ggg 4 4 +4 ggg 4 4 +select * +from t1, +(select * from t2, +(select a from t1 where b >= 'c') as t +where t2.c=t.a) as tt +where t1.b > 'f' and tt.a=t1.a; +a b c a +4 ggg 4 4 +4 ggg 4 4 +explain +select * +from t1, +(with t as (select a from t1 where b >= 'c') +select * from t2,t where t2.c=t.a) as tt +where t1.b > 'f' and tt.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (incremental, BNL join) +explain +select * +from t1, +(select * from t2, +(select a from t1 where b >= 'c') as t +where t2.c=t.a) as tt +where t1.b > 'f' and tt.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (incremental, BNL join) +# with claused in the specification of a view +create view v1 as +with t as (select a from t1 where b >= 'c') +select * from t2,t where t2.c=t.a; +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 WITH t AS (select `t1`.`a` AS `a` from `t1` where (`t1`.`b` >= 'c'))select `t2`.`c` AS `c`,`t`.`a` AS `a` from (`t2` join `t`) where (`t2`.`c` = `t`.`a`) latin1 latin1_swedish_ci +select * from v1; +c a +4 4 +3 3 +4 4 +explain +select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 32 +2 DERIVED t2 ALL NULL NULL NULL NULL 4 +2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +# with claused in the specification of a materialized view +create view v2 as +with t as (select a, count(*) from t1 where b >= 'c' group by a) +select * from t2,t where t2.c=t.a; +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS WITH t AS (select `t1`.`a` AS `a`,count(0) AS `count(*)` from `t1` where (`t1`.`b` >= 'c') group by `t1`.`a`)select `t2`.`c` AS `c`,`t`.`a` AS `a`,`t`.`count(*)` AS `count(*)` from (`t2` join `t`) where (`t2`.`c` = `t`.`a`) latin1 latin1_swedish_ci +select * from v2; +c a count(*) +4 4 2 +3 3 1 +explain +select * from v2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8 +2 DERIVED t2 ALL NULL NULL NULL NULL 4 Using where +2 DERIVED <derived3> ref key0 key0 5 test.t2.c 2 +3 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort +# with clause in the specification of a view that whose definition +# table alias for a with table +create view v3 as +with t(c) as (select a from t1 where b >= 'c') +select * from t r1 where r1.c=4; +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 WITH t AS (select `t1`.`a` AS `c` from `t1` where (`t1`.`b` >= 'c'))select `r1`.`c` AS `c` from `t` `r1` where (`r1`.`c` = 4) latin1 latin1_swedish_ci +select * from v3; +c +4 +4 +# with clause in the specification of a view that whose definition +# two table aliases for for the same with table +create view v4(c,d) as +with t(c) as (select a from t1 where b >= 'c') +select * from t r1, t r2 where r1.c=r2.c and r2.c=4; +show create view v4; +View Create View character_set_client collation_connection +v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS WITH t AS (select `t1`.`a` AS `c` from `t1` where (`t1`.`b` >= 'c'))select `r1`.`c` AS `c`,`r2`.`c` AS `d` from (`t` `r1` join `t` `r2`) where ((`r1`.`c` = `r2`.`c`) and (`r2`.`c` = 4)) latin1 latin1_swedish_ci +select * from v4; +c d +4 4 +4 4 +4 4 +4 4 +explain +select * from v4; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 64 +2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +drop view v1,v2,v3,v4; +# currently any views containing with clause are not updatable +create view v1(a) as +with t as (select a from t1 where b >= 'c') +select t.a from t2,t where t2.c=t.a; +update v1 set a=0 where a > 4; +ERROR HY000: The target table v1 of the UPDATE is not updatable +drop view v1; +# prepare of a query containing a definition of a with table t +prepare stmt1 from " +with t as (select a from t1 where b >= 'c') + select * from t2,t where t2.c=t.a; +"; +execute stmt1; +c a +4 4 +3 3 +4 4 +execute stmt1; +c a +4 4 +3 3 +4 4 +deallocate prepare stmt1; +# prepare of a query containing a definition of a materialized t +prepare stmt1 from " +with t as (select a, count(*) from t1 where b >= 'c' group by a) + select * from t2,t where t2.c=t.a; +"; +execute stmt1; +c a count(*) +4 4 2 +3 3 1 +execute stmt1; +c a count(*) +4 4 2 +3 3 1 +deallocate prepare stmt1; +# prepare of a query containing two references to with table t +prepare stmt1 from " +with t as (select * from t1 where b >= 'c') + select * from t as r1, t as r2 where r1.a=r2.a; +"; +execute stmt1; +a b a b +1 ccc 1 ccc +1 fff 1 ccc +4 dd 4 dd +4 ggg 4 dd +3 eee 3 eee +1 ccc 1 fff +1 fff 1 fff +4 dd 4 ggg +4 ggg 4 ggg +execute stmt1; +a b a b +1 ccc 1 ccc +1 fff 1 ccc +4 dd 4 dd +4 ggg 4 dd +3 eee 3 eee +1 ccc 1 fff +1 fff 1 fff +4 dd 4 ggg +4 ggg 4 ggg +deallocate prepare stmt1; +with t(f) as (select * from t1 where b >= 'c') +select * from t2,t where t2.c=t.f1; +ERROR HY000: WITH column list and SELECT field list have different column counts +with t(f1,f1) as (select * from t1 where b >= 'c') +select * from t2,t where t2.c=t.f1; +ERROR 42S21: Duplicate column name 'f1' +with t as (select * from t2 where c>3), +t as (select a from t1 where a>2) +select * from t,t1 where t1.a=t.c; +ERROR HY000: Duplicate query name in WITH clause +with t as (select a from s where a<5), +s as (select a from t1 where b>='d') +select * from t,s where t.a=s.a; +ERROR HY000: The definition of the table 't' refers to the table 's' defined later in a non-recursive WITH clause +with recursive +t as (select a from s where a<5), +s as (select a from t1 where b>='d') +select * from t,s where t.a=s.a; +a a +4 4 +4 4 +3 3 +1 1 +4 4 +4 4 +with recursive t as (select * from s where a>2), +s as (select a from t1,r where t1.a>r.c), +r as (select c from t,t2 where t.a=t2.c) +select * from r where r.c<7; +ERROR HY000: Recursive queries in WITH clause are not supported yet +with t as (select * from s where a>2), +s as (select a from t1,r where t1.a>r.c), +r as (select c from t,t2 where t.a=t2.c) +select * from r where r.c<7; +ERROR HY000: Recursive queries in WITH clause are not supported yet +with t as (select * from t1 +where a in (select c from s where b<='ccc') and b>'b'), +s as (select * from t1,t2 +where t1.a=t2.c and t1.c in (select a from t where a<5)) +select * from s where s.b>'aaa'; +ERROR HY000: Recursive queries in WITH clause are not supported yet +with t as (select * from t1 where b>'aaa' and b <='d') +select t.b from t,t2 +where t.a=t2.c and +t2.c in (with s as (select t1.a from s,t1 where t1.a=s.a and t1.b<'c') +select * from s); +ERROR HY000: Recursive queries in WITH clause are not supported yet +#erroneous definition of unreferenced with table t +with t as (select count(*) from t1 where d>='f' group by a) +select t1.b from t2,t1 where t1.a = t2.c; +ERROR 42S22: Unknown column 'd' in 'where clause' +with t as (select count(*) from t1 where b>='f' group by a) +select t1.b from t2,t1 where t1.a = t2.c; +b +aaaa +dd +eee +ggg +#erroneous definition of s referring to unreferenced t +with t(d) as (select count(*) from t1 where b<='ccc' group by b), +s as (select * from t1 where a in (select t2.d from t2,t where t2.c=t.d)) +select t1.b from t1,t2 where t1.a=t2.c; +ERROR 42S22: Unknown column 't2.d' in 'field list' +with t(d) as (select count(*) from t1 where b<='ccc' group by b), +s as (select * from t1 where a in (select t2.c from t2,t where t2.c=t.c)) +select t1.b from t1,t2 where t1.a=t2.c; +ERROR 42S22: Unknown column 't.c' in 'where clause' +with t(d) as (select count(*) from t1 where b<='ccc' group by b), +s as (select * from t1 where a in (select t2.c from t2,t where t2.c=t.d)) +select t1.b from t1,t2 where t1.a=t2.c; +b +aaaa +dd +eee +ggg +#erroneous definition of unreferenced with table t +with t(f) as (select * from t1 where b >= 'c') +select t1.b from t2,t1 where t1.a = t2.c; +ERROR HY000: WITH column list and SELECT field list have different column counts +#erroneous definition of unreferenced with table t +with t(f1,f1) as (select * from t1 where b >= 'c') +select t1.b from t2,t1 where t1.a = t2.c; +ERROR 42S21: Duplicate column name 'f1' +drop table t1,t2; diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result index 2f7cb7156a4..08d87fa292d 100644 --- a/mysql-test/r/ctype_uca.result +++ b/mysql-test/r/ctype_uca.result @@ -13728,3 +13728,23 @@ SET NAMES utf8; # # End of MariaDB-10.1 tests # +# +# Start of MariaDB-10.2 tests +# +# +# MDEV-9407 Illegal mix of collation when using GROUP_CONCAT in a VIEW +# +SET NAMES utf8; +CREATE TABLE t1 (col1 VARCHAR(12) CHARACTER SET utf8 COLLATE utf8_unicode_ci); +INSERT INTO t1 VALUES ('a'),('b'); +CREATE VIEW v1 AS SELECT group_concat('f') AS col1; +SELECT col1 FROM v1 UNION SELECT col1 FROM t1; +col1 +f +a +b +DROP VIEW v1; +DROP TABLE t1; +# +# End of MariaDB-10.2 tests +# diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result index a42f5af114c..46d586ac29d 100644 --- a/mysql-test/r/explain_json.result +++ b/mysql-test/r/explain_json.result @@ -1543,3 +1543,43 @@ ANALYZE set optimizer_switch=@tmp_optimizer_switch; set join_cache_level=@tmp_join_cache_level; drop table t1,t2,t3,t4; +# +# MDEV-9652: EXPLAIN FORMAT=JSON should show outer_ref_cond +# +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int); +insert into t1 select a,a from t0; +explain format=json +select a, (select max(a) from t1 where t0.a<5 and t1.b<t0.a) from t0; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t0", + "access_type": "ALL", + "rows": 10, + "filtered": 100 + }, + "subqueries": [ + { + "expression_cache": { + "state": "uninitialized", + "query_block": { + "select_id": 2, + "outer_ref_condition": "(t0.a < 5)", + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 10, + "filtered": 100, + "attached_condition": "((t0.a < 5) and (t1.b < t0.a))" + } + } + } + } + ] + } +} +drop table t0,t1; diff --git a/mysql-test/r/greedy_optimizer.result b/mysql-test/r/greedy_optimizer.result index 74fe9980958..de9db45cb15 100644 --- a/mysql-test/r/greedy_optimizer.result +++ b/mysql-test/r/greedy_optimizer.result @@ -118,10 +118,10 @@ select @@optimizer_prune_level; 1 set optimizer_search_depth=63; Warnings: -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead +Warning 1292 Truncated incorrect optimizer_search_depth value: '63' select @@optimizer_search_depth; @@optimizer_search_depth -63 +62 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 @@ -133,7 +133,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 821.837037 +Last_query_cost 1693.637037 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c12 = t2.c21 and t2.c22 = t3.c31 and t3.c32 = t4.c41 and t4.c42 = t5.c51 and t5.c52 = t6.c61 and t6.c62 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 @@ -145,55 +145,55 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t6.c62 1 Using index show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 821.837037 +Last_query_cost 1693.637037 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 794.837037 +Last_query_cost 844.037037 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where -1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using index -1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using index -1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using index +1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 794.837037 +Last_query_cost 844.037037 explain select t1.c11 from t1, t2, t3, t4, t5, t6, t7 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 794.837037 +Last_query_cost 844.037037 explain select t1.c11 from t7, t6, t5, t4, t3, t2, t1 where t1.c11 = t2.c21 and t1.c12 = t3.c31 and t1.c13 = t4.c41 and t1.c14 = t5.c51 and t1.c15 = t6.c61 and t1.c16 = t7.c71 and t2.c22 = t3.c32 and t2.c23 = t4.c42 and t2.c24 = t5.c52 and t2.c25 = t6.c62 and t2.c26 = t7.c72 and t3.c33 = t4.c43 and t3.c34 = t5.c53 and t3.c35 = t6.c63 and t3.c36 = t7.c73 and t4.c42 = t5.c54 and t4.c43 = t6.c64 and t4.c44 = t7.c74 and t5.c52 = t6.c65 and t5.c53 = t7.c75 and t6.c62 = t7.c76; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 +1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where +1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.c12 1 Using where 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t5 eq_ref PRIMARY PRIMARY 4 test.t1.c14 1 Using where 1 SIMPLE t6 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t7 eq_ref PRIMARY PRIMARY 4 test.t1.c16 1 Using where show status like 'Last_query_cost'; Variable_name Value -Last_query_cost 794.837037 +Last_query_cost 844.037037 set optimizer_prune_level=0; select @@optimizer_prune_level; @@optimizer_prune_level diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 90d305fb384..d816b1acf92 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -4691,6 +4691,9 @@ FROM t1 LEFT JOIN (t2 LEFT OUTER JOIN t3 ON t2.b = t3.b) ON t2.a = t1.b WHERE t3.a BETWEEN 3 AND 11 OR t1.a <= t2.c; a +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'h' +Warning 1292 Truncated incorrect INTEGER value: 'j' SET SESSION optimizer_switch = 'outer_join_with_cache=off'; SET SESSION join_cache_level = DEFAULT; DROP TABLE t1,t2,t3; diff --git a/mysql-test/r/mdev375.result b/mysql-test/r/mdev375.result index 32580804686..426336e5939 100644 --- a/mysql-test/r/mdev375.result +++ b/mysql-test/r/mdev375.result @@ -10,5 +10,8 @@ ERROR HY000: Too many connections SELECT 0; 0 0 +show status like "Threads_connected"; +Variable_name Value +Threads_connected 3 SET GLOBAL log_warnings=default; SET GLOBAL max_connections=default; diff --git a/mysql-test/r/mysqlbinlog_raw_mode.result b/mysql-test/r/mysqlbinlog_raw_mode.result new file mode 100644 index 00000000000..b64a2148a82 --- /dev/null +++ b/mysql-test/r/mysqlbinlog_raw_mode.result @@ -0,0 +1,274 @@ +reset master; +set timestamp=1000000000; +drop table if exists t1; +CREATE TABLE t1 (c01 BIT); +INSERT INTO t1 VALUES (0); +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +CREATE TABLE t1 (c01 BIT(7)); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (4); +INSERT INTO t1 VALUES (8); +INSERT INTO t1 VALUES (16); +INSERT INTO t1 VALUES (32); +INSERT INTO t1 VALUES (64); +INSERT INTO t1 VALUES (127); +DELETE FROM t1 WHERE c01=127; +UPDATE t1 SET c01=15 WHERE c01=16; +DROP TABLE t1; +CREATE TABLE t1 (a BIT(20), b CHAR(2)); +INSERT INTO t1 VALUES (b'00010010010010001001', 'ab'); +DROP TABLE t1; +CREATE TABLE t1 (c02 BIT(64)); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (128); +INSERT INTO t1 VALUES (b'1111111111111111111111111111111111111111111111111111111111111111'); +DROP TABLE t1; +CREATE TABLE t1 (c03 TINYINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t1 VALUES (-128); +UPDATE t1 SET c03=2 WHERE c03=1; +DELETE FROM t1 WHERE c03=-128; +DROP TABLE t1; +CREATE TABLE t1 (c04 TINYINT UNSIGNED); +INSERT INTO t1 VALUES (128), (255); +UPDATE t1 SET c04=2 WHERE c04=1; +DELETE FROM t1 WHERE c04=255; +DROP TABLE t1; +CREATE TABLE t1 (c06 BOOL); +INSERT INTO t1 VALUES (TRUE); +DELETE FROM t1 WHERE c06=TRUE; +DROP TABLE t1; +CREATE TABLE t1 (c07 SMALLINT); +INSERT INTO t1 VALUES (1234); +DELETE FROM t1 WHERE c07=1234; +DROP TABLE t1; +CREATE TABLE t1 (c08 SMALLINT UNSIGNED); +INSERT INTO t1 VALUES (32768), (65535); +UPDATE t1 SET c08=2 WHERE c08=32768; +DELETE FROM t1 WHERE c08=65535; +DROP TABLE t1; +CREATE TABLE t1 (c10 MEDIUMINT); +INSERT INTO t1 VALUES (12345); +DELETE FROM t1 WHERE c10=12345; +DROP TABLE t1; +CREATE TABLE t1 (c11 MEDIUMINT UNSIGNED); +INSERT INTO t1 VALUES (8388608), (16777215); +UPDATE t1 SET c11=2 WHERE c11=8388608; +DELETE FROM t1 WHERE c11=16777215; +DROP TABLE t1; +CREATE TABLE t1 (c13 INT); +INSERT INTO t1 VALUES (123456); +DELETE FROM t1 WHERE c13=123456; +DROP TABLE t1; +CREATE TABLE t1 (c14 INT UNSIGNED); +INSERT INTO t1 VALUES (2147483648), (4294967295); +UPDATE t1 SET c14=2 WHERE c14=2147483648; +DELETE FROM t1 WHERE c14=4294967295; +DROP TABLE t1; +CREATE TABLE t1 (c16 BIGINT); +INSERT INTO t1 VALUES (1234567890); +DELETE FROM t1 WHERE c16=1234567890; +DROP TABLE t1; +CREATE TABLE t1 (c17 BIGINT UNSIGNED); +INSERT INTO t1 VALUES (9223372036854775808), (18446744073709551615); +UPDATE t1 SET c17=2 WHERE c17=9223372036854775808; +DELETE FROM t1 WHERE c17=18446744073709551615; +DROP TABLE t1; +CREATE TABLE t1 (c19 FLOAT); +INSERT INTO t1 VALUES (123.2234); +DELETE FROM t1 WHERE c19>123; +DROP TABLE t1; +CREATE TABLE t1 (c22 DOUBLE); +INSERT INTO t1 VALUES (123434.22344545); +DELETE FROM t1 WHERE c22>123434; +DROP TABLE t1; +CREATE TABLE t1 (c25 DECIMAL(10,5)); +INSERT INTO t1 VALUES (124.45); +INSERT INTO t1 VALUES (-543.21); +DELETE FROM t1 WHERE c25=124.45; +DROP TABLE t1; +CREATE TABLE t1 (c28 DATE); +INSERT INTO t1 VALUES ('2001-02-03'); +DELETE FROM t1 WHERE c28='2001-02-03'; +DROP TABLE t1; +CREATE TABLE t1 (c29 DATETIME); +INSERT INTO t1 VALUES ('2001-02-03 10:20:30'); +DELETE FROM t1 WHERE c29='2001-02-03 10:20:30'; +DROP TABLE t1; +CREATE TABLE t1 (c30 TIMESTAMP); +INSERT INTO t1 VALUES ('2001-02-03 10:20:30'); +DELETE FROM t1 WHERE c30='2001-02-03 10:20:30'; +DROP TABLE t1; +CREATE TABLE t1 (c31 TIME); +INSERT INTO t1 VALUES ('11:22:33'); +DELETE FROM t1 WHERE c31='11:22:33'; +DROP TABLE t1; +CREATE TABLE t1 (c32 YEAR); +INSERT INTO t1 VALUES ('2001'); +DELETE FROM t1 WHERE c32=2001; +DROP TABLE t1; +CREATE TABLE t1 (c33 CHAR); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c33='a'; +DROP TABLE t1; +CREATE TABLE t1 (c34 CHAR(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c34=''; +DROP TABLE t1; +CREATE TABLE t1 (c35 CHAR(1)); +INSERT INTO t1 VALUES ('b'); +DELETE FROM t1 WHERE c35='b'; +DROP TABLE t1; +CREATE TABLE t1 (c36 CHAR(255)); +INSERT INTO t1 VALUES (repeat('c',255)); +DELETE FROM t1 WHERE c36>'c'; +DROP TABLE t1; +CREATE TABLE t1 (c37 NATIONAL CHAR); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c37='a'; +DROP TABLE t1; +CREATE TABLE t1 (c38 NATIONAL CHAR(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c38=''; +DROP TABLE t1; +CREATE TABLE t1 (c39 NATIONAL CHAR(1)); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c39='a'; +DROP TABLE t1; +CREATE TABLE t1 (c40 NATIONAL CHAR(255)); +INSERT INTO t1 VALUES (repeat('a', 255)); +INSERT INTO t1 VALUES (repeat(_latin1 0xDF, 255)); +DELETE FROM t1 WHERE c40>'a'; +DROP TABLE t1; +CREATE TABLE t1 (c45 VARCHAR(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c45=''; +DROP TABLE t1; +CREATE TABLE t1 (c46 VARCHAR(1)); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c46='a'; +DROP TABLE t1; +CREATE TABLE t1 (c47 VARCHAR(255)); +INSERT INTO t1 VALUES (repeat('a',255)); +DELETE FROM t1 WHERE c47>'a'; +DROP TABLE t1; +CREATE TABLE t1 (c48 VARCHAR(261)); +INSERT INTO t1 VALUES (repeat('a',261)); +DELETE FROM t1 WHERE c48>'a'; +DROP TABLE t1; +CREATE TABLE t1 (c49 NATIONAL VARCHAR(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c49=''; +DROP TABLE t1; +CREATE TABLE t1 (c50 NATIONAL VARCHAR(1)); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c50='a'; +DROP TABLE t1; +CREATE TABLE t1 (c51 NATIONAL VARCHAR(255)); +INSERT INTO t1 VALUES (repeat('a',255)); +INSERT INTO t1 VALUES (repeat(_latin1 0xDF, 255)); +DELETE FROM t1 WHERE c51>'a'; +DROP TABLE t1; +CREATE TABLE t1 (c52 NATIONAL VARCHAR(261)); +INSERT INTO t1 VALUES (repeat('a',261)); +INSERT INTO t1 VALUES (repeat(_latin1 0xDF, 261)); +DELETE FROM t1 WHERE c52>'a'; +DROP TABLE t1; +CREATE TABLE t1 (c57 BINARY); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c57='a'; +DROP TABLE t1; +CREATE TABLE t1 (c58 BINARY(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c58=''; +DROP TABLE t1; +CREATE TABLE t1 (c59 BINARY(1)); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c59='a'; +DROP TABLE t1; +CREATE TABLE t1 (c60 BINARY(255)); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES (repeat('a\0',120)); +DELETE FROM t1 WHERE c60<0x02; +DROP TABLE t1; +CREATE TABLE t1 (c61 VARBINARY(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c61=''; +DROP TABLE t1; +CREATE TABLE t1 (c62 VARBINARY(1)); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c62=0x02; +DROP TABLE t1; +CREATE TABLE t1 (c63 VARBINARY(255)); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES (repeat('a\0',120)); +DELETE FROM t1 WHERE c63=0x02; +DROP TABLE t1; +flush logs; +CREATE TABLE t1 (c65 TINYBLOB); +INSERT INTO t1 VALUES ('tinyblob1'); +DELETE FROM t1 WHERE c65='tinyblob1'; +DROP TABLE t1; +CREATE TABLE t1 (c68 BLOB); +INSERT INTO t1 VALUES ('blob1'); +DELETE FROM t1 WHERE c68='blob1'; +DROP TABLE t1; +CREATE TABLE t1 (c71 MEDIUMBLOB); +INSERT INTO t1 VALUES ('mediumblob1'); +DELETE FROM t1 WHERE c71='mediumblob1'; +DROP TABLE t1; +CREATE TABLE t1 (c74 LONGBLOB); +INSERT INTO t1 VALUES ('longblob1'); +DELETE FROM t1 WHERE c74='longblob1'; +DROP TABLE t1; +CREATE TABLE t1 (c66 TINYTEXT); +INSERT INTO t1 VALUES ('tinytext1'); +DELETE FROM t1 WHERE c66='tinytext1'; +DROP TABLE t1; +CREATE TABLE t1 (c69 TEXT); +INSERT INTO t1 VALUES ('text1'); +DELETE FROM t1 WHERE c69='text1'; +DROP TABLE t1; +CREATE TABLE t1 (c72 MEDIUMTEXT); +INSERT INTO t1 VALUES ('mediumtext1'); +DELETE FROM t1 WHERE c72='mediumtext1'; +DROP TABLE t1; +CREATE TABLE t1 (c75 LONGTEXT); +INSERT INTO t1 VALUES ('longtext1'); +DELETE FROM t1 WHERE c75='longtext1'; +DROP TABLE t1; +CREATE TABLE t1 (c77 ENUM('a','b','c')); +INSERT INTO t1 VALUES ('b'); +DELETE FROM t1 WHERE c77='b'; +DROP TABLE t1; +CREATE TABLE t1 (c78 SET('a','b','c','d','e','f')); +INSERT INTO t1 VALUES ('a,b'); +INSERT INTO t1 VALUES ('a,c'); +INSERT INTO t1 VALUES ('b,c'); +INSERT INTO t1 VALUES ('a,b,c'); +INSERT INTO t1 VALUES ('a,b,c,d'); +INSERT INTO t1 VALUES ('a,b,c,d,e'); +INSERT INTO t1 VALUES ('a,b,c,d,e,f'); +DELETE FROM t1 WHERE c78='a,b'; +DROP TABLE t1; +CREATE TABLE t1 (a int NOT NULL DEFAULT 0, b int NOT NULL DEFAULT 0); +CREATE TABLE t2 (a int NOT NULL DEFAULT 0, b int NOT NULL DEFAULT 0); +INSERT INTO t1 SET a=1; +INSERT INTO t1 SET b=1; +INSERT INTO t2 SET a=1; +INSERT INTO t2 SET b=1; +UPDATE t1, t2 SET t1.a=10, t2.a=20; +DROP TABLE t1,t2; +flush logs; +End of tests diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index bef03904a72..a35693eb93e 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -559,10 +559,7 @@ The following options may be given as the first argument: a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will - automatically pick a reasonable value; if set to 63, the - optimizer will switch to the original find_best search. - NOTE: The value 63 and its associated behaviour is - deprecated + automatically pick a reasonable value --optimizer-selectivity-sampling-limit=# Controls number of record samples to check condition selectivity @@ -977,6 +974,8 @@ The following options may be given as the first argument: replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave + --slave-parallel-workers=# + Alias for slave_parallel_threads --slave-run-triggers-for-rbr=name Modes for how triggers in row-base replication on slave side will be executed. Legal values are NO (default), YES @@ -1069,7 +1068,8 @@ The following options may be given as the first argument: Decision to use in heuristic recover process. One of: COMMIT, ROLLBACK --thread-cache-size=# - How many threads we should keep in a cache for reuse + How many threads we should keep in a cache for reuse. + These are freed after 5 minutes of idle time --thread-pool-idle-timeout=# Timeout in seconds for an idle thread in the thread pool.Worker thread will be shut down after timeout @@ -1127,7 +1127,8 @@ The following options may be given as the first argument: CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS tables in the INFORMATION_SCHEMA -v, --verbose Used with --help option for detailed help. - -V, --version Output version information and exit. + -V, --version[=name] + Output version information and exit. --wait-timeout=# The number of seconds the server waits for activity on a connection before closing it @@ -1340,7 +1341,7 @@ performance-schema-max-rwlock-instances -1 performance-schema-max-socket-classes 10 performance-schema-max-socket-instances -1 performance-schema-max-stage-classes 150 -performance-schema-max-statement-classes 178 +performance-schema-max-statement-classes 181 performance-schema-max-table-handles -1 performance-schema-max-table-instances -1 performance-schema-max-thread-classes 50 @@ -1402,6 +1403,7 @@ slave-net-timeout 3600 slave-parallel-max-queued 131072 slave-parallel-mode conservative slave-parallel-threads 0 +slave-parallel-workers 0 slave-run-triggers-for-rbr NO slave-skip-errors (No default value) slave-sql-verify-checksum TRUE @@ -1425,12 +1427,12 @@ table-cache 431 table-definition-cache 400 table-open-cache 431 tc-heuristic-recover COMMIT -thread-cache-size 0 +thread-cache-size 151 thread-pool-idle-timeout 60 thread-pool-max-threads 1000 thread-pool-oversubscribe 3 thread-pool-stall-limit 500 -thread-stack 295936 +thread-stack 296960 time-format %H:%i:%s timed-mutexes FALSE tmp-table-size 16777216 diff --git a/mysql-test/r/show_create_user.result b/mysql-test/r/show_create_user.result new file mode 100644 index 00000000000..63013eca074 --- /dev/null +++ b/mysql-test/r/show_create_user.result @@ -0,0 +1,39 @@ +create user foo; +show create user foo; +CREATE USER for foo@% +CREATE USER 'foo'@'%' +create user foo@test; +show create user foo@test; +CREATE USER for foo@test +CREATE USER 'foo'@'test' +create user foo2@test identified by 'password'; +show create user foo2@test; +CREATE USER for foo2@test +CREATE USER 'foo2'@'test' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' +alter user foo2@test identified with 'someplugin' as 'somepassword'; +show create user foo2@test; +CREATE USER for foo2@test +CREATE USER 'foo2'@'test' IDENTIFIED VIA someplugin USING 'somepassword' +create user foo3@test require SSL; +show create user foo3@test; +CREATE USER for foo3@test +CREATE USER 'foo3'@'test' REQUIRE SSL +create user foo4@test require cipher 'text' issuer 'foo_issuer' subject 'foo_subject'; +show create user foo4@test; +CREATE USER for foo4@test +CREATE USER 'foo4'@'test' REQUIRE ISSUER 'foo_issuer' SUBJECT 'foo_subject' CIPHER 'text' +create user foo5@test require SSL +with MAX_QUERIES_PER_HOUR 10 +MAX_UPDATES_PER_HOUR 20 +MAX_CONNECTIONS_PER_HOUR 30 +MAX_USER_CONNECTIONS 40 +MAX_STATEMENT_TIME 0.5; +show create user foo5@test; +CREATE USER for foo5@test +CREATE USER 'foo5'@'test' REQUIRE SSL WITH MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 20 MAX_CONNECTIONS_PER_HOUR 30 MAX_USER_CONNECTIONS 40 MAX_STATEMENT_TIME 0.500000 +drop user foo5@test; +drop user foo4@test; +drop user foo3@test; +drop user foo2@test; +drop user foo@test; +drop user foo; diff --git a/mysql-test/r/shutdown.result b/mysql-test/r/shutdown.result index 7039afb129e..748d8ec16a6 100644 --- a/mysql-test/r/shutdown.result +++ b/mysql-test/r/shutdown.result @@ -5,3 +5,7 @@ create procedure try_shutdown() shutdown; drop procedure try_shutdown; shutdown; drop user user1@localhost; +# +# MDEV-8491 - On shutdown, report the user and the host executed that. +# +FOUND /mysqld(\.exe)? \(root\[root\] @ localhost \[(::1)?\]\): Normal shutdown/ in mysqld.1.err diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 1f38e3888a0..c56597e6e44 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -779,7 +779,7 @@ drop procedure bug11394| CREATE PROCEDURE BUG_12490() HELP CONTENTS; ERROR 0A000: HELP is not allowed in stored procedures CREATE FUNCTION BUG_12490() RETURNS INT HELP CONTENTS; -ERROR 0A000: HELP is not allowed in stored procedures +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'HELP CONTENTS' at line 1 CREATE TABLE t_bug_12490(a int); CREATE TRIGGER BUG_12490 BEFORE UPDATE ON t_bug_12490 FOR EACH ROW HELP CONTENTS; ERROR 0A000: HELP is not allowed in stored procedures diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 24d9f0de35a..906f6a2f083 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -1294,7 +1294,7 @@ id select_type table type possible_keys key key_len ref rows Extra set @save_optimizer_search_depth=@@optimizer_search_depth; set @@optimizer_search_depth=63; Warnings: -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead +Warning 1292 Truncated incorrect optimizer_search_depth value: '63' explain select * from t1 where (a,b) in (select a,b from t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 10 diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result index 19d3d25148f..7cea1cadddd 100644 --- a/mysql-test/r/subselect3_jcl6.result +++ b/mysql-test/r/subselect3_jcl6.result @@ -1304,7 +1304,7 @@ id select_type table type possible_keys key key_len ref rows Extra set @save_optimizer_search_depth=@@optimizer_search_depth; set @@optimizer_search_depth=63; Warnings: -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead +Warning 1292 Truncated incorrect optimizer_search_depth value: '63' explain select * from t1 where (a,b) in (select a,b from t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result index 21d97b3faea..98a8907f741 100644 --- a/mysql-test/r/subselect_sj2.result +++ b/mysql-test/r/subselect_sj2.result @@ -937,6 +937,8 @@ SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); a b c +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'x' DROP TABLE t1, t2; # # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result index eb91fe6d61b..1b8c1fc1158 100644 --- a/mysql-test/r/subselect_sj2_jcl6.result +++ b/mysql-test/r/subselect_sj2_jcl6.result @@ -952,6 +952,8 @@ SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); a b c +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'x' DROP TABLE t1, t2; # # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index 16e8f88168d..ac38e57d60a 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -939,6 +939,8 @@ SELECT d FROM t2, t1 WHERE a = d AND ( pk < 2 OR d = 'z' ) ); a b c +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'x' DROP TABLE t1, t2; # # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 16990c2414d..bf3b6a6b7da 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -1140,3 +1140,54 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9337 ALTER from DECIMAL and INT to DATETIME returns a wrong result +# +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES (1000); +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1000); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1000); +ALTER TABLE t1 MODIFY a DATETIME; +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES (1000.0); +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a DATETIME); +CREATE TABLE t2 (a DECIMAL(4,0)); +INSERT INTO t2 VALUES (1000); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1,t2; +CREATE TABLE t1 (a DECIMAL(4,0)); +INSERT INTO t1 VALUES (1000); +ALTER TABLE t1 MODIFY a DATETIME; +SELECT * FROM t1; +a +2000-10-00 00:00:00 +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index d901434fd6e..f0152d08c32 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -2134,3 +2134,84 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# MDEV-9340 Copying from INT/DOUBLE to ENUM is inconsistent +# +CREATE TABLE t1 (a ENUM('9e200','9e100')); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES ('9e100'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (9e100); +ALTER TABLE t1 MODIFY a ENUM('9e200','9e100'); +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '9e100' +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1; +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES ('200'); +ALTER TABLE t1 MODIFY a ENUM('200','100'); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT *FROM t1; +a + +DROP TABLE t1; +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a ENUM('2001','2002')); +CREATE TABLE t2 (a YEAR); +INSERT INTO t2 VALUES ('2001'); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1,t2; +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES ('2001'); +ALTER TABLE t1 MODIFY a ENUM('2001','2002'); +Warnings: +Warning 1265 Data truncated for column 'a' at row 1 +SELECT * FROM t1; +a + +DROP TABLE t1; diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index e7267f012ae..e6f02d50f4c 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -638,3 +638,90 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-4102 Limitation on DOUBLE or REAL length is ignored with INSERT .. SELECT +# +CREATE TABLE t1 (d1 DOUBLE(5,2), d2 DOUBLE(10,2)); +INSERT INTO t1 VALUES (10000000.55, 10000000.55); +Warnings: +Warning 1264 Out of range value for column 'd1' at row 1 +INSERT INTO t1 SELECT d2, d2 FROM t1; +Warnings: +Warning 1264 Out of range value for column 'd1' at row 1 +SELECT * FROM t1; +d1 d2 +999.99 10000000.55 +999.99 10000000.55 +DROP TABLE t1; +# +# MDEV-9709 Unexpected modification of value and warning about out of range value upon ALTER +# +CREATE TABLE t1 ( +f FLOAT, +d10_10 DOUBLE PRECISION (10,10), +d53_10 DOUBLE(53,10) +); +INSERT INTO t1 (f,d10_10,d53_10) VALUES ( +-9999999999999999999999999999999999999999999.9999999999, +-9999999999999999999999999999999999999999999.9999999999, +-9999999999999999999999999999999999999999999.9999999999 +); +Warnings: +Warning 1264 Out of range value for column 'f' at row 1 +Warning 1264 Out of range value for column 'd10_10' at row 1 +SELECT * FROM t1; +f -3.40282e38 +d10_10 -0.9999999999 +d53_10 -10000000000000000000000000000000000000000000.0000000000 +INSERT INTO t1 (f,d10_10,d53_10) SELECT d53_10, d53_10, d53_10 FROM t1; +Warnings: +Level Warning +Code 1264 +Message Out of range value for column 'f' at row 1 +Level Warning +Code 1264 +Message Out of range value for column 'd10_10' at row 1 +SELECT * FROM t1; +f -3.40282e38 +d10_10 -0.9999999999 +d53_10 -10000000000000000000000000000000000000000000.0000000000 +f -3.40282e38 +d10_10 -0.9999999999 +d53_10 -10000000000000000000000000000000000000000000.0000000000 +ALTER TABLE t1 ADD COLUMN i INT; +SELECT * FROM t1; +f -3.40282e38 +d10_10 -0.9999999999 +d53_10 -10000000000000000000000000000000000000000000.0000000000 +i NULL +f -3.40282e38 +d10_10 -0.9999999999 +d53_10 -10000000000000000000000000000000000000000000.0000000000 +i NULL +DROP TABLE t1; +CREATE TABLE t1 (d10_10 DOUBLE (10,10)); +CREATE TABLE t2 (d53_10 DOUBLE (53,10)); +INSERT INTO t2 VALUES (-9999999999999999999999999999999999999999999.9999999999); +INSERT INTO t1 (d10_10) SELECT d53_10 FROM t2; +Warnings: +Warning 1264 Out of range value for column 'd10_10' at row 1 +SELECT * FROM t1; +d10_10 +-0.9999999999 +DROP TABLE t1,t2; +CREATE TABLE t1 (d2_2 FLOAT (2,2)); +CREATE TABLE t2 (d4_2 FLOAT (4,2)); +INSERT INTO t2 VALUES (99.99); +INSERT INTO t1 (d2_2) SELECT d4_2 FROM t2; +Warnings: +Warning 1264 Out of range value for column 'd2_2' at row 1 +SELECT * FROM t1; +d2_2 +0.99 +DROP TABLE t1,t2; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_int.result b/mysql-test/r/type_int.result index 4e7b928ac07..530a4134f4a 100644 --- a/mysql-test/r/type_int.result +++ b/mysql-test/r/type_int.result @@ -36,3 +36,60 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10.1),(10.9); +SELECT * FROM t1; +a +10 +11 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a DECIMAL(10,2)); +INSERT INTO t2 VALUES (10.1),(10.9); +INSERT INTO t1 SELECT a FROM t2; +SELECT * FROM t1; +a +10 +11 +DROP TABLE t1,t2; +CREATE TABLE t1 (a DECIMAL(10,2)); +INSERT INTO t1 VALUES (10.1),(10.9); +ALTER TABLE t1 MODIFY a INT; +SELECT * FROM t1; +a +10 +11 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (TIME'00:00:10.1'),(TIME'00:00:10.9'); +SELECT * FROM t1; +a +10 +10 +DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a TIME(1)); +INSERT INTO t2 VALUES (10.1),(10.9); +INSERT INTO t1 SELECT a FROM t2; +SELECT * FROM t1; +a +10 +10 +DROP TABLE t1,t2; +CREATE TABLE t1 (a TIME(1)); +INSERT INTO t1 VALUES (10.1),(10.9); +ALTER TABLE t1 MODIFY a INT; +SELECT * FROM t1; +a +10 +10 +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_num_innodb.result b/mysql-test/r/type_num_innodb.result new file mode 100644 index 00000000000..581a387b2e8 --- /dev/null +++ b/mysql-test/r/type_num_innodb.result @@ -0,0 +1,107 @@ +# +# Start of 10.2 tests +# +# +# MDEV-9391 InnoDB does not produce warnings when doing WHERE int_column=varchar_column +# +CREATE TABLE t1 ( +a DOUBLE, b VARCHAR(1), c INT, +KEY(a), KEY(b) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5), +(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9), +(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4), +(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0); +CREATE TABLE t2 ( +pk INT, d VARCHAR(1), e INT, +PRIMARY KEY(pk), KEY(d,e) +) ENGINE=InnoDB; +INSERT INTO t2 VALUES +(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5), +(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), +(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), +(15,'g',6),(16,'x',7),(17,'f',8); +SELECT * FROM t1,t2 WHERE a=d; +a b c pk d e +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'k' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'o' +Warning 1292 Truncated incorrect DOUBLE value: 'q' +Warning 1292 Truncated incorrect DOUBLE value: 'r' +Warning 1292 Truncated incorrect DOUBLE value: 'u' +Warning 1292 Truncated incorrect DOUBLE value: 'w' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'y' +ALTER TABLE t1 MODIFY a DECIMAL(10,0); +SELECT * FROM t1,t2 WHERE a=d; +a b c pk d e +Warnings: +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'g' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'k' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'o' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'q' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'r' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'u' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'w' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'x' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'x' +Warning 1918 Encountered illegal value '' when converting to DECIMAL +Warning 1292 Truncated incorrect DECIMAL value: 'y' +ALTER TABLE t1 MODIFY a DOUBLE; +SELECT * FROM t1,t2 WHERE a=d; +a b c pk d e +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'd' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'f' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'k' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'm' +Warning 1292 Truncated incorrect DOUBLE value: 'o' +Warning 1292 Truncated incorrect DOUBLE value: 'q' +Warning 1292 Truncated incorrect DOUBLE value: 'r' +Warning 1292 Truncated incorrect DOUBLE value: 'u' +Warning 1292 Truncated incorrect DOUBLE value: 'w' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'y' +DROP TABLE t1,t2; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index b5689d31aef..e4525f34ab4 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -1217,3 +1217,32 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field +# +CREATE TABLE t1 (a YEAR, b TIME, c YEAR); +CREATE TABLE t2 (a YEAR); +INSERT INTO t2 VALUES (0),(1999),(2000),(2030),(2050),(2070); +INSERT INTO t1 (a,b,c) SELECT a,a,a FROM t2; +Warnings: +Warning 1265 Data truncated for column 'b' at row 2 +Warning 1265 Data truncated for column 'b' at row 6 +ALTER TABLE t1 MODIFY c TIME; +Warnings: +Warning 1265 Data truncated for column 'c' at row 2 +Warning 1265 Data truncated for column 'c' at row 6 +SELECT * FROM t1; +a b c +0000 00:00:00 00:00:00 +1999 00:00:00 00:00:00 +2000 00:20:00 00:20:00 +2030 00:20:30 00:20:30 +2050 00:20:50 00:20:50 +2070 00:00:00 00:00:00 +DROP TABLE t1,t2; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result index 842a16e3b4a..4d28a7b8d25 100644 --- a/mysql-test/r/type_year.result +++ b/mysql-test/r/type_year.result @@ -438,3 +438,48 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9392 Copying from DECIMAL to YEAR is not consistent about warnings +# +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES (-0.1); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1; +CREATE TABLE t1 (a YEAR); +CREATE TABLE t2 (a DECIMAL(10,1)); +INSERT INTO t2 VALUES (-0.1); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1,t2; +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (-0.1); +ALTER TABLE t1 MODIFY a YEAR; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1; +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES (-0.1e0); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1; +CREATE TABLE t1 (a YEAR); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES (-0.1); +INSERT INTO t1 SELECT * FROM t2; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1,t2; +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (-0.1); +ALTER TABLE t1 MODIFY a YEAR; +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index d4a2a9b1b79..4a295762530 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5905,3 +5905,39 @@ drop table t1; # # End of 10.1 tests # +# +# Start of 10.2 tests +# +# +# MDEV-9408 CREATE TABLE SELECT MAX(int_column) creates different columns for table vs view +# +CREATE TABLE t1 ( +id int(11) NOT NULL PRIMARY KEY, +country varchar(32), +code int(11) default NULL +); +INSERT INTO t1 VALUES (1,'ITALY',100),(2,'ITALY',200),(3,'FRANCE',100), (4,'ITALY',100); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 AS +SELECT code, COUNT(DISTINCT country), MAX(id) FROM t1 GROUP BY code ORDER BY MAX(id); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `code` int(11) DEFAULT NULL, + `COUNT(DISTINCT country)` bigint(21) NOT NULL, + `MAX(id)` int(11) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +CREATE TABLE t3 AS +SELECT code, COUNT(DISTINCT country), MAX(id) FROM v1 GROUP BY code ORDER BY MAX(id); +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `code` int(11) DEFAULT NULL, + `COUNT(DISTINCT country)` bigint(21) NOT NULL, + `MAX(id)` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP VIEW v1; +DROP TABLE t1,t2,t3; +# +# End of 10.2 tests +# diff --git a/mysql-test/suite/binlog/r/binlog_reset_master.result b/mysql-test/suite/binlog/r/binlog_reset_master.result deleted file mode 100644 index b3d605560ff..00000000000 --- a/mysql-test/suite/binlog/r/binlog_reset_master.result +++ /dev/null @@ -1 +0,0 @@ -RESET MASTER; diff --git a/mysql-test/suite/binlog/t/binlog_reset_master.test b/mysql-test/suite/binlog/t/binlog_reset_master.test deleted file mode 100644 index 33b549ad357..00000000000 --- a/mysql-test/suite/binlog/t/binlog_reset_master.test +++ /dev/null @@ -1,26 +0,0 @@ -# ==== Purpose ==== -# -# Test bugs in RESET MASTER. - ---source include/have_debug.inc ---source include/have_log_bin.inc - -####################################################################### -# BUG#12574820: binlog.binlog_tmp_table timing out in daily and weekly trunk run -# Problem: MYSQL_BIN_LOG::reset_logs acquired LOCK_thread_count and -# LOCK_log in the wrong order. This could cause a deadlock when -# RESET MASTER was run concurrently with a disconnecting thread. -####################################################################### - -# We use sleep, not debug_sync, because the sync point needs to be in -# the thread shut down code after the debug sync facility has been -# shut down. ---let $write_var= SET debug_dbug="+d,sleep_after_lock_thread_count_before_delete_thd"; CREATE TEMPORARY TABLE test.t1 (a INT); ---let $write_to_file= GENERATE ---disable_query_log ---source include/write_var_to_file.inc ---enable_query_log - ---exec $MYSQL < $write_to_file -RESET MASTER; ---remove_file $write_to_file diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result index f0e1ee74e0b..655a5d3ff96 100644 --- a/mysql-test/suite/funcs_1/r/storedproc.result +++ b/mysql-test/suite/funcs_1/r/storedproc.result @@ -3816,7 +3816,7 @@ return 1' at line 1 CREATE FUNCTION fn1(a char) returns int lang sql return 1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'sql return 1' at line 1 CREATE FUNCTION fn1(a char) returns int deterministic( return 1); -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'return 1)' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '( return 1)' at line 1 CREATE FUNCTION fn1(a char) returns int non deterministic return 1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'deterministic return 1' at line 1 CREATE FUNCTION fn1(a char) returns int not deterministic comment 'abc' language sql sql security refiner return 1; diff --git a/mysql-test/suite/maria/maria-recover-master.opt b/mysql-test/suite/maria/maria-recover-master.opt index 7582a381a32..976c3882d2e 100644 --- a/mysql-test/suite/maria/maria-recover-master.opt +++ b/mysql-test/suite/maria/maria-recover-master.opt @@ -1 +1 @@ ---loose-aria-recover=backup --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp +--loose-aria-recover-options=backup --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp diff --git a/mysql-test/suite/maria/maria-recover.result b/mysql-test/suite/maria/maria-recover.result index 9b84c47720a..472d2351abe 100644 --- a/mysql-test/suite/maria/maria-recover.result +++ b/mysql-test/suite/maria/maria-recover.result @@ -1,17 +1,17 @@ -select @@global.aria_recover; -@@global.aria_recover +select @@global.aria_recover_options; +@@global.aria_recover_options BACKUP -set global aria_recover=off; -select @@global.aria_recover; -@@global.aria_recover +set global aria_recover_options=off; +select @@global.aria_recover_options; +@@global.aria_recover_options OFF -set global aria_recover=default; -select @@global.aria_recover; -@@global.aria_recover +set global aria_recover_options=default; +select @@global.aria_recover_options; +@@global.aria_recover_options NORMAL -set global aria_recover=normal; -select @@global.aria_recover; -@@global.aria_recover +set global aria_recover_options=normal; +select @@global.aria_recover_options; +@@global.aria_recover_options NORMAL drop database if exists mysqltest; create database mysqltest; @@ -35,5 +35,5 @@ a ThursdayMorningsMarket ThursdayMorningsMarketb drop database mysqltest; -set global aria_recover=backup; +set global aria_recover_options=backup; set global aria_checkpoint_interval=30; diff --git a/mysql-test/suite/maria/maria-recover.test b/mysql-test/suite/maria/maria-recover.test index 56259ad9a31..0f9f5e9cd26 100644 --- a/mysql-test/suite/maria/maria-recover.test +++ b/mysql-test/suite/maria/maria-recover.test @@ -1,4 +1,4 @@ -# Test of the --aria-recover option. +# Test of the --aria-recover-options option. --source include/have_maria.inc @@ -18,13 +18,13 @@ let $def_checkinterval=`select @@global.aria_checkpoint_interval`; # so that the perl code below can access it. let MYSQLD_DATADIR= `select @@datadir`; -select @@global.aria_recover; -set global aria_recover=off; -select @@global.aria_recover; -set global aria_recover=default; -select @@global.aria_recover; -set global aria_recover=normal; -select @@global.aria_recover; +select @@global.aria_recover_options; +set global aria_recover_options=off; +select @@global.aria_recover_options; +set global aria_recover_options=default; +select @@global.aria_recover_options; +set global aria_recover_options=normal; +select @@global.aria_recover_options; --disable_warnings drop database if exists mysqltest; @@ -72,5 +72,5 @@ select * from t_corrupted2; # should show corruption and repair messages select * from t_corrupted2; # should show just rows drop database mysqltest; -set global aria_recover=backup; +set global aria_recover_options=backup; eval set global aria_checkpoint_interval=$def_checkinterval; diff --git a/mysql-test/suite/maria/maria3.result b/mysql-test/suite/maria/maria3.result index feb5fa82cd4..7e0e55ed8c0 100644 --- a/mysql-test/suite/maria/maria3.result +++ b/mysql-test/suite/maria/maria3.result @@ -317,7 +317,7 @@ aria_pagecache_buffer_size 8388608 aria_pagecache_division_limit 100 aria_pagecache_file_hash_size 512 aria_page_checksum OFF -aria_recover NORMAL +aria_recover_options NORMAL aria_repair_threads 1 aria_sort_buffer_size 268434432 aria_stats_method nulls_unequal diff --git a/mysql-test/suite/maria/suite.pm b/mysql-test/suite/maria/suite.pm index c8ef6d8af72..d9af0f2ac43 100644 --- a/mysql-test/suite/maria/suite.pm +++ b/mysql-test/suite/maria/suite.pm @@ -2,7 +2,7 @@ package My::Suite::Maria; @ISA = qw(My::Suite); -return "Need Aria engine" unless defined $::mysqld_variables{'aria-recover'}; +return "Need Aria engine" unless defined $::mysqld_variables{'aria-recover-options'}; bless { }; diff --git a/mysql-test/suite/perfschema/r/start_server_low_digest.result b/mysql-test/suite/perfschema/r/start_server_low_digest.result index ba71e4ea6b0..0e9632eac4b 100644 --- a/mysql-test/suite/perfschema/r/start_server_low_digest.result +++ b/mysql-test/suite/perfschema/r/start_server_low_digest.result @@ -6,7 +6,7 @@ SELECT 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 #################################### # QUERYING PS STATEMENT DIGEST #################################### -SELECT event_name, digest, digest_text, sql_text FROM events_statements_history_long; -event_name digest digest_text sql_text -statement/sql/truncate 9d8bb20bae9d3c7cdfd36bc9d78b1d63 TRUNCATE TABLE truncate table events_statements_history_long -statement/sql/select d4c5d748dcc95f29805e3c04d47d7f64 SELECT ? + ? + SELECT 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 +SELECT event_name, digest_text, sql_text FROM events_statements_history_long; +event_name digest_text sql_text +statement/sql/truncate TRUNCATE TABLE truncate table events_statements_history_long +statement/sql/select SELECT ? + ? + SELECT 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 diff --git a/mysql-test/suite/perfschema/t/start_server_low_digest.test b/mysql-test/suite/perfschema/t/start_server_low_digest.test index 6f06def169b..f1ff90d2413 100644 --- a/mysql-test/suite/perfschema/t/start_server_low_digest.test +++ b/mysql-test/suite/perfschema/t/start_server_low_digest.test @@ -18,4 +18,4 @@ SELECT 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 --echo #################################### --echo # QUERYING PS STATEMENT DIGEST --echo #################################### -SELECT event_name, digest, digest_text, sql_text FROM events_statements_history_long; +SELECT event_name, digest_text, sql_text FROM events_statements_history_long; diff --git a/mysql-test/suite/perfschema/t/threads_mysql-master.opt b/mysql-test/suite/perfschema/t/threads_mysql-master.opt index f93413a61e5..00efa80d41e 100644 --- a/mysql-test/suite/perfschema/t/threads_mysql-master.opt +++ b/mysql-test/suite/perfschema/t/threads_mysql-master.opt @@ -1 +1 @@ ---event-scheduler +--event-scheduler --thread-cache-size=0 diff --git a/mysql-test/suite/sys_vars/r/aria_recover_basic.result b/mysql-test/suite/sys_vars/r/aria_recover_basic.result deleted file mode 100644 index 9cbc6617874..00000000000 --- a/mysql-test/suite/sys_vars/r/aria_recover_basic.result +++ /dev/null @@ -1,57 +0,0 @@ -SET @start_global_value = @@global.aria_recover; -select @@global.aria_recover; -@@global.aria_recover -NORMAL -select @@session.aria_recover; -ERROR HY000: Variable 'aria_recover' is a GLOBAL variable -show global variables like 'aria_recover'; -Variable_name Value -aria_recover NORMAL -show session variables like 'aria_recover'; -Variable_name Value -aria_recover NORMAL -select * from information_schema.global_variables where variable_name='aria_recover'; -VARIABLE_NAME VARIABLE_VALUE -ARIA_RECOVER NORMAL -select * from information_schema.session_variables where variable_name='aria_recover'; -VARIABLE_NAME VARIABLE_VALUE -ARIA_RECOVER NORMAL -set global aria_recover=1; -select @@global.aria_recover; -@@global.aria_recover -NORMAL -set session aria_recover=1; -ERROR HY000: Variable 'aria_recover' is a GLOBAL variable and should be set with SET GLOBAL -set global aria_recover=normal; -select @@global.aria_recover; -@@global.aria_recover -NORMAL -set global aria_recover=backup; -select @@global.aria_recover; -@@global.aria_recover -BACKUP -set global aria_recover='force'; -select @@global.aria_recover; -@@global.aria_recover -FORCE -set global aria_recover=off; -select @@global.aria_recover; -@@global.aria_recover -OFF -set global aria_recover='quick,force'; -select @@global.aria_recover; -@@global.aria_recover -FORCE,QUICK -set global aria_recover=16; -select @@global.aria_recover; -@@global.aria_recover -OFF -set global aria_recover=1.1; -ERROR 42000: Incorrect argument type to variable 'aria_recover' -set global aria_recover=1e1; -ERROR 42000: Incorrect argument type to variable 'aria_recover' -set global aria_recover="foo"; -ERROR 42000: Variable 'aria_recover' can't be set to the value of 'foo' -set global aria_recover=32; -ERROR 42000: Variable 'aria_recover' can't be set to the value of '32' -SET @@global.aria_recover = @start_global_value; diff --git a/mysql-test/suite/sys_vars/r/aria_recover_options_basic.result b/mysql-test/suite/sys_vars/r/aria_recover_options_basic.result new file mode 100644 index 00000000000..04c45aa0dbb --- /dev/null +++ b/mysql-test/suite/sys_vars/r/aria_recover_options_basic.result @@ -0,0 +1,57 @@ +SET @start_global_value = @@global.aria_recover_options; +select @@global.aria_recover_options; +@@global.aria_recover_options +NORMAL +select @@session.aria_recover_options; +ERROR HY000: Variable 'aria_recover_options' is a GLOBAL variable +show global variables like 'aria_recover_options'; +Variable_name Value +aria_recover_options NORMAL +show session variables like 'aria_recover_options'; +Variable_name Value +aria_recover_options NORMAL +select * from information_schema.global_variables where variable_name='aria_recover_options'; +VARIABLE_NAME VARIABLE_VALUE +ARIA_RECOVER_OPTIONS NORMAL +select * from information_schema.session_variables where variable_name='aria_recover_options'; +VARIABLE_NAME VARIABLE_VALUE +ARIA_RECOVER_OPTIONS NORMAL +set global aria_recover_options=1; +select @@global.aria_recover_options; +@@global.aria_recover_options +NORMAL +set session aria_recover_options=1; +ERROR HY000: Variable 'aria_recover_options' is a GLOBAL variable and should be set with SET GLOBAL +set global aria_recover_options=normal; +select @@global.aria_recover_options; +@@global.aria_recover_options +NORMAL +set global aria_recover_options=backup; +select @@global.aria_recover_options; +@@global.aria_recover_options +BACKUP +set global aria_recover_options='force'; +select @@global.aria_recover_options; +@@global.aria_recover_options +FORCE +set global aria_recover_options=off; +select @@global.aria_recover_options; +@@global.aria_recover_options +OFF +set global aria_recover_options='quick,force'; +select @@global.aria_recover_options; +@@global.aria_recover_options +FORCE,QUICK +set global aria_recover_options=16; +select @@global.aria_recover_options; +@@global.aria_recover_options +OFF +set global aria_recover_options=1.1; +ERROR 42000: Incorrect argument type to variable 'aria_recover_options' +set global aria_recover_options=1e1; +ERROR 42000: Incorrect argument type to variable 'aria_recover_options' +set global aria_recover_options="foo"; +ERROR 42000: Variable 'aria_recover_options' can't be set to the value of 'foo' +set global aria_recover_options=32; +ERROR 42000: Variable 'aria_recover_options' can't be set to the value of '32' +SET @@global.aria_recover_options = @start_global_value; diff --git a/mysql-test/suite/sys_vars/r/optimizer_search_depth_basic.result b/mysql-test/suite/sys_vars/r/optimizer_search_depth_basic.result index de448d3e2fc..75d99943288 100644 --- a/mysql-test/suite/sys_vars/r/optimizer_search_depth_basic.result +++ b/mysql-test/suite/sys_vars/r/optimizer_search_depth_basic.result @@ -10,7 +10,6 @@ SELECT @start_session_value; SET @@global.optimizer_search_depth = 100; Warnings: Warning 1292 Truncated incorrect optimizer_search_depth value: '100' -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead SET @@global.optimizer_search_depth = DEFAULT; SELECT @@global.optimizer_search_depth; @@global.optimizer_search_depth @@ -18,7 +17,6 @@ SELECT @@global.optimizer_search_depth; SET @@session.optimizer_search_depth = 200; Warnings: Warning 1292 Truncated incorrect optimizer_search_depth value: '200' -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead SET @@session.optimizer_search_depth = DEFAULT; SELECT @@session.optimizer_search_depth; @@session.optimizer_search_depth @@ -47,10 +45,10 @@ SELECT @@global.optimizer_search_depth; 62 SET @@global.optimizer_search_depth = 63; Warnings: -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead +Warning 1292 Truncated incorrect optimizer_search_depth value: '63' SELECT @@global.optimizer_search_depth; @@global.optimizer_search_depth -63 +62 '#--------------------FN_DYNVARS_116_04-------------------------#' SET @@session.optimizer_search_depth = 0; SELECT @@session.optimizer_search_depth; @@ -66,18 +64,17 @@ SELECT @@session.optimizer_search_depth; 62 SET @@session.optimizer_search_depth = 63; Warnings: -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead +Warning 1292 Truncated incorrect optimizer_search_depth value: '63' SELECT @@session.optimizer_search_depth; @@session.optimizer_search_depth -63 +62 '#------------------FN_DYNVARS_116_05-----------------------#' SET @@global.optimizer_search_depth = 64; Warnings: Warning 1292 Truncated incorrect optimizer_search_depth value: '64' -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead SELECT @@global.optimizer_search_depth; @@global.optimizer_search_depth -63 +62 SET @@global.optimizer_search_depth = -1; Warnings: Warning 1292 Truncated incorrect optimizer_search_depth value: '-1' @@ -87,27 +84,25 @@ SELECT @@global.optimizer_search_depth; SET @@global.optimizer_search_depth = 65536; Warnings: Warning 1292 Truncated incorrect optimizer_search_depth value: '65536' -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead SELECT @@global.optimizer_search_depth; @@global.optimizer_search_depth -63 +62 SET @@global.optimizer_search_depth = 65530.34; ERROR 42000: Incorrect argument type to variable 'optimizer_search_depth' SELECT @@global.optimizer_search_depth; @@global.optimizer_search_depth -63 +62 SET @@global.optimizer_search_depth = test; ERROR 42000: Incorrect argument type to variable 'optimizer_search_depth' SELECT @@global.optimizer_search_depth; @@global.optimizer_search_depth -63 +62 SET @@session.optimizer_search_depth = 64; Warnings: Warning 1292 Truncated incorrect optimizer_search_depth value: '64' -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead SELECT @@session.optimizer_search_depth; @@session.optimizer_search_depth -63 +62 SET @@session.optimizer_search_depth = -2; Warnings: Warning 1292 Truncated incorrect optimizer_search_depth value: '-2' @@ -119,15 +114,14 @@ ERROR 42000: Incorrect argument type to variable 'optimizer_search_depth' SET @@session.optimizer_search_depth = 65550; Warnings: Warning 1292 Truncated incorrect optimizer_search_depth value: '65550' -Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead SELECT @@session.optimizer_search_depth; @@session.optimizer_search_depth -63 +62 SET @@session.optimizer_search_depth = test; ERROR 42000: Incorrect argument type to variable 'optimizer_search_depth' SELECT @@session.optimizer_search_depth; @@session.optimizer_search_depth -63 +62 '#------------------FN_DYNVARS_116_06-----------------------#' SELECT @@global.optimizer_search_depth = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES diff --git a/mysql-test/suite/sys_vars/r/sysvars_aria.result b/mysql-test/suite/sys_vars/r/sysvars_aria.result index 2948b2ad3fc..f2418cf31db 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_aria.result +++ b/mysql-test/suite/sys_vars/r/sysvars_aria.result @@ -211,7 +211,7 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED -VARIABLE_NAME ARIA_RECOVER +VARIABLE_NAME ARIA_RECOVER_OPTIONS SESSION_VALUE NULL GLOBAL_VALUE NORMAL GLOBAL_VALUE_ORIGIN COMPILE-TIME diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff index 6d6dcda7bae..d2b99e23514 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_server_embedded.result 2016-03-23 01:02:33.000000000 +0100 -+++ suite/sys_vars/r/sysvars_server_embedded.reject 2016-03-23 01:09:44.000000000 +0100 +--- suite/sys_vars/r/sysvars_server_embedded.result ++++ suite/sys_vars/r/sysvars_server_embedded,32bit.reject @@ -57,7 +57,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE 1 @@ -664,9 +664,9 @@ VARIABLE_SCOPE SESSION -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to 63, the optimizer will switch to the original find_best search. NOTE: The value 63 and its associated behaviour is deprecated + VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value NUMERIC_MIN_VALUE 0 - NUMERIC_MAX_VALUE 63 + NUMERIC_MAX_VALUE 62 @@ -2437,7 +2437,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 100 @@ -885,7 +885,7 @@ NUMERIC_MAX_VALUE 256 @@ -2801,7 +2801,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME - DEFAULT_VALUE 178 + DEFAULT_VALUE 181 VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED @@ -1153,12 +1153,12 @@ NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 524288 @@ -3851,7 +3851,7 @@ - GLOBAL_VALUE_ORIGIN COMPILE-TIME - DEFAULT_VALUE 0 + GLOBAL_VALUE_ORIGIN AUTO + DEFAULT_VALUE 256 VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT How many threads we should keep in a cache for reuse + VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 @@ -3865,7 +3865,7 @@ diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index b5676810987..cfd336ef15b 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -2424,9 +2424,9 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 62 VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED -VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to 63, the optimizer will switch to the original find_best search. NOTE: The value 63 and its associated behaviour is deprecated +VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 63 +NUMERIC_MAX_VALUE 62 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO @@ -2797,9 +2797,9 @@ READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES SESSION_VALUE NULL -GLOBAL_VALUE 178 +GLOBAL_VALUE 181 GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE 178 +DEFAULT_VALUE 181 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Maximum number of statement instruments. diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff index 6661ea288fd..650bdc24681 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_server_notembedded.result 2016-03-22 21:25:49.000000000 +0100 -+++ suite/sys_vars/r/sysvars_server_notembedded.reject 2016-03-23 01:11:50.000000000 +0100 +--- suite/sys_vars/r/sysvars_server_notembedded.result ++++ suite/sys_vars/r/sysvars_server_notembedded.reject @@ -57,7 +57,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE 1 @@ -664,9 +664,9 @@ VARIABLE_SCOPE SESSION -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to 63, the optimizer will switch to the original find_best search. NOTE: The value 63 and its associated behaviour is deprecated + VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value NUMERIC_MIN_VALUE 0 - NUMERIC_MAX_VALUE 63 + NUMERIC_MAX_VALUE 62 @@ -2633,7 +2633,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 100 @@ -885,7 +885,7 @@ NUMERIC_MAX_VALUE 256 @@ -2997,7 +2997,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME - DEFAULT_VALUE 178 + DEFAULT_VALUE 181 VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED @@ -1134,7 +1134,16 @@ VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -4047,7 +4047,7 @@ +@@ -4005,7 +4005,7 @@ + GLOBAL_VALUE_ORIGIN COMPILE-TIME + DEFAULT_VALUE 0 + VARIABLE_SCOPE GLOBAL +-VARIABLE_TYPE BIGINT UNSIGNED ++VARIABLE_TYPE INT UNSIGNED + VARIABLE_COMMENT Alias for slave_parallel_threads + NUMERIC_MIN_VALUE 0 + NUMERIC_MAX_VALUE 16383 +@@ -4061,7 +4061,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE GLOBAL @@ -1143,7 +1152,7 @@ VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout, before giving up and stopping NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -4075,7 +4075,7 @@ +@@ -4089,7 +4089,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 2 VARIABLE_SCOPE GLOBAL @@ -1152,7 +1161,7 @@ VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 -@@ -4134,7 +4134,7 @@ +@@ -4148,7 +4148,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size NUMERIC_MIN_VALUE 1024 @@ -1161,7 +1170,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4425,7 +4425,7 @@ +@@ -4439,7 +4439,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 256 VARIABLE_SCOPE GLOBAL @@ -1170,7 +1179,7 @@ VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 524288 -@@ -4523,7 +4523,7 @@ +@@ -4537,7 +4537,7 @@ GLOBAL_VALUE_ORIGIN AUTO DEFAULT_VALUE 400 VARIABLE_SCOPE GLOBAL @@ -1179,7 +1188,7 @@ VARIABLE_COMMENT The number of cached table definitions NUMERIC_MIN_VALUE 400 NUMERIC_MAX_VALUE 524288 -@@ -4537,7 +4537,7 @@ +@@ -4551,7 +4551,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 2000 VARIABLE_SCOPE GLOBAL @@ -1188,16 +1197,16 @@ VARIABLE_COMMENT The number of cached open tables NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 524288 -@@ -4551,7 +4551,7 @@ - GLOBAL_VALUE_ORIGIN COMPILE-TIME - DEFAULT_VALUE 0 +@@ -4565,7 +4565,7 @@ + GLOBAL_VALUE_ORIGIN AUTO + DEFAULT_VALUE 256 VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_TYPE INT UNSIGNED - VARIABLE_COMMENT How many threads we should keep in a cache for reuse + VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 -@@ -4565,7 +4565,7 @@ +@@ -4579,7 +4579,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE GLOBAL @@ -1206,7 +1215,7 @@ VARIABLE_COMMENT Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.This variable has no effect, and is deprecated. It will be removed in a future release. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 512 -@@ -4750,7 +4750,7 @@ +@@ -4764,7 +4764,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM or Aria table NUMERIC_MIN_VALUE 1024 @@ -1215,7 +1224,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4761,7 +4761,7 @@ +@@ -4775,7 +4775,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 8192 VARIABLE_SCOPE SESSION @@ -1224,7 +1233,7 @@ VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4775,7 +4775,7 @@ +@@ -4789,7 +4789,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4096 VARIABLE_SCOPE SESSION @@ -1233,7 +1242,7 @@ VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4873,7 +4873,7 @@ +@@ -4887,7 +4887,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 28800 VARIABLE_SCOPE SESSION @@ -1242,7 +1251,7 @@ VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -4977,7 +4977,7 @@ +@@ -4991,7 +4991,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME OPEN_FILES_LIMIT VARIABLE_SCOPE GLOBAL @@ -1251,7 +1260,7 @@ VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -4990,7 +4990,7 @@ +@@ -5004,7 +5004,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1260,7 +1269,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -5000,7 +5000,7 @@ +@@ -5014,7 +5014,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1269,7 +1278,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -5085,7 +5085,7 @@ +@@ -5099,7 +5099,7 @@ VARIABLE_NAME LOG_TC_SIZE GLOBAL_VALUE_ORIGIN AUTO VARIABLE_SCOPE GLOBAL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 81cc32016e2..09c3d6e6c98 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -2620,9 +2620,9 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 62 VARIABLE_SCOPE SESSION VARIABLE_TYPE BIGINT UNSIGNED -VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to 63, the optimizer will switch to the original find_best search. NOTE: The value 63 and its associated behaviour is deprecated +VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value NUMERIC_MIN_VALUE 0 -NUMERIC_MAX_VALUE 63 +NUMERIC_MAX_VALUE 62 NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO @@ -2993,9 +2993,9 @@ READ_ONLY YES COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES SESSION_VALUE NULL -GLOBAL_VALUE 178 +GLOBAL_VALUE 181 GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE 178 +DEFAULT_VALUE 181 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Maximum number of statement instruments. @@ -3999,6 +3999,20 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME SLAVE_PARALLEL_WORKERS +SESSION_VALUE NULL +GLOBAL_VALUE 0 +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE 0 +VARIABLE_SCOPE GLOBAL +VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_COMMENT Alias for slave_parallel_threads +NUMERIC_MIN_VALUE 0 +NUMERIC_MAX_VALUE 16383 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME SLAVE_RUN_TRIGGERS_FOR_RBR SESSION_VALUE NULL GLOBAL_VALUE NO @@ -4547,12 +4561,12 @@ READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME THREAD_CACHE_SIZE SESSION_VALUE NULL -GLOBAL_VALUE 0 -GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE 0 +GLOBAL_VALUE 151 +GLOBAL_VALUE_ORIGIN AUTO +DEFAULT_VALUE 256 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED -VARIABLE_COMMENT How many threads we should keep in a cache for reuse +VARIABLE_COMMENT How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 NUMERIC_BLOCK_SIZE 1 @@ -4659,9 +4673,9 @@ READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME THREAD_STACK SESSION_VALUE NULL -GLOBAL_VALUE 295936 +GLOBAL_VALUE 296960 GLOBAL_VALUE_ORIGIN COMPILE-TIME -DEFAULT_VALUE 295936 +DEFAULT_VALUE 296960 VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The stack size for each thread diff --git a/mysql-test/suite/sys_vars/r/thread_cache_size_basic.result b/mysql-test/suite/sys_vars/r/thread_cache_size_basic.result index af6777fcf45..a50785c42b7 100644 --- a/mysql-test/suite/sys_vars/r/thread_cache_size_basic.result +++ b/mysql-test/suite/sys_vars/r/thread_cache_size_basic.result @@ -1,24 +1,24 @@ SET @start_global_value = @@global.thread_cache_size; SELECT @start_global_value; @start_global_value -0 +256 select @@global.thread_cache_size; @@global.thread_cache_size -0 +256 select @@session.thread_cache_size; ERROR HY000: Variable 'thread_cache_size' is a GLOBAL variable show global variables like 'thread_cache_size'; Variable_name Value -thread_cache_size 0 +thread_cache_size 256 show session variables like 'thread_cache_size'; Variable_name Value -thread_cache_size 0 +thread_cache_size 256 select * from information_schema.global_variables where variable_name='thread_cache_size'; VARIABLE_NAME VARIABLE_VALUE -THREAD_CACHE_SIZE 0 +THREAD_CACHE_SIZE 256 select * from information_schema.session_variables where variable_name='thread_cache_size'; VARIABLE_NAME VARIABLE_VALUE -THREAD_CACHE_SIZE 0 +THREAD_CACHE_SIZE 256 set global thread_cache_size=1; select @@global.thread_cache_size; @@global.thread_cache_size @@ -51,4 +51,4 @@ select @@global.thread_cache_size; SET @@global.thread_cache_size = @start_global_value; SELECT @@global.thread_cache_size; @@global.thread_cache_size -0 +256 diff --git a/mysql-test/suite/sys_vars/r/thread_stack_basic.result b/mysql-test/suite/sys_vars/r/thread_stack_basic.result index d5a30bbaf6e..5984ffebdaf 100644 --- a/mysql-test/suite/sys_vars/r/thread_stack_basic.result +++ b/mysql-test/suite/sys_vars/r/thread_stack_basic.result @@ -1,20 +1,20 @@ select @@global.thread_stack; @@global.thread_stack -295936 +296960 select @@session.thread_stack; ERROR HY000: Variable 'thread_stack' is a GLOBAL variable show global variables like 'thread_stack'; Variable_name Value -thread_stack 295936 +thread_stack 296960 show session variables like 'thread_stack'; Variable_name Value -thread_stack 295936 +thread_stack 296960 select * from information_schema.global_variables where variable_name='thread_stack'; VARIABLE_NAME VARIABLE_VALUE -THREAD_STACK 295936 +THREAD_STACK 296960 select * from information_schema.session_variables where variable_name='thread_stack'; VARIABLE_NAME VARIABLE_VALUE -THREAD_STACK 295936 +THREAD_STACK 296960 set global thread_stack=1; ERROR HY000: Variable 'thread_stack' is a read only variable set session thread_stack=1; diff --git a/mysql-test/suite/sys_vars/r/version.result b/mysql-test/suite/sys_vars/r/version.result new file mode 100644 index 00000000000..29a2fb8c7e9 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/version.result @@ -0,0 +1,4 @@ +SELECT @@version; +@@version +my_favorite_version +1 diff --git a/mysql-test/suite/sys_vars/t/aria_recover_basic.test b/mysql-test/suite/sys_vars/t/aria_recover_basic.test deleted file mode 100644 index 42e280b0499..00000000000 --- a/mysql-test/suite/sys_vars/t/aria_recover_basic.test +++ /dev/null @@ -1,53 +0,0 @@ -# set global ---source include/have_maria.inc - -SET @start_global_value = @@global.aria_recover; - -# -# exists as global only -# -select @@global.aria_recover; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -select @@session.aria_recover; -show global variables like 'aria_recover'; -show session variables like 'aria_recover'; -select * from information_schema.global_variables where variable_name='aria_recover'; -select * from information_schema.session_variables where variable_name='aria_recover'; - -# -# show that it's writable -# -set global aria_recover=1; -select @@global.aria_recover; ---error ER_GLOBAL_VARIABLE -set session aria_recover=1; - -# -# valid values -# -set global aria_recover=normal; -select @@global.aria_recover; -set global aria_recover=backup; -select @@global.aria_recover; -set global aria_recover='force'; -select @@global.aria_recover; -set global aria_recover=off; -select @@global.aria_recover; -set global aria_recover='quick,force'; -select @@global.aria_recover; -set global aria_recover=16; -select @@global.aria_recover; - -# -# incorrect types/values -# ---error ER_WRONG_TYPE_FOR_VAR -set global aria_recover=1.1; ---error ER_WRONG_TYPE_FOR_VAR -set global aria_recover=1e1; ---error ER_WRONG_VALUE_FOR_VAR -set global aria_recover="foo"; ---error ER_WRONG_VALUE_FOR_VAR -set global aria_recover=32; - -SET @@global.aria_recover = @start_global_value; diff --git a/mysql-test/suite/sys_vars/t/aria_recover_options_basic.test b/mysql-test/suite/sys_vars/t/aria_recover_options_basic.test new file mode 100644 index 00000000000..f621998b501 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/aria_recover_options_basic.test @@ -0,0 +1,53 @@ +# set global +--source include/have_maria.inc + +SET @start_global_value = @@global.aria_recover_options; + +# +# exists as global only +# +select @@global.aria_recover_options; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +select @@session.aria_recover_options; +show global variables like 'aria_recover_options'; +show session variables like 'aria_recover_options'; +select * from information_schema.global_variables where variable_name='aria_recover_options'; +select * from information_schema.session_variables where variable_name='aria_recover_options'; + +# +# show that it's writable +# +set global aria_recover_options=1; +select @@global.aria_recover_options; +--error ER_GLOBAL_VARIABLE +set session aria_recover_options=1; + +# +# valid values +# +set global aria_recover_options=normal; +select @@global.aria_recover_options; +set global aria_recover_options=backup; +select @@global.aria_recover_options; +set global aria_recover_options='force'; +select @@global.aria_recover_options; +set global aria_recover_options=off; +select @@global.aria_recover_options; +set global aria_recover_options='quick,force'; +select @@global.aria_recover_options; +set global aria_recover_options=16; +select @@global.aria_recover_options; + +# +# incorrect types/values +# +--error ER_WRONG_TYPE_FOR_VAR +set global aria_recover_options=1.1; +--error ER_WRONG_TYPE_FOR_VAR +set global aria_recover_options=1e1; +--error ER_WRONG_VALUE_FOR_VAR +set global aria_recover_options="foo"; +--error ER_WRONG_VALUE_FOR_VAR +set global aria_recover_options=32; + +SET @@global.aria_recover_options = @start_global_value; diff --git a/mysql-test/suite/sys_vars/t/slow_launch_time_func-master.opt b/mysql-test/suite/sys_vars/t/slow_launch_time_func-master.opt new file mode 100644 index 00000000000..e92bb2476ff --- /dev/null +++ b/mysql-test/suite/sys_vars/t/slow_launch_time_func-master.opt @@ -0,0 +1 @@ +--thread_cache_size=0 diff --git a/mysql-test/suite/sys_vars/t/thread_cache_size_basic-master.opt b/mysql-test/suite/sys_vars/t/thread_cache_size_basic-master.opt new file mode 100644 index 00000000000..f28fc33b28b --- /dev/null +++ b/mysql-test/suite/sys_vars/t/thread_cache_size_basic-master.opt @@ -0,0 +1 @@ +--max-connections=1024 diff --git a/mysql-test/suite/sys_vars/t/thread_cache_size_func-master.opt b/mysql-test/suite/sys_vars/t/thread_cache_size_func-master.opt new file mode 100644 index 00000000000..b8c19e1b5ff --- /dev/null +++ b/mysql-test/suite/sys_vars/t/thread_cache_size_func-master.opt @@ -0,0 +1 @@ +--thread-cache-size=0 diff --git a/mysql-test/suite/sys_vars/t/version.opt b/mysql-test/suite/sys_vars/t/version.opt new file mode 100644 index 00000000000..9b6be9b7eea --- /dev/null +++ b/mysql-test/suite/sys_vars/t/version.opt @@ -0,0 +1 @@ +--version="my_favorite_version" diff --git a/mysql-test/suite/sys_vars/t/version.test b/mysql-test/suite/sys_vars/t/version.test new file mode 100644 index 00000000000..daa95386fd4 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/version.test @@ -0,0 +1,6 @@ +SELECT @@version; +perl; + $cnt= $ENV{MYSQL_TEST} =~ /mysqltest_embedded / ? 1 : + grep /my_favorite_version/, `$ENV{MYSQL} -e status`; + print "$cnt\n"; +EOF diff --git a/mysql-test/t/alter_user.test b/mysql-test/t/alter_user.test new file mode 100644 index 00000000000..e32d0c29f2e --- /dev/null +++ b/mysql-test/t/alter_user.test @@ -0,0 +1,82 @@ +--source include/not_embedded.inc +--enable_connect_log + + +select * from mysql.user where user = 'root' and host = 'localhost'; +--echo # Test syntax +--echo # +--echo # These 2 selects should have no changes from the first one. +alter user CURRENT_USER; +select * from mysql.user where user = 'root' and host = 'localhost'; +alter user CURRENT_USER(); +select * from mysql.user where user = 'root' and host = 'localhost'; + +create user foo; +select * from mysql.user where user = 'foo'; +alter user foo; +select * from mysql.user where user = 'foo'; + +--echo # Test super privilege works correctly with a read only database. +SET @start_read_only = @@global.read_only; +SET GLOBAL read_only=1; +grant create user on *.* to foo; + +--echo # Currently no super privileges. +connect (a, localhost, foo); +select @@global.read_only; + +--error ER_OPTION_PREVENTS_STATEMENT +alter user foo; + +--echo # Grant super privilege to the user. +connection default; +grant super on *.* to foo; + +--echo # We now have super privilege. We should be able to run alter user. +connect (b, localhost, foo); +alter user foo; + +connection default; +SET GLOBAL read_only = @start_read_only; + +--echo # Test inexistant user. +--error ER_CANNOT_USER +alter user boo; +--echo #--warning ER_CANNOT_USER +alter if exists user boo; + +--echo # Test password related altering. +alter user foo identified by 'something'; +select * from mysql.user where user = 'foo'; + +alter user foo identified by 'something2'; +select * from mysql.user where user = 'foo'; + +alter user foo identified by password '*88C89BE093D4ECF72D039F62EBB7477EA1FD4D63'; +select * from mysql.user where user = 'foo'; + +alter user foo identified with 'somecoolplugin'; +select * from mysql.user where user = 'foo'; + +alter user foo identified with 'somecoolplugin' using 'somecoolpassphrase'; +select * from mysql.user where user = 'foo'; + +--echo # Test ssl related altering. +alter user foo identified by 'something' require SSL; +select * from mysql.user where user = 'foo'; + +alter user foo identified by 'something' require X509; +select * from mysql.user where user = 'foo'; + +alter user foo identified by 'something' +require cipher 'text' issuer 'foo_issuer' subject 'foo_subject'; +select * from mysql.user where user = 'foo'; + +--echo # Test resource limits altering. +alter user foo with MAX_QUERIES_PER_HOUR 10 + MAX_UPDATES_PER_HOUR 20 + MAX_CONNECTIONS_PER_HOUR 30 + MAX_USER_CONNECTIONS 40; +select * from mysql.user where user = 'foo'; +drop user foo; +--disable_connect_log diff --git a/mysql-test/t/connect2.cnf b/mysql-test/t/connect2.cnf new file mode 100644 index 00000000000..0acd221b871 --- /dev/null +++ b/mysql-test/t/connect2.cnf @@ -0,0 +1,9 @@ +!include include/default_my.cnf + +[mysqld.1] +extra-port= @ENV.MASTER_EXTRA_PORT +extra-max-connections=2 +thread_handling=pool-of-threads + +[ENV] +MASTER_EXTRA_PORT= @OPT.port diff --git a/mysql-test/t/connect2.test b/mysql-test/t/connect2.test new file mode 100644 index 00000000000..b4614a65a91 --- /dev/null +++ b/mysql-test/t/connect2.test @@ -0,0 +1,84 @@ +# This test is to check various cases of connections, some which require +# DBUG + +# This test makes no sense with the embedded server +--source include/not_embedded.inc +--source include/have_debug.inc +call mtr.add_suppression("Allocation failed"); +SET @old_debug= @@session.debug; +set @old_thread_cache_size=@@global.thread_cache_size; + +# Test connections to the + +connect(con1,localhost,root,,test,,); +select 1; +disconnect con1; +connection default; +set global debug_dbug='+d,simulate_failed_connection_1'; +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1041,2013 +connect(con1,localhost,root,,test,,); +connection default; +set global debug_dbug=@old_debug; +set global debug_dbug='+d,simulate_failed_connection_2'; +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1041,2013 +connect(con1,localhost,root,,test,,); +--enable_result_log +connection default; +set global debug_dbug=@old_debug; +connect(con1,localhost,root,,test,,); +select 1; +disconnect con1; + +# Test connections to the extra port. + +connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,); +select 1; +disconnect con1; +connection default; +set global debug_dbug='+d,simulate_failed_connection_1'; +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_EXTRA_PORT MASTER_PORT +--error 1041,2013 +connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,); +connection default; +set global debug_dbug=@old_debug; +set global debug_dbug='+d,simulate_failed_connection_2'; +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_EXTRA_PORT MASTER_PORT +--error 1041,2013 +connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,); +connection default; +set global debug_dbug=@old_debug; +connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,); +select 1; +disconnect con1; +connection default; + +# +# Test thread cache +# +set @@global.thread_cache_size=2; +connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,); +select 1; +connect(con2,localhost,root,,test,$MASTER_EXTRA_PORT,); +select 1; +disconnect con1; +disconnect con2; +connection default; +set global debug_dbug='+d,simulate_failed_connection_2'; +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_EXTRA_PORT MASTER_PORT +--error 1041,2013 +connect(con1,localhost,root,,test,$MASTER_EXTRA_PORT,); +connection default; + +# Check that threads_connected didn't count aborted connections +let $count_sessions= 1; +--source include/wait_until_count_sessions.inc +show status like "Threads_connected"; + +# +# Cleanup +# + +set global debug_dbug=@old_debug; +set global thread_cache_size=@old_thread_cache_size; diff --git a/mysql-test/t/create_user.test b/mysql-test/t/create_user.test new file mode 100644 index 00000000000..f04cb3e302a --- /dev/null +++ b/mysql-test/t/create_user.test @@ -0,0 +1,58 @@ +--source include/not_embedded.inc + +create user foo; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo identified by 'password'; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo identified by 'password' require SSL; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo identified by 'password' require X509; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo identified by 'password' require CIPHER 'cipher'; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo identified by 'password' require ISSUER 'issuer'; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo identified by 'password' require SUBJECT 'subject'; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo identified by 'password' require CIPHER 'cipher' + SUBJECT 'subject'; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo identified by 'password' require CIPHER 'cipher' + AND SUBJECT 'subject' + AND ISSUER 'issuer'; +select * from mysql.user where user = 'foo'; +drop user foo; + +create user foo, foo2 identified by 'password' require CIPHER 'cipher' + AND SUBJECT 'subject' + AND ISSUER 'issuer'; +select * from mysql.user where user like 'foo'; + +--echo #--warning ER_USER_CREATE_EXISTS +create user if not exists foo, foo2 identified by 'password2' + require CIPHER 'cipher2' AND SUBJECT 'subject2' AND ISSUER 'issuer2'; +select * from mysql.user where user like 'foo'; +drop user foo, foo2; + +create user foo with MAX_QUERIES_PER_HOUR 10 + MAX_UPDATES_PER_HOUR 20 + MAX_CONNECTIONS_PER_HOUR 30 + MAX_USER_CONNECTIONS 40; +select * from mysql.user where user like 'foo'; +drop user foo; diff --git a/mysql-test/t/cte_grant.test b/mysql-test/t/cte_grant.test new file mode 100644 index 00000000000..44fd4a0bc6e --- /dev/null +++ b/mysql-test/t/cte_grant.test @@ -0,0 +1,79 @@ +# Can't test with embedded server +-- source include/not_embedded.inc + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +connect (root,localhost,root,,test); +connection root; + +--disable_warnings +create database mysqltest; +--enable_warnings + +create user mysqltest_1@localhost; +connect (user1,localhost,mysqltest_1,,test); +connection user1; + +connection root; + +create table mysqltest.t1 (a int, b int); +insert into mysqltest.t1 values (2,10), (1,30); +create table mysqltest.t2 (c int, d char(32)); +insert into mysqltest.t2 values (1,'xxx'), (1,'zzz'); + +grant select on mysqltest.t1 to mysqltest_1@localhost; +grant select (c) on mysqltest.t2 to mysqltest_1@localhost; + +connection user1; +with t as (select c from mysqltest.t2 where c < 2) +select t.c,t1.b from t,mysqltest.t1 where t.c=t1.a; +--error ER_COLUMNACCESS_DENIED_ERROR +select t.c,t.d,t1.b +from (select c,d from mysqltest.t2 where c < 2) as t, mysqltest.t1 +where t.c=t1.a; +--error ER_COLUMNACCESS_DENIED_ERROR +with t as (select c,d from mysqltest.t2 where c < 2) +select t.c,t.d,t1.b from t,mysqltest.t1 where t.c=t1.a; + +connection root; + +create view mysqltest.v1(f1,f2) as +with t as (select c from mysqltest.t2 where c < 2) +select t.c,t1.b from t,mysqltest.t1 where t.c=t1.a; +create view mysqltest.v2(c,d) as +with t as (select a from mysqltest.t1 where a>=3) +select t.a,b from t,mysqltest.t1 where mysqltest.t1.a = t.a; + +grant select on mysqltest.v1 to mysqltest_1@localhost; +grant select (c) on mysqltest.v2 to mysqltest_1@localhost; +grant create view on mysqltest.* to mysqltest_1@localhost; + +connection user1; + +create view mysqltest.v3(c,d) as +with t as (select c from mysqltest.t2 where c < 2) +select t.c,t1.b from t,mysqltest.t1 where t.c=t1.a; +--error ER_COLUMNACCESS_DENIED_ERROR +create view mysqltest.v4(f1,f2,f3) as +with t as (select c,d from mysqltest.t2 where c < 2) +select t.c,t.d,t1.b from t,mysqltest.t1 where t.c=t1.a; + +select * from mysqltest.v1; + +select c from mysqltest.v2; +# there are no privileges on column 'd' +--error ER_COLUMNACCESS_DENIED_ERROR +select d from mysqltest.v2; + +--error ER_TABLEACCESS_DENIED_ERROR +select * from mysqltest.v3; +connection root; +grant select on mysqltest.v3 to mysqltest_1@localhost; +connection user1; +select * from mysqltest.v3; + +connection root; +revoke all privileges on mysqltest.v1 from mysqltest_1@localhost; +drop user mysqltest_1@localhost; +drop database mysqltest;
\ No newline at end of file diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test new file mode 100644 index 00000000000..5a6e07e0c0c --- /dev/null +++ b/mysql-test/t/cte_nonrecursive.test @@ -0,0 +1,436 @@ +create table t1 (a int, b varchar(32)); +insert into t1 values + (4,'aaaa' ), (7,'bb'), (1,'ccc'), (4,'dd'); +insert into t1 values + (3,'eee'), (7,'bb'), (1,'fff'), (4,'ggg'); +create table t2 (c int); +insert into t2 values + (2), (4), (5), (3); + +--echo # select certain field in the specification of t +with t as (select a from t1 where b >= 'c') + select * from t2,t where t2.c=t.a; +select * from t2, (select a from t1 where b >= 'c') as t + where t2.c=t.a; +explain +with t as (select a from t1 where b >= 'c') + select * from t2,t where t2.c=t.a; +explain +select * from t2, (select a from t1 where b >= 'c') as t + where t2.c=t.a; + +--echo # select '*' in the specification of t +with t as (select * from t1 where b >= 'c') + select * from t2,t where t2.c=t.a; +select * from t2, (select * from t1 where b >= 'c') as t + where t2.c=t.a; +explain +with t as (select * from t1 where b >= 'c') + select * from t2,t where t2.c=t.a; +explain +select * from t2, (select * from t1 where b >= 'c') as t + where t2.c=t.a; + +--echo # rename fields returned by the specication when defining t +with t(f1,f2) as (select * from t1 where b >= 'c') + select * from t2,t where t2.c=t.f1; +explain +with t(f1,f2) as (select * from t1 where b >= 'c') + select * from t2,t where t2.c=t.f1; + +--echo # materialized query specifying t +with t as (select a, count(*) from t1 where b >= 'c' group by a) + select * from t2,t where t2.c=t.a; +select * from t2, (select a, count(*) from t1 where b >= 'c' group by a) as t + where t2.c=t.a; +explain +with t as (select a, count(*) from t1 where b >= 'c' group by a) + select * from t2,t where t2.c=t.a; +explain +select * from t2, (select a, count(*) from t1 where b >= 'c' group by a) as t + where t2.c=t.a; + +--echo # specivication of t contains having +with t as (select a, count(*) from t1 where b >= 'c' + group by a having count(*)=1 ) + select * from t2,t where t2.c=t.a; +select * from t2, (select a, count(*) from t1 where b >= 'c' + group by a having count(*)=1) t + where t2.c=t.a; + +--echo # main query contains having +with t as (select * from t2 where c <= 4) + select a, count(*) from t1,t where t1.a=t.c group by a having count(*)=1; +select a, count(*) from t1, (select * from t2 where c <= 4) t + where t1.a=t.c group by a having count(*)=1; + +--echo # main query contains group by + order by +with t as (select * from t2 where c <= 4 ) + select a, count(*) from t1,t where t1.a=t.c group by a order by count(*); +select a, count(*) from t1, (select * from t2 where c <= 4 ) t + where t1.a=t.c group by a order by count(*); + +--echo # main query contains group by + order by + limit +with t as (select * from t2 where c <= 4 ) + select a, count(*) from t1,t + where t1.a=t.c group by a order by count(*) desc limit 1; +select a, count(*) from t1, (select * from t2 where c <= 4 ) t + where t1.a=t.c group by a order by count(*) desc limit 1; + + +--echo # t is used in a subquery +with t as (select a from t1 where a<5) + select * from t2 where c in (select a from t); +select * from t2 + where c in (select a from (select a from t1 where a<5) as t); +explain +with t as (select a from t1 where a<5) + select * from t2 where c in (select a from t); +explain +select * from t2 + where c in (select a from (select a from t1 where a<5) as t); + +--echo # materialized t is used in a subquery +with t as (select count(*) as c from t1 where b >= 'c' group by a) + select * from t2 where c in (select c from t); +select * from t2 + where c in (select c from (select count(*) as c from t1 + where b >= 'c' group by a) as t); +explain +with t as (select count(*) as c from t1 where b >= 'c' group by a) + select * from t2 where c in (select c from t); +explain +select * from t2 + where c in (select c from (select count(*) as c from t1 + where b >= 'c' group by a) as t); + +--echo # two references to t specified by a query +--echo # selecting a field: both in main query +with t as (select a from t1 where b >= 'c') + select * from t as r1, t as r2 where r1.a=r2.a; +select * from (select a from t1 where b >= 'c') as r1, + (select a from t1 where b >= 'c') as r2 + where r1.a=r2.a; +explain +with t as (select a from t1 where b >= 'c') + select * from t as r1, t as r2 where r1.a=r2.a; +explain +select * from (select a from t1 where b >= 'c') as r1, + (select a from t1 where b >= 'c') as r2 + where r1.a=r2.a; + +--echo # two references to materialized t: both in main query +with t as (select distinct a from t1 where b >= 'c') + select * from t as r1, t as r2 where r1.a=r2.a; +select * from (select distinct a from t1 where b >= 'c') as r1, + (select distinct a from t1 where b >= 'c') as r2 + where r1.a=r2.a; +explain +with t as (select distinct a from t1 where b >= 'c') + select * from t as r1, t as r2 where r1.a=r2.a; +explain +select * from (select distinct a from t1 where b >= 'c') as r1, + (select distinct a from t1 where b >= 'c') as r2 + where r1.a=r2.a; + +--echo # two references to t specified by a query +--echo # selecting all fields: both in main query +with t as (select * from t1 where b >= 'c') + select * from t as r1, t as r2 where r1.a=r2.a; +select * from (select * from t1 where b >= 'c') as r1, + (select * from t1 where b >= 'c') as r2 + where r1.a=r2.a; +explain +with t as (select * from t1 where b >= 'c') + select * from t as r1, t as r2 where r1.a=r2.a; +explain +select * from (select * from t1 where b >= 'c') as r1, + (select * from t1 where b >= 'c') as r2 + where r1.a=r2.a; + +--echo # two references to t specifying explicitly column names +with t(c) as (select a from t1 where b >= 'c') + select * from t r1, t r2 where r1.c=r2.c; + +--echo # specification of t contains union +with t as (select a from t1 where b >= 'f' + union + select c as a from t2 where c < 4) + select * from t2,t where t2.c=t.a; +select * from t2, + (select a from t1 where b >= 'f' + union + select c as a from t2 where c < 4) as t + where t2.c=t.a; +explain +with t as (select a from t1 where b >= 'f' + union + select c as a from t2 where c < 4) + select * from t2,t where t2.c=t.a; +explain +select * from t2, + (select a from t1 where b >= 'f' + union + select c as a from t2 where c < 4) as t + where t2.c=t.a; + +--echo # t is defined in the with clause of a subquery +select t1.a,t1.b from t1,t2 + where t1.a>t2.c and + t2.c in (with t as (select * from t1 where t1.a<5) + select t2.c from t2,t where t2.c=t.a); +select t1.a,t1.b from t1,t2 + where t1.a>t2.c and + t2.c in (select t2.c + from t2,(select * from t1 where t1.a<5) as t + where t2.c=t.a); +explain +select t1.a,t1.b from t1,t2 + where t1.a>t2.c and + t2.c in (with t as (select * from t1 where t1.a<5) + select t2.c from t2,t where t2.c=t.a); +explain +select t1.a,t1.b from t1,t2 + where t1.a>t2.c and + t2.c in (select t2.c + from t2,(select * from t1 where t1.a<5) as t + where t2.c=t.a); + +--echo # two different definitions of t: one in the with clause of the main query, +--echo # the other in the with clause of a subquery +with t as (select c from t2 where c >= 4) + select t1.a,t1.b from t1,t + where t1.a=t.c and + t.c in (with t as (select * from t1 where t1.a<5) + select t2.c from t2,t where t2.c=t.a); +select t1.a,t1.b from t1, (select c from t2 where c >= 4) as t + where t1.a=t.c and + t.c in (select t2.c from t2, (select * from t1 where t1.a<5) as t + where t2.c=t.a); +explain +with t as (select c from t2 where c >= 4) + select t1.a,t1.b from t1,t + where t1.a=t.c and + t.c in (with t as (select * from t1 where t1.a<5) + select t2.c from t2,t where t2.c=t.a); +explain +select t1.a,t1.b from t1, (select c from t2 where c >= 4) as t + where t1.a=t.c and + t.c in (select t2.c from t2, (select * from t1 where t1.a<5) as t + where t2.c=t.a); + +--echo # another with table tt is defined in the with clause of a subquery +--echo # from the specification of t +with t as (select * from t1 + where a>2 and + b in (with tt as (select * from t2 where t2.c<5) + select t1.b from t1,tt where t1.a=tt.c)) + select t.a, count(*) from t1,t where t1.a=t.a group by t.a; +select t.a, count(*) + from t1, + (select * from t1 + where a>2 and + b in (select t1.b + from t1, + (select * from t2 where t2.c<5) as tt + where t1.a=tt.c)) as t + where t1.a=t.a group by t.a; +explain +with t as (select * from t1 + where a>2 and + b in (with tt as (select * from t2 where t2.c<5) + select t1.b from t1,tt where t1.a=tt.c)) + select t.a, count(*) from t1,t where t1.a=t.a group by t.a; +explain +select t.a, count(*) + from t1, + (select * from t1 + where a>2 and + b in (select t1.b + from t1, + (select * from t2 where t2.c<5) as tt + where t1.a=tt.c)) as t + where t1.a=t.a group by t.a; + +--echo # with clause in the specification of a derived table +select * + from t1, + (with t as (select a from t1 where b >= 'c') + select * from t2,t where t2.c=t.a) as tt + where t1.b > 'f' and tt.a=t1.a; +select * + from t1, + (select * from t2, + (select a from t1 where b >= 'c') as t + where t2.c=t.a) as tt + where t1.b > 'f' and tt.a=t1.a; +explain +select * + from t1, + (with t as (select a from t1 where b >= 'c') + select * from t2,t where t2.c=t.a) as tt + where t1.b > 'f' and tt.a=t1.a; +explain +select * + from t1, + (select * from t2, + (select a from t1 where b >= 'c') as t + where t2.c=t.a) as tt + where t1.b > 'f' and tt.a=t1.a; + +--echo # with claused in the specification of a view +create view v1 as +with t as (select a from t1 where b >= 'c') + select * from t2,t where t2.c=t.a; +show create view v1; +select * from v1; +explain +select * from v1; + +--echo # with claused in the specification of a materialized view +create view v2 as +with t as (select a, count(*) from t1 where b >= 'c' group by a) + select * from t2,t where t2.c=t.a; +show create view v2; +select * from v2; +explain +select * from v2; + +--echo # with clause in the specification of a view that whose definition +--echo # table alias for a with table +create view v3 as +with t(c) as (select a from t1 where b >= 'c') +select * from t r1 where r1.c=4; +show create view v3; +select * from v3; + +--echo # with clause in the specification of a view that whose definition +--echo # two table aliases for for the same with table +create view v4(c,d) as +with t(c) as (select a from t1 where b >= 'c') +select * from t r1, t r2 where r1.c=r2.c and r2.c=4; +show create view v4; +select * from v4; +explain +select * from v4; + +drop view v1,v2,v3,v4; + + +--echo # currently any views containing with clause are not updatable +create view v1(a) as +with t as (select a from t1 where b >= 'c') + select t.a from t2,t where t2.c=t.a; +--error ER_NON_UPDATABLE_TABLE +update v1 set a=0 where a > 4; +drop view v1; + + +--echo # prepare of a query containing a definition of a with table t +prepare stmt1 from " +with t as (select a from t1 where b >= 'c') + select * from t2,t where t2.c=t.a; +"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + +--echo # prepare of a query containing a definition of a materialized t +prepare stmt1 from " +with t as (select a, count(*) from t1 where b >= 'c' group by a) + select * from t2,t where t2.c=t.a; +"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + +--echo # prepare of a query containing two references to with table t +prepare stmt1 from " +with t as (select * from t1 where b >= 'c') + select * from t as r1, t as r2 where r1.a=r2.a; +"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + +--ERROR ER_WITH_COL_WRONG_LIST +with t(f) as (select * from t1 where b >= 'c') + select * from t2,t where t2.c=t.f1; + +--ERROR ER_DUP_FIELDNAME +with t(f1,f1) as (select * from t1 where b >= 'c') + select * from t2,t where t2.c=t.f1; + +--ERROR ER_DUP_QUERY_NAME +with t as (select * from t2 where c>3), + t as (select a from t1 where a>2) + select * from t,t1 where t1.a=t.c; + +--ERROR ER_WRONG_ORDER_IN_WITH_CLAUSE +with t as (select a from s where a<5), + s as (select a from t1 where b>='d') + select * from t,s where t.a=s.a; + +with recursive + t as (select a from s where a<5), + s as (select a from t1 where b>='d') + select * from t,s where t.a=s.a; + +--ERROR ER_RECURSIVE_QUERY_IN_WITH_CLAUSE +with recursive t as (select * from s where a>2), + s as (select a from t1,r where t1.a>r.c), + r as (select c from t,t2 where t.a=t2.c) + select * from r where r.c<7; + +--ERROR ER_RECURSIVE_QUERY_IN_WITH_CLAUSE +with t as (select * from s where a>2), + s as (select a from t1,r where t1.a>r.c), + r as (select c from t,t2 where t.a=t2.c) + select * from r where r.c<7; + +--ERROR ER_RECURSIVE_QUERY_IN_WITH_CLAUSE +with t as (select * from t1 + where a in (select c from s where b<='ccc') and b>'b'), + s as (select * from t1,t2 + where t1.a=t2.c and t1.c in (select a from t where a<5)) + select * from s where s.b>'aaa'; + +--ERROR ER_RECURSIVE_QUERY_IN_WITH_CLAUSE +with t as (select * from t1 where b>'aaa' and b <='d') + select t.b from t,t2 + where t.a=t2.c and + t2.c in (with s as (select t1.a from s,t1 where t1.a=s.a and t1.b<'c') + select * from s); +--echo #erroneous definition of unreferenced with table t +--ERROR ER_BAD_FIELD_ERROR +with t as (select count(*) from t1 where d>='f' group by a) + select t1.b from t2,t1 where t1.a = t2.c; + +with t as (select count(*) from t1 where b>='f' group by a) + select t1.b from t2,t1 where t1.a = t2.c; + +--echo #erroneous definition of s referring to unreferenced t +--ERROR ER_BAD_FIELD_ERROR +with t(d) as (select count(*) from t1 where b<='ccc' group by b), + s as (select * from t1 where a in (select t2.d from t2,t where t2.c=t.d)) + select t1.b from t1,t2 where t1.a=t2.c; +--ERROR ER_BAD_FIELD_ERROR +with t(d) as (select count(*) from t1 where b<='ccc' group by b), + s as (select * from t1 where a in (select t2.c from t2,t where t2.c=t.c)) + select t1.b from t1,t2 where t1.a=t2.c; + +with t(d) as (select count(*) from t1 where b<='ccc' group by b), + s as (select * from t1 where a in (select t2.c from t2,t where t2.c=t.d)) + select t1.b from t1,t2 where t1.a=t2.c; + +--echo #erroneous definition of unreferenced with table t +--ERROR ER_WITH_COL_WRONG_LIST +with t(f) as (select * from t1 where b >= 'c') + select t1.b from t2,t1 where t1.a = t2.c; + +--echo #erroneous definition of unreferenced with table t +--ERROR ER_DUP_FIELDNAME +with t(f1,f1) as (select * from t1 where b >= 'c') + select t1.b from t2,t1 where t1.a = t2.c; + +drop table t1,t2; diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test index 3e5fa873e9b..9ef4c8e2ae8 100644 --- a/mysql-test/t/ctype_uca.test +++ b/mysql-test/t/ctype_uca.test @@ -646,3 +646,24 @@ SET NAMES utf8; --echo # --echo # End of MariaDB-10.1 tests --echo # + + +--echo # +--echo # Start of MariaDB-10.2 tests +--echo # + +--echo # +--echo # MDEV-9407 Illegal mix of collation when using GROUP_CONCAT in a VIEW +--echo # +SET NAMES utf8; +CREATE TABLE t1 (col1 VARCHAR(12) CHARACTER SET utf8 COLLATE utf8_unicode_ci); +INSERT INTO t1 VALUES ('a'),('b'); +CREATE VIEW v1 AS SELECT group_concat('f') AS col1; +SELECT col1 FROM v1 UNION SELECT col1 FROM t1; +DROP VIEW v1; +DROP TABLE t1; + + +--echo # +--echo # End of MariaDB-10.2 tests +--echo # diff --git a/mysql-test/t/explain_json.test b/mysql-test/t/explain_json.test index 153d85359c9..22bfd5aedcd 100644 --- a/mysql-test/t/explain_json.test +++ b/mysql-test/t/explain_json.test @@ -394,5 +394,15 @@ set join_cache_level=@tmp_join_cache_level; drop table t1,t2,t3,t4; +--echo # +--echo # MDEV-9652: EXPLAIN FORMAT=JSON should show outer_ref_cond +--echo # +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int); +insert into t1 select a,a from t0; +explain format=json +select a, (select max(a) from t1 where t0.a<5 and t1.b<t0.a) from t0; +drop table t0,t1; diff --git a/mysql-test/t/mdev375.test b/mysql-test/t/mdev375.test index fe259b37808..92e403b6513 100644 --- a/mysql-test/t/mdev375.test +++ b/mysql-test/t/mdev375.test @@ -17,6 +17,7 @@ SELECT 2; --connection default SELECT 0; +show status like "Threads_connected"; SET GLOBAL log_warnings=default; SET GLOBAL max_connections=default; diff --git a/mysql-test/t/mysqlbinlog_raw_mode.test b/mysql-test/t/mysqlbinlog_raw_mode.test new file mode 100644 index 00000000000..26fb31516f6 --- /dev/null +++ b/mysql-test/t/mysqlbinlog_raw_mode.test @@ -0,0 +1,387 @@ +--source include/have_log_bin.inc +reset master; + +# we need this for getting fixed timestamps inside of this test +set timestamp=1000000000; + +--disable_warnings +drop table if exists t1; +--enable_warnings +CREATE TABLE t1 (c01 BIT); +INSERT INTO t1 VALUES (0); +INSERT INTO t1 VALUES (1); +DROP TABLE t1; + +CREATE TABLE t1 (c01 BIT(7)); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (4); +INSERT INTO t1 VALUES (8); +INSERT INTO t1 VALUES (16); +INSERT INTO t1 VALUES (32); +INSERT INTO t1 VALUES (64); +INSERT INTO t1 VALUES (127); +DELETE FROM t1 WHERE c01=127; +UPDATE t1 SET c01=15 WHERE c01=16; +DROP TABLE t1; + +CREATE TABLE t1 (a BIT(20), b CHAR(2)); +INSERT INTO t1 VALUES (b'00010010010010001001', 'ab'); +DROP TABLE t1; + +CREATE TABLE t1 (c02 BIT(64)); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (128); +INSERT INTO t1 VALUES (b'1111111111111111111111111111111111111111111111111111111111111111'); +DROP TABLE t1; + + +CREATE TABLE t1 (c03 TINYINT); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t1 VALUES (-128); +UPDATE t1 SET c03=2 WHERE c03=1; +DELETE FROM t1 WHERE c03=-128; +DROP TABLE t1; + +CREATE TABLE t1 (c04 TINYINT UNSIGNED); +INSERT INTO t1 VALUES (128), (255); +UPDATE t1 SET c04=2 WHERE c04=1; +DELETE FROM t1 WHERE c04=255; +DROP TABLE t1; + +CREATE TABLE t1 (c06 BOOL); +INSERT INTO t1 VALUES (TRUE); +DELETE FROM t1 WHERE c06=TRUE; +DROP TABLE t1; + +CREATE TABLE t1 (c07 SMALLINT); +INSERT INTO t1 VALUES (1234); +DELETE FROM t1 WHERE c07=1234; +DROP TABLE t1; + +CREATE TABLE t1 (c08 SMALLINT UNSIGNED); +INSERT INTO t1 VALUES (32768), (65535); +UPDATE t1 SET c08=2 WHERE c08=32768; +DELETE FROM t1 WHERE c08=65535; +DROP TABLE t1; + +CREATE TABLE t1 (c10 MEDIUMINT); +INSERT INTO t1 VALUES (12345); +DELETE FROM t1 WHERE c10=12345; +DROP TABLE t1; + +CREATE TABLE t1 (c11 MEDIUMINT UNSIGNED); +INSERT INTO t1 VALUES (8388608), (16777215); +UPDATE t1 SET c11=2 WHERE c11=8388608; +DELETE FROM t1 WHERE c11=16777215; +DROP TABLE t1; + +CREATE TABLE t1 (c13 INT); +INSERT INTO t1 VALUES (123456); +DELETE FROM t1 WHERE c13=123456; +DROP TABLE t1; + +CREATE TABLE t1 (c14 INT UNSIGNED); +INSERT INTO t1 VALUES (2147483648), (4294967295); +UPDATE t1 SET c14=2 WHERE c14=2147483648; +DELETE FROM t1 WHERE c14=4294967295; +DROP TABLE t1; + +CREATE TABLE t1 (c16 BIGINT); +INSERT INTO t1 VALUES (1234567890); +DELETE FROM t1 WHERE c16=1234567890; +DROP TABLE t1; + +CREATE TABLE t1 (c17 BIGINT UNSIGNED); +INSERT INTO t1 VALUES (9223372036854775808), (18446744073709551615); +UPDATE t1 SET c17=2 WHERE c17=9223372036854775808; +DELETE FROM t1 WHERE c17=18446744073709551615; +DROP TABLE t1; + +CREATE TABLE t1 (c19 FLOAT); +INSERT INTO t1 VALUES (123.2234); +DELETE FROM t1 WHERE c19>123; +DROP TABLE t1; + +CREATE TABLE t1 (c22 DOUBLE); +INSERT INTO t1 VALUES (123434.22344545); +DELETE FROM t1 WHERE c22>123434; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c25 DECIMAL(10,5)); +INSERT INTO t1 VALUES (124.45); +INSERT INTO t1 VALUES (-543.21); +DELETE FROM t1 WHERE c25=124.45; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c28 DATE); +INSERT INTO t1 VALUES ('2001-02-03'); +DELETE FROM t1 WHERE c28='2001-02-03'; +DROP TABLE t1; + +CREATE TABLE t1 (c29 DATETIME); +INSERT INTO t1 VALUES ('2001-02-03 10:20:30'); +DELETE FROM t1 WHERE c29='2001-02-03 10:20:30'; +DROP TABLE t1; + +CREATE TABLE t1 (c30 TIMESTAMP); +INSERT INTO t1 VALUES ('2001-02-03 10:20:30'); +DELETE FROM t1 WHERE c30='2001-02-03 10:20:30'; +DROP TABLE t1; + +CREATE TABLE t1 (c31 TIME); +INSERT INTO t1 VALUES ('11:22:33'); +DELETE FROM t1 WHERE c31='11:22:33'; +DROP TABLE t1; + +CREATE TABLE t1 (c32 YEAR); +INSERT INTO t1 VALUES ('2001'); +DELETE FROM t1 WHERE c32=2001; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c33 CHAR); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c33='a'; +DROP TABLE t1; + +CREATE TABLE t1 (c34 CHAR(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c34=''; +DROP TABLE t1; + +CREATE TABLE t1 (c35 CHAR(1)); +INSERT INTO t1 VALUES ('b'); +DELETE FROM t1 WHERE c35='b'; +DROP TABLE t1; + +CREATE TABLE t1 (c36 CHAR(255)); +INSERT INTO t1 VALUES (repeat('c',255)); +DELETE FROM t1 WHERE c36>'c'; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c37 NATIONAL CHAR); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c37='a'; +DROP TABLE t1; + +CREATE TABLE t1 (c38 NATIONAL CHAR(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c38=''; +DROP TABLE t1; + +CREATE TABLE t1 (c39 NATIONAL CHAR(1)); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c39='a'; +DROP TABLE t1; + +CREATE TABLE t1 (c40 NATIONAL CHAR(255)); +INSERT INTO t1 VALUES (repeat('a', 255)); +INSERT INTO t1 VALUES (repeat(_latin1 0xDF, 255)); +DELETE FROM t1 WHERE c40>'a'; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c45 VARCHAR(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c45=''; +DROP TABLE t1; + +CREATE TABLE t1 (c46 VARCHAR(1)); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c46='a'; +DROP TABLE t1; + +CREATE TABLE t1 (c47 VARCHAR(255)); +INSERT INTO t1 VALUES (repeat('a',255)); +DELETE FROM t1 WHERE c47>'a'; +DROP TABLE t1; + +CREATE TABLE t1 (c48 VARCHAR(261)); +INSERT INTO t1 VALUES (repeat('a',261)); +DELETE FROM t1 WHERE c48>'a'; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c49 NATIONAL VARCHAR(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c49=''; +DROP TABLE t1; + +CREATE TABLE t1 (c50 NATIONAL VARCHAR(1)); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c50='a'; +DROP TABLE t1; + +CREATE TABLE t1 (c51 NATIONAL VARCHAR(255)); +INSERT INTO t1 VALUES (repeat('a',255)); +INSERT INTO t1 VALUES (repeat(_latin1 0xDF, 255)); +DELETE FROM t1 WHERE c51>'a'; +DROP TABLE t1; + +CREATE TABLE t1 (c52 NATIONAL VARCHAR(261)); +INSERT INTO t1 VALUES (repeat('a',261)); +INSERT INTO t1 VALUES (repeat(_latin1 0xDF, 261)); +DELETE FROM t1 WHERE c52>'a'; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c57 BINARY); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c57='a'; +DROP TABLE t1; + +CREATE TABLE t1 (c58 BINARY(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c58=''; +DROP TABLE t1; + +CREATE TABLE t1 (c59 BINARY(1)); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c59='a'; +DROP TABLE t1; + +CREATE TABLE t1 (c60 BINARY(255)); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES (repeat('a\0',120)); +DELETE FROM t1 WHERE c60<0x02; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c61 VARBINARY(0)); +INSERT INTO t1 VALUES (''); +DELETE FROM t1 WHERE c61=''; +DROP TABLE t1; + +CREATE TABLE t1 (c62 VARBINARY(1)); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES ('a'); +DELETE FROM t1 WHERE c62=0x02; +DROP TABLE t1; + +CREATE TABLE t1 (c63 VARBINARY(255)); +INSERT INTO t1 VALUES (0x00); +INSERT INTO t1 VALUES (0x02); +INSERT INTO t1 VALUES (repeat('a\0',120)); +DELETE FROM t1 WHERE c63=0x02; +DROP TABLE t1; + +# +flush logs; + +CREATE TABLE t1 (c65 TINYBLOB); +INSERT INTO t1 VALUES ('tinyblob1'); +DELETE FROM t1 WHERE c65='tinyblob1'; +DROP TABLE t1; + +CREATE TABLE t1 (c68 BLOB); +INSERT INTO t1 VALUES ('blob1'); +DELETE FROM t1 WHERE c68='blob1'; +DROP TABLE t1; + +CREATE TABLE t1 (c71 MEDIUMBLOB); +INSERT INTO t1 VALUES ('mediumblob1'); +DELETE FROM t1 WHERE c71='mediumblob1'; +DROP TABLE t1; + +CREATE TABLE t1 (c74 LONGBLOB); +INSERT INTO t1 VALUES ('longblob1'); +DELETE FROM t1 WHERE c74='longblob1'; +DROP TABLE t1; + +CREATE TABLE t1 (c66 TINYTEXT); +INSERT INTO t1 VALUES ('tinytext1'); +DELETE FROM t1 WHERE c66='tinytext1'; +DROP TABLE t1; + +CREATE TABLE t1 (c69 TEXT); +INSERT INTO t1 VALUES ('text1'); +DELETE FROM t1 WHERE c69='text1'; +DROP TABLE t1; + +CREATE TABLE t1 (c72 MEDIUMTEXT); +INSERT INTO t1 VALUES ('mediumtext1'); +DELETE FROM t1 WHERE c72='mediumtext1'; +DROP TABLE t1; + +CREATE TABLE t1 (c75 LONGTEXT); +INSERT INTO t1 VALUES ('longtext1'); +DELETE FROM t1 WHERE c75='longtext1'; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c77 ENUM('a','b','c')); +INSERT INTO t1 VALUES ('b'); +DELETE FROM t1 WHERE c77='b'; +DROP TABLE t1; + +# + +CREATE TABLE t1 (c78 SET('a','b','c','d','e','f')); +INSERT INTO t1 VALUES ('a,b'); +INSERT INTO t1 VALUES ('a,c'); +INSERT INTO t1 VALUES ('b,c'); +INSERT INTO t1 VALUES ('a,b,c'); +INSERT INTO t1 VALUES ('a,b,c,d'); +INSERT INTO t1 VALUES ('a,b,c,d,e'); +INSERT INTO t1 VALUES ('a,b,c,d,e,f'); +DELETE FROM t1 WHERE c78='a,b'; +DROP TABLE t1; + +# +# Check multi-table update +# +CREATE TABLE t1 (a int NOT NULL DEFAULT 0, b int NOT NULL DEFAULT 0); +CREATE TABLE t2 (a int NOT NULL DEFAULT 0, b int NOT NULL DEFAULT 0); +INSERT INTO t1 SET a=1; +INSERT INTO t1 SET b=1; +INSERT INTO t2 SET a=1; +INSERT INTO t2 SET b=1; +UPDATE t1, t2 SET t1.a=10, t2.a=20; +DROP TABLE t1,t2; + +flush logs; + +let $MYSQLD_DATADIR= `select @@datadir`; + +# Test reading one file in raw mode +--exec $MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --result-file=$MYSQLTEST_VARDIR/tmp/ master-bin.000001 +--diff_files $MYSQLTEST_VARDIR/tmp/master-bin.000001 $MYSQLD_DATADIR/master-bin.000001 +--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000001 + +# Test reading all files in raw mode +# Don't test the end file since this is still open with mysqld so will be different +--exec $MYSQL_BINLOG --raw --read-from-remote-server --to-last-log --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --result-file=$MYSQLTEST_VARDIR/tmp/ master-bin.000001 +--diff_files $MYSQLTEST_VARDIR/tmp/master-bin.000001 $MYSQLD_DATADIR/master-bin.000001 +--diff_files $MYSQLTEST_VARDIR/tmp/master-bin.000002 $MYSQLD_DATADIR/master-bin.000002 + +--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000001 +--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000002 +--remove_file $MYSQLTEST_VARDIR/tmp/master-bin.000003 + + +# Test output to different filename +--exec $MYSQL_BINLOG --raw --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --result-file=$MYSQLTEST_VARDIR/tmp/server1- master-bin.000001 +--diff_files $MYSQLTEST_VARDIR/tmp/server1-master-bin.000001 $MYSQLD_DATADIR/master-bin.000001 +--remove_file $MYSQLTEST_VARDIR/tmp/server1-master-bin.000001 + +--echo End of tests diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index d7aba43999e..12fd968b212 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -31,7 +31,7 @@ perl; connect null-audit aria oqgraph sphinx thread-handling test-sql-discovery rpl-semi-sync query-cache-info query-response-time metadata-lock-info locales unix-socket - wsrep file-key-management cracklib-password-check/; + wsrep file-key-management cracklib-password-check user-variables/; # And substitute the content some environment variables with their # names: diff --git a/mysql-test/t/show_create_user.test b/mysql-test/t/show_create_user.test new file mode 100644 index 00000000000..a10c8aeeda6 --- /dev/null +++ b/mysql-test/t/show_create_user.test @@ -0,0 +1,34 @@ +--source include/not_embedded.inc + +create user foo; +show create user foo; + +create user foo@test; +show create user foo@test; + +create user foo2@test identified by 'password'; +show create user foo2@test; + +alter user foo2@test identified with 'someplugin' as 'somepassword'; +show create user foo2@test; + +create user foo3@test require SSL; +show create user foo3@test; + +create user foo4@test require cipher 'text' issuer 'foo_issuer' subject 'foo_subject'; +show create user foo4@test; + +create user foo5@test require SSL + with MAX_QUERIES_PER_HOUR 10 + MAX_UPDATES_PER_HOUR 20 + MAX_CONNECTIONS_PER_HOUR 30 + MAX_USER_CONNECTIONS 40 + MAX_STATEMENT_TIME 0.5; +show create user foo5@test; + +drop user foo5@test; +drop user foo4@test; +drop user foo3@test; +drop user foo2@test; +drop user foo@test; +drop user foo; diff --git a/mysql-test/t/shutdown.test b/mysql-test/t/shutdown.test index ac7f06b116d..7080f9a1a71 100644 --- a/mysql-test/t/shutdown.test +++ b/mysql-test/t/shutdown.test @@ -30,3 +30,10 @@ drop procedure try_shutdown; drop user user1@localhost; +--echo # +--echo # MDEV-8491 - On shutdown, report the user and the host executed that. +--echo # +--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_RANGE= -50000 +--let SEARCH_PATTERN=mysqld(\.exe)? \(root\[root\] @ localhost \[(::1)?\]\): Normal shutdown +--source include/search_pattern_in_file.inc diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index a47fbe7a372..d403b19eff7 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -1093,7 +1093,7 @@ delimiter ;| # --error ER_SP_BADSTATEMENT CREATE PROCEDURE BUG_12490() HELP CONTENTS; ---error ER_SP_BADSTATEMENT +--error ER_PARSE_ERROR CREATE FUNCTION BUG_12490() RETURNS INT HELP CONTENTS; CREATE TABLE t_bug_12490(a int); --error ER_SP_BADSTATEMENT diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 444ab02d223..7c9d56a0780 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -695,3 +695,51 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9337 ALTER from DECIMAL and INT to DATETIME returns a wrong result +--echo # +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES (1000); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DATETIME); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (1000); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1000); +ALTER TABLE t1 MODIFY a DATETIME; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a DATETIME); +INSERT INTO t1 VALUES (1000.0); +SELECT * FROM t1; +DROP TABLE IF EXISTS t1; + +CREATE TABLE t1 (a DATETIME); +CREATE TABLE t2 (a DECIMAL(4,0)); +INSERT INTO t2 VALUES (1000); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DECIMAL(4,0)); +INSERT INTO t1 VALUES (1000); +ALTER TABLE t1 MODIFY a DATETIME; +SELECT * FROM t1; +DROP TABLE t1; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test index 314cb237dd3..63e9e9e7b09 100644 --- a/mysql-test/t/type_enum.test +++ b/mysql-test/t/type_enum.test @@ -388,3 +388,65 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + + +--echo # +--echo # MDEV-9340 Copying from INT/DOUBLE to ENUM is inconsistent +--echo # + +# DOUBLE -> ENUM +CREATE TABLE t1 (a ENUM('9e200','9e100')); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES ('9e100'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (9e100); +ALTER TABLE t1 MODIFY a ENUM('9e200','9e100'); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +# INT -> ENUM +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES ('200'); +ALTER TABLE t1 MODIFY a ENUM('200','100'); +SELECT *FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a ENUM('200','100')); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES ('100'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + + +# YEAR -> ENUM +CREATE TABLE t1 (a ENUM('2001','2002')); +CREATE TABLE t2 (a YEAR); +INSERT INTO t2 VALUES ('2001'); +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES ('2001'); +ALTER TABLE t1 MODIFY a ENUM('2001','2002'); +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 3717dc028ba..ec0256beeef 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -458,3 +458,57 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-4102 Limitation on DOUBLE or REAL length is ignored with INSERT .. SELECT +--echo # +CREATE TABLE t1 (d1 DOUBLE(5,2), d2 DOUBLE(10,2)); +INSERT INTO t1 VALUES (10000000.55, 10000000.55); +INSERT INTO t1 SELECT d2, d2 FROM t1; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # MDEV-9709 Unexpected modification of value and warning about out of range value upon ALTER +--echo # + +CREATE TABLE t1 ( + f FLOAT, + d10_10 DOUBLE PRECISION (10,10), + d53_10 DOUBLE(53,10) +); +INSERT INTO t1 (f,d10_10,d53_10) VALUES ( + -9999999999999999999999999999999999999999999.9999999999, + -9999999999999999999999999999999999999999999.9999999999, + -9999999999999999999999999999999999999999999.9999999999 +); +--vertical_results +SELECT * FROM t1; +INSERT INTO t1 (f,d10_10,d53_10) SELECT d53_10, d53_10, d53_10 FROM t1; +SELECT * FROM t1; +ALTER TABLE t1 ADD COLUMN i INT; +SELECT * FROM t1; +DROP TABLE t1; +--horizontal_results + +CREATE TABLE t1 (d10_10 DOUBLE (10,10)); +CREATE TABLE t2 (d53_10 DOUBLE (53,10)); +INSERT INTO t2 VALUES (-9999999999999999999999999999999999999999999.9999999999); +INSERT INTO t1 (d10_10) SELECT d53_10 FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (d2_2 FLOAT (2,2)); +CREATE TABLE t2 (d4_2 FLOAT (4,2)); +INSERT INTO t2 VALUES (99.99); +INSERT INTO t1 (d2_2) SELECT d4_2 FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_int.test b/mysql-test/t/type_int.test index e8b9b2cffcd..271b4d5862a 100644 --- a/mysql-test/t/type_int.test +++ b/mysql-test/t/type_int.test @@ -26,3 +26,53 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field +--echo # + +# DECIMAL -> INT +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (10.1),(10.9); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a DECIMAL(10,2)); +INSERT INTO t2 VALUES (10.1),(10.9); +INSERT INTO t1 SELECT a FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DECIMAL(10,2)); +INSERT INTO t1 VALUES (10.1),(10.9); +ALTER TABLE t1 MODIFY a INT; +SELECT * FROM t1; +DROP TABLE t1; + +# TIME -> INT +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (TIME'00:00:10.1'),(TIME'00:00:10.9'); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a TIME(1)); +INSERT INTO t2 VALUES (10.1),(10.9); +INSERT INTO t1 SELECT a FROM t2; +SELECT * FROM t1; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a TIME(1)); +INSERT INTO t1 VALUES (10.1),(10.9); +ALTER TABLE t1 MODIFY a INT; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_num_innodb.test b/mysql-test/t/type_num_innodb.test new file mode 100644 index 00000000000..04bdd4c63b0 --- /dev/null +++ b/mysql-test/t/type_num_innodb.test @@ -0,0 +1,41 @@ +--source include/have_innodb.inc + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9391 InnoDB does not produce warnings when doing WHERE int_column=varchar_column +--echo # + +CREATE TABLE t1 ( + a DOUBLE, b VARCHAR(1), c INT, + KEY(a), KEY(b) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5), +(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9), +(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4), +(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0); +CREATE TABLE t2 ( + pk INT, d VARCHAR(1), e INT, + PRIMARY KEY(pk), KEY(d,e) +) ENGINE=InnoDB; +INSERT INTO t2 VALUES +(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5), +(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1), +(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5), +(15,'g',6),(16,'x',7),(17,'f',8); +SELECT * FROM t1,t2 WHERE a=d; + +ALTER TABLE t1 MODIFY a DECIMAL(10,0); +SELECT * FROM t1,t2 WHERE a=d; + +ALTER TABLE t1 MODIFY a DOUBLE; +SELECT * FROM t1,t2 WHERE a=d; + +DROP TABLE t1,t2; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index 27679b9ec5a..c4b93d6dbb2 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -726,3 +726,25 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + + +--echo # +--echo # MDEV-9393 Split Copy_field::get_copy_func() into virtual methods in Field +--echo # + +CREATE TABLE t1 (a YEAR, b TIME, c YEAR); +CREATE TABLE t2 (a YEAR); +INSERT INTO t2 VALUES (0),(1999),(2000),(2030),(2050),(2070); +INSERT INTO t1 (a,b,c) SELECT a,a,a FROM t2; +ALTER TABLE t1 MODIFY c TIME; +SELECT * FROM t1; +DROP TABLE t1,t2; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index d9fa2af1eb4..22f164a757c 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -210,3 +210,45 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9392 Copying from DECIMAL to YEAR is not consistent about warnings +--echo # +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES (-0.1); +DROP TABLE t1; + +CREATE TABLE t1 (a YEAR); +CREATE TABLE t2 (a DECIMAL(10,1)); +INSERT INTO t2 VALUES (-0.1); +INSERT INTO t1 SELECT * FROM t2; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DECIMAL(10,1)); +INSERT INTO t1 VALUES (-0.1); +ALTER TABLE t1 MODIFY a YEAR; +DROP TABLE t1; + +CREATE TABLE t1 (a YEAR); +INSERT INTO t1 VALUES (-0.1e0); +DROP TABLE t1; + +CREATE TABLE t1 (a YEAR); +CREATE TABLE t2 (a DOUBLE); +INSERT INTO t2 VALUES (-0.1); +INSERT INTO t1 SELECT * FROM t2; +DROP TABLE t1,t2; + +CREATE TABLE t1 (a DOUBLE); +INSERT INTO t1 VALUES (-0.1); +ALTER TABLE t1 MODIFY a YEAR; +DROP TABLE t1; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index f1288e6a63d..83b7e5839ef 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5768,3 +5768,31 @@ drop table t1; --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-9408 CREATE TABLE SELECT MAX(int_column) creates different columns for table vs view +--echo # +CREATE TABLE t1 ( + id int(11) NOT NULL PRIMARY KEY, + country varchar(32), + code int(11) default NULL +); +INSERT INTO t1 VALUES (1,'ITALY',100),(2,'ITALY',200),(3,'FRANCE',100), (4,'ITALY',100); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 AS +SELECT code, COUNT(DISTINCT country), MAX(id) FROM t1 GROUP BY code ORDER BY MAX(id); +SHOW CREATE TABLE t2; +CREATE TABLE t3 AS +SELECT code, COUNT(DISTINCT country), MAX(id) FROM v1 GROUP BY code ORDER BY MAX(id); +SHOW CREATE TABLE t3; +DROP VIEW v1; +DROP TABLE t1,t2,t3; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 3263459bd72..3077415b243 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -1068,7 +1068,7 @@ static void link_into_queue(KEYCACHE_WQUEUE *wqueue, static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, struct st_my_thread_var *thread) { - KEYCACHE_DBUG_PRINT("unlink_from_queue", ("thread %ld", thread->id)); + KEYCACHE_DBUG_PRINT("unlink_from_queue", ("thread %ld", (ulong) thread->id)); DBUG_ASSERT(thread->next && thread->prev); if (thread->next == thread) @@ -1145,7 +1145,7 @@ static void wait_on_queue(KEYCACHE_WQUEUE *wqueue, */ do { - KEYCACHE_DBUG_PRINT("wait", ("suspend thread %ld", thread->id)); + KEYCACHE_DBUG_PRINT("wait", ("suspend thread %ld", (ulong) thread->id)); keycache_pthread_cond_wait(&thread->suspend, mutex); } while (thread->next); @@ -1184,7 +1184,7 @@ static void release_whole_queue(KEYCACHE_WQUEUE *wqueue) thread=next; DBUG_ASSERT(thread && thread->init == 1); KEYCACHE_DBUG_PRINT("release_whole_queue: signal", - ("thread %ld", thread->id)); + ("thread %ld", (ulong) thread->id)); /* Take thread from queue. */ next= thread->next; thread->next= NULL; @@ -1388,7 +1388,8 @@ static void link_block(SIMPLE_KEY_CACHE_CB *keycache, BLOCK_LINK *block, */ if ((HASH_LINK *) thread->keycache_link == hash_link) { - KEYCACHE_DBUG_PRINT("link_block: signal", ("thread %ld", thread->id)); + KEYCACHE_DBUG_PRINT("link_block: signal", + ("thread %ld", (ulong) thread->id)); keycache_pthread_cond_signal(&thread->suspend); unlink_from_queue(&keycache->waiting_for_block, thread); block->requests++; @@ -1677,7 +1678,7 @@ static void wait_for_readers(SIMPLE_KEY_CACHE_CB *keycache, { KEYCACHE_DBUG_PRINT("wait_for_readers: wait", ("suspend thread %ld block %u", - thread->id, BLOCK_NUMBER(block))); + (ulong) thread->id, BLOCK_NUMBER(block))); /* There must be no other waiter. We have no queue here. */ DBUG_ASSERT(!block->condvar); block->condvar= &thread->suspend; @@ -1737,7 +1738,8 @@ static void unlink_hash(SIMPLE_KEY_CACHE_CB *keycache, HASH_LINK *hash_link) */ if (page->file == hash_link->file && page->filepos == hash_link->diskpos) { - KEYCACHE_DBUG_PRINT("unlink_hash: signal", ("thread %ld", thread->id)); + KEYCACHE_DBUG_PRINT("unlink_hash: signal", + ("thread %ld", (ulong) thread->id)); keycache_pthread_cond_signal(&thread->suspend); unlink_from_queue(&keycache->waiting_for_hash_link, thread); } @@ -1821,7 +1823,7 @@ restart: thread->keycache_link= (void *) &page; link_into_queue(&keycache->waiting_for_hash_link, thread); KEYCACHE_DBUG_PRINT("get_hash_link: wait", - ("suspend thread %ld", thread->id)); + ("suspend thread %ld", (ulong) thread->id)); keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); thread->keycache_link= NULL; @@ -1987,7 +1989,7 @@ restart: do { KEYCACHE_DBUG_PRINT("find_key_block: wait", - ("suspend thread %ld", thread->id)); + ("suspend thread %ld", (ulong) thread->id)); keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); } while (thread->next); @@ -2334,7 +2336,7 @@ restart: do { KEYCACHE_DBUG_PRINT("find_key_block: wait", - ("suspend thread %ld", thread->id)); + ("suspend thread %ld", (ulong) thread->id)); keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock); } @@ -4585,7 +4587,7 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache) KEYCACHE_PAGE *page; uint i; - fprintf(keycache_dump_file, "thread:%u\n", thread->id); + fprintf(keycache_dump_file, "thread:%lu\n", (ulong) thread->id); i=0; thread=last=waiting_for_hash_link.last_thread; @@ -4596,8 +4598,8 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache) thread=thread->next; page= (KEYCACHE_PAGE *) thread->keycache_link; fprintf(keycache_dump_file, - "thread:%u, (file,filepos)=(%u,%lu)\n", - thread->id,(uint) page->file,(ulong) page->filepos); + "thread:%lu, (file,filepos)=(%u,%lu)\n", + (ulong) thread->id,(uint) page->file,(ulong) page->filepos); if (++i == MAX_QUEUE_LEN) break; } @@ -4612,8 +4614,8 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache) thread=thread->next; hash_link= (HASH_LINK *) thread->keycache_link; fprintf(keycache_dump_file, - "thread:%u hash_link:%u (file,filepos)=(%u,%lu)\n", - thread->id, (uint) HASH_LINK_NUMBER(hash_link), + "thread:%lu hash_link:%u (file,filepos)=(%u,%lu)\n", + (ulong) thread->id, (uint) HASH_LINK_NUMBER(hash_link), (uint) hash_link->file,(ulong) hash_link->diskpos); if (++i == MAX_QUEUE_LEN) break; @@ -4640,7 +4642,7 @@ static void keycache_dump(SIMPLE_KEY_CACHE_CB *keycache) { thread=thread->next; fprintf(keycache_dump_file, - "thread:%u\n", thread->id); + "thread:%lu\n", (ulong) thread->id); if (++i == MAX_QUEUE_LEN) break; } diff --git a/mysys/my_context.c b/mysys/my_context.c index 60c0014b3b9..5faa041361a 100644 --- a/mysys/my_context.c +++ b/mysys/my_context.c @@ -24,7 +24,7 @@ #include "m_string.h" #include "my_context.h" -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H #include <valgrind/valgrind.h> #endif @@ -134,7 +134,7 @@ my_context_init(struct my_context *c, size_t stack_size) if (!(c->stack= malloc(stack_size))) return -1; /* Out of memory */ c->stack_size= stack_size; -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H c->valgrind_stack_id= VALGRIND_STACK_REGISTER(c->stack, ((unsigned char *)(c->stack))+stack_size); #endif @@ -146,7 +146,7 @@ my_context_destroy(struct my_context *c) { if (c->stack) { -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id); #endif free(c->stack); @@ -384,7 +384,7 @@ my_context_init(struct my_context *c, size_t stack_size) (( ((intptr)c->stack_bot + stack_size) & ~(intptr)0xf) - 16); bzero(c->stack_top, 16); -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H c->valgrind_stack_id= VALGRIND_STACK_REGISTER(c->stack_bot, c->stack_top); #endif @@ -397,7 +397,7 @@ my_context_destroy(struct my_context *c) if (c->stack_bot) { free(c->stack_bot); -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id); #endif } @@ -620,7 +620,7 @@ my_context_init(struct my_context *c, size_t stack_size) (( ((intptr)c->stack_bot + stack_size) & ~(intptr)0xf) - 16); bzero(c->stack_top, 16); -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H c->valgrind_stack_id= VALGRIND_STACK_REGISTER(c->stack_bot, c->stack_top); #endif @@ -633,7 +633,7 @@ my_context_destroy(struct my_context *c) if (c->stack_bot) { free(c->stack_bot); -#ifdef HAVE_VALGRIND +#ifdef HAVE_VALGRIND_MEMCHECK_H VALGRIND_STACK_DEREGISTER(c->valgrind_stack_id); #endif } diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 5d19647c989..9916650308a 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -55,6 +55,9 @@ struct st_irem struct st_irem *next; /* Linked list of structures */ struct st_irem *prev; /* Other link */ size_t datasize; /* Size requested */ +#if SIZEOF_SIZE_T == 4 + size_t pad; /* Compensate 32bit datasize */ +#endif #ifdef HAVE_BACKTRACE void *frame[SF_REMEMBER_FRAMES]; /* call stack */ #endif @@ -375,7 +378,7 @@ void sf_report_leaked_memory(my_thread_id id) { my_thread_id tid = irem->thread_id && irem->flags & MY_THREAD_SPECIFIC ? irem->thread_id : 0; - fprintf(stderr, "Warning: %4lu bytes lost at %p, allocated by T@%lu at ", + fprintf(stderr, "Warning: %4lu bytes lost at %p, allocated by T@%llu at ", (ulong) irem->datasize, (char*) (irem + 1), tid); print_stack(irem->frame); total+= irem->datasize; diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 8990cbd5a14..da653b12314 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -772,7 +772,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) mysql_mutex_lock(&lock->mutex); DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx type: %d", - (long) data, data->owner->thread_id, + (long) data, (ulong) data->owner->thread_id, (long) lock, (int) lock_type)); check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ? "enter read_lock" : "enter write_lock", lock_type, 0); @@ -809,7 +809,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) */ DBUG_PRINT("lock",("write locked 1 by thread: 0x%lx", - lock->write.data->owner->thread_id)); + (ulong) lock->write.data->owner->thread_id)); if (thr_lock_owner_equal(data->owner, lock->write.data->owner) || (lock->write.data->type <= TL_WRITE_DELAYED && (((int) lock_type <= (int) TL_READ_HIGH_PRIORITY) || @@ -968,7 +968,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) goto end; } DBUG_PRINT("lock",("write locked 2 by thread: 0x%lx", - lock->write.data->owner->thread_id)); + (ulong) lock->write.data->owner->thread_id)); } else { @@ -1004,7 +1004,8 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner, ulong lock_wait_timeout) } } DBUG_PRINT("lock",("write locked 3 by thread: 0x%lx type: %d", - lock->read.data->owner->thread_id, data->type)); + (ulong) lock->read.data->owner->thread_id, + data->type)); } #ifdef WITH_WSREP if (wsrep_break_lock(data, &lock->write, &lock->write_wait)) @@ -1069,7 +1070,7 @@ static inline void free_all_read_locks(THR_LOCK *lock, } /* purecov: begin inspected */ DBUG_PRINT("lock",("giving read lock to thread: 0x%lx", - data->owner->thread_id)); + (ulong) data->owner->thread_id)); /* purecov: end */ data->cond=0; /* Mark thread free */ mysql_cond_signal(cond); @@ -1087,8 +1088,9 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags) THR_LOCK *lock=data->lock; enum thr_lock_type lock_type=data->type; DBUG_ENTER("thr_unlock"); - DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx", - (long) data, data->owner->thread_id, (long) lock)); + DBUG_PRINT("lock",("data: %p thread: 0x%lx lock: %p", + data, (ulong) data->owner->thread_id, + lock)); mysql_mutex_lock(&lock->mutex); check_locks(lock,"start of release lock", lock_type, 0); @@ -1181,7 +1183,7 @@ static void wake_up_waiters(THR_LOCK *lock) data->type=TL_WRITE; /* Upgrade lock */ /* purecov: begin inspected */ DBUG_PRINT("lock",("giving write lock of type %d to thread: 0x%lx", - data->type, data->owner->thread_id)); + data->type, (ulong) data->owner->thread_id)); /* purecov: end */ { mysql_cond_t *cond= data->cond; @@ -1423,9 +1425,9 @@ void thr_multi_unlock(THR_LOCK_DATA **data,uint count, uint unlock_flags) thr_unlock(*pos, unlock_flags); else { - DBUG_PRINT("lock",("Free lock: data: 0x%lx thread: 0x%lx lock: 0x%lx", - (long) *pos, (*pos)->owner->thread_id, - (long) (*pos)->lock)); + DBUG_PRINT("lock",("Free lock: data: %p thread: 0x%lx lock: %p", + *pos, (ulong) (*pos)->owner->thread_id, + (*pos)->lock)); } } DBUG_VOID_RETURN; @@ -1673,7 +1675,7 @@ static void thr_print_lock(const char* name,struct st_lock_list *list) prev= &list->data; for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next) { - printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->thread_id, + printf("%p (%lu:%d); ", data, (ulong) data->owner->thread_id, (int) data->type); if (data->prev != prev) printf("\nWarning: prev didn't point at previous lock\n"); diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index 18af5f47b10..f1e83db2bb6 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -105,8 +105,6 @@ void my_mutex_init() #if defined(SAFE_MUTEX_DEFINED) safe_mutex_global_init(); -#elif defined(MY_PTHREAD_FASTMUTEX) - fastmutex_global_init(); #endif } @@ -512,7 +510,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, fprintf(stderr, "safe_mutex: Count was %d in thread 0x%lx when locking mutex %s " "at %s, line %d\n", - mp->count-1, my_thread_dbug_id(), mp->name, file, line); + mp->count-1, (ulong) my_thread_dbug_id(), mp->name, file, line); fflush(stderr); abort(); } @@ -566,7 +564,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, fprintf(stderr, "safe_mutex: Count was %d in thread 0x%lx when locking mutex " "%s at %s, line %d (error: %d (%d))\n", - mp->count-1, my_thread_dbug_id(), mp->name, file, line, + mp->count-1, (ulong) my_thread_dbug_id(), mp->name, file, line, error, error); fflush(stderr); abort(); @@ -838,88 +836,4 @@ static void print_deadlock_warning(safe_mutex_t *new_mutex, DBUG_VOID_RETURN; } -#elif defined(MY_PTHREAD_FASTMUTEX) /* !SAFE_MUTEX_DEFINED */ - -static ulong mutex_delay(ulong delayloops) -{ - ulong i; - volatile ulong j; - - j = 0; - - for (i = 0; i < delayloops * 50; i++) - j += i; - - return(j); -} - -#define MY_PTHREAD_FASTMUTEX_SPINS 8 -#define MY_PTHREAD_FASTMUTEX_DELAY 4 - -static int cpu_count= 0; - -int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp, - const pthread_mutexattr_t *attr) -{ - if ((cpu_count > 1) && (attr == MY_MUTEX_INIT_FAST)) - mp->spins= MY_PTHREAD_FASTMUTEX_SPINS; - else - mp->spins= 0; - mp->rng_state= 1; - return pthread_mutex_init(&mp->mutex, attr); -} - -/** - Park-Miller random number generator. A simple linear congruential - generator that operates in multiplicative group of integers modulo n. - - x_{k+1} = (x_k g) mod n - - Popular pair of parameters: n = 2^32 − 5 = 4294967291 and g = 279470273. - The period of the generator is about 2^31. - Largest value that can be returned: 2147483646 (RAND_MAX) - - Reference: - - S. K. Park and K. W. Miller - "Random number generators: good ones are hard to find" - Commun. ACM, October 1988, Volume 31, No 10, pages 1192-1201. -*/ - -static double park_rng(my_pthread_fastmutex_t *mp) -{ - mp->rng_state= ((my_ulonglong)mp->rng_state * 279470273U) % 4294967291U; - return (mp->rng_state / 2147483647.0); -} - -int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp) -{ - int res; - uint i; - uint maxdelay= MY_PTHREAD_FASTMUTEX_DELAY; - - for (i= 0; i < mp->spins; i++) - { - res= pthread_mutex_trylock(&mp->mutex); - - if (res == 0) - return 0; - - if (res != EBUSY) - return res; - - mutex_delay(maxdelay); - maxdelay += park_rng(mp) * MY_PTHREAD_FASTMUTEX_DELAY + 1; - } - return pthread_mutex_lock(&mp->mutex); -} - - -void fastmutex_global_init(void) -{ -#ifdef _SC_NPROCESSORS_CONF - cpu_count= sysconf(_SC_NPROCESSORS_CONF); #endif -} - -#endif /* defined(MY_PTHREAD_FASTMUTEX) && defined(SAFE_MUTEX_DEFINED) */ diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index 773ae887891..f7b9f440fcd 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -265,6 +265,7 @@ ret: thd->set_status_var_init(); thread_count--; thd->killed= KILL_CONNECTION; + thd->unlink(); mysql_cond_broadcast(&COND_thread_count); mysql_mutex_unlock(&LOCK_thread_count); delete thd; @@ -280,9 +281,7 @@ pthread_handler_t background_thread(void *arg __attribute__((unused))) if (my_thread_init()) return 0; - mysql_mutex_lock(&LOCK_thread_count); - thd_thread_id= thread_id++; - mysql_mutex_unlock(&LOCK_thread_count); + thd_thread_id= next_thread_id(); if (slept_ok(startup_interval)) { diff --git a/plugin/handler_socket/handlersocket/database.cpp b/plugin/handler_socket/handlersocket/database.cpp index b05b6384565..94eedbf6d04 100644 --- a/plugin/handler_socket/handlersocket/database.cpp +++ b/plugin/handler_socket/handlersocket/database.cpp @@ -309,11 +309,9 @@ dbcontext::init_thread(const void *stack_bottom, volatile int& shutdown_flag) DBG_THR(fprintf(stderr, "HNDSOCK x0 %p\n", thd)); } { - pthread_mutex_lock(&LOCK_thread_count); - thd->thread_id = thread_id++; - threads.append(thd); - ++thread_count; - pthread_mutex_unlock(&LOCK_thread_count); + thd->thread_id = next_thread_id(); + thread_safe_increment32(&thread_count); + add_to_active_threads(thd); } DBG_THR(fprintf(stderr, "HNDSOCK init thread wsts\n")); diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 30b7cdb5dcb..9df0d75e3c6 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -97,13 +97,11 @@ static void closelog() {} #define FLOGGER_NO_PSI /* How to access the pthread_mutex in mysql_mutex_t */ -//#ifdef SAFE_MUTEX -//#define mysql_mutex_real_mutex(A) &(A)->m_mutex.mutex -//#elif defined(MY_PTHREAD_FASTMUTEX) -//#define mysql_mutex_real_mutex(A) &(A)->m_mutex.mutex -//#else +#ifdef SAFE_MUTEX +#define mysql_mutex_real_mutex(A) &(A)->m_mutex.mutex +#else #define mysql_mutex_real_mutex(A) &(A)->m_mutex -//#endif +#endif #define flogger_mutex_init(A,B,C) do{}while(0) #define flogger_mutex_destroy(A) do{}while(0) diff --git a/plugin/simple_password_check/simple_password_check.c b/plugin/simple_password_check/simple_password_check.c index 1b7668204b6..7ad8bfc811a 100644 --- a/plugin/simple_password_check/simple_password_check.c +++ b/plugin/simple_password_check/simple_password_check.c @@ -49,15 +49,18 @@ static int validate(MYSQL_LEX_STRING *username, MYSQL_LEX_STRING *password) others < min_others; } -static void fix_min_length(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var, - void *var_ptr, const void *save) + +static void +fix_min_length(MYSQL_THD thd __attribute__((unused)), + struct st_mysql_sys_var *var __attribute__((unused)), + void *var_ptr, const void *save) { *((unsigned int *)var_ptr)= *((unsigned int *)save); if (min_length < min_digits + 2 * min_letters + min_others) min_length= min_digits + 2 * min_letters + min_others; } + static MYSQL_SYSVAR_UINT(minimal_length, min_length, PLUGIN_VAR_RQCMDARG, "Minimal required password length", NULL, fix_min_length, 8, 0, 1000, 1); diff --git a/plugin/user_variables/CMakeLists.txt b/plugin/user_variables/CMakeLists.txt new file mode 100644 index 00000000000..b9ec7d18ba1 --- /dev/null +++ b/plugin/user_variables/CMakeLists.txt @@ -0,0 +1 @@ +MYSQL_ADD_PLUGIN(user_variables user_variables.cc) diff --git a/plugin/user_variables/mysql-test/user_variables/basic.result b/plugin/user_variables/mysql-test/user_variables/basic.result new file mode 100644 index 00000000000..02de31b5e09 --- /dev/null +++ b/plugin/user_variables/mysql-test/user_variables/basic.result @@ -0,0 +1,63 @@ +SELECT PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_STATUS, PLUGIN_TYPE, PLUGIN_AUTHOR, PLUGIN_DESCRIPTION, PLUGIN_LICENSE, LOAD_OPTION, PLUGIN_MATURITY FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='user_variables'; +PLUGIN_NAME user_variables +PLUGIN_VERSION 1.0 +PLUGIN_STATUS ACTIVE +PLUGIN_TYPE INFORMATION SCHEMA +PLUGIN_AUTHOR Sergey Vojtovich +PLUGIN_DESCRIPTION User-defined variables +PLUGIN_LICENSE GPL +LOAD_OPTION ON +PLUGIN_MATURITY Alpha +SHOW CREATE TABLE INFORMATION_SCHEMA.USER_VARIABLES; +Table Create Table +user_variables CREATE TEMPORARY TABLE `user_variables` ( + `VARIABLE_NAME` varchar(64) NOT NULL DEFAULT '', + `VARIABLE_VALUE` varchar(2048) DEFAULT NULL, + `VARIABLE_TYPE` varchar(64) NOT NULL DEFAULT '', + `CHARACTER_SET_NAME` varchar(32) DEFAULT NULL +) ENGINE=MEMORY DEFAULT CHARSET=utf8 +FLUSH USER_VARIABLES; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.USER_VARIABLES; +COUNT(*) +0 +SET @int_var=1; +SET @uint_var=CAST(2 AS UNSIGNED INTEGER); +SET @str_var='Value of string variable'; +SET @utf8str_var=_utf8 'UTF8 string value'; +SET @double_var=CAST(1 AS DOUBLE); +SET @dec_var=CAST(1 AS DECIMAL(20, 10)); +SET @time_var=CAST('2016-02-25' AS DATE); +SET @' @#^%'='Value of variable with odd name'; +SET @''='Value of variable with empty name'; +SET @null_var=NULL; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.USER_VARIABLES; +COUNT(*) +10 +SELECT * FROM INFORMATION_SCHEMA.USER_VARIABLES ORDER BY VARIABLE_NAME; +VARIABLE_NAME VARIABLE_VALUE VARIABLE_TYPE CHARACTER_SET_NAME + Value of variable with empty name VARCHAR latin1 + @#^% Value of variable with odd name VARCHAR latin1 +dec_var 1.0000000000 DECIMAL latin1 +double_var 1 DOUBLE latin1 +int_var 1 INT latin1 +null_var NULL VARCHAR binary +str_var Value of string variable VARCHAR latin1 +time_var 2016-02-25 VARCHAR latin1 +uint_var 2 INT UNSIGNED latin1 +utf8str_var UTF8 string value VARCHAR utf8 +SHOW USER_VARIABLES; +Variable_name Value + Value of variable with empty name + @#^% Value of variable with odd name +dec_var 1.0000000000 +double_var 1 +int_var 1 +null_var NULL +str_var Value of string variable +time_var 2016-02-25 +uint_var 2 +utf8str_var UTF8 string value +FLUSH USER_VARIABLES; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.USER_VARIABLES; +COUNT(*) +0 diff --git a/plugin/user_variables/mysql-test/user_variables/basic.test b/plugin/user_variables/mysql-test/user_variables/basic.test new file mode 100644 index 00000000000..7e67e4fa5af --- /dev/null +++ b/plugin/user_variables/mysql-test/user_variables/basic.test @@ -0,0 +1,24 @@ +query_vertical SELECT PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_STATUS, PLUGIN_TYPE, PLUGIN_AUTHOR, PLUGIN_DESCRIPTION, PLUGIN_LICENSE, LOAD_OPTION, PLUGIN_MATURITY FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='user_variables'; +SHOW CREATE TABLE INFORMATION_SCHEMA.USER_VARIABLES; + +FLUSH USER_VARIABLES; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.USER_VARIABLES; + +SET @int_var=1; +SET @uint_var=CAST(2 AS UNSIGNED INTEGER); +SET @str_var='Value of string variable'; +SET @utf8str_var=_utf8 'UTF8 string value'; +SET @double_var=CAST(1 AS DOUBLE); +SET @dec_var=CAST(1 AS DECIMAL(20, 10)); +SET @time_var=CAST('2016-02-25' AS DATE); +SET @' @#^%'='Value of variable with odd name'; +SET @''='Value of variable with empty name'; +SET @null_var=NULL; + +SELECT COUNT(*) FROM INFORMATION_SCHEMA.USER_VARIABLES; +SELECT * FROM INFORMATION_SCHEMA.USER_VARIABLES ORDER BY VARIABLE_NAME; +--sorted_result +SHOW USER_VARIABLES; + +FLUSH USER_VARIABLES; +SELECT COUNT(*) FROM INFORMATION_SCHEMA.USER_VARIABLES; diff --git a/plugin/user_variables/mysql-test/user_variables/suite.opt b/plugin/user_variables/mysql-test/user_variables/suite.opt new file mode 100644 index 00000000000..6140014d569 --- /dev/null +++ b/plugin/user_variables/mysql-test/user_variables/suite.opt @@ -0,0 +1 @@ +--plugin-load-add=$USER_VARIABLES_SO --plugin-user-variables=ON diff --git a/plugin/user_variables/mysql-test/user_variables/suite.pm b/plugin/user_variables/mysql-test/user_variables/suite.pm new file mode 100644 index 00000000000..ae757eedee4 --- /dev/null +++ b/plugin/user_variables/mysql-test/user_variables/suite.pm @@ -0,0 +1,13 @@ +package My::Suite::User_variables; + +@ISA = qw(My::Suite); + +return "No USER_VARIABLES plugin" unless + $ENV{USER_VARIABLES_SO} or + $::mysqld_variables{'user-variables'} eq "ON"; + +return "Not run for embedded server" if $::opt_embedded_server; + +sub is_default { 1 } + +bless { }; diff --git a/plugin/user_variables/user_variables.cc b/plugin/user_variables/user_variables.cc new file mode 100644 index 00000000000..c6c48d09303 --- /dev/null +++ b/plugin/user_variables/user_variables.cc @@ -0,0 +1,139 @@ +/* Copyright (C) 2016 MariaDB Foundation and Sergey Vojtovich + + 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 */ + +#define MYSQL_SERVER +#include <sql_class.h> +#include <table.h> +#include <sql_show.h> + + +static const LEX_CSTRING result_types[]= +{ + STRING_WITH_LEN("VARCHAR"), + STRING_WITH_LEN("DOUBLE"), + STRING_WITH_LEN("INT"), + STRING_WITH_LEN("<IMPOSSIBLE1>"), // ROW_RESULT + STRING_WITH_LEN("DECIMAL"), + STRING_WITH_LEN("<IMPOSSIBLE2>") // TIME_RESULT +}; + + +static const LEX_CSTRING unsigned_result_types[]= +{ + STRING_WITH_LEN("<IMPOSSIBLE3>"), // UNSIGNED STRING_RESULT + STRING_WITH_LEN("DOUBLE UNSIGNED"), + STRING_WITH_LEN("INT UNSIGNED"), + STRING_WITH_LEN("<IMPOSSIBLE4>"), // UNSIGNED ROW_RESULT + STRING_WITH_LEN("DECIMAL UNSIGNED"), + STRING_WITH_LEN("<IMPOSSIBLE5>") // UNSIGNED TIME_RESULT +}; + + +static ST_FIELD_INFO user_variables_fields_info[] = +{ + { "VARIABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Variable_name", 0 }, + { "VARIABLE_VALUE", 2048, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, "Value", 0 }, + { "VARIABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, 0 }, + { "CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, + MY_I_S_MAYBE_NULL, 0, 0 }, + { 0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0 } +}; + + +static int user_variables_fill(THD *thd, TABLE_LIST *tables, COND *cond) +{ + ulong i; + TABLE *table= tables->table; + Field **field= table->field; + String buff; + bool is_null; + + for (i= 0; i < thd->user_vars.records; i++) + { + user_var_entry *var= (user_var_entry*) my_hash_element(&thd->user_vars, i); + + field[0]->store(var->name.str, var->name.length, system_charset_info); + + if (var->val_str(&is_null, &buff, NOT_FIXED_DEC)) + { + field[1]->store(buff.ptr(), buff.length(), buff.charset()); + field[1]->set_notnull(); + } + else if (is_null) + field[1]->set_null(); + else + return 1; + + const LEX_CSTRING *tmp= var->unsigned_flag ? + &unsigned_result_types[var->type] : + &result_types[var->type]; + field[2]->store(tmp->str, tmp->length, system_charset_info); + + if (var->charset()) + { + field[3]->store(var->charset()->csname, strlen(var->charset()->csname), + system_charset_info); + field[3]->set_notnull(); + } + else + field[3]->set_null(); + + if (schema_table_store_record(thd, table)) + return 1; + } + return 0; +} + + +int user_variables_reset(void) +{ + THD *thd= current_thd; + if (thd) + my_hash_reset(&thd->user_vars); + return 0; +} + + +static int user_variables_init(void *p) +{ + ST_SCHEMA_TABLE *is= (ST_SCHEMA_TABLE *) p; + is->fields_info= user_variables_fields_info; + is->fill_table= user_variables_fill; + is->reset_table= user_variables_reset; + return 0; +} + + +static struct st_mysql_information_schema user_variables_descriptor= +{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; + + +maria_declare_plugin(user_variables) +{ + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &user_variables_descriptor, + "user_variables", + "Sergey Vojtovich", + "User-defined variables", + PLUGIN_LICENSE_GPL, + user_variables_init, + NULL, + 0x0100, + NULL, + NULL, + "1.0", + MariaDB_PLUGIN_MATURITY_ALPHA +} +maria_declare_plugin_end; diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index e79ece53911..eeb44b75322 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -133,42 +133,6 @@ ENDIF() SET(HOSTNAME "hostname") SET(MYSQLD_USER "mysql") - -# Required for mysqlbug until autotools are deprecated, once done remove these -# and expand default cmake variables -SET(CC ${CMAKE_C_COMPILER}) -SET(CXX ${CMAKE_CXX_COMPILER}) -SET(SAVE_CC ${CMAKE_C_COMPILER}) -SET(SAVE_CXX ${CMAKE_CXX_COMPILER}) -SET(SAVE_CFLAGS ${CFLAGS}) -SET(SAVE_CXXFLAGS ${CXXFLAGS}) -# XXX no cmake equivalent for this, just make one up -SET(CONFIGURE_LINE "Built using CMake") - -# Also required for mysqlbug, autoconf only supports --version so for now we -# just explicitly require GNU -EXECUTE_PROCESS( - COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1} --version - COMMAND sed 1q - ERROR_QUIET - OUTPUT_VARIABLE CC_VERSION) -EXECUTE_PROCESS( - COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} --version - COMMAND sed 1q - ERROR_QUIET - OUTPUT_VARIABLE CXX_VERSION) - -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysqlbug.sh - ${CMAKE_CURRENT_BINARY_DIR}/mysqlbug ESCAPE_QUOTES @ONLY) - EXECUTE_PROCESS( - COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/mysqlbug - ) - -INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/mysqlbug - DESTINATION ${INSTALL_BINDIR} - COMPONENT Server - ) - ENDIF(UNIX) # Really ugly, one script, "mysql_install_db", needs prefix set to ".", @@ -287,7 +251,6 @@ ELSE() mysql_fix_extensions mysql_setpermission mysql_secure_installation - mysql_zap mysqlaccess mysql_convert_table_format mysql_find_rows diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index f8f36bfd28b..9dcd23a8392 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -427,7 +427,7 @@ mysqld_install_cmd_line() # Create the system and help tables by passing them to "mysqld --bootstrap" s_echo "Installing MariaDB/MySQL system tables in '$ldata' ..." -if { echo "use mysql;"; cat "$create_system_tables" "$create_system_tables2" "$fill_system_tables"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null +if { echo "use mysql;"; cat "$create_system_tables" "$create_system_tables2" "$fill_system_tables" "$fill_help_tables" "$maria_add_gis_sp"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null then s_echo "OK" else @@ -462,26 +462,6 @@ else exit 1 fi -s_echo "Filling help tables..." -if { echo "use mysql;"; cat "$fill_help_tables"; } | mysqld_install_cmd_line > /dev/null -then - s_echo "OK" -else - echo - echo "WARNING: HELP FILES ARE NOT COMPLETELY INSTALLED!" - echo "The \"HELP\" command might not work properly." -fi - -s_echo "Creating OpenGIS required SP-s..." -if { echo "use test;"; cat "$maria_add_gis_sp"; } | mysqld_install_cmd_line > /dev/null -then - s_echo "OK" -else - echo - echo "WARNING: OPENGIS REQUIRED SP-S WERE NOT COMPLETELY INSTALLED!" - echo "GIS extentions might not work properly." -fi - # Don't output verbose information if running inside bootstrap or using # --srcdir for testing. In such cases, there's no end user looking at diff --git a/scripts/mysql_zap.sh b/scripts/mysql_zap.sh deleted file mode 100644 index 98c3603df15..00000000000 --- a/scripts/mysql_zap.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/perl -# Copyright (c) 2000-2002, 2004, 2006 MySQL AB, 2009 Sun Microsystems, Inc. -# Use is subject to license terms. -# -# 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 - -# This is a utility for MariaDB. It is not needed by any standard part -# of MariaDB. - -# Usage: mysql_zap [-signal] [-f] [-t] pattern - -# Configuration parameters. - -$sig = ""; # Default to try all signals -$ans = "y"; -$opt_f= 0; -$opt_t= 0; -$opt_a = ""; - -$BSD = -f '/vmunix' || $ENV{"OS"} eq "SunOS4"; -$LINUX = $^O eq 'linux' || $^O eq 'darwin'; -$pscmd = $BSD ? "/bin/ps -auxww" : $LINUX ? "/bin/ps axuw" : "/bin/ps -ef"; - -open(TTYIN, "</dev/tty") || die "can't read /dev/tty: $!"; -open(TTYOUT, ">/dev/tty") || die "can't write /dev/tty: $!"; -select(TTYOUT); -$| = 1; -select(STDOUT); -$SIG{'INT'} = 'cleanup'; - -while ($#ARGV >= $[ && $ARGV[0] =~ /^-/) { - if ($ARGV[0] =~ /(ZERO|HUP|INT|QUIT|ILL|TRAP|ABRT|EMT|FPE|KILL|BUS|SEGV|SYS|PIPE|ALRM|TERM|URG|STOP|TSTP|CONT|CLD|TTIN|TTOU|IO|XCPU|XFSZ|VTALRM|PROF|WINCH|LOST|USR1|USR2)/ || $ARGV[0] =~ /-(\d+)$/) { - $sig = $1; - } elsif ($ARGV[0] eq "-f") { - $opt_f=1; - } elsif ($ARGV[0] eq "-t") { - $opt_t=1; - $ans = "n"; - } - elsif ($ARGV[0] eq "-a") - { - $opt_a = 1; - } - elsif ($ARGV[0] eq "-?" || $ARGV[0] eq "-I" || $ARGV[0] eq "--help") - { - &usage; - } - else { - print STDERR "$0: illegal argument $ARGV[0] ignored\n"; - } - shift; -} - -&usage if $#ARGV < 0; - -if (!$opt_f) -{ - if ($BSD) { - system "stty cbreak </dev/tty >/dev/tty 2>&1"; - } - else { - system "stty", 'cbreak', - system "stty", 'eol', '^A'; - } -} - -open(PS, "$pscmd|") || die "can't run $pscmd: $!"; -$title = <PS>; -print TTYOUT $title; - -# Catch any errors with eval. A bad pattern, for instance. -eval <<'EOF'; -process: while ($cand = <PS>) -{ - chop($cand); - ($user, $pid) = split(' ', $cand); - next if $pid == $$; - $found = !@ARGV; - if ($opt_a) { $found = 1; } - foreach $pat (@ARGV) - { - if ($opt_a) - { - if (! ($cand =~ $pat)) - { - next process; - } - } - else - { - $found = 1 if $cand =~ $pat; - } - } - next if (!$found); - if (! $opt_f && ! $opt_t) - { - print TTYOUT "$cand? "; - read(TTYIN, $ans, 1); - print TTYOUT "\n" if ($ans ne "\n"); - } - else - { - print TTYOUT "$cand\n"; - } - if ($ans =~ /^y/i) { &killpid($sig, $pid); } - if ($ans =~ /^q/i) { last; } -} -EOF - -&cleanup; - - -sub usage { - print <<EOF; -Usage: $0 [-signal] [-?Ift] [--help] pattern -Options: -I or -? "info" -f "force" -t "test". - -Version 1.0 -Kill processes that match the pattern. -If -f isn't given, ask user for confirmation for each process to kill. -If signal isn't given, try first with signal 15, then with signal 9. -If -t is given, the processes are only shown on stdout. -EOF - exit(1); -} - -sub cleanup { - if ($BSD) { - system "stty -cbreak </dev/tty >/dev/tty 2>&1"; - } - else { - system "stty", 'icanon'; - system "stty", 'eol', '^@'; - } - print "\n"; - exit; -} - -sub killpid { - local($signal,$pid) = @_; - if ($signal) - { - kill $signal,$pid; - } - else - { - print "kill -15\n"; - kill 15, $pid; - for (1..5) { - sleep 2; - return if kill(0, $pid) == 0; - } - print "kill -9\n"; - kill 9, $pid; - for (1..5) { - sleep 2; - return if kill(0, $pid) == 0; - } - print "$pid will not die!\n"; - } -} diff --git a/scripts/mysqlbug.sh b/scripts/mysqlbug.sh deleted file mode 100644 index e9df210fa84..00000000000 --- a/scripts/mysqlbug.sh +++ /dev/null @@ -1,406 +0,0 @@ -#!/bin/sh -# Copyright (C) 2000-2002, 2004 MySQL AB -# Use is subject to license terms -# -# 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 - -# Create a bug report and mail it to the mysql mailing list -# Based on glibc bug reporting script. - -echo "Finding system information for a MySQL bug report" - -VERSION="@VERSION@@MYSQL_SERVER_SUFFIX@" -COMPILATION_COMMENT="@COMPILATION_COMMENT@" -BUGmysql="maria-developers@lists.launchpad.net" -# This is set by configure -COMP_CALL_INFO="CC='@SAVE_CC@' CFLAGS='@SAVE_CFLAGS@' CXX='@SAVE_CXX@' CXXFLAGS='@SAVE_CXXFLAGS@' LDFLAGS='@SAVE_LDFLAGS@' ASFLAGS='@SAVE_ASFLAGS@'" -COMP_RUN_INFO="CC='@CC@' CFLAGS='@CFLAGS@' CXX='@CXX@' CXXFLAGS='@CXXFLAGS@' LDFLAGS='@LDFLAGS@' ASFLAGS='@ASFLAGS@'" -CONFIGURE_LINE="@CONF_COMMAND@" - -LIBC_INFO="" -for pat in /lib/libc.* /lib/libc-* /usr/lib/libc.* /usr/lib/libc-* -do - TMP=`ls -l $pat 2>/dev/null` - if test $? = 0 - then - LIBC_INFO="$LIBC_INFO -$TMP" - fi -done - -PATH=../client:$PATH:/bin:/usr/bin:/usr/local/bin -export PATH - -BUGADDR=${1-$BUGmysql} -ENVIRONMENT=`uname -a` - -: ${USER=${LOGNAME-`whoami`}} - -COMMAND=`echo $0|sed 's%.*/\([^/]*\)%\1%'` - -# Try to create a secure tmpfile -umask 077 -TEMPDIR=/tmp/mysqlbug-$$ -mkdir $TEMPDIR || (echo "can not create directory in /tmp, aborting"; exit 1;) -TEMP=${TEMPDIR}/mysqlbug - -trap 'rm -f $TEMP $TEMP.x; rmdir $TEMPDIR; exit 1' 1 2 3 13 15 -trap 'rm -f $TEMP $TEMP.x; rmdir $TEMPDIR' 0 - -# How to read the passwd database. -PASSWD="cat /etc/passwd" - -if test -f /usr/lib/sendmail -then - MAIL_AGENT="/usr/lib/sendmail -oi -t" -elif test -f /usr/sbin/sendmail -then - MAIL_AGENT="/usr/sbin/sendmail -oi -t" -else - MAIL_AGENT="rmail $BUGmysql" -fi - -# Figure out how to echo a string without a trailing newline -N=`echo 'hi there\c'` -case "$N" in - *c) ECHON1='echo -n' ECHON2= ;; - *) ECHON1=echo ECHON2='\c' ;; -esac - -# Find out the name of the originator of this PR. -if test -n "$NAME" -then - ORIGINATOR="$NAME" -elif test -f $HOME/.fullname -then - ORIGINATOR="`sed -e '1q' $HOME/.fullname`" -else - # Must use temp file due to incompatibilities in quoting behavior - # and to protect shell metacharacters in the expansion of $LOGNAME - $PASSWD | grep "^$LOGNAME:" | awk -F: '{print $5}' | sed -e 's/,.*//' > $TEMP - ORIGINATOR="`cat $TEMP`" - rm -f $TEMP -fi - -if test -n "$ORGANIZATION" -then - if test -f "$ORGANIZATION" - then - ORGANIZATION="`cat $ORGANIZATION`" - fi -else - if test -f $HOME/.organization - then - ORGANIZATION="`cat $HOME/.organization`" - elif test -f $HOME/.signature - then - ORGANIZATION=`sed -e "s/^/ /" $HOME/.signature; echo ">"` - fi -fi - -PATH_DIRS=`echo $PATH | sed -e 's/^:/. /' -e 's/:$/ ./' -e 's/::/ . /g' -e 's/:/ /g' ` - -which_1 () -{ - for cmd - do - # Absolute path ?. - if expr "x$cmd" : "x/" > /dev/null - then - echo "$cmd" - exit 0 - else - for d in $PATH_DIRS - do - file="$d/$cmd" - if test -x "$file" -a ! -d "$file" - then - echo "$file" - exit 0 - fi - done - fi - done - exit 1 -} - -change_editor () -{ - echo "You can change editor by setting the environment variable VISUAL." - echo "If your shell is a bourne shell (sh) do" - echo "VISUAL=your_editors_name; export VISUAL" - echo "If your shell is a C shell (csh) do" - echo "setenv VISUAL your_editors_name" -} - -# If they don't have a preferred editor set, then use emacs -if test -z "$VISUAL" -then - if test -z "$EDITOR" - then - # Honor debian sensible-editor - if test -x "/usr/bin/sensible-editor" - then - EDIT=/usr/bin/sensible-editor - else - EDIT=emacs - fi - else - EDIT="$EDITOR" - fi -else - EDIT="$VISUAL" -fi - -#which_1 $EDIT -used_editor=`which_1 $EDIT` - -echo "test -x $used_editor" -if test -x "$used_editor" -then - echo "Using editor $used_editor"; - change_editor - sleep 2 -else - echo "Could not find a text editor. (tried $EDIT)" - change_editor - exit 1 -fi - -# Find out some information. -SYSTEM=`( test -f /bin/uname && /bin/uname -a ) || \ - ( test -f /usr/bin/uname && /usr/bin/uname -a ) || echo ""` -ARCH=`test -f /bin/arch && /bin/arch` -MACHINE=`test -f /bin/machine && /bin/machine` -FILE_PATHS= - -for cmd in perl make gmake gcc cc -do - file=`which_1 $cmd` - if test $? = 0 - then - if test $cmd = "gcc" - then - GCC_INFO=`$file -v 2>&1` - elif test $cmd = "perl" - then - PERL_INFO=`$file -v | grep -i version 2>&1` - fi - FILE_PATHS="$FILE_PATHS $file" - fi -done - -admin=`which_1 mysqladmin` -MYSQL_SERVER= -if test -x "$admin" -then - MYSQL_SERVER=`$admin version 2> /dev/null` - if test "$?" = "1" - then - MYSQL_SERVER="" - fi -fi - -SUBJECT_C="[50 character or so descriptive subject here (for reference)]" -ORGANIZATION_C='<organization of PR author (multiple lines)>' -LICENCE_C='[none | licence | email support | extended email support ]' -SYNOPSIS_C='<synopsis of the problem (one line)>' -SEVERITY_C='<[ non-critical | serious | critical ] (one line)>' -PRIORITY_C='<[ low | medium | high ] (one line)>' -CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>' -RELEASE_C='<release number or tag (one line)>' -ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>' -DESCRIPTION_C='<precise description of the problem (multiple lines)>' -HOW_TO_REPEAT_C='<code/input/activities to reproduce the problem (multiple lines)>' -FIX_C='<how to correct or work around the problem, if known (multiple lines)>' - - -cat > $TEMP <<EOF -SEND-PR: -*- send-pr -*- -SEND-PR: Lines starting with \`SEND-PR' will be removed automatically, as -SEND-PR: will all comments (text enclosed in \`<' and \`>'). -SEND-PR: -From: ${USER} -To: ${BUGADDR} -Subject: $SUBJECT_C - ->Description: - $DESCRIPTION_C ->How-To-Repeat: - $HOW_TO_REPEAT_C ->Fix: - $FIX_C - ->Submitter-Id: <submitter ID> ->Originator: ${ORIGINATOR} ->Organization: -${ORGANIZATION- $ORGANIZATION_C} ->MySQL support: $LICENCE_C ->Synopsis: $SYNOPSIS_C ->Severity: $SEVERITY_C ->Priority: $PRIORITY_C ->Category: mysql ->Class: $CLASS_C ->Release: mysql-${VERSION} ($COMPILATION_COMMENT) -`test -n "$MYSQL_SERVER" && echo ">Server: $MYSQL_SERVER"` ->C compiler: @CC_VERSION@ ->C++ compiler: @CXX_VERSION@ ->Environment: - $ENVIRONMENT_C -`test -n "$SYSTEM" && echo "System: $SYSTEM"` -`test -n "$ARCH" && echo "Architecture: $ARCH"` -`test -n "$MACHINE" && echo "Machine: $MACHINE"` -`test -n "$FILE_PATHS" && echo "Some paths: $FILE_PATHS"` -`test -n "$GCC_INFO" && echo "GCC: $GCC_INFO"` -`test -n "$COMP_CALL_INFO" && echo "Compilation info (call): $COMP_CALL_INFO"` -`test -n "$COMP_RUN_INFO" && echo "Compilation info (used): $COMP_RUN_INFO"` -`test -n "$LIBC_INFO" && echo "LIBC: $LIBC_INFO"` -`test -n "$CONFIGURE_LINE" && echo "Configure command: $CONFIGURE_LINE"` -`test -n "$PERL_INFO" && echo "Perl: $PERL_INFO"` -EOF - -chmod u+w $TEMP -cp $TEMP $TEMP.x - -eval $EDIT $TEMP - -if cmp -s $TEMP $TEMP.x -then - echo "File not changed, no bug report submitted." - mv -f $TEMP /tmp/failed-mysql-bugreport - echo "The raw bug report exists in /tmp/failed-mysql-bugreport" - echo "If you use this remember that the first lines of the report are now a lie.." - exit 1 -fi - -# -# Check the enumeration fields - -# This is a "sed-subroutine" with one keyword parameter -# (with workaround for Sun sed bug) -# -SED_CMD=' -/$PATTERN/{ -s||| -s|<.*>|| -s|^[ ]*|| -s|[ ]*$|| -p -q -}' - - -while :; do - CNT=0 - - # - # 1) Severity - # - PATTERN=">Severity:" - SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$SEVERITY" in - ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'." - esac - # - # 2) Priority - # - PATTERN=">Priority:" - PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$PRIORITY" in - ""|low|medium|high) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'." - esac - # - # 3) Class - # - PATTERN=">Class:" - CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$CLASS" in - ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'." - esac - - # - # 4) Synopsis - # - VALUE=`grep "^>Synopsis:" $TEMP | sed 's/>Synopsis:[ ]*//'` - case "$VALUE" in - "$SYNOPSIS_C") echo "$COMMAND: \`$VALUE' is not a valid value for \`Synopsis'." ;; - *) CNT=`expr $CNT + 1` - esac - - test $CNT -lt 4 && - echo "Errors were found with the problem report." - - - # Check if subject of mail was changed, if not, use Synopsis field - # - subject=`grep "^Subject" $TEMP| sed 's/^Subject:[ ]*//'` - if [ X"$subject" = X"$SUBJECT_C" -o X"$subject" = X"$SYNOPSIS_C" ]; then - subject=`grep Synopsis $TEMP | sed 's/>Synopsis:[ ]*//'` - sed "s/^Subject:[ ]*.*/Subject: $subject/" $TEMP > $TEMP.tmp - mv -f $TEMP.tmp $TEMP - fi - - while :; do - $ECHON1 "a)bort, e)dit or s)end? $ECHON2" - read input - case "$input" in - a*) - echo "$COMMAND: problem report saved in $HOME/dead.mysqlbug." - cat $TEMP >> $HOME/dead.mysqlbug - xs=1; exit - ;; - e*) - eval $EDIT $TEMP - continue 2 - ;; - s*) - break 2 - ;; - esac - done -done -# -# Remove comments and send the problem report -# (we have to use patterns, where the comment contains regex chars) -# -# /^>Originator:/s;$ORIGINATOR;; -sed -e " -/^SEND-PR:/d -/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;; -/^>Confidential:/s;<.*>;; -/^>Synopsis:/s;$SYNOPSIS_C;; -/^>Severity:/s;<.*>;; -/^>Priority:/s;<.*>;; -/^>Class:/s;<.*>;; -/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;; -/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;; -/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;; -/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;; -/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;; -" $TEMP > $TEMP.x - -if $MAIL_AGENT < $TEMP.x -then - echo "$COMMAND: problem report sent" - xs=0; exit -else - echo "$COMMAND: mysterious mail failure, report not sent." - echo "$COMMAND: problem report saved in $HOME/dead.mysqlbug." - cat $TEMP >> $HOME/dead.mysqlbug -fi - -exit 0 diff --git a/sql-common/client.c b/sql-common/client.c index 9904719e616..b96231fcc13 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -601,7 +601,7 @@ restart: uint last_errno=uint2korr(pos); if (last_errno == 65535 && - (mysql->server_capabilities & CLIENT_PROGRESS)) + (mysql->server_capabilities & CLIENT_PROGRESS_OBSOLETE)) { if (cli_report_progress(mysql, pos+2, (uint) (len-3))) { diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index ec7e9207f38..6136c39fc9c 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -112,7 +112,8 @@ SET (SQL_SOURCE sql_statistics.cc sql_string.cc sql_table.cc sql_test.cc sql_trigger.cc sql_udf.cc sql_union.cc sql_update.cc sql_view.cc strfunc.cc table.cc thr_malloc.cc - sql_time.cc tztime.cc uniques.cc unireg.cc item_xmlfunc.cc + sql_time.cc tztime.cc unireg.cc item_xmlfunc.cc + uniques.cc uniques.h rpl_tblmap.cc sql_binlog.cc event_scheduler.cc event_data_objects.cc event_queue.cc event_db_repository.cc sql_tablespace.cc events.cc ../sql-common/my_user.c @@ -137,6 +138,7 @@ SET (SQL_SOURCE my_json_writer.cc my_json_writer.h rpl_gtid.cc rpl_parallel.cc sql_type.cc sql_type.h + sql_cte.cc sql_cte.h ${WSREP_SOURCES} table_cache.cc encryption.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc @@ -317,8 +319,7 @@ IF(WIN32 OR HAVE_DLOPEN AND NOT DISABLE_SHARED) ENDIF() ENDIF() -FOREACH(tool glibtoolize libtoolize aclocal autoconf autoheader automake gtar - tar git) +FOREACH(tool gtar tar git) STRING(TOUPPER ${tool} TOOL) FIND_PROGRAM(${TOOL}_EXECUTABLE ${tool} DOC "path to the executable") MARK_AS_ADVANCED(${TOOL}_EXECUTABLE) diff --git a/sql/bounded_queue.h b/sql/bounded_queue.h index 2d4e6cff96d..88c2bbc238d 100644 --- a/sql/bounded_queue.h +++ b/sql/bounded_queue.h @@ -16,11 +16,11 @@ #ifndef BOUNDED_QUEUE_INCLUDED #define BOUNDED_QUEUE_INCLUDED -#include <string.h> #include "my_global.h" #include "my_base.h" #include "my_sys.h" #include "queues.h" +#include <string.h> class Sort_param; diff --git a/sql/client_settings.h b/sql/client_settings.h index f2ad1797b8e..486862b276d 100644 --- a/sql/client_settings.h +++ b/sql/client_settings.h @@ -28,7 +28,7 @@ When adding capabilities here, consider if they should be also added to the libmysql version. */ -#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | \ +#define CLIENT_CAPABILITIES (CLIENT_MYSQL | \ CLIENT_LONG_FLAG | \ CLIENT_TRANSACTIONS | \ CLIENT_PROTOCOL_41 | \ diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 666f6e3e24c..5d0754cf766 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -499,7 +499,8 @@ Event_db_repository::table_scan_all_for_i_s(THD *thd, TABLE *schema_table, READ_RECORD read_record_info; DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s"); - if (init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE)) + if (init_read_record(&read_record_info, thd, event_table, NULL, NULL, 1, 0, + FALSE)) DBUG_RETURN(TRUE); /* @@ -1015,7 +1016,7 @@ Event_db_repository::drop_schema_events(THD *thd, LEX_STRING schema) DBUG_VOID_RETURN; /* only enabled events are in memory, so we go now and delete the rest */ - if (init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE)) + if (init_read_record(&read_record_info, thd, table, NULL, NULL, 1, 0, FALSE)) goto end; while (!ret && !(read_record_info.read_record(&read_record_info)) ) diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 95c5f6d9047..6a8bdabb948 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -135,9 +135,7 @@ post_init_event_thread(THD *thd) } thread_safe_increment32(&thread_count); - mysql_mutex_lock(&LOCK_thread_count); - threads.append(thd); - mysql_mutex_unlock(&LOCK_thread_count); + add_to_active_threads(thd); inc_thread_running(); return FALSE; } @@ -191,9 +189,7 @@ pre_init_event_thread(THD* thd) thd->net.read_timeout= slave_net_timeout; thd->variables.option_bits|= OPTION_AUTO_IS_NULL; thd->client_capabilities|= CLIENT_MULTI_RESULTS; - mysql_mutex_lock(&LOCK_thread_count); - thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - mysql_mutex_unlock(&LOCK_thread_count); + thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id(); /* Guarantees that we will see the thread in SHOW PROCESSLIST though its @@ -479,7 +475,7 @@ Event_scheduler::run(THD *thd) DBUG_ENTER("Event_scheduler::run"); sql_print_information("Event Scheduler: scheduler thread started with id %lu", - thd->thread_id); + (ulong) thd->thread_id); /* Recalculate the values in the queue because there could have been stops in executions of the scheduler and some times could have passed by. @@ -669,13 +665,13 @@ Event_scheduler::stop() state= STOPPING; DBUG_PRINT("info", ("Scheduler thread has id %lu", - scheduler_thd->thread_id)); + (ulong) scheduler_thd->thread_id)); /* Lock from delete */ mysql_mutex_lock(&scheduler_thd->LOCK_thd_data); /* This will wake up the thread if it waits on Queue's conditional */ sql_print_information("Event Scheduler: Killing the scheduler thread, " "thread id %lu", - scheduler_thd->thread_id); + (ulong) scheduler_thd->thread_id); scheduler_thd->awake(KILL_CONNECTION); mysql_mutex_unlock(&scheduler_thd->LOCK_thd_data); @@ -832,7 +828,8 @@ Event_scheduler::dump_internal_status() puts(""); puts("Event scheduler status:"); printf("State : %s\n", scheduler_states_names[state].str); - printf("Thread id : %lu\n", scheduler_thd? scheduler_thd->thread_id : 0); + printf("Thread id : %lu\n", scheduler_thd ? + (ulong) scheduler_thd->thread_id : (ulong) 0); printf("LLA : %s:%u\n", mutex_last_locked_in_func, mutex_last_locked_at_line); printf("LUA : %s:%u\n", mutex_last_unlocked_in_func, diff --git a/sql/events.cc b/sql/events.cc index 77dbb8b82e5..f428bc17927 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -1147,7 +1147,7 @@ Events::load_events_from_db(THD *thd) DBUG_RETURN(TRUE); } - if (init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE)) + if (init_read_record(&read_record_info, thd, table, NULL, NULL, 0, 1, FALSE)) { close_thread_tables(thd); DBUG_RETURN(TRUE); diff --git a/sql/field.cc b/sql/field.cc index ffa7beb275b..6be45005d48 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1322,6 +1322,31 @@ bool Field::can_optimize_range(const Item_bool_func *cond, } +int Field::store_hex_hybrid(const char *str, uint length) +{ + DBUG_ASSERT(result_type() != STRING_RESULT); + ulonglong nr; + + if (length > 8) + { + nr= flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX; + goto warn; + } + nr= (ulonglong) longlong_from_hex_hybrid(str, length); + if ((length == 8) && !(flags & UNSIGNED_FLAG) && (nr > LONGLONG_MAX)) + { + nr= LONGLONG_MAX; + goto warn; + } + return store((longlong) nr, true); // Assume hex numbers are unsigned + +warn: + if (!store((longlong) nr, true)) + set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); + return 1; +} + + /** Numeric fields base class constructor. */ @@ -1648,9 +1673,7 @@ Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, part_of_key_not_clustered(0), part_of_sortkey(0), unireg_check(unireg_check_arg), field_length(length_arg), null_bit(null_bit_arg), is_created_from_null_item(FALSE), - read_stats(NULL), collected_stats(0), - vcol_info(0), - stored_in_db(TRUE) + read_stats(NULL), collected_stats(0), vcol_info(0) { flags=null_ptr ? 0: NOT_NULL_FLAG; comment.str= (char*) ""; @@ -8905,7 +8928,7 @@ void Field_set::sql_type(String &res) const 0 if the fields are unequally defined */ -bool Field::eq_def(Field *field) +bool Field::eq_def(const Field *field) const { if (real_type() != field->real_type() || charset() != field->charset() || pack_length() != field->pack_length()) @@ -8937,7 +8960,7 @@ static bool compare_type_names(CHARSET_INFO *charset, TYPELIB *t1, TYPELIB *t2) returns 1 if the fields are equally defined */ -bool Field_enum::eq_def(Field *field) +bool Field_enum::eq_def(const Field *field) const { TYPELIB *values; @@ -9014,7 +9037,7 @@ const uchar *Field_enum::unpack(uchar *to, const uchar *from, @return returns 1 if the fields are equally defined */ -bool Field_num::eq_def(Field *field) +bool Field_num::eq_def(const Field *field) const { if (!Field::eq_def(field)) return 0; @@ -9670,7 +9693,7 @@ void Field_bit_as_char::sql_type(String &res) const Convert create_field::length from number of characters to number of bytes. */ -void Create_field::create_length_to_internal_length(void) +void Column_definition::create_length_to_internal_length(void) { switch (sql_type) { case MYSQL_TYPE_TINY_BLOB: @@ -9718,135 +9741,34 @@ void Create_field::create_length_to_internal_length(void) } -/** - Init for a tmp table field. To be extended if need be. -*/ -void Create_field::init_for_tmp_table(enum_field_types sql_type_arg, - uint32 length_arg, uint32 decimals_arg, - bool maybe_null, bool is_unsigned, - uint pack_length_arg) -{ - DBUG_ENTER("Create_field::init_for_tmp_table"); - - field_name= ""; - sql_type= sql_type_arg; - char_length= length= length_arg;; - unireg_check= Field::NONE; - interval= 0; - charset= &my_charset_bin; - geom_type= Field::GEOM_GEOMETRY; - - DBUG_PRINT("enter", ("sql_type: %d, length: %u, pack_length: %u", - sql_type_arg, length_arg, pack_length_arg)); - - /* - These pack flags are crafted to get it correctly through the - branches of make_field(). - */ - switch (sql_type_arg) - { - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_SET: - pack_flag= 0; - break; - - case MYSQL_TYPE_GEOMETRY: - pack_flag= FIELDFLAG_GEOM; - break; - - case MYSQL_TYPE_ENUM: - pack_flag= FIELDFLAG_INTERVAL; - break; - - case MYSQL_TYPE_NEWDECIMAL: - DBUG_ASSERT(decimals_arg <= DECIMAL_MAX_SCALE); - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - pack_flag= FIELDFLAG_NUMBER | - (decimals_arg & FIELDFLAG_MAX_DEC) << FIELDFLAG_DEC_SHIFT; - break; - - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - pack_flag= FIELDFLAG_BLOB; - break; - - case MYSQL_TYPE_BIT: - pack_flag= FIELDFLAG_NUMBER | FIELDFLAG_TREAT_BIT_AS_CHAR; - break; - - default: - pack_flag= FIELDFLAG_NUMBER; - break; - } - - /* - Set the pack flag correctly for the blob-like types. This sets the - packtype to something that make_field can use. If the pack type is - not set correctly, the packlength will be reeeeally wierd (like - 129 or so). - */ - switch (sql_type_arg) - { - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_GEOMETRY: - // If you are going to use the above types, you have to pass a - // pack_length as parameter. Assert that is really done. - DBUG_ASSERT(pack_length_arg != ~0U); - pack_flag|= pack_length_to_packflag(pack_length_arg); - break; - default: - /* Nothing */ - break; - } - - pack_flag|= - (maybe_null ? FIELDFLAG_MAYBE_NULL : 0) | - (is_unsigned ? 0 : FIELDFLAG_DECIMAL); - - DBUG_PRINT("debug", ("pack_flag: %s%s%s%s%s%s, pack_type: %d", - FLAGSTR(pack_flag, FIELDFLAG_BINARY), - FLAGSTR(pack_flag, FIELDFLAG_NUMBER), - FLAGSTR(pack_flag, FIELDFLAG_INTERVAL), - FLAGSTR(pack_flag, FIELDFLAG_GEOM), - FLAGSTR(pack_flag, FIELDFLAG_BLOB), - FLAGSTR(pack_flag, FIELDFLAG_DECIMAL), - f_packtype(pack_flag))); - vcol_info= 0; - create_if_not_exists= FALSE; - stored_in_db= TRUE; - - DBUG_VOID_RETURN; -} - - static inline bool is_item_func(Item* x) { return x != NULL && x->type() == Item::FUNC_ITEM; } -bool Create_field::check(THD *thd) +bool Column_definition::check(THD *thd) { const uint conditional_type_modifiers= AUTO_INCREMENT_FLAG; uint sign_len, allowed_type_modifier= 0; ulong max_field_charlength= MAX_FIELD_CHARLENGTH; DBUG_ENTER("Create_field::check"); + /* Initialize data for a computed field */ if (vcol_info) { + DBUG_ASSERT(vcol_info->expr_item); + vcol_info->set_field_type(sql_type); - sql_type= (enum enum_field_types)MYSQL_TYPE_VIRTUAL; + /* + Walk through the Item tree checking if all items are valid + to be part of the virtual column + */ + if (vcol_info->expr_item->walk(&Item::check_vcol_func_processor, 0, NULL)) + { + my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name); + DBUG_RETURN(TRUE); + } } if (length > MAX_FIELD_BLOBLENGTH) @@ -9922,30 +9844,6 @@ bool Create_field::check(THD *thd) DBUG_RETURN(1); } - /* Initialize data for a computed field */ - if (sql_type == MYSQL_TYPE_VIRTUAL) - { - DBUG_ASSERT(vcol_info && vcol_info->expr_item); - stored_in_db= vcol_info->is_stored(); - /* - Walk through the Item tree checking if all items are valid - to be part of the virtual column - */ - if (vcol_info->expr_item->walk(&Item::check_vcol_func_processor, 0, NULL)) - { - my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name); - DBUG_RETURN(TRUE); - } - - /* - Make a field created for the real type. - Note that regular and computed fields differ from each other only by - Field::vcol_info. It is is always NULL for a column that is not - computed. - */ - sql_type= vcol_info->get_real_type(); - } - sign_len= flags & UNSIGNED_FLAG ? 0 : 1; switch (sql_type) { @@ -10506,10 +10404,10 @@ Field *make_field(TABLE_SHARE *share, /** Create a field suitable for create of table. */ -Create_field::Create_field(THD *thd, Field *old_field, Field *orig_field) +Column_definition::Column_definition(THD *thd, Field *old_field, + Field *orig_field) { - field= old_field; - field_name=change=old_field->field_name; + field_name= old_field->field_name; length= old_field->field_length; flags= old_field->flags; unireg_check=old_field->unireg_check; @@ -10520,10 +10418,7 @@ Create_field::Create_field(THD *thd, Field *old_field, Field *orig_field) comment= old_field->comment; decimals= old_field->decimals(); vcol_info= old_field->vcol_info; - create_if_not_exists= FALSE; - stored_in_db= old_field->stored_in_db; option_list= old_field->option_list; - option_struct= old_field->option_struct; switch (sql_type) { case MYSQL_TYPE_BLOB: @@ -10614,7 +10509,7 @@ Create_field::Create_field(THD *thd, Field *old_field, Field *orig_field) { StringBuffer<MAX_FIELD_WIDTH> tmp(charset); String *res= orig_field->val_str(&tmp, orig_field->ptr_in_record(dv)); - char *pos= (char*) sql_strmake(res->ptr(), res->length()); + char *pos= (char*) thd->strmake(res->ptr(), res->length()); def= new (thd->mem_root) Item_string(thd, pos, res->length(), charset); } } diff --git a/sql/field.h b/sql/field.h index 08905f2c9e9..736c51c2ac3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -33,6 +33,7 @@ #include "compat56.h" class Send_field; +class Copy_field; class Protocol; class Create_field; class Relay_log_info; @@ -280,6 +281,16 @@ protected: return decimal_value; } + longlong longlong_from_hex_hybrid(const char *str, uint32 length) + { + const char *end= str + length; + const char *ptr= end - MY_MIN(length, sizeof(longlong)); + ulonglong value= 0; + for ( ; ptr != end ; ptr++) + value= (value << 8) + (ulonglong) (uchar) *ptr; + return (longlong) value; + } + longlong longlong_from_string_with_check(const String *str) const { return longlong_from_string_with_check(str->charset(), @@ -392,8 +403,6 @@ struct ha_field_option_struct; struct st_cache_field; int field_conv(Field *to,Field *from); -int field_conv_incompatible(Field *to,Field *from); -bool memcpy_field_possible(Field *to, Field *from); int truncate_double(double *nr, uint field_length, uint dec, bool unsigned_flag, double max_value); longlong double_to_longlong(double nr, bool unsigned_flag, bool *error); @@ -555,12 +564,12 @@ private: when a Create_field object is created/initialized. */ enum_field_types field_type; /* Real field type*/ - /* Flag indicating that the field is physically stored in the database */ - bool stored_in_db; /* Flag indicating that the field used in a partitioning expression */ bool in_partitioning_expr; public: + /* Flag indicating that the field is physically stored in the database */ + bool stored_in_db; /* The expression to compute the value of the virtual column */ Item *expr_item; /* Text representation of the defining expression */ @@ -568,7 +577,7 @@ public: Virtual_column_info() : field_type((enum enum_field_types)MYSQL_TYPE_VIRTUAL), - stored_in_db(FALSE), in_partitioning_expr(FALSE), + in_partitioning_expr(FALSE), stored_in_db(FALSE), expr_item(NULL) { expr_str.str= NULL; @@ -613,11 +622,23 @@ class Field: public Value_source { Field(const Item &); /* Prevent use of these */ void operator=(Field &); +protected: + int save_in_field_str(Field *to) + { + StringBuffer<MAX_FIELD_WIDTH> result(charset()); + val_str(&result); + return to->store(result.ptr(), result.length(), charset()); + } + static void do_field_int(Copy_field *copy); + static void do_field_real(Copy_field *copy); + static void do_field_string(Copy_field *copy); + static void do_field_temporal(Copy_field *copy); + static void do_field_decimal(Copy_field *copy); public: static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return alloc_root(mem_root, size); } static void *operator new(size_t size) throw () - { return sql_alloc(size); } + { return thd_alloc(current_thd, size); } static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) { DBUG_ASSERT(0); } @@ -720,19 +741,31 @@ public: can be computed from other fields. */ Virtual_column_info *vcol_info; - /* - Flag indicating that the field is physically stored in tables - rather than just computed from other fields. - As of now, FALSE can be set only for computed virtual columns. - */ - bool stored_in_db; Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg); virtual ~Field() {} + /** + Convenience definition of a copy function returned by + Field::get_copy_func() + */ + typedef void Copy_func(Copy_field*); + virtual Copy_func *get_copy_func(const Field *from) const= 0; /* Store functions returns 1 on overflow and -1 on fatal error */ + virtual int store_field(Field *from) { return from->save_in_field(this); } + virtual int save_in_field(Field *to)= 0; + /** + Check if it is possible just copy the value + of the field 'from' to the field 'this', e.g. for + INSERT INTO t1 (field1) SELECT field2 FROM t2; + @param from - The field to copy from + @retval true - it is possible to just copy value of 'from' to 'this' + @retval false - conversion is needed + */ + virtual bool memcpy_field_possible(const Field *from) const= 0; virtual int store(const char *to, uint length,CHARSET_INFO *cs)=0; + virtual int store_hex_hybrid(const char *str, uint length); virtual int store(double nr)=0; virtual int store(longlong nr, bool unsigned_val)=0; virtual int store_decimal(const my_decimal *d)=0; @@ -762,6 +795,7 @@ public: */ virtual String *val_str(String*,String *)=0; String *val_int_as_str(String *val_buffer, bool unsigned_flag); + fast_field_copier get_fast_field_copier(const Field *from); /* str_needs_quotes() returns TRUE if the value returned by val_str() needs to be quoted when used in constructing an SQL query. @@ -777,7 +811,7 @@ public: return (ptr == field->ptr && null_ptr == field->null_ptr && null_bit == field->null_bit && field->type() == type()); } - virtual bool eq_def(Field *field); + virtual bool eq_def(const Field *field) const; /* pack_length() returns size (in bytes) used to store field data in memory @@ -1064,6 +1098,8 @@ public: null_bit= p_null_bit; } + bool stored_in_db() const { return !vcol_info || vcol_info->stored_in_db; } + inline THD *get_thd() const { return likely(table) ? table->in_use : current_thd; } @@ -1248,6 +1284,7 @@ protected: return (op_result == E_DEC_OVERFLOW); } int warn_if_overflow(int op_result); + Copy_func *get_identical_copy_func() const; public: void set_table_name(String *alias) { @@ -1510,7 +1547,22 @@ public: void make_field(Send_field *); uint decimals() const { return (uint) dec; } uint size_of() const { return sizeof(*this); } - bool eq_def(Field *field); + bool eq_def(const Field *field) const; + Copy_func *get_copy_func(const Field *from) const + { + return do_field_int; + } + int save_in_field(Field *to) + { + return to->store(val_int(), MY_TEST(flags & UNSIGNED_FLAG)); + } + bool memcpy_field_possible(const Field *from) const + { + return real_type() == from->real_type() && + pack_length() == from->pack_length() && + !((flags & UNSIGNED_FLAG) && !(from->flags & UNSIGNED_FLAG)) && + decimals() == from->decimals(); + } int store_decimal(const my_decimal *); my_decimal *val_decimal(my_decimal *); bool val_bool() { return val_int() != 0; } @@ -1543,10 +1595,21 @@ public: const char *field_name_arg, CHARSET_INFO *charset); Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } + int save_in_field(Field *to) { return save_in_field_str(to); } + bool memcpy_field_possible(const Field *from) const + { + return real_type() == from->real_type() && + pack_length() == from->pack_length() && + charset() == from->charset(); + } int store(double nr); int store(longlong nr, bool unsigned_val)=0; int store_decimal(const my_decimal *); int store(const char *to,uint length,CHARSET_INFO *cs)=0; + int store_hex_hybrid(const char *str, uint length) + { + return store(str, length, &my_charset_bin); + } uint repertoire(void) const { return my_charset_repertoire(field_charset); @@ -1639,6 +1702,21 @@ public: not_fixed(dec_arg >= NOT_FIXED_DEC) {} Item_result result_type () const { return REAL_RESULT; } + Copy_func *get_copy_func(const Field *from) const + { + return do_field_real; + } + int save_in_field(Field *to) { return to->store(val_real()); } + bool memcpy_field_possible(const Field *from) const + { + /* + Cannot do memcpy from a longer field to a shorter field, + e.g. a DOUBLE(53,10) into a DOUBLE(10,10). + But it should be OK the other way around. + */ + return Field_num::memcpy_field_possible(from) && + field_length >= from->field_length; + } int store_decimal(const my_decimal *); int store_time_dec(MYSQL_TIME *ltime, uint dec); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); @@ -1663,6 +1741,10 @@ public: enum_field_types type() const { return MYSQL_TYPE_DECIMAL;} enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } + Copy_func *get_copy_func(const Field *from) const + { + return eq_def(from) ? get_identical_copy_func() : do_field_string; + } int reset(void); int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); @@ -1706,6 +1788,22 @@ public: enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } Item_result result_type () const { return DECIMAL_RESULT; } + Copy_func *get_copy_func(const Field *from) const + { + // if (from->real_type() == MYSQL_TYPE_BIT) // QQ: why? + // return do_field_int; + return do_field_decimal; + } + int save_in_field(Field *to) + { + my_decimal buff; + return to->store_decimal(val_decimal(&buff)); + } + bool memcpy_field_possible(const Field *from) const + { + return Field_num::memcpy_field_possible(from) && + field_length == from->field_length; + } int reset(void); bool store_value(const my_decimal *decimal_value); void set_value_on_overflow(my_decimal *decimal_value, bool sign); @@ -2042,6 +2140,10 @@ public: unireg_check_arg, field_name_arg, cs) {} enum_field_types type() const { return MYSQL_TYPE_NULL;} + Copy_func *get_copy_func(const Field *from) const + { + return do_field_string; + } int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } int store(double nr) { null[0]=1; return 0; } @@ -2088,6 +2190,19 @@ public: field_name_arg) { flags|= BINARY_FLAG; } Item_result result_type () const { return STRING_RESULT; } + int store_hex_hybrid(const char *str, uint length) + { + return store(str, length, &my_charset_bin); + } + Copy_func *get_copy_func(const Field *from) const; + int save_in_field(Field *to) + { + MYSQL_TIME ltime; + if (get_date(<ime, 0)) + return to->reset(); + return to->store_time_dec(<ime, decimals()); + } + bool memcpy_field_possible(const Field *from) const; uint32 max_display_length() { return field_length; } bool str_needs_quotes() { return TRUE; } enum Derivation derivation(void) const { return DERIVATION_NUMERIC; } @@ -2098,7 +2213,7 @@ public: enum Item_result cmp_type () const { return TIME_RESULT; } bool val_bool() { return val_real() != 0e0; } uint is_equal(Create_field *new_field); - bool eq_def(Field *field) + bool eq_def(const Field *field) const { return (Field::eq_def(field) && decimals() == field->decimals()); } @@ -2351,6 +2466,28 @@ public: unireg_check_arg, field_name_arg, 1, 1) {} enum_field_types type() const { return MYSQL_TYPE_YEAR;} + Copy_func *get_copy_func(const Field *from) const + { + if (eq_def(from)) + return get_identical_copy_func(); + switch (from->cmp_type()) { + case STRING_RESULT: + return do_field_string; + case TIME_RESULT: + return do_field_temporal; + case DECIMAL_RESULT: + return do_field_decimal; + case REAL_RESULT: + return do_field_real; + case INT_RESULT: + break; + case ROW_RESULT: + default: + DBUG_ASSERT(0); + break; + } + return do_field_int; + } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); @@ -2440,6 +2577,7 @@ protected: int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str, int was_cut, int have_smth_to_conv); bool check_zero_in_date_with_warn(ulonglong fuzzydate); + static void do_field_time(Copy_field *copy); public: Field_time(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, @@ -2449,6 +2587,19 @@ public: {} enum_field_types type() const { return MYSQL_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } + Copy_func *get_copy_func(const Field *from) const + { + return from->cmp_type() == REAL_RESULT ? do_field_string : // MDEV-9344 + from->type() == MYSQL_TYPE_YEAR ? do_field_int : + from->type() == MYSQL_TYPE_BIT ? do_field_int : + eq_def(from) ? get_identical_copy_func() : + do_field_time; + } + bool memcpy_field_possible(const Field *from) const + { + return real_type() == from->real_type() && + decimals() == from->decimals(); + } int store_time_dec(MYSQL_TIME *ltime, uint dec); int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); @@ -2817,6 +2968,7 @@ public: enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; } bool zero_pack() const { return 0; } + Copy_func *get_copy_func(const Field *from) const; int reset(void) { charset()->cset->fill(charset(),(char*) ptr, field_length, @@ -2913,6 +3065,12 @@ public: return (uint32) field_length + (field_charset == &my_charset_bin ? length_bytes : 0); } + Copy_func *get_copy_func(const Field *from) const; + bool memcpy_field_possible(const Field *from) const + { + return Field_str::memcpy_field_possible(from) && + length_bytes == ((Field_varstring*) from)->length_bytes; + } int store(const char *to,uint length,CHARSET_INFO *charset); int store(longlong nr, bool unsigned_val); int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */ @@ -2965,7 +3123,9 @@ protected: The 'value'-object is a cache fronting the storage engine. */ String value; - + + static void do_copy_blob(Copy_field *copy); + static void do_conv_blob(Copy_field *copy); public: Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, @@ -3000,6 +3160,31 @@ public: enum_field_types type() const { return MYSQL_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } + Copy_func *get_copy_func(const Field *from) const + { + /* + TODO: MDEV-9331 + if (from->type() == MYSQL_TYPE_BIT) + return do_field_int; + */ + if (!(from->flags & BLOB_FLAG) || from->charset() != charset()) + return do_conv_blob; + if (from->pack_length() != Field_blob::pack_length()) + return do_copy_blob; + return get_identical_copy_func(); + } + int store_field(Field *from) + { // Be sure the value is stored + from->val_str(&value); + if (table->copy_blobs || (!value.is_alloced() && from->is_updatable())) + value.copy(); + return store(value.ptr(), value.length(), from->charset()); + } + bool memcpy_field_possible(const Field *from) const + { + return Field_str::memcpy_field_possible(from) && + !table->copy_blobs; + } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); @@ -3103,7 +3288,6 @@ public: uint max_packed_col_length(uint max_length); void free() { value.free(); } inline void clear_temporary() { bzero((uchar*) &value,sizeof(value)); } - friend int field_conv_incompatible(Field *to,Field *from); uint size_of() const { return sizeof(*this); } bool has_charset(void) const { return charset() == &my_charset_bin ? FALSE : TRUE; } @@ -3175,6 +3359,7 @@ uint gis_field_options_read(const uchar *buf, uint buf_len, class Field_enum :public Field_str { + static void do_field_enum(Copy_field *copy_field); protected: uint packlength; public: @@ -3195,6 +3380,33 @@ public: enum_field_types type() const { return MYSQL_TYPE_STRING; } enum Item_result cmp_type () const { return INT_RESULT; } enum ha_base_keytype key_type() const; + Copy_func *get_copy_func(const Field *from) const + { + if (eq_def(from)) + return get_identical_copy_func(); + if (real_type() == MYSQL_TYPE_ENUM && + from->real_type() == MYSQL_TYPE_ENUM) + return do_field_enum; + if (from->result_type() == STRING_RESULT) + return do_field_string; + return do_field_int; + } + int store_field(Field *from) + { + if (from->real_type() == MYSQL_TYPE_ENUM && from->val_int() == 0) + { + store_type(0); + return 0; + } + return from->save_in_field(this); + } + int save_in_field(Field *to) + { + if (to->result_type() != STRING_RESULT) + return to->store(val_int(), 0); + return save_in_field_str(to); + } + bool memcpy_field_possible(const Field *from) const { return false; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); @@ -3213,7 +3425,7 @@ public: uint row_pack_length() const { return pack_length(); } virtual bool zero_pack() const { return 0; } bool optimize_range(uint idx, uint part) { return 0; } - bool eq_def(Field *field); + bool eq_def(const Field *field) const; bool has_charset(void) const { return TRUE; } /* enum and set are sorted as integers */ CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } @@ -3258,6 +3470,7 @@ public: { flags=(flags & ~ENUM_FLAG) | SET_FLAG; } + int store_field(Field *from) { return from->save_in_field(this); } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr) { return Field_set::store((longlong) nr, FALSE); } int store(longlong nr, bool unsigned_val); @@ -3309,6 +3522,12 @@ public: clr_rec_bits(bit_ptr, bit_ofs, bit_len); return 0; } + Copy_func *get_copy_func(const Field *from) const + { + return do_field_int; + } + int save_in_field(Field *to) { return to->store(val_int(), true); } + bool memcpy_field_possible(const Field *from) const { return false; } int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); @@ -3437,16 +3656,24 @@ public: extern const LEX_STRING null_lex_str; + + +Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, + uchar *ptr, uint32 field_length, + uchar *null_pos, uchar null_bit, + uint pack_flag, enum_field_types field_type, + CHARSET_INFO *cs, + Field::geometry_type geom_type, uint srid, + Field::utype unireg_check, + TYPELIB *interval, const char *field_name); + /* Create field class for CREATE TABLE */ - -class Create_field :public Sql_alloc +class Column_definition: public Sql_alloc { public: const char *field_name; - const char *change; // If done with alter table - const char *after; // Put column after this one LEX_STRING comment; // Comment for field Item *def, *on_update; // Default value enum enum_field_types sql_type; @@ -3463,20 +3690,13 @@ public: uint decimals, flags, pack_length, key_length; Field::utype unireg_check; TYPELIB *interval; // Which interval to use - TYPELIB *save_interval; // Temporary copy for the above - // Used only for UCS2 intervals List<String> interval_list; CHARSET_INFO *charset; uint32 srid; Field::geometry_type geom_type; - Field *field; // For alter table engine_option_value *option_list; - /** structure with parsed options (for comparing fields in ALTER TABLE) */ - ha_field_option_struct *option_struct; - uint8 interval_id; // For rea_create_table - uint offset,pack_flag; - bool create_if_not_exists; // Used in ALTER TABLE IF NOT EXISTS + uint pack_flag; /* This is additinal data provided for any computed(virtual) field. @@ -3484,37 +3704,25 @@ public: can be computed from other fields. */ Virtual_column_info *vcol_info; - /* - Flag indicating that the field is physically stored in tables - rather than just computed from other fields. - As of now, FALSE can be set only for computed virtual columns. - */ - bool stored_in_db; - Create_field() :change(0), after(0), comment(null_lex_str), - def(0), on_update(0), sql_type(MYSQL_TYPE_NULL), - flags(0), pack_length(0), key_length(0), interval(0), - srid(0), geom_type(Field::GEOM_GEOMETRY), - field(0), option_list(NULL), option_struct(NULL), - create_if_not_exists(false), vcol_info(0), - stored_in_db(true) + Column_definition(): + comment(null_lex_str), + def(0), on_update(0), sql_type(MYSQL_TYPE_NULL), + flags(0), pack_length(0), key_length(0), interval(0), + srid(0), geom_type(Field::GEOM_GEOMETRY), + option_list(NULL), + vcol_info(0) { interval_list.empty(); } - Create_field(THD *thd, Field *field, Field *orig_field); - /* Used to make a clone of this object for ALTER/CREATE TABLE */ - Create_field *clone(MEM_ROOT *mem_root) const; + Column_definition(THD *thd, Field *field, Field *orig_field); void create_length_to_internal_length(void); - /* Init for a tmp table field. To be extended if need be. */ - void init_for_tmp_table(enum_field_types sql_type_arg, - uint32 max_length, uint32 decimals, - bool maybe_null, bool is_unsigned, - uint pack_length = ~0U); - bool check(THD *thd); + bool stored_in_db() const { return !vcol_info || vcol_info->stored_in_db; } + ha_storage_media field_storage_type() const { return (ha_storage_media) @@ -3539,6 +3747,54 @@ public: unireg_check == Field::TIMESTAMP_UN_FIELD || unireg_check == Field::NEXT_NUMBER); } + + Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, + uchar *ptr, uchar *null_pos, uchar null_bit, + const char *field_name_arg) const + { + return ::make_field(share, mem_root, ptr, + (uint32)length, null_pos, null_bit, + pack_flag, sql_type, charset, + geom_type, srid, unireg_check, interval, + field_name_arg); + } + Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, + const char *field_name_arg) + { + return make_field(share, mem_root, (uchar *) 0, (uchar *) "", 0, + field_name_arg); + } +}; + + +class Create_field :public Column_definition +{ +public: + const char *change; // If done with alter table + const char *after; // Put column after this one + Field *field; // For alter table + TYPELIB *save_interval; // Temporary copy for the above + // Used only for UCS2 intervals + + /** structure with parsed options (for comparing fields in ALTER TABLE) */ + ha_field_option_struct *option_struct; + uint offset; + uint8 interval_id; // For rea_create_table + bool create_if_not_exists; // Used in ALTER TABLE IF NOT EXISTS + + Create_field(): + Column_definition(), change(0), after(0), + field(0), option_struct(NULL), + create_if_not_exists(false) + { } + Create_field(THD *thd, Field *old_field, Field *orig_field): + Column_definition(thd, old_field, orig_field), + change(old_field->field_name), after(0), + field(old_field), option_struct(old_field->option_struct), + create_if_not_exists(false) + { } + /* Used to make a clone of this object for ALTER/CREATE TABLE */ + Create_field *clone(MEM_ROOT *mem_root) const; }; @@ -3563,12 +3819,6 @@ class Send_field :public Sql_alloc { */ class Copy_field :public Sql_alloc { - /** - Convenience definition of a copy function returned by - get_copy_func. - */ - typedef void Copy_func(Copy_field*); - Copy_func *get_copy_func(Field *to, Field *from); public: uchar *from_ptr,*to_ptr; uchar *from_null_ptr,*to_null_ptr; @@ -3589,7 +3839,7 @@ public: Note that for VARCHARs, do_copy() will be do_varstring*() which only copies the length-bytes (1 or 2) + the actual length of the - text instead of from/to_length bytes. @see get_copy_func() + text instead of from/to_length bytes. */ uint from_length,to_length; Field *from_field,*to_field; @@ -3604,14 +3854,6 @@ public: }; -Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root, - uchar *ptr, uint32 field_length, - uchar *null_pos, uchar null_bit, - uint pack_flag, enum_field_types field_type, - CHARSET_INFO *cs, - Field::geometry_type geom_type, uint srid, - Field::utype unireg_check, - TYPELIB *interval, const char *field_name); uint pack_length_to_packflag(uint type); enum_field_types get_blob_type_from_length(ulong length); uint32 calc_pack_length(enum_field_types type,uint32 length); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 7b57c7da104..263c5bb5017 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -334,12 +334,12 @@ static void do_copy_next_number(Copy_field *copy) } -static void do_copy_blob(Copy_field *copy) +void Field_blob::do_copy_blob(Copy_field *copy) { ((Field_blob*) copy->to_field)->copy_value(((Field_blob*) copy->from_field)); } -static void do_conv_blob(Copy_field *copy) +void Field_blob::do_conv_blob(Copy_field *copy) { copy->from_field->val_str(©->tmp); ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(), @@ -361,7 +361,7 @@ static void do_save_blob(Copy_field *copy) } -static void do_field_string(Copy_field *copy) +void Field::do_field_string(Copy_field *copy) { char buff[MAX_FIELD_WIDTH]; String res(buff, sizeof(buff), copy->from_field->charset()); @@ -372,7 +372,7 @@ static void do_field_string(Copy_field *copy) } -static void do_field_enum(Copy_field *copy) +void Field_enum::do_field_enum(Copy_field *copy) { if (copy->from_field->val_int() == 0) ((Field_enum *) copy->to_field)->store_type((ulonglong) 0); @@ -396,32 +396,45 @@ static void do_field_varbinary_pre50(Copy_field *copy) } -static void do_field_int(Copy_field *copy) +void Field::do_field_int(Copy_field *copy) { longlong value= copy->from_field->val_int(); copy->to_field->store(value, MY_TEST(copy->from_field->flags & UNSIGNED_FLAG)); } -static void do_field_real(Copy_field *copy) +void Field::do_field_real(Copy_field *copy) { double value=copy->from_field->val_real(); copy->to_field->store(value); } -static void do_field_decimal(Copy_field *copy) +void Field::do_field_decimal(Copy_field *copy) { my_decimal value; copy->to_field->store_decimal(copy->from_field->val_decimal(&value)); } -static void do_field_temporal(Copy_field *copy) +void Field::do_field_temporal(Copy_field *copy) { MYSQL_TIME ltime; - copy->from_field->get_date(<ime, 0); - copy->to_field->store_time_dec(<ime, copy->from_field->decimals()); + // TODO: we now need to check result + if (copy->from_field->get_date(<ime, 0)) + copy->to_field->reset(); + else + copy->to_field->store_time_dec(<ime, copy->from_field->decimals()); +} + + +void Field_time::do_field_time(Copy_field *copy) +{ + MYSQL_TIME ltime; + if (copy->from_field->get_date(<ime, TIME_TIME_ONLY)) + copy->to_field->reset(); + else + copy->to_field->store_time_dec(<ime, copy->from_field->decimals()); } @@ -694,122 +707,72 @@ void Copy_field::set(Field *to,Field *from,bool save) if ((to->flags & BLOB_FLAG) && save) do_copy2= do_save_blob; else - do_copy2= get_copy_func(to,from); + do_copy2= to->get_copy_func(from); if (!do_copy) // Not null do_copy=do_copy2; } -Copy_field::Copy_func * -Copy_field::get_copy_func(Field *to,Field *from) +Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const +{ + /* If types are not 100 % identical then convert trough get_date() */ + if (from->cmp_type() == REAL_RESULT) + return do_field_string; // TODO: MDEV-9344 + if (from->type() == MYSQL_TYPE_YEAR) + return do_field_string; // TODO: MDEV-9343 + if (from->type() == MYSQL_TYPE_BIT) + return do_field_int; + if (!eq_def(from) || + (table->in_use->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))) + return do_field_temporal; + return get_identical_copy_func(); +} + + +Field::Copy_func *Field_varstring::get_copy_func(const Field *from) const +{ + if (from->type() == MYSQL_TYPE_BIT) + return do_field_int; + /* + Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and + use special copy function that removes trailing spaces and thus + repairs data. + */ + if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() && + !Field_varstring::has_charset()) + return do_field_varbinary_pre50; + if (Field_varstring::real_type() != from->real_type() || + Field_varstring::charset() != from->charset() || + length_bytes != ((const Field_varstring*) from)->length_bytes) + return do_field_string; + return length_bytes == 1 ? + (from->charset()->mbmaxlen == 1 ? do_varstring1 : do_varstring1_mb) : + (from->charset()->mbmaxlen == 1 ? do_varstring2 : do_varstring2_mb); +} + + +Field::Copy_func *Field_string::get_copy_func(const Field *from) const +{ + if (from->type() == MYSQL_TYPE_BIT) + return do_field_int; + if (Field_string::real_type() != from->real_type() || + Field_string::charset() != from->charset()) + return do_field_string; + if (Field_string::pack_length() < from->pack_length()) + return (Field_string::charset()->mbmaxlen == 1 ? + do_cut_string : do_cut_string_complex); + if (Field_string::pack_length() > from->pack_length()) + return Field_string::charset() == &my_charset_bin ? do_expand_binary : + do_expand_string; + return get_identical_copy_func(); +} + + +Field::Copy_func *Field::get_identical_copy_func() const { - if (to->flags & BLOB_FLAG) - { - if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset()) - return do_conv_blob; - if (from_length != to_length) - return do_copy_blob; - } - else - { - if (to->real_type() == MYSQL_TYPE_BIT || - from->real_type() == MYSQL_TYPE_BIT) - return do_field_int; - if (to->result_type() == DECIMAL_RESULT) - return do_field_decimal; - if (from->cmp_type() == TIME_RESULT) - { - /* If types are not 100 % identical then convert trough get_date() */ - if (!to->eq_def(from) || - ((to->table->in_use->variables.sql_mode & - (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)) && - mysql_type_to_time_type(to->type()) != MYSQL_TIMESTAMP_TIME)) - return do_field_temporal; - /* Do binary copy */ - } - // Check if identical fields - if (from->result_type() == STRING_RESULT) - { - /* - Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and - use special copy function that removes trailing spaces and thus - repairs data. - */ - if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() && - to->type() == MYSQL_TYPE_VARCHAR && !to->has_charset()) - return do_field_varbinary_pre50; - - if (to->real_type() != from->real_type()) - { - if (from->real_type() == MYSQL_TYPE_ENUM || - from->real_type() == MYSQL_TYPE_SET) - if (to->result_type() != STRING_RESULT) - return do_field_int; // Convert SET to number - return do_field_string; - } - if (to->real_type() == MYSQL_TYPE_ENUM || - to->real_type() == MYSQL_TYPE_SET) - { - if (!to->eq_def(from)) - { - if (from->real_type() == MYSQL_TYPE_ENUM && - to->real_type() == MYSQL_TYPE_ENUM) - return do_field_enum; - return do_field_string; - } - } - else if (to->charset() != from->charset()) - return do_field_string; - else if (to->real_type() == MYSQL_TYPE_VARCHAR) - { - if (((Field_varstring*) to)->length_bytes != - ((Field_varstring*) from)->length_bytes) - return do_field_string; - return (((Field_varstring*) to)->length_bytes == 1 ? - (from->charset()->mbmaxlen == 1 ? do_varstring1 : - do_varstring1_mb) : - (from->charset()->mbmaxlen == 1 ? do_varstring2 : - do_varstring2_mb)); - } - else if (to_length < from_length) - return (from->charset()->mbmaxlen == 1 ? - do_cut_string : do_cut_string_complex); - else if (to_length > from_length) - { - if (to->charset() == &my_charset_bin) - return do_expand_binary; - return do_expand_string; - } - } - else if (to->real_type() != from->real_type() || - to_length != from_length) - { - if ((to->real_type() == MYSQL_TYPE_ENUM || - to->real_type() == MYSQL_TYPE_SET) && - from->real_type() == MYSQL_TYPE_NEWDECIMAL) - return do_field_decimal; - if (to->real_type() == MYSQL_TYPE_DECIMAL || - to->result_type() == STRING_RESULT) - return do_field_string; - if (to->result_type() == INT_RESULT) - return do_field_int; - return do_field_real; - } - else - { - if (!to->eq_def(from)) - { - if (to->real_type() == MYSQL_TYPE_DECIMAL) - return do_field_string; - if (to->result_type() == INT_RESULT) - return do_field_int; - else - return do_field_real; - } - } - } /* Identical field types */ - switch (to_length) { + switch (pack_length()) { case 1: return do_field_1; case 2: return do_field_2; case 3: return do_field_3; @@ -820,61 +783,25 @@ Copy_field::get_copy_func(Field *to,Field *from) return do_field_eq; } -/** - Check if it is possible just copy value of the fields - @param to The field to copy to - @param from The field to copy from +bool Field_temporal::memcpy_field_possible(const Field *from) const +{ + return real_type() == from->real_type() && + decimals() == from->decimals() && + !sql_mode_for_dates(table->in_use); +} - @retval TRUE - it is possible to just copy value of 'from' to 'to'. - @retval FALSE - conversion is needed -*/ -bool memcpy_field_possible(Field *to,Field *from) +static int field_conv_memcpy(Field *to, Field *from) { - const enum_field_types to_real_type= to->real_type(); - const enum_field_types from_real_type= from->real_type(); /* - Warning: Calling from->type() may be unsafe in some (unclear) circumstances - related to SPs. See MDEV-6799. + This may happen if one does 'UPDATE ... SET x=x' + The test is here mostly for valgrind, but can also be relevant + if memcpy() is implemented with prefetch-write */ - return (to_real_type == from_real_type && - !(to->flags & BLOB_FLAG && to->table->copy_blobs) && - to->pack_length() == from->pack_length() && - !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && - to->decimals() == from->decimals() && - to_real_type != MYSQL_TYPE_ENUM && - to_real_type != MYSQL_TYPE_SET && - to_real_type != MYSQL_TYPE_BIT && - (to_real_type != MYSQL_TYPE_NEWDECIMAL || - to->field_length == from->field_length) && - from->charset() == to->charset() && - (!sql_mode_for_dates(to->table->in_use) || - (from->type()!= MYSQL_TYPE_DATE && - from->type()!= MYSQL_TYPE_DATETIME && - from->type()!= MYSQL_TYPE_TIMESTAMP)) && - (from_real_type != MYSQL_TYPE_VARCHAR || - ((Field_varstring*)from)->length_bytes == - ((Field_varstring*)to)->length_bytes)); -} - - -/** Simple quick field convert that is called on insert. */ - -int field_conv(Field *to,Field *from) -{ - if (memcpy_field_possible(to, from)) - { // Identical fields - /* - This may happen if one does 'UPDATE ... SET x=x' - The test is here mostly for valgrind, but can also be relevant - if memcpy() is implemented with prefetch-write - */ - if (to->ptr != from->ptr) - memcpy(to->ptr, from->ptr, to->pack_length()); - return 0; - } - return field_conv_incompatible(to, from); + if (to->ptr != from->ptr) + memcpy(to->ptr,from->ptr, to->pack_length()); + return 0; } @@ -884,70 +811,34 @@ int field_conv(Field *to,Field *from) @note Impossibility of simple copy should be checked before this call. @param to The field to copy to - @param from The field to copy from @retval TRUE ERROR @retval FALSE OK + +*/ +static int field_conv_incompatible(Field *to, Field *from) +{ + return to->store_field(from); +} + + +/** + Simple quick field converter that is called on insert, e.g.: + INSERT INTO t1 (field1) SELECT field2 FROM t2; */ -int field_conv_incompatible(Field *to, Field *from) +int field_conv(Field *to,Field *from) { - const enum_field_types to_real_type= to->real_type(); - const enum_field_types from_real_type= from->real_type(); - if (to->flags & BLOB_FLAG) - { // Be sure the value is stored - Field_blob *blob=(Field_blob*) to; - from->val_str(&blob->value); + return to->memcpy_field_possible(from) ? + field_conv_memcpy(to, from) : + field_conv_incompatible(to, from); +} - /* - Copy value if copy_blobs is set, or source is part of the table's - writeset. - */ - if (to->table->copy_blobs || - (!blob->value.is_alloced() && from->is_updatable())) - blob->value.copy(); - return blob->store(blob->value.ptr(),blob->value.length(),from->charset()); - } - if (from_real_type == MYSQL_TYPE_ENUM && - to_real_type == MYSQL_TYPE_ENUM && - from->val_int() == 0) - { - ((Field_enum *)(to))->store_type(0); - return 0; - } - Item_result from_result_type= from->result_type(); - if (from_result_type == REAL_RESULT) - return to->store(from->val_real()); - if (from_result_type == DECIMAL_RESULT) - { - my_decimal buff; - return to->store_decimal(from->val_decimal(&buff)); - } - if (from->cmp_type() == TIME_RESULT) - { - MYSQL_TIME ltime; - if (from->get_date(<ime, 0)) - return to->reset(); - else - return to->store_time_dec(<ime, from->decimals()); - } - if ((from_result_type == STRING_RESULT && - (to->result_type() == STRING_RESULT || - (from_real_type != MYSQL_TYPE_ENUM && - from_real_type != MYSQL_TYPE_SET))) || - to->type() == MYSQL_TYPE_DECIMAL) - { - char buff[MAX_FIELD_WIDTH]; - String result(buff,sizeof(buff),from->charset()); - from->val_str(&result); - /* - We use c_ptr_quick() here to make it easier if to is a float/double - as the conversion routines will do a copy of the result doesn't - end with \0. Can be replaced with .ptr() when we have our own - string->double conversion. - */ - return to->store(result.c_ptr_quick(),result.length(),from->charset()); - } - return to->store(from->val_int(), MY_TEST(from->flags & UNSIGNED_FLAG)); +fast_field_copier Field::get_fast_field_copier(const Field *from) +{ + DBUG_ENTER("Field::get_fast_field_copier"); + DBUG_RETURN(memcpy_field_possible(from) ? + &field_conv_memcpy : + &field_conv_incompatible); } diff --git a/sql/filesort.cc b/sql/filesort.cc index 917b9de6038..54a79421d2e 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -50,26 +50,27 @@ if (my_b_write((file),(uchar*) (from),param->ref_length)) \ static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count, uchar *buf); static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, - Filesort_info *fs_info, + SORT_INFO *fs_info, IO_CACHE *buffer_file, IO_CACHE *tempfile, Bounded_queue<uchar, uchar> *pq, ha_rows *found_rows); -static bool write_keys(Sort_param *param, Filesort_info *fs_info, +static bool write_keys(Sort_param *param, SORT_INFO *fs_info, uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile); static void make_sortkey(Sort_param *param, uchar *to, uchar *ref_pos); static void register_used_fields(Sort_param *param); static bool save_index(Sort_param *param, uint count, - Filesort_info *table_sort); + SORT_INFO *table_sort); static uint suffix_length(ulong string_length); static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset); static SORT_ADDON_FIELD *get_addon_fields(ulong max_length_for_sort_data, Field **ptabfield, - uint sortlength, uint *plength); + uint sortlength, + LEX_STRING *addon_buf); static void unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff, uchar *buff_end); -static bool check_if_pq_applicable(Sort_param *param, Filesort_info *info, +static bool check_if_pq_applicable(Sort_param *param, SORT_INFO *info, TABLE *table, ha_rows records, ulong memory_available); @@ -78,6 +79,8 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table, ulong max_length_for_sort_data, ha_rows maxrows, bool sort_positions) { + DBUG_ASSERT(addon_field == 0 && addon_buf.length == 0); + sort_length= sortlen; ref_length= table->file->ref_length; if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && @@ -85,13 +88,13 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table, { /* Get the descriptors of all fields whose values are appended - to sorted fields and get its total length in addon_length. + to sorted fields and get its total length in addon_buf.length */ addon_field= get_addon_fields(max_length_for_sort_data, - table->field, sort_length, &addon_length); + table->field, sort_length, &addon_buf); } if (addon_field) - res_length= addon_length; + res_length= addon_buf.length; else { res_length= ref_length; @@ -101,7 +104,7 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table, */ sort_length+= ref_length; } - rec_length= sort_length + addon_length; + rec_length= sort_length + addon_buf.length; max_rows= maxrows; } @@ -115,8 +118,9 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table, Before calling filesort, one must have done table->file->info(HA_STATUS_VARIABLE) - The result set is stored in table->io_cache or - table->record_pointers. + The result set is stored in + filesort_info->io_cache or + filesort_info->record_pointers. @param thd Current thread @param table Table to sort @@ -124,28 +128,24 @@ void Sort_param::init_for_filesort(uint sortlen, TABLE *table, @param s_length Number of elements in sortorder @param select Condition to apply to the rows @param max_rows Return only this many rows - @param sort_positions Set to TRUE if we want to force sorting by position + @param sort_positions Set to TRUE if we want to force sorting by + position (Needed by UPDATE/INSERT or ALTER TABLE or when rowids are required by executor) - @param[out] examined_rows Store number of examined rows here - @param[out] found_rows Store the number of found rows here - @note If we sort by position (like if sort_positions is 1) filesort() will call table->prepare_for_position(). @retval - HA_POS_ERROR Error - @retval - \# Number of rows + 0 Error + # SORT_INFO */ -ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, - SQL_SELECT *select, ha_rows max_rows, - bool sort_positions, - ha_rows *examined_rows, - ha_rows *found_rows, - Filesort_tracker* tracker) +SORT_INFO *filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, + uint s_length, + SQL_SELECT *select, ha_rows max_rows, + bool sort_positions, + Filesort_tracker* tracker) { int error; size_t memory_available= thd->variables.sortbuff_size; @@ -162,33 +162,37 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, #ifdef SKIP_DBUG_IN_FILESORT DBUG_PUSH(""); /* No DBUG here */ #endif - Filesort_info table_sort= table->sort; + SORT_INFO *sort; TABLE_LIST *tab= table->pos_in_table_list; Item_subselect *subselect= tab ? tab->containing_subselect() : 0; - MYSQL_FILESORT_START(table->s->db.str, table->s->table_name.str); DEBUG_SYNC(thd, "filesort_start"); + if (!(sort= new SORT_INFO)) + return 0; + + if (subselect && subselect->filesort_buffer.is_allocated()) + { + /* Reuse cache from last call */ + sort->filesort_buffer= subselect->filesort_buffer; + sort->buffpek= subselect->sortbuffer; + subselect->filesort_buffer.reset(); + subselect->sortbuffer.str=0; + } + + outfile= &sort->io_cache; + /* Release InnoDB's adaptive hash index latch (if holding) before running a sort. */ ha_release_temporary_latches(thd); - /* - Don't use table->sort in filesort as it is also used by - QUICK_INDEX_MERGE_SELECT. Work with a copy and put it back at the end - when index_merge select has finished with it. - */ - table->sort.io_cache= NULL; - DBUG_ASSERT(table_sort.record_pointers == NULL); - - outfile= table_sort.io_cache; my_b_clear(&tempfile); my_b_clear(&buffpek_pointers); buffpek=0; error= 1; - *found_rows= HA_POS_ERROR; + sort->found_rows= HA_POS_ERROR; param.init_for_filesort(sortlength(thd, sortorder, s_length, &multi_byte_charset), @@ -196,14 +200,12 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, thd->variables.max_length_for_sort_data, max_rows, sort_positions); - table_sort.addon_buf= 0; - table_sort.addon_length= param.addon_length; - table_sort.addon_field= param.addon_field; - table_sort.unpack= unpack_addon_fields; - if (param.addon_field && - !(table_sort.addon_buf= - (uchar *) my_malloc(param.addon_length, MYF(MY_WME | - MY_THREAD_SPECIFIC)))) + sort->addon_buf= param.addon_buf; + sort->addon_field= param.addon_field; + sort->unpack= unpack_addon_fields; + if (multi_byte_charset && + !(param.tmp_buffer= (char*) my_malloc(param.sort_length, + MYF(MY_WME | MY_THREAD_SPECIFIC)))) goto err; if (select && select->quick) @@ -216,12 +218,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, // If number of rows is not known, use as much of sort buffer as possible. num_rows= table->file->estimate_rows_upper_bound(); - if (multi_byte_charset && - !(param.tmp_buffer= (char*) my_malloc(param.sort_length, - MYF(MY_WME | MY_THREAD_SPECIFIC)))) - goto err; - - if (check_if_pq_applicable(¶m, &table_sort, + if (check_if_pq_applicable(¶m, sort, table, num_rows, memory_available)) { DBUG_PRINT("info", ("filesort PQ is applicable")); @@ -233,45 +230,31 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, true, // max_at_top NULL, // compare_function compare_length, - &make_sortkey, ¶m, table_sort.get_sort_keys())) + &make_sortkey, ¶m, sort->get_sort_keys())) { /* If we fail to init pq, we have to give up: out of memory means my_malloc() will call my_error(). */ DBUG_PRINT("info", ("failed to allocate PQ")); - table_sort.free_sort_buffer(); DBUG_ASSERT(thd->is_error()); goto err; } // For PQ queries (with limit) we initialize all pointers. - table_sort.init_record_pointers(); + sort->init_record_pointers(); } else { DBUG_PRINT("info", ("filesort PQ is not applicable")); - size_t min_sort_memory= MY_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2); + size_t min_sort_memory= MY_MAX(MIN_SORT_MEMORY, + param.sort_length*MERGEBUFF2); set_if_bigger(min_sort_memory, sizeof(BUFFPEK*)*MERGEBUFF2); while (memory_available >= min_sort_memory) { ulonglong keys= memory_available / (param.rec_length + sizeof(char*)); param.max_keys_per_buffer= (uint) MY_MIN(num_rows, keys); - if (table_sort.get_sort_keys()) - { - // If we have already allocated a buffer, it better have same size! - if (!table_sort.check_sort_buffer_properties(param.max_keys_per_buffer, - param.rec_length)) - { - /* - table->sort will still have a pointer to the same buffer, - but that will be overwritten by the assignment below. - */ - table_sort.free_sort_buffer(); - } - } - table_sort.alloc_sort_buffer(param.max_keys_per_buffer, param.rec_length); - if (table_sort.get_sort_keys()) + if (sort->alloc_sort_buffer(param.max_keys_per_buffer, param.rec_length)) break; size_t old_memory_available= memory_available; memory_available= memory_available/4*3; @@ -284,7 +267,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR + ME_FATALERROR)); goto err; } - tracker->report_sort_buffer_size(table_sort.sort_buffer_size()); + tracker->report_sort_buffer_size(sort->sort_buffer_size()); } if (open_cached_file(&buffpek_pointers,mysql_tmpdir,TEMP_PREFIX, @@ -294,21 +277,21 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, param.sort_form= table; param.end=(param.local_sortorder=sortorder)+s_length; num_rows= find_all_keys(thd, ¶m, select, - &table_sort, + sort, &buffpek_pointers, &tempfile, pq.is_initialized() ? &pq : NULL, - found_rows); + &sort->found_rows); if (num_rows == HA_POS_ERROR) goto err; maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek)); tracker->report_merge_passes_at_start(thd->query_plan_fsort_passes); - tracker->report_row_numbers(param.examined_rows, *found_rows, num_rows); + tracker->report_row_numbers(param.examined_rows, sort->found_rows, num_rows); if (maxbuffer == 0) // The whole set is in memory { - if (save_index(¶m, (uint) num_rows, &table_sort)) + if (save_index(¶m, (uint) num_rows, sort)) goto err; } else @@ -316,17 +299,17 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, /* filesort cannot handle zero-length records during merge. */ DBUG_ASSERT(param.sort_length != 0); - if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer) + if (sort->buffpek.str && sort->buffpek.length < maxbuffer) { - my_free(table_sort.buffpek); - table_sort.buffpek= 0; + my_free(sort->buffpek.str); + sort->buffpek.str= 0; } - if (!(table_sort.buffpek= - (uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer, - table_sort.buffpek))) + if (!(sort->buffpek.str= + (char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer, + (uchar*) sort->buffpek.str))) goto err; - buffpek= (BUFFPEK *) table_sort.buffpek; - table_sort.buffpek_len= maxbuffer; + sort->buffpek.length= maxbuffer; + buffpek= (BUFFPEK *) sort->buffpek.str; close_cached_file(&buffpek_pointers); /* Open cached file if it isn't open */ if (! my_b_inited(outfile) && @@ -345,7 +328,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, param.rec_length - 1); maxbuffer--; // Offset from 0 if (merge_many_buff(¶m, - (uchar*) table_sort.get_sort_keys(), + (uchar*) sort->get_sort_keys(), buffpek,&maxbuffer, &tempfile)) goto err; @@ -353,7 +336,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) goto err; if (merge_index(¶m, - (uchar*) table_sort.get_sort_keys(), + (uchar*) sort->get_sort_keys(), buffpek, maxbuffer, &tempfile, @@ -372,11 +355,18 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, my_free(param.tmp_buffer); if (!subselect || !subselect->is_uncacheable()) { - table_sort.free_sort_buffer(); - my_free(buffpek); - table_sort.buffpek= 0; - table_sort.buffpek_len= 0; + sort->free_sort_buffer(); + my_free(sort->buffpek.str); + } + else + { + /* Remember sort buffers for next subquery call */ + subselect->filesort_buffer= sort->filesort_buffer; + subselect->sortbuffer= sort->buffpek; + sort->filesort_buffer.reset(); // Don't free this } + sort->buffpek.str= 0; + close_cached_file(&tempfile); close_cached_file(&buffpek_pointers); if (my_b_inited(outfile)) @@ -397,13 +387,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, int kill_errno= thd->killed_errno(); DBUG_ASSERT(thd->is_error() || kill_errno || thd->killed == ABORT_QUERY); - /* - We replace the table->sort at the end. - Hence calling free_io_cache to make sure table->sort.io_cache - used for QUICK_INDEX_MERGE_SELECT is free. - */ - free_io_cache(table); - my_printf_error(ER_FILSORT_ABORT, "%s: %s", MYF(0), @@ -424,50 +407,26 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, } else thd->inc_status_sort_rows(num_rows); - *examined_rows= param.examined_rows; + + sort->examined_rows= param.examined_rows; + sort->return_rows= num_rows; #ifdef SKIP_DBUG_IN_FILESORT DBUG_POP(); /* Ok to DBUG */ #endif - /* table->sort.io_cache should be free by this time */ - DBUG_ASSERT(NULL == table->sort.io_cache); - - // Assign the copy back! - table->sort= table_sort; - DBUG_PRINT("exit", - ("num_rows: %ld examined_rows: %ld found_rows: %ld", - (long) num_rows, (long) *examined_rows, (long) *found_rows)); + ("num_rows: %lld examined_rows: %lld found_rows: %lld", + (longlong) sort->return_rows, (longlong) sort->examined_rows, + (longlong) sort->found_rows)); MYSQL_FILESORT_DONE(error, num_rows); - DBUG_RETURN(error ? HA_POS_ERROR : num_rows); -} /* filesort */ - - -void filesort_free_buffers(TABLE *table, bool full) -{ - DBUG_ENTER("filesort_free_buffers"); - - my_free(table->sort.record_pointers); - table->sort.record_pointers= NULL; - if (unlikely(full)) - { - table->sort.free_sort_buffer(); - my_free(table->sort.buffpek); - table->sort.buffpek= NULL; - table->sort.buffpek_len= 0; - } - - /* addon_buf is only allocated if addon_field is set */ - if (unlikely(table->sort.addon_field)) + if (error) { - my_free(table->sort.addon_field); - my_free(table->sort.addon_buf); - table->sort.addon_buf= NULL; - table->sort.addon_field= NULL; + delete sort; + sort= 0; } - DBUG_VOID_RETURN; -} + DBUG_RETURN(sort); +} /* filesort */ /** Read 'count' number of buffer pointers into memory. */ @@ -672,7 +631,7 @@ static void dbug_print_record(TABLE *table, bool print_rowid) */ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, - Filesort_info *fs_info, + SORT_INFO *fs_info, IO_CACHE *buffpek_pointers, IO_CACHE *tempfile, Bounded_queue<uchar, uchar> *pq, @@ -877,7 +836,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, const ha_rows retval= my_b_inited(tempfile) ? (ha_rows) (my_b_tell(tempfile)/param->rec_length) : idx; - DBUG_PRINT("info", ("find_all_keys return %u", (uint) retval)); + DBUG_PRINT("info", ("find_all_keys return %llu", (ulonglong) retval)); DBUG_RETURN(retval); } /* find_all_keys */ @@ -905,7 +864,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, */ static bool -write_keys(Sort_param *param, Filesort_info *fs_info, uint count, +write_keys(Sort_param *param, SORT_INFO *fs_info, uint count, IO_CACHE *buffpek_pointers, IO_CACHE *tempfile) { size_t rec_length; @@ -964,6 +923,177 @@ static inline void store_length(uchar *to, uint length, uint pack_length) } +void +Type_handler_string_result::make_sort_key(uchar *to, Item *item, + const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const +{ + CHARSET_INFO *cs= item->collation.collation; + bool maybe_null= item->maybe_null; + + if (maybe_null) + *to++= 1; + char *tmp_buffer= param->tmp_buffer ? param->tmp_buffer : (char*) to; + String tmp(tmp_buffer, param->sort_length, cs); + String *res= item->str_result(&tmp); + if (!res) + { + if (maybe_null) + memset(to - 1, 0, sort_field->length + 1); + else + { + /* purecov: begin deadcode */ + /* + This should only happen during extreme conditions if we run out + of memory or have an item marked not null when it can be null. + This code is here mainly to avoid a hard crash in this case. + */ + DBUG_ASSERT(0); + DBUG_PRINT("warning", + ("Got null on something that shouldn't be null")); + memset(to, 0, sort_field->length); // Avoid crash + /* purecov: end */ + } + return; + } + + if (use_strnxfrm(cs)) + { + uint tmp_length __attribute__((unused)); + tmp_length= cs->coll->strnxfrm(cs, to, sort_field->length, + item->max_char_length() * + cs->strxfrm_multiply, + (uchar*) res->ptr(), res->length(), + MY_STRXFRM_PAD_WITH_SPACE | + MY_STRXFRM_PAD_TO_MAXLEN); + DBUG_ASSERT(tmp_length == sort_field->length); + } + else + { + uint diff; + uint sort_field_length= sort_field->length - sort_field->suffix_length; + uint length= res->length(); + if (sort_field_length < length) + { + diff= 0; + length= sort_field_length; + } + else + diff= sort_field_length - length; + if (sort_field->suffix_length) + { + /* Store length last in result_string */ + store_length(to + sort_field_length, length, sort_field->suffix_length); + } + /* apply cs->sort_order for case-insensitive comparison if needed */ + my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length); + char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' '); + cs->cset->fill(cs, (char *)to+length,diff,fill_char); + } +} + + +void +Type_handler_int_result::make_sort_key(uchar *to, Item *item, + const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const +{ + longlong value= item->val_int_result(); + make_sort_key_longlong(to, item->maybe_null, item->null_value, + item->unsigned_flag, value); +} + + +void +Type_handler_temporal_result::make_sort_key(uchar *to, Item *item, + const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const +{ + MYSQL_TIME buf; + if (item->get_date_result(&buf, TIME_INVALID_DATES)) + { + DBUG_ASSERT(item->maybe_null); + DBUG_ASSERT(item->null_value); + make_sort_key_longlong(to, item->maybe_null, true, + item->unsigned_flag, 0); + } + else + make_sort_key_longlong(to, item->maybe_null, false, + item->unsigned_flag, pack_time(&buf)); +} + + +void +Type_handler::make_sort_key_longlong(uchar *to, + bool maybe_null, + bool null_value, + bool unsigned_flag, + longlong value) const + +{ + if (maybe_null) + { + if (null_value) + { + memset(to, 0, 9); + return; + } + *to++= 1; + } + to[7]= (uchar) value; + to[6]= (uchar) (value >> 8); + to[5]= (uchar) (value >> 16); + to[4]= (uchar) (value >> 24); + to[3]= (uchar) (value >> 32); + to[2]= (uchar) (value >> 40); + to[1]= (uchar) (value >> 48); + if (unsigned_flag) /* Fix sign */ + to[0]= (uchar) (value >> 56); + else + to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */ +} + + +void +Type_handler_decimal_result::make_sort_key(uchar *to, Item *item, + const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const +{ + my_decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf); + if (item->maybe_null) + { + if (item->null_value) + { + memset(to, 0, sort_field->length + 1); + return; + } + *to++= 1; + } + my_decimal2binary(E_DEC_FATAL_ERROR, dec_val, to, + item->max_length - (item->decimals ? 1 : 0), + item->decimals); +} + + +void +Type_handler_real_result::make_sort_key(uchar *to, Item *item, + const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const +{ + double value= item->val_result(); + if (item->maybe_null) + { + if (item->null_value) + { + memset(to, 0, sort_field->length + 1); + return; + } + *to++= 1; + } + change_double_for_sort(value, to); +} + + /** Make a sort-key from record. */ static void make_sortkey(register Sort_param *param, @@ -986,161 +1116,9 @@ static void make_sortkey(register Sort_param *param, } else { // Item - Item *item=sort_field->item; - maybe_null= item->maybe_null; - switch (sort_field->result_type) { - case STRING_RESULT: - { - CHARSET_INFO *cs=item->collation.collation; - char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' '); - - if (maybe_null) - *to++=1; - char *tmp_buffer= param->tmp_buffer ? param->tmp_buffer : (char*)to; - String tmp(tmp_buffer, param->sort_length, cs); - String *res= item->str_result(&tmp); - if (!res) - { - if (maybe_null) - memset(to-1, 0, sort_field->length+1); - else - { - /* purecov: begin deadcode */ - /* - This should only happen during extreme conditions if we run out - of memory or have an item marked not null when it can be null. - This code is here mainly to avoid a hard crash in this case. - */ - DBUG_ASSERT(0); - DBUG_PRINT("warning", - ("Got null on something that shouldn't be null")); - memset(to, 0, sort_field->length); // Avoid crash - /* purecov: end */ - } - break; - } - length= res->length(); - if (sort_field->need_strxnfrm) - { - uint tmp_length __attribute__((unused)); - tmp_length= cs->coll->strnxfrm(cs, to, sort_field->length, - item->max_char_length() * - cs->strxfrm_multiply, - (uchar*) res->ptr(), length, - MY_STRXFRM_PAD_WITH_SPACE | - MY_STRXFRM_PAD_TO_MAXLEN); - DBUG_ASSERT(tmp_length == sort_field->length); - } - else - { - uint diff; - uint sort_field_length= sort_field->length - - sort_field->suffix_length; - if (sort_field_length < length) - { - diff= 0; - length= sort_field_length; - } - else - diff= sort_field_length - length; - if (sort_field->suffix_length) - { - /* Store length last in result_string */ - store_length(to + sort_field_length, length, - sort_field->suffix_length); - } - /* apply cs->sort_order for case-insensitive comparison if needed */ - my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length); - cs->cset->fill(cs, (char *)to+length,diff,fill_char); - } - break; - } - case INT_RESULT: - case TIME_RESULT: - { - longlong UNINIT_VAR(value); - if (sort_field->result_type == INT_RESULT) - value= item->val_int_result(); - else - { - MYSQL_TIME buf; - if (item->get_date_result(&buf, TIME_INVALID_DATES)) - { - DBUG_ASSERT(maybe_null); - DBUG_ASSERT(item->null_value); - } - else - value= pack_time(&buf); - } - if (maybe_null) - { - *to++=1; /* purecov: inspected */ - if (item->null_value) - { - if (maybe_null) - memset(to-1, 0, sort_field->length+1); - else - { - DBUG_PRINT("warning", - ("Got null on something that shouldn't be null")); - memset(to, 0, sort_field->length); - } - break; - } - } - to[7]= (uchar) value; - to[6]= (uchar) (value >> 8); - to[5]= (uchar) (value >> 16); - to[4]= (uchar) (value >> 24); - to[3]= (uchar) (value >> 32); - to[2]= (uchar) (value >> 40); - to[1]= (uchar) (value >> 48); - if (item->unsigned_flag) /* Fix sign */ - to[0]= (uchar) (value >> 56); - else - to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */ - break; - } - case DECIMAL_RESULT: - { - my_decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf); - if (maybe_null) - { - if (item->null_value) - { - memset(to, 0, sort_field->length+1); - to++; - break; - } - *to++=1; - } - my_decimal2binary(E_DEC_FATAL_ERROR, dec_val, to, - item->max_length - (item->decimals ? 1:0), - item->decimals); - break; - } - case REAL_RESULT: - { - double value= item->val_result(); - if (maybe_null) - { - if (item->null_value) - { - memset(to, 0, sort_field->length+1); - to++; - break; - } - *to++=1; - } - change_double_for_sort(value,(uchar*) to); - break; - } - case ROW_RESULT: - default: - // This case should never be choosen - DBUG_ASSERT(0); - break; - } + sort_field->item->make_sort_key(to, sort_field->item, sort_field, param); + if ((maybe_null= sort_field->item->maybe_null)) + to++; } if (sort_field->reverse) { /* Revers key */ @@ -1255,11 +1233,13 @@ static void register_used_fields(Sort_param *param) } -static bool save_index(Sort_param *param, uint count, Filesort_info *table_sort) +static bool save_index(Sort_param *param, uint count, + SORT_INFO *table_sort) { uint offset,res_length; uchar *to; DBUG_ENTER("save_index"); + DBUG_ASSERT(table_sort->record_pointers == 0); table_sort->sort_buffer(param, count); res_length= param->res_length; @@ -1308,7 +1288,7 @@ static bool save_index(Sort_param *param, uint count, Filesort_info *table_sort) */ bool check_if_pq_applicable(Sort_param *param, - Filesort_info *filesort_info, + SORT_INFO *filesort_info, TABLE *table, ha_rows num_rows, ulong memory_available) { @@ -1342,9 +1322,8 @@ bool check_if_pq_applicable(Sort_param *param, // The whole source set fits into memory. if (param->max_rows < num_rows/PQ_slowness ) { - filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, - param->rec_length); - DBUG_RETURN(filesort_info->get_sort_keys() != NULL); + DBUG_RETURN(filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, + param->rec_length) != NULL); } else { @@ -1356,9 +1335,8 @@ bool check_if_pq_applicable(Sort_param *param, // Do we have space for LIMIT rows in memory? if (param->max_keys_per_buffer < num_available_keys) { - filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, - param->rec_length); - DBUG_RETURN(filesort_info->get_sort_keys() != NULL); + DBUG_RETURN(filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, + param->rec_length) != NULL); } // Try to strip off addon fields. @@ -1394,17 +1372,14 @@ bool check_if_pq_applicable(Sort_param *param, if (sort_merge_cost < pq_cost) DBUG_RETURN(false); - filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, - param->sort_length + param->ref_length); - if (filesort_info->get_sort_keys()) + if (filesort_info->alloc_sort_buffer(param->max_keys_per_buffer, + param->sort_length + + param->ref_length)) { - // Make attached data to be references instead of fields. - my_free(filesort_info->addon_buf); + /* Make attached data to be references instead of fields. */ my_free(filesort_info->addon_field); - filesort_info->addon_buf= NULL; filesort_info->addon_field= NULL; param->addon_field= NULL; - param->addon_length= 0; param->res_length= param->ref_length; param->sort_length+= param->ref_length; @@ -1842,6 +1817,64 @@ static uint suffix_length(ulong string_length) } +void +Type_handler_string_result::sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *sortorder) const +{ + CHARSET_INFO *cs; + sortorder->length= item->max_length; + set_if_smaller(sortorder->length, thd->variables.max_sort_length); + if (use_strnxfrm((cs= item->collation.collation))) + { + sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length); + } + else if (cs == &my_charset_bin) + { + /* Store length last to be able to sort blob/varbinary */ + sortorder->suffix_length= suffix_length(sortorder->length); + sortorder->length+= sortorder->suffix_length; + } +} + + +void +Type_handler_temporal_result::sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *sortorder) const +{ + sortorder->length= 8; // Sizof intern longlong +} + + +void +Type_handler_int_result::sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *sortorder) const +{ + sortorder->length= 8; // Sizof intern longlong +} + + +void +Type_handler_real_result::sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *sortorder) const +{ + sortorder->length= sizeof(double); +} + + +void +Type_handler_decimal_result::sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *sortorder) const +{ + sortorder->length= + my_decimal_get_binary_size(item->max_length - (item->decimals ? 1 : 0), + item->decimals); +} + /** Calculate length of sort key. @@ -1854,8 +1887,6 @@ static uint suffix_length(ulong string_length) @note sortorder->length is updated for each sort item. - @n - sortorder->need_strxnfrm is set 1 if we have to use strxnfrm @return Total length of sort buffer in bytes @@ -1866,23 +1897,19 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset) { uint length; - CHARSET_INFO *cs; *multi_byte_charset= 0; length=0; for (; s_length-- ; sortorder++) { - sortorder->need_strxnfrm= 0; sortorder->suffix_length= 0; if (sortorder->field) { - cs= sortorder->field->sort_charset(); + CHARSET_INFO *cs= sortorder->field->sort_charset(); sortorder->length= sortorder->field->sort_length(); - if (use_strnxfrm((cs=sortorder->field->sort_charset()))) { - sortorder->need_strxnfrm= 1; - *multi_byte_charset= 1; + *multi_byte_charset= true; sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length); } if (sortorder->field->maybe_null()) @@ -1890,42 +1917,10 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, } else { - sortorder->result_type= sortorder->item->cmp_type(); - switch (sortorder->result_type) { - case STRING_RESULT: - sortorder->length=sortorder->item->max_length; - set_if_smaller(sortorder->length, thd->variables.max_sort_length); - if (use_strnxfrm((cs=sortorder->item->collation.collation))) - { - sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length); - sortorder->need_strxnfrm= 1; - *multi_byte_charset= 1; - } - else if (cs == &my_charset_bin) - { - /* Store length last to be able to sort blob/varbinary */ - sortorder->suffix_length= suffix_length(sortorder->length); - sortorder->length+= sortorder->suffix_length; - } - break; - case TIME_RESULT: - case INT_RESULT: - sortorder->length=8; // Size of intern longlong - break; - case DECIMAL_RESULT: - sortorder->length= - my_decimal_get_binary_size(sortorder->item->max_length - - (sortorder->item->decimals ? 1 : 0), - sortorder->item->decimals); - break; - case REAL_RESULT: - sortorder->length=sizeof(double); - break; - case ROW_RESULT: - default: - // This case should never be choosen - DBUG_ASSERT(0); - break; + sortorder->item->sortlength(thd, sortorder->item, sortorder); + if (use_strnxfrm(sortorder->item->collation.collation)) + { + *multi_byte_charset= true; } if (sortorder->item->maybe_null) length++; // Place for NULL marker @@ -1954,7 +1949,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, @param thd Current thread @param ptabfield Array of references to the table fields @param sortlength Total length of sorted fields - @param[out] plength Total length of appended fields + @param [out] addon_buf Buffer to us for appended fields @note The null bits for the appended values are supposed to be put together @@ -1968,7 +1963,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, static SORT_ADDON_FIELD * get_addon_fields(ulong max_length_for_sort_data, - Field **ptabfield, uint sortlength, uint *plength) + Field **ptabfield, uint sortlength, LEX_STRING *addon_buf) { Field **pfield; Field *field; @@ -1977,6 +1972,7 @@ get_addon_fields(ulong max_length_for_sort_data, uint fields= 0; uint null_fields= 0; MY_BITMAP *read_set= (*ptabfield)->table->read_set; + DBUG_ENTER("get_addon_fields"); /* If there is a reference to a field in the query add it @@ -1988,31 +1984,33 @@ get_addon_fields(ulong max_length_for_sort_data, the values directly from sorted fields. But beware the case when item->cmp_type() != item->result_type() */ - *plength= 0; + addon_buf->str= 0; + addon_buf->length= 0; for (pfield= ptabfield; (field= *pfield) ; pfield++) { if (!bitmap_is_set(read_set, field->field_index)) continue; if (field->flags & BLOB_FLAG) - return 0; + DBUG_RETURN(0); length+= field->max_packed_col_length(field->pack_length()); if (field->maybe_null()) null_fields++; fields++; } if (!fields) - return 0; + DBUG_RETURN(0); length+= (null_fields+7)/8; if (length+sortlength > max_length_for_sort_data || - !(addonf= (SORT_ADDON_FIELD *) my_malloc(sizeof(SORT_ADDON_FIELD)* - (fields+1), - MYF(MY_WME | - MY_THREAD_SPECIFIC)))) - return 0; + !my_multi_malloc(MYF(MY_WME | MY_THREAD_SPECIFIC), + &addonf, sizeof(SORT_ADDON_FIELD) * (fields+1), + &addon_buf->str, length, + NullS)) + + DBUG_RETURN(0); - *plength= length; + addon_buf->length= length; length= (null_fields+7)/8; null_fields= 0; for (pfield= ptabfield; (field= *pfield) ; pfield++) @@ -2039,7 +2037,7 @@ get_addon_fields(ulong max_length_for_sort_data, addonf->field= 0; // Put end marker DBUG_PRINT("info",("addon_length: %d",length)); - return (addonf-fields); + DBUG_RETURN(addonf-fields); } @@ -2125,3 +2123,13 @@ void change_double_for_sort(double nr,uchar *to) } } +/** + Free SORT_INFO +*/ + +SORT_INFO::~SORT_INFO() +{ + DBUG_ENTER("~SORT_INFO::SORT_INFO()"); + free_data(); + DBUG_VOID_RETURN; +} diff --git a/sql/filesort.h b/sql/filesort.h index 4c95f1202b2..454c745b5c0 100644 --- a/sql/filesort.h +++ b/sql/filesort.h @@ -16,23 +16,101 @@ #ifndef FILESORT_INCLUDED #define FILESORT_INCLUDED -class SQL_SELECT; - -#include "my_global.h" /* uint, uchar */ #include "my_base.h" /* ha_rows */ +#include "filesort_utils.h" class SQL_SELECT; class THD; struct TABLE; -typedef struct st_sort_field SORT_FIELD; +struct SORT_FIELD; class Filesort_tracker; -ha_rows filesort(THD *thd, TABLE *table, st_sort_field *sortorder, - uint s_length, SQL_SELECT *select, - ha_rows max_rows, bool sort_positions, - ha_rows *examined_rows, ha_rows *found_rows, - Filesort_tracker* tracker); -void filesort_free_buffers(TABLE *table, bool full); +class SORT_INFO +{ + /// Buffer for sorting keys. + Filesort_buffer filesort_buffer; + +public: + SORT_INFO() + :addon_field(0), record_pointers(0) + { + buffpek.str= 0; + my_b_clear(&io_cache); + } + + ~SORT_INFO(); + + void free_data() + { + close_cached_file(&io_cache); + my_free(record_pointers); + my_free(buffpek.str); + my_free(addon_field); + } + + void reset() + { + free_data(); + record_pointers= 0; + buffpek.str= 0; + addon_field= 0; + } + + + IO_CACHE io_cache; /* If sorted through filesort */ + LEX_STRING buffpek; /* Buffer for buffpek structures */ + LEX_STRING addon_buf; /* Pointer to a buffer if sorted with fields */ + struct st_sort_addon_field *addon_field; /* Pointer to the fields info */ + /* To unpack back */ + void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *); + uchar *record_pointers; /* If sorted in memory */ + /* + How many rows in final result. + Also how many rows in record_pointers, if used + */ + ha_rows return_rows; + ha_rows examined_rows; /* How many rows read */ + ha_rows found_rows; /* How many rows was accepted */ + + /** Sort filesort_buffer */ + void sort_buffer(Sort_param *param, uint count) + { filesort_buffer.sort_buffer(param, count); } + + /** + Accessors for Filesort_buffer (which @c). + */ + uchar *get_record_buffer(uint idx) + { return filesort_buffer.get_record_buffer(idx); } + + uchar **get_sort_keys() + { return filesort_buffer.get_sort_keys(); } + + uchar **alloc_sort_buffer(uint num_records, uint record_length) + { return filesort_buffer.alloc_sort_buffer(num_records, record_length); } + + void free_sort_buffer() + { filesort_buffer.free_sort_buffer(); } + + void init_record_pointers() + { filesort_buffer.init_record_pointers(); } + + size_t sort_buffer_size() const + { return filesort_buffer.sort_buffer_size(); } + + friend SORT_INFO *filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, + uint s_length, + SQL_SELECT *select, ha_rows max_rows, + bool sort_positions, + Filesort_tracker* tracker); +}; + + +SORT_INFO *filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, + uint s_length, + SQL_SELECT *select, ha_rows max_rows, + bool sort_positions, + Filesort_tracker* tracker); + void change_double_for_sort(double nr,uchar *to); #endif /* FILESORT_INCLUDED */ diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc index 1cef30b6a56..34110dcfc1f 100644 --- a/sql/filesort_utils.cc +++ b/sql/filesort_utils.cc @@ -85,31 +85,66 @@ double get_merge_many_buffs_cost_fast(ha_rows num_rows, return total_cost; } -uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length) -{ - ulong sort_buff_sz; +/* + alloc_sort_buffer() - DBUG_ENTER("alloc_sort_buffer"); + Allocate buffer for sorting keys. + Try to reuse old buffer if possible. + @return + 0 Error + # Pointer to allocated buffer +*/ + +uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, + uint record_length) +{ + size_t buff_size; + uchar **sort_keys, **start_of_data; + DBUG_ENTER("alloc_sort_buffer"); DBUG_EXECUTE_IF("alloc_sort_buffer_fail", DBUG_SET("+d,simulate_out_of_memory");); - if (m_idx_array.is_null()) + buff_size= num_records * (record_length + sizeof(uchar*)); + set_if_bigger(buff_size, record_length * MERGEBUFF2); + + if (!m_idx_array.is_null()) { - sort_buff_sz= num_records * (record_length + sizeof(uchar*)); - set_if_bigger(sort_buff_sz, record_length * MERGEBUFF2); - uchar **sort_keys= - (uchar**) my_malloc(sort_buff_sz, MYF(MY_THREAD_SPECIFIC)); - m_idx_array= Idx_array(sort_keys, num_records); - m_record_length= record_length; - uchar **start_of_data= m_idx_array.array() + m_idx_array.size(); - m_start_of_data= reinterpret_cast<uchar*>(start_of_data); + /* + Reuse old buffer if exists and is large enough + Note that we don't make the buffer smaller, as we want to be + prepared for next subquery iteration. + */ + + sort_keys= m_idx_array.array(); + if (buff_size > allocated_size) + { + /* + Better to free and alloc than realloc as we don't have to remember + the old values + */ + my_free(sort_keys); + if (!(sort_keys= (uchar**) my_malloc(buff_size, + MYF(MY_THREAD_SPECIFIC)))) + { + reset(); + DBUG_RETURN(0); + } + allocated_size= buff_size; + } } else { - DBUG_ASSERT(num_records == m_idx_array.size()); - DBUG_ASSERT(record_length == m_record_length); + if (!(sort_keys= (uchar**) my_malloc(buff_size, MYF(MY_THREAD_SPECIFIC)))) + DBUG_RETURN(0); + allocated_size= buff_size; } + + m_idx_array= Idx_array(sort_keys, num_records); + m_record_length= record_length; + start_of_data= m_idx_array.array() + m_idx_array.size(); + m_start_of_data= reinterpret_cast<uchar*>(start_of_data); + DBUG_RETURN(m_idx_array.array()); } @@ -117,8 +152,7 @@ uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length) void Filesort_buffer::free_sort_buffer() { my_free(m_idx_array.array()); - m_idx_array= Idx_array(); - m_record_length= 0; + m_idx_array.reset(); m_start_of_data= NULL; } diff --git a/sql/filesort_utils.h b/sql/filesort_utils.h index 00fa6f2566b..d537b602edf 100644 --- a/sql/filesort_utils.h +++ b/sql/filesort_utils.h @@ -60,9 +60,23 @@ double get_merge_many_buffs_cost_fast(ha_rows num_rows, class Filesort_buffer { public: - Filesort_buffer() : - m_idx_array(), m_record_length(0), m_start_of_data(NULL) + Filesort_buffer() + : m_idx_array(), m_start_of_data(NULL), allocated_size(0) {} + + ~Filesort_buffer() + { + my_free(m_idx_array.array()); + } + + bool is_allocated() + { + return m_idx_array.array() != 0; + } + void reset() + { + m_idx_array.reset(); + } /** Sort me... */ void sort_buffer(const Sort_param *param, uint count); @@ -84,20 +98,12 @@ public: /// Returns total size: pointer array + record buffers. size_t sort_buffer_size() const { - return m_idx_array.size() * (m_record_length + sizeof(uchar*)); + return allocated_size; } /// Allocates the buffer, but does *not* initialize pointers. uchar **alloc_sort_buffer(uint num_records, uint record_length); - - /// Check <num_records, record_length> for the buffer - bool check_sort_buffer_properties(uint num_records, uint record_length) - { - return (static_cast<uint>(m_idx_array.size()) == num_records && - m_record_length == record_length); - } - /// Frees the buffer. void free_sort_buffer(); @@ -115,15 +121,17 @@ public: m_idx_array= rhs.m_idx_array; m_record_length= rhs.m_record_length; m_start_of_data= rhs.m_start_of_data; + allocated_size= rhs.allocated_size; return *this; } private: typedef Bounds_checked_array<uchar*> Idx_array; - Idx_array m_idx_array; + Idx_array m_idx_array; /* Pointers to key data */ uint m_record_length; - uchar *m_start_of_data; + uchar *m_start_of_data; /* Start of key data */ + size_t allocated_size; }; #endif // FILESORT_UTILS_INCLUDED diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 90efd730875..173a5f709c1 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1281,8 +1281,8 @@ static bool print_admin_msg(THD* thd, uint len, length=(uint) (strxmov(name, db_name, ".", table_name.c_ptr_safe(), NullS) - name); /* TODO: switch from protocol to push_warning here. The main reason we didn't - it yet is parallel repair. Due to following trace: - mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr. + it yet is parallel repair, which threads have no THD object accessible via + current_thd. Also we likely need to lock mutex here (in both cases with protocol and push_warning). @@ -9058,7 +9058,7 @@ int ha_partition::check_for_upgrade(HA_CHECK_OPT *check_opt) } m_part_info->key_algorithm= partition_info::KEY_ALGORITHM_51; if (skip_generation || - !(part_buf= generate_partition_syntax(m_part_info, + !(part_buf= generate_partition_syntax(thd, m_part_info, &part_buf_len, true, true, diff --git a/sql/handler.cc b/sql/handler.cc index fb2921f9ba3..748a51f5c59 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -30,11 +30,10 @@ #include "sql_table.h" // build_table_filename #include "sql_parse.h" // check_stack_overrun #include "sql_acl.h" // SUPER_ACL -#include "sql_base.h" // free_io_cache +#include "sql_base.h" // TDC_element #include "discover.h" // extension_based_table_discovery, etc #include "log_event.h" // *_rows_log_event #include "create_options.h" -#include "rpl_filter.h" #include <myisampack.h> #include "transaction.h" #include "myisam.h" @@ -3931,9 +3930,7 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) if it is started. */ -inline -void -handler::mark_trx_read_write() +void handler::mark_trx_read_write_internal() { Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0]; /* @@ -5050,7 +5047,9 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name, Table_exists_error_handler no_such_table_handler; thd->push_internal_handler(&no_such_table_handler); - TABLE_SHARE *share= tdc_acquire_share(thd, db, table_name, flags); + table.init_one_table(db, strlen(db), table_name, strlen(table_name), + table_name, TL_READ); + TABLE_SHARE *share= tdc_acquire_share(thd, &table, flags); thd->pop_internal_handler(); if (hton && share) @@ -5579,30 +5578,47 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) correct for the table. A row in the given table should be replicated if: + - It's not called by partition engine - Row-based replication is enabled in the current thread - The binlog is enabled - It is not a temporary table - The binary log is open - The database the table resides in shall be binlogged (binlog_*_db rules) - table is not mysql.event + + RETURN VALUE + 0 No binary logging in row format + 1 Row needs to be logged */ -static bool check_table_binlog_row_based(THD *thd, TABLE *table) +inline bool handler::check_table_binlog_row_based(bool binlog_row) { - if (table->s->cached_row_logging_check == -1) + if (unlikely((table->in_use->variables.sql_log_bin_off))) + return 0; /* Called by partitioning engine */ + if (unlikely((!check_table_binlog_row_based_done))) { - int const check(table->s->tmp_table == NO_TMP_TABLE && - ! table->no_replicate && - binlog_filter->db_ok(table->s->db.str)); - table->s->cached_row_logging_check= check; + check_table_binlog_row_based_done= 1; + check_table_binlog_row_based_result= + check_table_binlog_row_based_internal(binlog_row); } + return check_table_binlog_row_based_result; +} - DBUG_ASSERT(table->s->cached_row_logging_check == 0 || - table->s->cached_row_logging_check == 1); +bool handler::check_table_binlog_row_based_internal(bool binlog_row) +{ + THD *thd= table->in_use; - return (thd->is_current_stmt_binlog_format_row() && - table->s->cached_row_logging_check && #ifdef WITH_WSREP + /* only InnoDB tables will be replicated through binlog emulation */ + if (binlog_row && + ((WSREP_EMULATE_BINLOG(thd) && + table->file->partition_ht()->db_type != DB_TYPE_INNODB) || + (thd->wsrep_ignore_table == true))) + return 0; +#endif + + return (table->s->cached_row_logging_check && + thd->is_current_stmt_binlog_format_row() && /* Wsrep partially enables binary logging if it have not been explicitly turned on. As a result we return 'true' if we are in @@ -5617,14 +5633,13 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table) Otherwise, return 'true' if binary logging is on. */ - (thd->variables.sql_log_bin_off != 1) && - ((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)) || - ((WSREP(thd) || (thd->variables.option_bits & OPTION_BIN_LOG)) && - mysql_bin_log.is_open()))); -#else - (thd->variables.option_bits & OPTION_BIN_LOG) && - mysql_bin_log.is_open()); -#endif + IF_WSREP(((WSREP_EMULATE_BINLOG(thd) && + (thd->wsrep_exec_mode != REPL_RECV)) || + ((WSREP(thd) || + (thd->variables.option_bits & OPTION_BIN_LOG)) && + mysql_bin_log.is_open())), + (thd->variables.option_bits & OPTION_BIN_LOG) && + mysql_bin_log.is_open())); } @@ -5658,54 +5673,51 @@ static int write_locked_table_maps(THD *thd) DBUG_PRINT("debug", ("get_binlog_table_maps(): %d", thd->get_binlog_table_maps())); - if (thd->get_binlog_table_maps() == 0) + MYSQL_LOCK *locks[2]; + locks[0]= thd->extra_lock; + locks[1]= thd->lock; + my_bool with_annotate= thd->variables.binlog_annotate_row_events && + thd->query() && thd->query_length(); + + for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i ) { - MYSQL_LOCK *locks[2]; - locks[0]= thd->extra_lock; - locks[1]= thd->lock; - my_bool with_annotate= thd->variables.binlog_annotate_row_events && - thd->query() && thd->query_length(); + MYSQL_LOCK const *const lock= locks[i]; + if (lock == NULL) + continue; - for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i ) + TABLE **const end_ptr= lock->table + lock->table_count; + for (TABLE **table_ptr= lock->table ; + table_ptr != end_ptr ; + ++table_ptr) { - MYSQL_LOCK const *const lock= locks[i]; - if (lock == NULL) - continue; - - TABLE **const end_ptr= lock->table + lock->table_count; - for (TABLE **table_ptr= lock->table ; - table_ptr != end_ptr ; - ++table_ptr) + TABLE *const table= *table_ptr; + DBUG_PRINT("info", ("Checking table %s", table->s->table_name.str)); + if (table->current_lock == F_WRLCK && + table->file->check_table_binlog_row_based(0)) { - TABLE *const table= *table_ptr; - DBUG_PRINT("info", ("Checking table %s", table->s->table_name.str)); - if (table->current_lock == F_WRLCK && - check_table_binlog_row_based(thd, table)) - { - /* - We need to have a transactional behavior for SQLCOM_CREATE_TABLE - (e.g. CREATE TABLE... SELECT * FROM TABLE) in order to keep a - compatible behavior with the STMT based replication even when - the table is not transactional. In other words, if the operation - fails while executing the insert phase nothing is written to the - binlog. - - Note that at this point, we check the type of a set of tables to - create the table map events. In the function binlog_log_row(), - which calls the current function, we check the type of the table - of the current row. - */ - bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE || - table->file->has_transactions(); - int const error= thd->binlog_write_table_map(table, has_trans, - &with_annotate); - /* - If an error occurs, it is the responsibility of the caller to - roll back the transaction. - */ - if (unlikely(error)) - DBUG_RETURN(1); - } + /* + We need to have a transactional behavior for SQLCOM_CREATE_TABLE + (e.g. CREATE TABLE... SELECT * FROM TABLE) in order to keep a + compatible behavior with the STMT based replication even when + the table is not transactional. In other words, if the operation + fails while executing the insert phase nothing is written to the + binlog. + + Note that at this point, we check the type of a set of tables to + create the table map events. In the function binlog_log_row(), + which calls the current function, we check the type of the table + of the current row. + */ + bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE || + table->file->has_transactions(); + int const error= thd->binlog_write_table_map(table, has_trans, + &with_annotate); + /* + If an error occurs, it is the responsibility of the caller to + roll back the transaction. + */ + if (unlikely(error)) + DBUG_RETURN(1); } } } @@ -5715,50 +5727,50 @@ static int write_locked_table_maps(THD *thd) typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*); -static int binlog_log_row(TABLE* table, - const uchar *before_record, - const uchar *after_record, - Log_func *log_func) + + +static int binlog_log_row_internal(TABLE* table, + const uchar *before_record, + const uchar *after_record, + Log_func *log_func) { bool error= 0; THD *const thd= table->in_use; -#ifdef WITH_WSREP /* - Only InnoDB tables will be replicated through binlog emulation. Also - updates in mysql.gtid_slave_state table should not be binlogged. + If there are no table maps written to the binary log, this is + the first row handled in this statement. In that case, we need + to write table maps for all locked tables to the binary log. */ - if ((WSREP_EMULATE_BINLOG(thd) && - table->file->partition_ht()->db_type != DB_TYPE_INNODB) || - (thd->wsrep_ignore_table == true)) - return 0; -#endif /* WITH_WSREP */ - - if (check_table_binlog_row_based(thd, table)) + if (likely(!(error= ((thd->get_binlog_table_maps() == 0 && + write_locked_table_maps(thd)))))) { /* - If there are no table maps written to the binary log, this is - the first row handled in this statement. In that case, we need - to write table maps for all locked tables to the binary log. + We need to have a transactional behavior for SQLCOM_CREATE_TABLE + (i.e. CREATE TABLE... SELECT * FROM TABLE) in order to keep a + compatible behavior with the STMT based replication even when + the table is not transactional. In other words, if the operation + fails while executing the insert phase nothing is written to the + binlog. */ - if (likely(!(error= write_locked_table_maps(thd)))) - { - /* - We need to have a transactional behavior for SQLCOM_CREATE_TABLE - (i.e. CREATE TABLE... SELECT * FROM TABLE) in order to keep a - compatible behavior with the STMT based replication even when - the table is not transactional. In other words, if the operation - fails while executing the insert phase nothing is written to the - binlog. - */ - bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE || - table->file->has_transactions(); - error= (*log_func)(thd, table, has_trans, before_record, after_record); - } + bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE || + table->file->has_transactions(); + error= (*log_func)(thd, table, has_trans, before_record, after_record); } return error ? HA_ERR_RBR_LOGGING_FAILED : 0; } +static inline int binlog_log_row(TABLE* table, + const uchar *before_record, + const uchar *after_record, + Log_func *log_func) +{ + if (!table->file->check_table_binlog_row_based(1)) + return 0; + return binlog_log_row_internal(table, before_record, after_record, log_func); +} + + int handler::ha_external_lock(THD *thd, int lock_type) { int error; @@ -5851,12 +5863,12 @@ int handler::ha_reset() DBUG_ASSERT(table->key_read == 0); /* ensure that ha_index_end / ha_rnd_end has been called */ DBUG_ASSERT(inited == NONE); - /* Free cache used by filesort */ - free_io_cache(table); /* reset the bitmaps to point to defaults */ table->default_column_bitmaps(); pushed_cond= NULL; tracker= NULL; + mark_trx_read_write_done= check_table_binlog_row_based_done= + check_table_binlog_row_based_result= 0; /* Reset information about pushed engine conditions */ cancel_pushed_idx_cond(); /* Reset information about pushed index conditions */ @@ -5881,14 +5893,13 @@ int handler::ha_write_row(uchar *buf) { error= write_row(buf); }) MYSQL_INSERT_ROW_DONE(error); - if (unlikely(error)) - DBUG_RETURN(error); - rows_changed++; - if (unlikely(error= binlog_log_row(table, 0, buf, log_func))) - DBUG_RETURN(error); /* purecov: inspected */ - + if (likely(!error)) + { + rows_changed++; + error= binlog_log_row(table, 0, buf, log_func); + } DEBUG_SYNC_C("ha_write_row_end"); - DBUG_RETURN(0); + DBUG_RETURN(error); } @@ -5914,12 +5925,12 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data) { error= update_row(old_data, new_data);}) MYSQL_UPDATE_ROW_DONE(error); - if (unlikely(error)) - return error; - rows_changed++; - if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func))) - return error; - return 0; + if (likely(!error)) + { + rows_changed++; + error= binlog_log_row(table, old_data, new_data, log_func); + } + return error; } int handler::ha_delete_row(const uchar *buf) @@ -5941,12 +5952,12 @@ int handler::ha_delete_row(const uchar *buf) TABLE_IO_WAIT(tracker, m_psi, PSI_TABLE_DELETE_ROW, active_index, 0, { error= delete_row(buf);}) MYSQL_DELETE_ROW_DONE(error); - if (unlikely(error)) - return error; - rows_changed++; - if (unlikely(error= binlog_log_row(table, buf, 0, log_func))) - return error; - return 0; + if (likely(!error)) + { + rows_changed++; + error= binlog_log_row(table, buf, 0, log_func); + } + return error; } diff --git a/sql/handler.h b/sql/handler.h index 34b7b147d58..6054ec2db35 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2581,11 +2581,6 @@ public: RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */ HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */ uint ranges_in_seq; /* Total number of ranges in the traversed sequence */ - /* TRUE <=> source MRR ranges and the output are ordered */ - bool mrr_is_output_sorted; - - /** TRUE <=> we're currently traversing a range in mrr_cur_range. */ - bool mrr_have_range; /** Current range (the one we're now returning rows from) */ KEY_MULTI_RANGE mrr_cur_range; @@ -2593,23 +2588,32 @@ public: key_range save_end_range, *end_range; KEY_PART_INFO *range_key_part; int key_compare_result_on_equal; - bool eq_range; - bool internal_tmp_table; /* If internal tmp table */ - uint errkey; /* Last dup key */ - uint key_used_on_scan; - uint active_index; + /* TRUE <=> source MRR ranges and the output are ordered */ + bool mrr_is_output_sorted; + /** TRUE <=> we're currently traversing a range in mrr_cur_range. */ + bool mrr_have_range; + bool eq_range; + bool internal_tmp_table; /* If internal tmp table */ + bool implicit_emptied; /* Can be !=0 only if HEAP */ + bool mark_trx_read_write_done; /* mark_trx_read_write was called */ + bool check_table_binlog_row_based_done; /* check_table_binlog.. was called */ + bool check_table_binlog_row_based_result; /* cached check_table_binlog... */ /* TRUE <=> the engine guarantees that returned records are within the range being scanned. */ bool in_range_check_pushed_down; + uint errkey; /* Last dup key */ + uint key_used_on_scan; + uint active_index; + /** Length of ref (1-8 or the clustered key length) */ uint ref_length; FT_INFO *ft_handler; enum {NONE=0, INDEX, RND} inited; - bool implicit_emptied; /* Can be !=0 only if HEAP */ + const COND *pushed_cond; /** next_insert_id is the next value which should be inserted into the @@ -2693,11 +2697,16 @@ public: handler(handlerton *ht_arg, TABLE_SHARE *share_arg) :table_share(share_arg), table(0), estimation_rows_to_insert(0), ht(ht_arg), - ref(0), end_range(NULL), key_used_on_scan(MAX_KEY), active_index(MAX_KEY), + ref(0), end_range(NULL), + implicit_emptied(0), + mark_trx_read_write_done(0), + check_table_binlog_row_based_done(0), + check_table_binlog_row_based_result(0), in_range_check_pushed_down(FALSE), + key_used_on_scan(MAX_KEY), + active_index(MAX_KEY), ref_length(sizeof(my_off_t)), ft_handler(0), inited(NONE), - implicit_emptied(0), pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0), tracker(NULL), pushed_idx_cond(NULL), @@ -3875,10 +3884,22 @@ protected: */ virtual int delete_table(const char *name); +public: + inline bool check_table_binlog_row_based(bool binlog_row); private: + /* Cache result to avoid extra calls */ + inline void mark_trx_read_write() + { + if (unlikely(!mark_trx_read_write_done)) + { + mark_trx_read_write_done= 1; + mark_trx_read_write_internal(); + } + } + void mark_trx_read_write_internal(); + bool check_table_binlog_row_based_internal(bool binlog_row); + /* Private helpers */ - inline void mark_trx_read_write(); -private: inline void increment_statistics(ulong SSV::*offset) const; inline void decrement_statistics(ulong SSV::*offset) const; diff --git a/sql/hostname.cc b/sql/hostname.cc index 6aef84f1b26..a84aebdf3c8 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -412,7 +412,7 @@ static inline bool is_hostname_valid(const char *hostname) int ip_to_hostname(struct sockaddr_storage *ip_storage, const char *ip_string, - char **hostname, + const char **hostname, uint *connect_errors) { const struct sockaddr *ip= (const sockaddr *) ip_storage; @@ -436,7 +436,7 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage, DBUG_PRINT("info", ("Loopback address detected.")); /* Do not count connect errors from localhost. */ - *hostname= (char *) my_localhost; + *hostname= my_localhost; DBUG_RETURN(0); } diff --git a/sql/hostname.h b/sql/hostname.h index 81a1d0de88d..d6137b7c260 100644 --- a/sql/hostname.h +++ b/sql/hostname.h @@ -168,7 +168,7 @@ extern ulong host_cache_size; #define RC_BLOCKED_HOST 1 int ip_to_hostname(struct sockaddr_storage *ip_storage, const char *ip_string, - char **hostname, uint *connect_errors); + const char **hostname, uint *connect_errors); void inc_host_errors(const char *ip_string, Host_errors *errors); void reset_host_connect_errors(const char *ip_string); diff --git a/sql/item.cc b/sql/item.cc index f1362e7e5da..7cdb2d2e7e4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -629,48 +629,6 @@ void Item::rename(char *new_name) name= new_name; } -Item_result Item::cmp_type() const -{ - switch (field_type()) { - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: - return DECIMAL_RESULT; - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_BIT: - return INT_RESULT; - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - return REAL_RESULT; - case MYSQL_TYPE_NULL: - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_GEOMETRY: - return STRING_RESULT; - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_TIMESTAMP2: - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_TIME2: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_DATETIME2: - case MYSQL_TYPE_NEWDATE: - return TIME_RESULT; - }; - DBUG_ASSERT(0); - return STRING_RESULT; -} /** Traverse item tree possibly transforming it (replacing items). @@ -969,7 +927,7 @@ bool Item::check_cols(uint c) } -void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) +void Item::set_name(THD *thd, const char *str, uint length, CHARSET_INFO *cs) { if (!length) { @@ -1000,7 +958,6 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) if (str != str_start && !is_autogenerated_name) { char buff[SAFE_NAME_LEN]; - THD *thd= current_thd; strmake(buff, str_start, MY_MIN(sizeof(buff)-1, length + (int) (str-str_start))); @@ -1018,28 +975,29 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) if (!my_charset_same(cs, system_charset_info)) { size_t res_length; - name= sql_strmake_with_convert(str, length, cs, + name= sql_strmake_with_convert(thd, str, length, cs, MAX_ALIAS_NAME, system_charset_info, &res_length); name_length= res_length; } else - name= sql_strmake(str, (name_length= MY_MIN(length,MAX_ALIAS_NAME))); + name= thd->strmake(str, (name_length= MY_MIN(length,MAX_ALIAS_NAME))); } -void Item::set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs) +void Item::set_name_no_truncate(THD *thd, const char *str, uint length, + CHARSET_INFO *cs) { if (!my_charset_same(cs, system_charset_info)) { size_t res_length; - name= sql_strmake_with_convert(str, length, cs, + name= sql_strmake_with_convert(thd, str, length, cs, UINT_MAX, system_charset_info, &res_length); name_length= res_length; } else - name= sql_strmake(str, (name_length= length)); + name= thd->strmake(str, (name_length= length)); } @@ -1048,7 +1006,7 @@ void Item::set_name_for_rollback(THD *thd, const char *str, uint length, { char *old_name, *new_name; old_name= name; - set_name(str, length, cs); + set_name(thd, str, length, cs); new_name= name; if (old_name != new_name) { @@ -1494,8 +1452,7 @@ Item_splocal::Item_splocal(THD *thd, const LEX_STRING &sp_var_name, sp_var_type= real_type_to_type(sp_var_type); m_type= sp_map_item_type(sp_var_type); - m_field_type= sp_var_type; - m_result_type= sp_map_result_type(sp_var_type); + set_handler_by_field_type(sp_var_type); } @@ -1718,7 +1675,8 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref) } if (is_autogenerated_name) { - set_name(item_name->ptr(), (uint) item_name->length(), system_charset_info); + set_name(thd, item_name->ptr(), (uint) item_name->length(), + system_charset_info); } collation.set(value_item->collation.collation, DERIVATION_IMPLICIT); max_length= value_item->max_length; @@ -2183,7 +2141,7 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll, } -void Item_ident_for_show::make_field(Send_field *tmp_field) +void Item_ident_for_show::make_field(THD *thd, Send_field *tmp_field) { tmp_field->table_name= tmp_field->org_table_name= table_name; tmp_field->db_name= db_name; @@ -3055,11 +3013,10 @@ default_set_param_func(Item_param *param, Item_param::Item_param(THD *thd, uint pos_in_query_arg): Item_basic_value(thd), Rewritable_query_parameter(pos_in_query_arg, 1), + Type_handler_hybrid_field_type(MYSQL_TYPE_VARCHAR), state(NO_VALUE), - item_result_type(STRING_RESULT), /* Don't pretend to be a literal unless value for this item is set. */ item_type(PARAM_ITEM), - param_type(MYSQL_TYPE_VARCHAR), set_param_func(default_set_param_func), m_out_param_info(NULL) { @@ -3259,25 +3216,25 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) DBUG_ENTER("Item_param::set_from_user_var"); if (entry && entry->value) { - item_result_type= entry->type; unsigned_flag= entry->unsigned_flag; if (limit_clause_param) { bool unused; set_int(entry->val_int(&unused), MY_INT64_NUM_DECIMAL_DIGITS); item_type= Item::INT_ITEM; + set_handler_by_result_type(entry->type); DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0); } - switch (item_result_type) { + switch (entry->type) { case REAL_RESULT: set_double(*(double*)entry->value); item_type= Item::REAL_ITEM; - param_type= MYSQL_TYPE_DOUBLE; + set_handler_by_field_type(MYSQL_TYPE_DOUBLE); break; case INT_RESULT: set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS); item_type= Item::INT_ITEM; - param_type= MYSQL_TYPE_LONGLONG; + set_handler_by_field_type(MYSQL_TYPE_LONGLONG); break; case STRING_RESULT: { @@ -3300,7 +3257,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) charset of connection, so we have to set it later. */ item_type= Item::STRING_ITEM; - param_type= MYSQL_TYPE_VARCHAR; + set_handler_by_field_type(MYSQL_TYPE_VARCHAR); if (set_str((const char *)entry->value, entry->length)) DBUG_RETURN(1); @@ -3316,7 +3273,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry) my_decimal_precision_to_length_no_truncation(ent_value->precision(), decimals, unsigned_flag); item_type= Item::DECIMAL_ITEM; - param_type= MYSQL_TYPE_NEWDECIMAL; + set_handler_by_field_type(MYSQL_TYPE_NEWDECIMAL); break; } case ROW_RESULT: @@ -3741,10 +3698,9 @@ void Item_param::set_param_type_and_swap_value(Item_param *src) { Type_std_attributes::set(src); - param_type= src->param_type; + set_handler(src->type_handler()); set_param_func= src->set_param_func; item_type= src->item_type; - item_result_type= src->item_result_type; maybe_null= src->maybe_null; null_value= src->null_value; @@ -3832,7 +3788,7 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) return FALSE; } - item_result_type= arg->result_type(); + set_handler_by_result_type(arg->result_type()); item_type= arg->type(); return FALSE; } @@ -3851,7 +3807,7 @@ void Item_param::set_out_param_info(Send_field *info) { m_out_param_info= info; - param_type= m_out_param_info->type; + set_handler_by_field_type(m_out_param_info->type); } @@ -3880,9 +3836,9 @@ Item_param::get_out_param_info() const @param field container for meta-data to be filled */ -void Item_param::make_field(Send_field *field) +void Item_param::make_field(THD *thd, Send_field *field) { - Item::make_field(field); + Item::make_field(thd, field); if (!m_out_param_info) return; @@ -5413,34 +5369,18 @@ void Item::init_make_field(Send_field *tmp_field, tmp_field->flags |= UNSIGNED_FLAG; } -void Item::make_field(Send_field *tmp_field) +void Item::make_field(THD *thd, Send_field *tmp_field) { init_make_field(tmp_field, field_type()); } -void Item_empty_string::make_field(Send_field *tmp_field) +void Item_empty_string::make_field(THD *thd, Send_field *tmp_field) { init_make_field(tmp_field, string_field_type()); } -enum_field_types Item::field_type() const -{ - switch (result_type()) { - case STRING_RESULT: return string_field_type(); - case INT_RESULT: return MYSQL_TYPE_LONGLONG; - case DECIMAL_RESULT: return MYSQL_TYPE_NEWDECIMAL; - case REAL_RESULT: return MYSQL_TYPE_DOUBLE; - case ROW_RESULT: - case TIME_RESULT: - DBUG_ASSERT(0); - return MYSQL_TYPE_VARCHAR; - } - return MYSQL_TYPE_VARCHAR; -} - - /** Verifies that the input string is well-formed according to its character set. @param send_error If true, call my_error if string is not well-formed. @@ -5513,8 +5453,7 @@ String_copier_for_item::copy_with_warn(CHARSET_INFO *dstcs, String *dst, if (const char *pos= cannot_convert_error_pos()) { char buf[16]; - int mblen= srccs->cset->charlen(srccs, (const uchar *) pos, - (const uchar *) src + src_length); + int mblen= my_charlen(srccs, pos, src + src_length); DBUG_ASSERT(mblen > 0 && mblen * 2 + 1 <= (int) sizeof(buf)); octet2hex(buf, pos, mblen); push_warning_printf(m_thd, Sql_condition::WARN_LEVEL_WARN, @@ -5739,7 +5678,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, /* ARGSUSED */ -void Item_field::make_field(Send_field *tmp_field) +void Item_field::make_field(THD *thd, Send_field *tmp_field) { field->make_field(tmp_field); DBUG_ASSERT(tmp_field->table_name != 0); @@ -5803,19 +5742,9 @@ static int save_field_in_field(Field *from, bool *null_value, } -static int memcpy_field_value(Field *to, Field *from) -{ - if (to->ptr != from->ptr) - memcpy(to->ptr,from->ptr, to->pack_length()); - return 0; -} - fast_field_copier Item_field::setup_fast_field_copier(Field *to) { - DBUG_ENTER("Item_field::setup_fast_field_copier"); - DBUG_RETURN(memcpy_field_possible(to, field) ? - &memcpy_field_value : - &field_conv_incompatible); + return to->get_fast_field_copier(field); } @@ -6173,50 +6102,6 @@ void Item_hex_constant::hex_string_init(THD *thd, const char *str, unsigned_flag= 1; } -longlong Item_hex_hybrid::val_int() -{ - // following assert is redundant, because fixed=1 assigned in constructor - DBUG_ASSERT(fixed == 1); - char *end=(char*) str_value.ptr()+str_value.length(), - *ptr=end-MY_MIN(str_value.length(),sizeof(longlong)); - - ulonglong value=0; - for (; ptr != end ; ptr++) - value=(value << 8)+ (ulonglong) (uchar) *ptr; - return (longlong) value; -} - - -int Item_hex_hybrid::save_in_field(Field *field, bool no_conversions) -{ - field->set_notnull(); - if (field->result_type() == STRING_RESULT) - return field->store(str_value.ptr(), str_value.length(), - collation.collation); - - ulonglong nr; - uint32 length= str_value.length(); - - if (length > 8) - { - nr= field->flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX; - goto warn; - } - nr= (ulonglong) val_int(); - if ((length == 8) && !(field->flags & UNSIGNED_FLAG) && (nr > LONGLONG_MAX)) - { - nr= LONGLONG_MAX; - goto warn; - } - return field->store((longlong) nr, TRUE); // Assume hex numbers are unsigned - -warn: - if (!field->store((longlong) nr, TRUE)) - field->set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - 1); - return 1; -} - void Item_hex_hybrid::print(String *str, enum_query_type query_type) { @@ -7354,9 +7239,9 @@ void Item_ref::save_org_in_field(Field *field, fast_field_copier optimizer_data) } -void Item_ref::make_field(Send_field *field) +void Item_ref::make_field(THD *thd, Send_field *field) { - (*ref)->make_field(field); + (*ref)->make_field(thd, field); /* Non-zero in case of a view */ if (name) field->col_name= name; @@ -8516,7 +8401,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) Item *new_item= NULL; Item_result res_type= item_cmp_type(comp_item, item); - char *name=item->name; // Alloced by sql_alloc + char *name= item->name; // Alloced on THD::mem_root MEM_ROOT *mem_root= thd->mem_root; switch (res_type) { @@ -8541,7 +8426,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) else { uint length= result->length(); - char *tmp_str= sql_strmake(result->ptr(), length); + char *tmp_str= thd->strmake(result->ptr(), length); new_item= new (mem_root) Item_string(thd, name, tmp_str, length, result->charset()); } break; @@ -8841,8 +8726,9 @@ Item_cache_temporal::Item_cache_temporal(THD *thd, enum_field_types field_type_arg): Item_cache_int(thd, field_type_arg) { - if (mysql_type_to_time_type(cached_field_type) == MYSQL_TIMESTAMP_ERROR) - cached_field_type= MYSQL_TYPE_DATETIME; + if (mysql_type_to_time_type(Item_cache_temporal::field_type()) == + MYSQL_TIMESTAMP_ERROR) + set_handler_by_field_type(MYSQL_TYPE_DATETIME); } @@ -8985,7 +8871,7 @@ void Item_cache_temporal::store_packed(longlong val_arg, Item *example_arg) Item *Item_cache_temporal::clone_item(THD *thd) { Item_cache_temporal *item= new (thd->mem_root) - Item_cache_temporal(thd, cached_field_type); + Item_cache_temporal(thd, Item_cache_temporal::field_type()); item->store_packed(value, example); return item; } @@ -9282,14 +9168,28 @@ void Item_cache_row::set_null() Item_type_holder::Item_type_holder(THD *thd, Item *item) - :Item(thd, item), enum_set_typelib(0), fld_type(get_real_type(item)) + :Item(thd, item), + Type_handler_hybrid_real_field_type(get_real_type(item)), + enum_set_typelib(0) { DBUG_ASSERT(item->fixed); maybe_null= item->maybe_null; collation.set(item->collation); get_full_info(item); + /** + Field::result_merge_type(real_field_type()) should be equal to + result_type(), with one exception when "this" is a Item_field for + a BIT field: + - Field_bit::result_type() returns INT_RESULT, so does its Item_field. + - Field::result_merge_type(MYSQL_TYPE_BIT) returns STRING_RESULT. + Perhaps we need a new method in Type_handler to cover these type + merging rules for UNION. + */ + DBUG_ASSERT(real_field_type() == MYSQL_TYPE_BIT || + Item_type_holder::result_type() == + Field::result_merge_type(Item_type_holder::real_field_type())); /* fix variable decimals which always is NOT_FIXED_DEC */ - if (Field::result_merge_type(fld_type) == INT_RESULT) + if (Field::result_merge_type(real_field_type()) == INT_RESULT) decimals= 0; prev_decimal_int_part= item->decimal_int_part(); #ifdef HAVE_SPATIAL @@ -9300,19 +9200,6 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item) /** - Return expression type of Item_type_holder. - - @return - Item_result (type of internal MySQL expression result) -*/ - -Item_result Item_type_holder::result_type() const -{ - return Field::result_merge_type(fld_type); -} - - -/** Find real field type of item. @return @@ -9362,7 +9249,7 @@ enum_field_types Item_type_holder::get_real_type(Item *item) */ switch (item->result_type()) { case STRING_RESULT: - return MYSQL_TYPE_VAR_STRING; + return MYSQL_TYPE_VARCHAR; case INT_RESULT: return MYSQL_TYPE_LONGLONG; case REAL_RESULT: @@ -9372,10 +9259,21 @@ enum_field_types Item_type_holder::get_real_type(Item *item) case ROW_RESULT: case TIME_RESULT: DBUG_ASSERT(0); - return MYSQL_TYPE_VAR_STRING; + return MYSQL_TYPE_VARCHAR; } } break; + case TYPE_HOLDER: + /* + Item_type_holder and Item_blob should not appear in this context. + In case they for some reasons do, returning field_type() is wrong anyway. + They must return Item_type_holder::real_field_type() instead, to make + the code in sql_type.cc and sql_type.h happy, as it expectes + Field::real_type()-compatible rather than Field::field_type()-compatible + valies in some places, and may in the future add some asserts preventing + use of field_type() instead of real_type() and the other way around. + */ + DBUG_ASSERT(0); default: break; } @@ -9401,25 +9299,26 @@ bool Item_type_holder::join_types(THD *thd, Item *item) uint decimals_orig= decimals; DBUG_ENTER("Item_type_holder::join_types"); DBUG_PRINT("info:", ("was type %d len %d, dec %d name %s", - fld_type, max_length, decimals, + real_field_type(), max_length, decimals, (name ? name : "<NULL>"))); DBUG_PRINT("info:", ("in type %d len %d, dec %d", get_real_type(item), item->max_length, item->decimals)); - fld_type= Field::field_type_merge(fld_type, get_real_type(item)); + set_handler_by_real_type(Field::field_type_merge(real_field_type(), + get_real_type(item))); { uint item_decimals= item->decimals; /* fix variable decimals which always is NOT_FIXED_DEC */ - if (Field::result_merge_type(fld_type) == INT_RESULT) + if (Field::result_merge_type(real_field_type()) == INT_RESULT) item_decimals= 0; decimals= MY_MAX(decimals, item_decimals); } - if (fld_type == FIELD_TYPE_GEOMETRY) + if (Item_type_holder::field_type() == FIELD_TYPE_GEOMETRY) geometry_type= Field_geom::geometry_type_merge(geometry_type, item->get_geometry_type()); - if (Field::result_merge_type(fld_type) == DECIMAL_RESULT) + if (Field::result_merge_type(real_field_type()) == DECIMAL_RESULT) { decimals= MY_MIN(MY_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE); int item_int_part= item->decimal_int_part(); @@ -9431,7 +9330,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item) unsigned_flag); } - switch (Field::result_merge_type(fld_type)) + switch (Field::result_merge_type(real_field_type())) { case STRING_RESULT: { @@ -9478,12 +9377,14 @@ bool Item_type_holder::join_types(THD *thd, Item *item) int delta1= max_length_orig - decimals_orig; int delta2= item->max_length - item->decimals; max_length= MY_MAX(delta1, delta2) + decimals; - if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2) + if (Item_type_holder::real_field_type() == MYSQL_TYPE_FLOAT && + max_length > FLT_DIG + 2) { max_length= MAX_FLOAT_STR_LENGTH; decimals= NOT_FIXED_DEC; } - else if (fld_type == MYSQL_TYPE_DOUBLE && max_length > DBL_DIG + 2) + else if (Item_type_holder::real_field_type() == MYSQL_TYPE_DOUBLE && + max_length > DBL_DIG + 2) { max_length= MAX_DOUBLE_STR_LENGTH; decimals= NOT_FIXED_DEC; @@ -9491,7 +9392,8 @@ bool Item_type_holder::join_types(THD *thd, Item *item) } } else - max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7; + max_length= (Item_type_holder::field_type() == MYSQL_TYPE_FLOAT) ? + FLT_DIG+6 : DBL_DIG+7; break; } default: @@ -9503,7 +9405,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item) /* Remember decimal integer part to be used in DECIMAL_RESULT handleng */ prev_decimal_int_part= decimal_int_part(); DBUG_PRINT("info", ("become type: %d len: %u dec: %u", - (int) fld_type, max_length, (uint) decimals)); + (int) real_field_type(), max_length, (uint) decimals)); DBUG_RETURN(FALSE); } @@ -9584,7 +9486,7 @@ Field *Item_type_holder::make_field_by_type(TABLE *table) uchar *null_ptr= maybe_null ? (uchar*) "" : 0; Field *field; - switch (fld_type) { + switch (Item_type_holder::real_field_type()) { case MYSQL_TYPE_ENUM: DBUG_ASSERT(enum_set_typelib); field= new Field_enum((uchar *) 0, max_length, null_ptr, 0, @@ -9620,8 +9522,8 @@ Field *Item_type_holder::make_field_by_type(TABLE *table) */ void Item_type_holder::get_full_info(Item *item) { - if (fld_type == MYSQL_TYPE_ENUM || - fld_type == MYSQL_TYPE_SET) + if (Item_type_holder::real_field_type() == MYSQL_TYPE_ENUM || + Item_type_holder::real_field_type() == MYSQL_TYPE_SET) { if (item->type() == Item::SUM_FUNC_ITEM && (((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC || diff --git a/sql/item.h b/sql/item.h index 6e0a4aa82ce..d67a29dee5a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -25,7 +25,6 @@ #include "sql_priv.h" /* STRING_BUFFER_USUAL_SIZE */ #include "unireg.h" #include "sql_const.h" /* RAND_TABLE_BIT, MAX_FIELD_NAME */ -#include "thr_malloc.h" /* sql_calloc */ #include "field.h" /* Derivation */ #include "sql_type.h" @@ -657,6 +656,12 @@ protected: SEL_TREE *get_mm_tree_for_const(RANGE_OPT_PARAM *param); + virtual Field *make_string_field(TABLE *table); + Field *tmp_table_field_from_field_type(TABLE *table, + bool fixed_length, + bool set_blob_packlength); + Field *create_tmp_field(bool group, TABLE *table, uint convert_int_length); + public: /* Cache val_str() into the own buffer, e.g. to evaluate constant @@ -697,7 +702,7 @@ public: bool with_subselect; /* If this item is a subselect or some of its arguments is or contains a subselect */ - // alloc & destruct is done as start of select using sql_alloc + // alloc & destruct is done as start of select on THD::mem_root Item(THD *thd); /* Constructor used by Item_field, Item_ref & aggregate (sum) functions. @@ -714,15 +719,15 @@ public: name=0; #endif } /*lint -e1509 */ - void set_name(const char *str, uint length, CHARSET_INFO *cs); - void set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs); + void set_name(THD *thd, const char *str, uint length, CHARSET_INFO *cs); + void set_name_no_truncate(THD *thd, const char *str, uint length, + CHARSET_INFO *cs); void set_name_for_rollback(THD *thd, const char *str, uint length, CHARSET_INFO *cs); void rename(char *new_name); void init_make_field(Send_field *tmp_field,enum enum_field_types type); virtual void cleanup(); - virtual void make_field(Send_field *field); - virtual Field *make_string_field(TABLE *table); + virtual void make_field(THD *thd, Send_field *field); virtual bool fix_fields(THD *, Item **); /* Fix after some tables has been pulled out. Basically re-calculate all @@ -755,16 +760,41 @@ public: { return save_in_field(field, 1); } virtual bool send(Protocol *protocol, String *str); virtual bool eq(const Item *, bool binary_cmp) const; + const Type_handler *type_handler() const + { + return get_handler_by_field_type(field_type()); + } + Field *make_num_distinct_aggregator_field(MEM_ROOT *mem_root, + const Item *item) const + { + return type_handler()->make_num_distinct_aggregator_field(mem_root, this); + } + Field *make_conversion_table_field(TABLE *table, + uint metadata, const Field *target) const + { + DBUG_ASSERT(0); // Should not be called in Item context + return NULL; + } /* result_type() of an item specifies how the value should be returned */ - Item_result result_type() const { return REAL_RESULT; } + Item_result result_type() const { return type_handler()->result_type(); } /* ... while cmp_type() specifies how it should be compared */ - Item_result cmp_type() const; + Item_result cmp_type() const { return type_handler()->cmp_type(); } + void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const + { + type_handler()->make_sort_key(to, item, sort_field, param); + } + void sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const + { + type_handler()->sortlength(thd, item, attr); + } virtual Item_result cast_to_int_type() const { return cmp_type(); } enum_field_types string_field_type() const { return Type_handler::string_type_handler(max_length)->field_type(); } - enum_field_types field_type() const; virtual enum Type type() const =0; /* real_type() is the type of base item. This is same as type() for @@ -1021,8 +1051,6 @@ public: int save_str_value_in_field(Field *field, String *result); virtual Field *get_tmp_table_field() { return 0; } - /* This is also used to create fields in CREATE ... SELECT: */ - virtual Field *tmp_table_field(TABLE *t_arg) { return 0; } virtual Field *create_field_for_create_select(THD *thd, TABLE *table); virtual Field *create_field_for_schema(THD *thd, TABLE *table); virtual const char *full_name() const { return name ? name : "???"; } @@ -1630,9 +1658,15 @@ public: // used in row subselects to get value of elements virtual void bring_value() {} - Field *tmp_table_field_from_field_type(TABLE *table, - bool fixed_length, - bool set_blob_packlength); + virtual Field *create_tmp_field(bool group, TABLE *table) + { + /* + Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into + Field_long : make them Field_longlong. + */ + return create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS - 2); + } + virtual Item_field *field_for_view_update() { return 0; } virtual Item *neg_transformer(THD *thd) { return NULL; } @@ -1984,7 +2018,7 @@ public: bool is_null(); public: - inline void make_field(Send_field *field); + inline void make_field(THD *thd, Send_field *field); inline bool const_item() const; @@ -1996,15 +2030,15 @@ public: Item_sp_variable inline implementation. *****************************************************************************/ -inline void Item_sp_variable::make_field(Send_field *field) +inline void Item_sp_variable::make_field(THD *thd, Send_field *field) { Item *it= this_item(); if (name) - it->set_name(name, (uint) strlen(name), system_charset_info); + it->set_name(thd, name, (uint) strlen(name), system_charset_info); else - it->set_name(m_name.str, (uint) m_name.length, system_charset_info); - it->make_field(field); + it->set_name(thd, m_name.str, (uint) m_name.length, system_charset_info); + it->make_field(thd, field); } inline bool Item_sp_variable::const_item() const @@ -2030,13 +2064,12 @@ inline bool Item_sp_variable::send(Protocol *protocol, String *str) class Item_splocal :public Item_sp_variable, private Settable_routine_parameter, - public Rewritable_query_parameter + public Rewritable_query_parameter, + public Type_handler_hybrid_field_type { uint m_var_idx; Type m_type; - Item_result m_result_type; - enum_field_types m_field_type; public: Item_splocal(THD *thd, const LEX_STRING &sp_var_name, uint sp_var_idx, enum_field_types sp_var_type, @@ -2054,8 +2087,12 @@ public: inline uint get_var_idx() const; inline enum Type type() const; - inline Item_result result_type() const; - inline enum_field_types field_type() const { return m_field_type; } + enum_field_types field_type() const + { return Type_handler_hybrid_field_type::field_type(); } + enum Item_result result_type () const + { return Type_handler_hybrid_field_type::result_type(); } + enum Item_result cmp_type () const + { return Type_handler_hybrid_field_type::cmp_type(); } private: bool set_value(THD *thd, sp_rcontext *ctx, Item **it); @@ -2091,12 +2128,6 @@ inline enum Item::Type Item_splocal::type() const return m_type; } -inline Item_result Item_splocal::result_type() const -{ - return m_result_type; -} - - /***************************************************************************** A reference to case expression in SP, used in runtime. *****************************************************************************/ @@ -2113,6 +2144,7 @@ public: inline enum Type type() const; inline Item_result result_type() const; + enum_field_types field_type() const { return this_item()->field_type(); } public: /* @@ -2173,6 +2205,11 @@ public: bool is_null(); virtual void print(String *str, enum_query_type query_type); + enum_field_types field_type() const + { + return value_item->field_type(); + } + Item_result result_type() const { return value_item->result_type(); @@ -2224,7 +2261,6 @@ public: {} ~Item_result_field() {} /* Required with gcc 2.95 */ Field *get_tmp_table_field() { return result_field; } - Field *tmp_table_field(TABLE *t_arg) { return result_field; } /* This implementation of used_tables() used by Item_avg_field and Item_variance_field which work when only temporary table left, so theu @@ -2327,9 +2363,10 @@ public: longlong val_int() { return field->val_int(); } String *val_str(String *str) { return field->val_str(str); } my_decimal *val_decimal(my_decimal *dec) { return field->val_decimal(dec); } - void make_field(Send_field *tmp_field); + void make_field(THD *thd, Send_field *tmp_field); CHARSET_INFO *charset_for_protocol(void) const { return field->charset_for_protocol(); } + enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } }; @@ -2383,7 +2420,7 @@ public: void reset_field(Field *f); bool fix_fields(THD *, Item **); void fix_after_pullout(st_select_lex *new_parent, Item **ref); - void make_field(Send_field *tmp_field); + void make_field(THD *thd, Send_field *tmp_field); int save_in_field(Field *field,bool no_conversions); void save_org_in_field(Field *field, fast_field_copier optimizer_data); fast_field_copier setup_fast_field_copier(Field *field); @@ -2590,11 +2627,22 @@ public: } }; -/* Item represents one placeholder ('?') of prepared statement */ +/* + Item represents one placeholder ('?') of prepared statement + + Notes: + Item_param::field_type() is used when this item is in a temporary table. + This is NOT placeholder metadata sent to client, as this value + is assigned after sending metadata (in setup_one_conversion_function). + For example in case of 'SELECT ?' you'll get MYSQL_TYPE_STRING both + in result set and placeholders metadata, no matter what type you will + supply for this placeholder in mysql_stmt_execute. +*/ class Item_param :public Item_basic_value, private Settable_routine_parameter, - public Rewritable_query_parameter + public Rewritable_query_parameter, + public Type_handler_hybrid_field_type { public: enum enum_item_param_state @@ -2641,25 +2689,18 @@ public: MYSQL_TIME time; } value; - /* Cached values for virtual methods to save us one switch. */ - enum Item_result item_result_type; enum Type item_type; - /* - Used when this item is used in a temporary table. - This is NOT placeholder metadata sent to client, as this value - is assigned after sending metadata (in setup_one_conversion_function). - For example in case of 'SELECT ?' you'll get MYSQL_TYPE_STRING both - in result set and placeholders metadata, no matter what type you will - supply for this placeholder in mysql_stmt_execute. - */ - enum enum_field_types param_type; + enum_field_types field_type() const + { return Type_handler_hybrid_field_type::field_type(); } + enum Item_result result_type () const + { return Type_handler_hybrid_field_type::result_type(); } + enum Item_result cmp_type () const + { return Type_handler_hybrid_field_type::cmp_type(); } Item_param(THD *thd, uint pos_in_query_arg); - enum Item_result result_type () const { return item_result_type; } enum Type type() const { return item_type; } - enum_field_types field_type() const { return param_type; } double val_real(); longlong val_int(); @@ -2736,7 +2777,7 @@ private: public: virtual const Send_field *get_out_param_info() const; - virtual void make_field(Send_field *field); + virtual void make_field(THD *thd, Send_field *field); private: Send_field *m_out_param_info; @@ -2928,10 +2969,11 @@ protected: // it is constant => can be used without fix_fields (and frequently used) fixed= 1; } - void fix_and_set_name_from_value(Derivation dv, const Metadata metadata) + void fix_and_set_name_from_value(THD *thd, Derivation dv, + const Metadata metadata) { fix_from_value(dv, metadata); - set_name(str_value.ptr(), str_value.length(), str_value.charset()); + set_name(thd, str_value.ptr(), str_value.length(), str_value.charset()); } protected: /* Just create an item and do not fill string representation */ @@ -2940,7 +2982,7 @@ protected: { collation.set(cs, dv); max_length= 0; - set_name(NULL, 0, system_charset_info); + set_name(thd, NULL, 0, system_charset_info); decimals= NOT_FIXED_DEC; fixed= 1; } @@ -2949,7 +2991,7 @@ public: Item_basic_constant(thd) { collation.set(csi, DERIVATION_COERCIBLE); - set_name(NULL, 0, system_charset_info); + set_name(thd, NULL, 0, system_charset_info); decimals= NOT_FIXED_DEC; fixed= 1; str_value.copy(str_arg, length_arg, csi); @@ -2960,14 +3002,14 @@ public: Derivation dv, uint repertoire): Item_basic_constant(thd) { str_value.set_or_copy_aligned(str, length, cs); - fix_and_set_name_from_value(dv, Metadata(&str_value, repertoire)); + fix_and_set_name_from_value(thd, dv, Metadata(&str_value, repertoire)); } Item_string(THD *thd, const char *str, uint length, CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE): Item_basic_constant(thd) { str_value.set_or_copy_aligned(str, length, cs); - fix_and_set_name_from_value(dv, Metadata(&str_value)); + fix_and_set_name_from_value(thd, dv, Metadata(&str_value)); } Item_string(THD *thd, const String *str, CHARSET_INFO *tocs, uint *conv_errors, Derivation dv, uint repertoire): Item_basic_constant(thd) @@ -2975,7 +3017,7 @@ public: if (str_value.copy(str, tocs, conv_errors)) str_value.set("", 0, tocs); // EOM ? str_value.mark_as_const(); - fix_and_set_name_from_value(dv, Metadata(&str_value, repertoire)); + fix_and_set_name_from_value(thd, dv, Metadata(&str_value, repertoire)); } // Constructors with an externally provided item name Item_string(THD *thd, const char *name_par, const char *str, uint length, @@ -2984,7 +3026,7 @@ public: { str_value.set_or_copy_aligned(str, length, cs); fix_from_value(dv, Metadata(&str_value)); - set_name(name_par, 0, system_charset_info); + set_name(thd, name_par, 0, system_charset_info); } Item_string(THD *thd, const char *name_par, const char *str, uint length, CHARSET_INFO *cs, Derivation dv, uint repertoire): @@ -2992,7 +3034,7 @@ public: { str_value.set_or_copy_aligned(str, length, cs); fix_from_value(dv, Metadata(&str_value, repertoire)); - set_name(name_par, 0, system_charset_info); + set_name(thd, name_par, 0, system_charset_info); } void print_value(String *to) const { @@ -3221,7 +3263,7 @@ public: Item_partition_func_safe_string(thd, "", 0, cs ? cs : &my_charset_utf8_general_ci) { name=(char*) header; max_length= length * collation.collation->mbmaxlen; } - void make_field(Send_field *field); + void make_field(THD *thd, Send_field *field); }; @@ -3292,7 +3334,12 @@ public: DBUG_ASSERT(fixed == 1); return (double) (ulonglong) Item_hex_hybrid::val_int(); } - longlong val_int(); + longlong val_int() + { + // following assert is redundant, because fixed=1 assigned in constructor + DBUG_ASSERT(fixed == 1); + return longlong_from_hex_hybrid(str_value.ptr(), str_value.length()); + } my_decimal *val_decimal(my_decimal *decimal_value) { // following assert is redundant, because fixed=1 assigned in constructor @@ -3301,7 +3348,11 @@ public: int2my_decimal(E_DEC_FATAL_ERROR, value, TRUE, decimal_value); return decimal_value; } - int save_in_field(Field *field, bool no_conversions); + int save_in_field(Field *field, bool no_conversions) + { + field->set_notnull(); + return field->store_hex_hybrid(str_value.ptr(), str_value.length()); + } enum Item_result cast_to_int_type() const { return INT_RESULT; } void print(String *str, enum_query_type query_type); }; @@ -3397,8 +3448,6 @@ public: { return val_real_from_date(); } my_decimal *val_decimal(my_decimal *decimal_value) { return val_decimal_from_date(decimal_value); } - Field *tmp_table_field(TABLE *table) - { return tmp_table_field_from_field_type(table, false, false); } int save_in_field(Field *field, bool no_conversions) { return save_date_in_field(field); } }; @@ -3562,28 +3611,28 @@ public: { args[0]= a; args[1]= b; } - Item_args(Item *a, Item *b, Item *c) + Item_args(THD *thd, Item *a, Item *b, Item *c) { arg_count= 0; - if ((args= (Item**) sql_alloc(sizeof(Item*) * 3))) + if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 3))) { arg_count= 3; args[0]= a; args[1]= b; args[2]= c; } } - Item_args(Item *a, Item *b, Item *c, Item *d) + Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d) { arg_count= 0; - if ((args= (Item**) sql_alloc(sizeof(Item*) * 4))) + if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 4))) { arg_count= 4; args[0]= a; args[1]= b; args[2]= c; args[3]= d; } } - Item_args(Item *a, Item *b, Item *c, Item *d, Item* e) + Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e) { arg_count= 5; - if ((args= (Item**) sql_alloc(sizeof(Item*) * 5))) + if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 5))) { arg_count= 5; args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e; @@ -3792,11 +3841,11 @@ public: Item_func_or_sum(THD *thd, Item *a, Item *b): Item_result_field(thd), Item_args(a, b) { } Item_func_or_sum(THD *thd, Item *a, Item *b, Item *c): - Item_result_field(thd), Item_args(a, b, c) { } + Item_result_field(thd), Item_args(thd, a, b, c) { } Item_func_or_sum(THD *thd, Item *a, Item *b, Item *c, Item *d): - Item_result_field(thd), Item_args(a, b, c, d) { } + Item_result_field(thd), Item_args(thd, a, b, c, d) { } Item_func_or_sum(THD *thd, Item *a, Item *b, Item *c, Item *d, Item *e): - Item_result_field(thd), Item_args(a, b, c, d, e) { } + Item_result_field(thd), Item_args(thd, a, b, c, d, e) { } Item_func_or_sum(THD *thd, Item_func_or_sum *item): Item_result_field(thd, item), Item_args(thd, item), Used_tables_and_const_cache(item) { } @@ -3892,7 +3941,7 @@ public: bool val_bool_result(); bool is_null_result(); bool send(Protocol *prot, String *tmp); - void make_field(Send_field *field); + void make_field(THD *thd, Send_field *field); bool fix_fields(THD *, Item **); void fix_after_pullout(st_select_lex *new_parent, Item **ref); int save_in_field(Field *field, bool no_conversions); @@ -3903,7 +3952,6 @@ public: enum_field_types field_type() const { return (*ref)->field_type(); } Field *get_tmp_table_field() { return result_field ? result_field : (*ref)->get_tmp_table_field(); } - Field *tmp_table_field(TABLE *t_arg) { return 0; } Item *get_tmp_table_item(THD *thd); table_map used_tables() const; void update_used_tables(); @@ -4157,7 +4205,8 @@ public: virtual void print(String *str, enum_query_type query_type); virtual const char *full_name() const { return orig_item->full_name(); } - virtual void make_field(Send_field *field) { orig_item->make_field(field); } + virtual void make_field(THD *thd, Send_field *field) + { orig_item->make_field(thd, field); } bool eq(const Item *item, bool binary_cmp) const { Item *it= ((Item *) item)->real_item(); @@ -4528,26 +4577,21 @@ public: from Item_). */ -class Item_copy :public Item +class Item_copy :public Item, + public Type_handler_hybrid_field_type { protected: /** - Stores the type of the resulting field that would be used to store the data + Type_handler_hybrid_field_type is used to + store the type of the resulting field that would be used to store the data in the cache. This is to avoid calls to the original item. */ - enum enum_field_types cached_field_type; /** The original item that is copied */ Item *item; /** - Stores the result type of the original item, so it can be returned - without calling the original item's method - */ - Item_result cached_result_type; - - /** Constructor of the Item_copy class stores metadata information about the original class as well as a @@ -4559,8 +4603,7 @@ protected: null_value=maybe_null=item->maybe_null; Type_std_attributes::set(item); name=item->name; - cached_field_type= item->field_type(); - cached_result_type= item->result_type(); + set_handler_by_field_type(item->field_type()); fixed= item->fixed; } @@ -4585,10 +4628,15 @@ public: Item *get_item() { return item; } /** All of the subclasses should have the same type tag */ enum Type type() const { return COPY_STR_ITEM; } - enum_field_types field_type() const { return cached_field_type; } - enum Item_result result_type () const { return cached_result_type; } - void make_field(Send_field *field) { item->make_field(field); } + enum_field_types field_type() const + { return Type_handler_hybrid_field_type::field_type(); } + enum Item_result result_type () const + { return Type_handler_hybrid_field_type::result_type(); } + enum Item_result cmp_type () const + { return Type_handler_hybrid_field_type::cmp_type(); } + + void make_field(THD *thd, Send_field *field) { item->make_field(thd, field); } table_map used_tables() const { return (table_map) 1L; } bool const_item() const { return 0; } bool is_null() { return null_value; } @@ -4789,11 +4837,11 @@ class Cached_item_field :public Cached_item uint length; public: - Cached_item_field(Field *arg_field) : field(arg_field) + Cached_item_field(THD *thd, Field *arg_field): field(arg_field) { field= arg_field; /* TODO: take the memory allocation below out of the constructor. */ - buff= (uchar*) sql_calloc(length=field->pack_length()); + buff= (uchar*) thd_calloc(thd, length= field->pack_length()); } bool cmp(void); }; @@ -4967,7 +5015,8 @@ public: for any value. */ -class Item_cache: public Item_basic_constant +class Item_cache: public Item_basic_constant, + public Type_handler_hybrid_field_type { protected: Item *example; @@ -4977,7 +5026,6 @@ protected: by IN->EXISTS transformation. */ Field *cached_field; - enum enum_field_types cached_field_type; /* TRUE <=> cache holds value of the last stored item (i.e actual value). store() stores item to be cached and sets this flag to FALSE. @@ -4989,18 +5037,19 @@ protected: public: Item_cache(THD *thd): Item_basic_constant(thd), + Type_handler_hybrid_field_type(MYSQL_TYPE_STRING), example(0), cached_field(0), - cached_field_type(MYSQL_TYPE_STRING), value_cached(0) { fixed= 1; maybe_null= 1; null_value= 1; } +protected: Item_cache(THD *thd, enum_field_types field_type_arg): Item_basic_constant(thd), + Type_handler_hybrid_field_type(field_type_arg), example(0), cached_field(0), - cached_field_type(field_type_arg), value_cached(0) { fixed= 1; @@ -5008,6 +5057,7 @@ public: null_value= 1; } +public: virtual bool allocate(THD *thd, uint i) { return 0; } virtual bool setup(THD *thd, Item *item) { @@ -5018,12 +5068,19 @@ public: return 0; }; enum Type type() const { return CACHE_ITEM; } - enum_field_types field_type() const { return cached_field_type; } + + enum_field_types field_type() const + { return Type_handler_hybrid_field_type::field_type(); } + enum Item_result result_type () const + { return Type_handler_hybrid_field_type::result_type(); } + enum Item_result cmp_type () const + { return Type_handler_hybrid_field_type::cmp_type(); } + static Item_cache* get_cache(THD *thd, const Item *item); static Item_cache* get_cache(THD *thd, const Item* item, const Item_result type); virtual void keep_array() {} virtual void print(String *str, enum_query_type query_type); - bool eq_def(Field *field) + bool eq_def(const Field *field) { return cached_field ? cached_field->eq_def (field) : FALSE; } @@ -5167,7 +5224,7 @@ public: Item_cache_str(THD *thd, const Item *item): Item_cache(thd, item->field_type()), value(0), is_varbinary(item->type() == FIELD_ITEM && - cached_field_type == MYSQL_TYPE_VARCHAR && + Item_cache_str::field_type() == MYSQL_TYPE_VARCHAR && !((const Item_field *) item)->field->has_charset()) { collation.set(const_cast<DTCollation&>(item->collation)); @@ -5228,7 +5285,7 @@ public: bool setup(THD *thd, Item *item); void store(Item *item); void illegal_method_call(const char *); - void make_field(Send_field *) + void make_field(THD *thd, Send_field *) { illegal_method_call((const char*)"make_field"); }; @@ -5284,11 +5341,11 @@ public: Item_type_holder do not need cleanup() because its time of live limited by single SP/PS execution. */ -class Item_type_holder: public Item +class Item_type_holder: public Item, + public Type_handler_hybrid_real_field_type { protected: TYPELIB *enum_set_typelib; - enum_field_types fld_type; Field::geometry_type geometry_type; void get_full_info(Item *item); @@ -5298,8 +5355,27 @@ protected: public: Item_type_holder(THD*, Item*); - Item_result result_type() const; - enum_field_types field_type() const { return fld_type; }; + enum_field_types field_type() const + { return Type_handler_hybrid_real_field_type::field_type(); } + enum_field_types real_field_type() const + { return Type_handler_hybrid_real_field_type::real_field_type(); } + enum Item_result result_type () const + { + /* + In 10.1 Item_type_holder::result_type() returned + Field::result_merge_type(field_type()), which returned STRING_RESULT + for the BIT data type. In 10.2 it returns INT_RESULT, similar + to what Field_bit::result_type() does. This should not be + important because Item_type_holder is a limited purpose Item + and its result_type() should not be called from outside of + Item_type_holder. It's called only internally from decimal_int_part() + from join_types(), to calculate "decimals" of the result data type. + As soon as we get BIT as one of the joined types, the result field + type cannot be numeric: it's either BIT, or VARBINARY. + */ + return Type_handler_hybrid_real_field_type::result_type(); + } + enum Type type() const { return TYPE_HOLDER; } double val_real(); longlong val_int(); diff --git a/sql/item_buff.cc b/sql/item_buff.cc index d1134525f7b..62c2f76dc2e 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -43,7 +43,7 @@ Cached_item *new_Cached_item(THD *thd, Item *item, bool pass_through_ref) { Item_field *real_item= (Item_field *) item->real_item(); Field *cached_field= real_item->field; - return new Cached_item_field(cached_field); + return new (thd->mem_root) Cached_item_field(thd, cached_field); } switch (item->result_type()) { case STRING_RESULT: diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1ce8bad933b..01dcfb39e0e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1846,8 +1846,8 @@ void Item_func_interval::fix_length_and_dec() } if (not_null_consts && - (intervals= - (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1)))) + (intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) * + (rows - 1)))) { if (use_decimal_comparison) { @@ -2256,11 +2256,6 @@ uint Item_func_case_abbreviation2::decimal_precision2(Item **args) const } -Field *Item_func_ifnull::tmp_table_field(TABLE *table) -{ - return tmp_table_field_from_field_type(table, false, false); -} - double Item_func_ifnull::real_op() { @@ -3567,8 +3562,9 @@ bool in_vector::find(Item *item) return ((*compare)(collation, base+start*size, result) == 0); } -in_string::in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs) - :in_vector(elements, sizeof(String), cmp_func, cs), +in_string::in_string(THD *thd, uint elements, qsort2_cmp cmp_func, + CHARSET_INFO *cs) + :in_vector(thd, elements, sizeof(String), cmp_func, cs), tmp(buff, sizeof(buff), &my_charset_bin) {} @@ -3576,7 +3572,7 @@ in_string::~in_string() { if (base) { - // base was allocated with help of sql_alloc => following is OK + // base was allocated on THD::mem_root => following is OK for (uint i=0 ; i < count ; i++) ((String*) base)[i].free(); } @@ -3651,8 +3647,9 @@ void in_row::set(uint pos, Item *item) DBUG_VOID_RETURN; } -in_longlong::in_longlong(uint elements) - :in_vector(elements,sizeof(packed_longlong),(qsort2_cmp) cmp_longlong, 0) +in_longlong::in_longlong(THD *thd, uint elements) + :in_vector(thd, elements, sizeof(packed_longlong), + (qsort2_cmp) cmp_longlong, 0) {} void in_longlong::set(uint pos,Item *item) @@ -3709,8 +3706,8 @@ Item *in_datetime::create_item(THD *thd) } -in_double::in_double(uint elements) - :in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0) +in_double::in_double(THD *thd, uint elements) + :in_vector(thd, elements, sizeof(double), (qsort2_cmp) cmp_double, 0) {} void in_double::set(uint pos,Item *item) @@ -3732,8 +3729,8 @@ Item *in_double::create_item(THD *thd) } -in_decimal::in_decimal(uint elements) - :in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0) +in_decimal::in_decimal(THD *thd, uint elements) + :in_vector(thd, elements, sizeof(my_decimal), (qsort2_cmp) cmp_decimal, 0) {} @@ -4209,14 +4206,15 @@ void Item_func_in::fix_length_and_dec() } switch (m_compare_type) { case STRING_RESULT: - array=new (thd->mem_root) in_string(arg_count-1,(qsort2_cmp) srtcmp_in, + array=new (thd->mem_root) in_string(thd, arg_count - 1, + (qsort2_cmp) srtcmp_in, cmp_collation.collation); break; case INT_RESULT: - array= new (thd->mem_root) in_longlong(arg_count-1); + array= new (thd->mem_root) in_longlong(thd, arg_count - 1); break; case REAL_RESULT: - array= new (thd->mem_root) in_double(arg_count-1); + array= new (thd->mem_root) in_double(thd, arg_count - 1); break; case ROW_RESULT: /* @@ -4227,11 +4225,11 @@ void Item_func_in::fix_length_and_dec() ((in_row*)array)->tmp.store_value(args[0]); break; case DECIMAL_RESULT: - array= new (thd->mem_root) in_decimal(arg_count - 1); + array= new (thd->mem_root) in_decimal(thd, arg_count - 1); break; case TIME_RESULT: date_arg= find_date_time_item(args, arg_count, 0); - array= new (thd->mem_root) in_datetime(date_arg, arg_count - 1); + array= new (thd->mem_root) in_datetime(thd, date_arg, arg_count - 1); break; } if (!array || thd->is_fatal_error) // OOM @@ -6722,10 +6720,9 @@ longlong Item_func_dyncol_exists::val_int() } else { - uint strlen; + uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1; uint dummy_errors; - buf.str= (char *)sql_alloc((strlen= nm->length() * - my_charset_utf8_general_ci.mbmaxlen + 1)); + buf.str= (char *) current_thd->alloc(strlen); if (buf.str) { buf.length= diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 39f2cf5590d..2d197a86d9b 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -23,7 +23,6 @@ #pragma interface /* gcc class implementation */ #endif -#include "thr_malloc.h" /* sql_calloc */ #include "item_func.h" /* Item_int_func, Item_bool_func */ #define PCRE_STATIC 1 /* Important on Windows */ #include "pcre.h" /* pcre header file */ @@ -951,7 +950,9 @@ public: maybe_null= args[1]->maybe_null; } const char *func_name() const { return "ifnull"; } - Field *tmp_table_field(TABLE *table); + Field *create_field_for_create_select(THD *thd, TABLE *table) + { return tmp_table_field_from_field_type(table, false, false); } + table_map not_null_tables() const { return 0; } uint decimal_precision() const { @@ -1064,9 +1065,9 @@ public: uint count; uint used_count; in_vector() {} - in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, + in_vector(THD *thd, uint elements, uint element_length, qsort2_cmp cmp_func, CHARSET_INFO *cmp_coll) - :base((char*) sql_calloc(elements*element_length)), + :base((char*) thd_calloc(thd, elements * element_length)), size(element_length), compare(cmp_func), collation(cmp_coll), count(elements), used_count(elements) {} virtual ~in_vector() {} @@ -1123,7 +1124,7 @@ class in_string :public in_vector } }; public: - in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs); + in_string(THD *thd, uint elements, qsort2_cmp cmp_func, CHARSET_INFO *cs); ~in_string(); void set(uint pos,Item *item); uchar *get_value(Item *item); @@ -1151,7 +1152,7 @@ protected: longlong unsigned_flag; // Use longlong, not bool, to preserve alignment } tmp; public: - in_longlong(uint elements); + in_longlong(THD *thd, uint elements); void set(uint pos,Item *item); uchar *get_value(Item *item); Item* create_item(THD *thd); @@ -1182,8 +1183,8 @@ public: /* Cache for the left item. */ Item *lval_cache; - in_datetime(Item *warn_item_arg, uint elements) - :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg), + in_datetime(THD *thd, Item *warn_item_arg, uint elements) + :in_longlong(thd, elements), thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}; void set(uint pos,Item *item); uchar *get_value(Item *item); @@ -1202,7 +1203,7 @@ class in_double :public in_vector { double tmp; public: - in_double(uint elements); + in_double(THD *thd, uint elements); void set(uint pos,Item *item); uchar *get_value(Item *item); Item *create_item(THD *thd); @@ -1218,7 +1219,7 @@ class in_decimal :public in_vector { my_decimal val; public: - in_decimal(uint elements); + in_decimal(THD *thd, uint elements); void set(uint pos, Item *item); uchar *get_value(Item *item); Item *create_item(THD *thd); diff --git a/sql/item_func.cc b/sql/item_func.cc index e5c1f4c75f6..50b6f4a6b68 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -509,43 +509,6 @@ bool Item_func::eq(const Item *item, bool binary_cmp) const } -Field *Item_func::tmp_table_field(TABLE *table) -{ - Field *field= NULL; - MEM_ROOT *mem_root= table->in_use->mem_root; - - switch (result_type()) { - case INT_RESULT: - if (max_char_length() > MY_INT32_NUM_DECIMAL_DIGITS) - field= new (mem_root) - Field_longlong(max_char_length(), maybe_null, name, - unsigned_flag); - else - field= new (mem_root) - Field_long(max_char_length(), maybe_null, name, - unsigned_flag); - break; - case REAL_RESULT: - field= new (mem_root) - Field_double(max_char_length(), maybe_null, name, decimals); - break; - case STRING_RESULT: - return make_string_field(table); - case DECIMAL_RESULT: - field= Field_new_decimal::create_from_item(mem_root, this); - break; - case ROW_RESULT: - case TIME_RESULT: - // This case should never be chosen - DBUG_ASSERT(0); - field= 0; - break; - } - if (field) - field->init(table); - return field; -} - /* bool Item_func::is_expensive_processor(uchar *arg) { @@ -2910,10 +2873,10 @@ void Item_func_min_max::fix_length_and_dec() collation.set_numeric(); fix_char_length(float_length(decimals)); /* - Set type to DOUBLE, as Item_func::tmp_table_field() does not + Set type to DOUBLE, as Item_func::create_tmp_field() does not distinguish between DOUBLE and FLOAT and always creates Field_double. Perhaps we should eventually change this to use agg_field_type() here, - and fix Item_func::tmp_table_field() to create Field_float when possible. + and fix Item_func::create_tmp_field() to create Field_float when possible. */ set_handler_by_field_type(MYSQL_TYPE_DOUBLE); break; @@ -3555,7 +3518,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, func->used_tables_and_const_cache_join(item); f_args.arg_type[i]=item->result_type(); } - //TODO: why all following memory is not allocated with 1 call of sql_alloc? + //TODO: why all following memory is not allocated with 1 thd->alloc() call? if (!(buffers=new String[arg_count]) || !(f_args.args= (char**) thd->alloc(arg_count * sizeof(char *))) || !(f_args.lengths= (ulong*) thd->alloc(arg_count * sizeof(long))) || @@ -5347,7 +5310,7 @@ bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg) return Item::send(protocol, str_arg); } -void Item_func_set_user_var::make_field(Send_field *tmp_field) +void Item_func_set_user_var::make_field(THD *thd, Send_field *tmp_field) { if (result_field) { @@ -5357,7 +5320,7 @@ void Item_func_set_user_var::make_field(Send_field *tmp_field) tmp_field->col_name=Item::name; // Use user supplied name } else - Item::make_field(tmp_field); + Item::make_field(thd, tmp_field); } @@ -5813,7 +5776,7 @@ Item_func_get_system_var(THD *thd, sys_var *var_arg, enum_var_type var_type_arg, orig_var_type(var_type_arg), component(*component_arg), cache_present(0) { /* set_name() will allocate the name */ - set_name(name_arg, (uint) name_len_arg, system_charset_info); + set_name(thd, name_arg, (uint) name_len_arg, system_charset_info); } @@ -6768,7 +6731,7 @@ error: void -Item_func_sp::make_field(Send_field *tmp_field) +Item_func_sp::make_field(THD *thd, Send_field *tmp_field) { DBUG_ENTER("Item_func_sp::make_field"); DBUG_ASSERT(sp_result_field); @@ -6803,16 +6766,6 @@ longlong Item_func_found_rows::val_int() } -Field * -Item_func_sp::tmp_table_field(TABLE *t_arg) -{ - DBUG_ENTER("Item_func_sp::tmp_table_field"); - - DBUG_ASSERT(sp_result_field); - DBUG_RETURN(sp_result_field); -} - - /** @brief Checks if requested access to function can be granted to user. If function isn't found yet, it searches function first. diff --git a/sql/item_func.h b/sql/item_func.h index a5f6bf26134..2ce199b3565 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -173,12 +173,11 @@ public: } void signal_divide_by_null(); friend class udf_handler; - Field *tmp_table_field() { return result_field; } - Field *tmp_table_field(TABLE *t_arg); Field *create_field_for_create_select(THD *thd, TABLE *table) { + DBUG_ASSERT(thd == table->in_use); return result_type() != STRING_RESULT ? - tmp_table_field(table) : + create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS) : tmp_table_field_from_field_type(table, false, false); } Item *get_tmp_table_item(THD *thd); @@ -378,6 +377,7 @@ public: longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); } enum Item_result result_type () const { return REAL_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } void fix_length_and_dec() { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); } }; @@ -450,8 +450,6 @@ class Item_func_hybrid_field_type: public Item_hybrid_func DBUG_ASSERT((res != NULL) ^ null_value); return res; } -protected: - Item_result cached_result_type; public: Item_func_hybrid_field_type(THD *thd): @@ -599,6 +597,7 @@ public: double val_real(); String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void fix_length_and_dec() {} }; @@ -1119,6 +1118,7 @@ public: const char *func_name() const { return "rollup_const"; } bool const_item() const { return 0; } Item_result result_type() const { return args[0]->result_type(); } + enum_field_types field_type() const { return args[0]->field_type(); } void fix_length_and_dec() { collation= args[0]->collation; @@ -1477,6 +1477,7 @@ class Item_func_udf_float :public Item_udf_func } double val_real(); String *val_str(String *str); + enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } void fix_length_and_dec() { fix_num_length_and_dec(); } }; @@ -1493,6 +1494,7 @@ public: double val_real() { return (double) Item_func_udf_int::val_int(); } String *val_str(String *str); enum Item_result result_type () const { return INT_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void fix_length_and_dec() { decimals= 0; max_length= 21; } }; @@ -1509,6 +1511,7 @@ public: my_decimal *val_decimal(my_decimal *); String *val_str(String *str); enum Item_result result_type () const { return DECIMAL_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; } void fix_length_and_dec() { fix_num_length_and_dec(); } }; @@ -1546,6 +1549,7 @@ public: return dec_buf; } enum Item_result result_type () const { return STRING_RESULT; } + enum_field_types field_type() const { return string_field_type(); } void fix_length_and_dec(); }; @@ -1757,7 +1761,7 @@ public: bool update_hash(void *ptr, uint length, enum Item_result type, CHARSET_INFO *cs, bool unsigned_arg); bool send(Protocol *protocol, String *str_arg); - void make_field(Send_field *tmp_field); + void make_field(THD *thd, Send_field *tmp_field); bool check(bool use_result_field); void save_item_result(Item *item); bool update(); @@ -1766,7 +1770,7 @@ public: Field *create_field_for_create_select(THD *thd, TABLE *table) { return result_type() != STRING_RESULT ? - tmp_table_field(table) : + create_tmp_field(false, table, MY_INT32_NUM_DECIMAL_DIGITS) : tmp_table_field_from_field_type(table, false, true); } table_map used_tables() const @@ -1843,7 +1847,7 @@ class Item_user_var_as_out_param :public Item user_var_entry *entry; public: Item_user_var_as_out_param(THD *thd, LEX_STRING a): Item(thd), name(a) - { set_name(a.str, 0, system_charset_info); } + { set_name(thd, a.str, 0, system_charset_info); } /* We should return something different from FIELD_ITEM here */ enum Type type() const { return STRING_ITEM;} double val_real(); @@ -1855,6 +1859,7 @@ public: void print_for_load(THD *thd, String *str); void set_null_value(CHARSET_INFO* cs); void set_value(const char *str, uint length, CHARSET_INFO* cs); + enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } }; @@ -2043,6 +2048,33 @@ enum Cast_target }; +struct Lex_cast_type_st: public Lex_length_and_dec_st +{ +private: + Cast_target m_type; +public: + void set(Cast_target type, const char *length, const char *dec) + { + m_type= type; + Lex_length_and_dec_st::set(length, dec); + } + void set(Cast_target type, Lex_length_and_dec_st length_and_dec) + { + m_type= type; + Lex_length_and_dec_st::operator=(length_and_dec); + } + void set(Cast_target type, const char *length) + { + set(type, length, 0); + } + void set(Cast_target type) + { + set(type, 0, 0); + } + Cast_target type() const { return m_type; } +}; + + class Item_func_row_count :public Item_int_func { public: @@ -2107,9 +2139,13 @@ public: enum enum_field_types field_type() const; - Field *tmp_table_field(TABLE *t_arg); - - void make_field(Send_field *tmp_field); + Field *create_field_for_create_select(THD *thd, TABLE *table) + { + return result_type() != STRING_RESULT ? + sp_result_field : + tmp_table_field_from_field_type(table, false, false); + } + void make_field(THD *thd, Send_field *tmp_field); Item_result result_type() const; diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index a515f292975..39d06fd7a26 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -41,7 +41,7 @@ #include "opt_range.h" -Field *Item_geometry_func::tmp_table_field(TABLE *t_arg) +Field *Item_geometry_func::create_field_for_create_select(THD *thd, TABLE *t_arg) { Field *result; if ((result= new Field_geom(max_length, maybe_null, name, t_arg->s, diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index b72661fe054..56e2a729924 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -40,7 +40,7 @@ public: Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {} void fix_length_and_dec(); enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; } - Field *tmp_table_field(TABLE *t_arg); + Field *create_field_for_create_select(THD *thd, TABLE *table); }; class Item_func_geometry_from_text: public Item_geometry_func diff --git a/sql/item_row.h b/sql/item_row.h index 25c9ec7915b..153a6f085b3 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -58,7 +58,7 @@ public: enum Type type() const { return ROW_ITEM; }; void illegal_method_call(const char *); bool is_null() { return null_value; } - void make_field(Send_field *) + void make_field(THD *thd, Send_field *) { illegal_method_call((const char*)"make_field"); }; @@ -91,6 +91,11 @@ public: bool const_item() const { return const_item_cache; }; enum Item_result result_type() const { return ROW_RESULT; } Item_result cmp_type() const { return ROW_RESULT; } + enum_field_types field_type() const + { + DBUG_ASSERT(0); + return MYSQL_TYPE_DOUBLE; + } void update_used_tables() { used_tables_and_const_cache_init(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 8bf1521e971..7c1c5f7da7d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -4312,7 +4312,7 @@ void Item_func_dyncol_create::fix_length_and_dec() decimals= 0; } -bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) +bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg) { char buff[STRING_BUFFER_USUAL_SIZE]; String *res, tmp(buff, sizeof(buff), &my_charset_bin); @@ -4432,15 +4432,13 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) if (my_charset_same(res->charset(), &my_charset_utf8_general_ci)) { keys_str[i].length= res->length(); - keys_str[i].str= sql_strmake(res->ptr(), res->length()); + keys_str[i].str= thd->strmake(res->ptr(), res->length()); } else { - uint strlen; + uint strlen= res->length() * my_charset_utf8_general_ci.mbmaxlen + 1; uint dummy_errors; - char *str= - (char *)sql_alloc((strlen= res->length() * - my_charset_utf8_general_ci.mbmaxlen + 1)); + char *str= (char *) thd->alloc(strlen); if (str) { keys_str[i].length= @@ -4489,7 +4487,7 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) if (res && defs[i].cs) res->set_charset(defs[i].cs); if (res && - (vals[i].x.string.value.str= sql_strmake(res->ptr(), res->length()))) + (vals[i].x.string.value.str= thd->strmake(res->ptr(), res->length()))) { vals[i].x.string.value.length= res->length(); vals[i].x.string.charset= res->charset(); @@ -4521,7 +4519,7 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg) case DYN_COL_DATETIME: case DYN_COL_DATE: args[valpos]->get_date(&vals[i].x.time_value, - sql_mode_for_dates(current_thd)); + sql_mode_for_dates(thd)); break; case DYN_COL_TIME: args[valpos]->get_time(&vals[i].x.time_value); @@ -4547,7 +4545,8 @@ String *Item_func_dyncol_create::val_str(String *str) enum enum_dyncol_func_result rc; DBUG_ASSERT((arg_count & 0x1) == 0); // even number of arguments - if (prepare_arguments(FALSE)) + /* FIXME: add thd argument to Item::val_str() */ + if (prepare_arguments(current_thd, FALSE)) { res= NULL; null_value= 1; @@ -4692,7 +4691,8 @@ String *Item_func_dyncol_add::val_str(String *str) col.length= res->length(); memcpy(col.str, res->ptr(), col.length); - if (prepare_arguments(mariadb_dyncol_has_names(&col))) + /* FIXME: add thd argument to Item::val_str() */ + if (prepare_arguments(current_thd, mariadb_dyncol_has_names(&col))) goto null; if ((rc= ((names || force_names) ? @@ -4742,7 +4742,8 @@ void Item_func_dyncol_add::print(String *str, This function ensures that null_value is set correctly */ -bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp) +bool Item_dyncol_get::get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val, + String *tmp) { DYNAMIC_COLUMN dyn_str; String *res; @@ -4770,10 +4771,9 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp) } else { - uint strlen; + uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1; uint dummy_errors; - buf.str= (char *)sql_alloc((strlen= nm->length() * - my_charset_utf8_general_ci.mbmaxlen + 1)); + buf.str= (char *) thd->alloc(strlen); if (buf.str) { buf.length= @@ -4823,7 +4823,7 @@ String *Item_dyncol_get::val_str(String *str_result) char buff[STRING_BUFFER_USUAL_SIZE]; String tmp(buff, sizeof(buff), &my_charset_bin); - if (get_dyn_value(&val, &tmp)) + if (get_dyn_value(current_thd, &val, &tmp)) return NULL; switch (val.type) { @@ -4905,11 +4905,12 @@ null: longlong Item_dyncol_get::val_int() { + THD *thd= current_thd; DYNAMIC_COLUMN_VALUE val; char buff[STRING_BUFFER_USUAL_SIZE]; String tmp(buff, sizeof(buff), &my_charset_bin); - if (get_dyn_value(&val, &tmp)) + if (get_dyn_value(thd, &val, &tmp)) return 0; switch (val.type) { @@ -4930,7 +4931,6 @@ longlong Item_dyncol_get::val_int() num= double_to_longlong(val.x.double_value, unsigned_flag, &error); if (error) { - THD *thd= current_thd; char buff[30]; sprintf(buff, "%lg", val.x.double_value); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -4950,7 +4950,6 @@ longlong Item_dyncol_get::val_int() num= my_strtoll10(val.x.string.value.str, &end, &error); if (end != org_end || error > 0) { - THD *thd= current_thd; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_BAD_DATA, ER_THD(thd, ER_BAD_DATA), @@ -4987,11 +4986,12 @@ null: double Item_dyncol_get::val_real() { + THD *thd= current_thd; DYNAMIC_COLUMN_VALUE val; char buff[STRING_BUFFER_USUAL_SIZE]; String tmp(buff, sizeof(buff), &my_charset_bin); - if (get_dyn_value(&val, &tmp)) + if (get_dyn_value(thd, &val, &tmp)) return 0.0; switch (val.type) { @@ -5014,7 +5014,6 @@ double Item_dyncol_get::val_real() if (end != (char*) val.x.string.value.str + val.x.string.value.length || error) { - THD *thd= current_thd; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_BAD_DATA, ER_THD(thd, ER_BAD_DATA), @@ -5046,11 +5045,12 @@ null: my_decimal *Item_dyncol_get::val_decimal(my_decimal *decimal_value) { + THD *thd= current_thd; DYNAMIC_COLUMN_VALUE val; char buff[STRING_BUFFER_USUAL_SIZE]; String tmp(buff, sizeof(buff), &my_charset_bin); - if (get_dyn_value(&val, &tmp)) + if (get_dyn_value(thd, &val, &tmp)) return NULL; switch (val.type) { @@ -5075,7 +5075,6 @@ my_decimal *Item_dyncol_get::val_decimal(my_decimal *decimal_value) if (rc != E_DEC_OK || end != val.x.string.value.str + val.x.string.value.length) { - THD *thd= current_thd; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_BAD_DATA, ER_THD(thd, ER_BAD_DATA), @@ -5110,7 +5109,7 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) String tmp(buff, sizeof(buff), &my_charset_bin); bool signed_value= 0; - if (get_dyn_value(&val, &tmp)) + if (get_dyn_value(current_thd, &val, &tmp)) return 1; // Error switch (val.type) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 65c286819d3..0ff38157c25 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -65,6 +65,7 @@ public: double val_real(); my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return STRING_RESULT; } + enum_field_types field_type() const { return string_field_type(); } void left_right_max_length(); bool fix_fields(THD *thd, Item **ref); void update_null_value() @@ -1197,7 +1198,7 @@ protected: uint *keys_num; LEX_STRING *keys_str; bool names, force_names; - bool prepare_arguments(bool force_names); + bool prepare_arguments(THD *thd, bool force_names); void print_arguments(String *str, enum_query_type query_type); public: Item_func_dyncol_create(THD *thd, List<Item> &args, DYNCALL_CREATE_DEF *dfs); @@ -1255,7 +1256,7 @@ public: longlong val_int(); double val_real(); my_decimal *val_decimal(my_decimal *); - bool get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp); + bool get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val, String *tmp); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); void print(String *str, enum_query_type query_type); }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index dea58bf8e0c..8745baa8c69 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -58,6 +58,8 @@ Item_subselect::Item_subselect(THD *thd_arg): { DBUG_ENTER("Item_subselect::Item_subselect"); DBUG_PRINT("enter", ("this: 0x%lx", (ulong) this)); + sortbuffer.str= 0; + #ifndef DBUG_OFF exec_counter= 0; #endif @@ -153,6 +155,9 @@ void Item_subselect::cleanup() if (engine) engine->cleanup(); reset(); + filesort_buffer.free_sort_buffer(); + my_free(sortbuffer.str); + value_assigned= 0; expr_cache= 0; forced_const= FALSE; @@ -1149,7 +1154,8 @@ void Item_singlerow_subselect::fix_length_and_dec() } else { - if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns))) + if (!(row= (Item_cache**) current_thd->alloc(sizeof(Item_cache*) * + max_columns))) return; engine->fix_length_and_dec(row); value= *row; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 670d0a66639..58b5a948048 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -95,6 +95,9 @@ public: subselect_engine *engine; /* unit of subquery */ st_select_lex_unit *unit; + /* Cached buffers used when calling filesort in sub queries */ + Filesort_buffer filesort_buffer; + LEX_STRING sortbuffer; /* A reference from inside subquery predicate to somewhere outside of it */ class Ref_to_outside : public Sql_alloc { @@ -378,6 +381,7 @@ public: void no_rows_in_result(); enum Item_result result_type() const { return INT_RESULT;} + enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } longlong val_int(); double val_real(); String *val_str(String*); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 1cfee1a9241..0c85cf53e18 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -29,6 +29,7 @@ #include <my_global.h> #include "sql_priv.h" #include "sql_select.h" +#include "uniques.h" /** Calculate the affordable RAM limit for structures like TREE or Unique @@ -496,37 +497,6 @@ Item *Item_sum::get_tmp_table_item(THD *thd) } -Field *Item_sum::create_tmp_field(bool group, TABLE *table) -{ - Field *UNINIT_VAR(field); - MEM_ROOT *mem_root= table->in_use->mem_root; - - switch (result_type()) { - case REAL_RESULT: - field= new (mem_root) - Field_double(max_length, maybe_null, name, decimals, TRUE); - break; - case INT_RESULT: - field= new (mem_root) - Field_longlong(max_length, maybe_null, name, unsigned_flag); - break; - case STRING_RESULT: - return make_string_field(table); - case DECIMAL_RESULT: - field= Field_new_decimal::create_from_item(mem_root, this); - break; - case ROW_RESULT: - case TIME_RESULT: - // This case should never be choosen - DBUG_ASSERT(0); - return 0; - } - if (field) - field->init(table); - return field; -} - - void Item_sum::update_used_tables () { if (!Item_sum::const_item()) @@ -677,32 +647,6 @@ int Aggregator_distinct::composite_key_cmp(void* arg, uchar* key1, uchar* key2) } -static enum enum_field_types -calc_tmp_field_type(enum enum_field_types table_field_type, - Item_result result_type) -{ - /* Adjust tmp table type according to the chosen aggregation type */ - switch (result_type) { - case STRING_RESULT: - case REAL_RESULT: - if (table_field_type != MYSQL_TYPE_FLOAT) - table_field_type= MYSQL_TYPE_DOUBLE; - break; - case INT_RESULT: - table_field_type= MYSQL_TYPE_LONGLONG; - /* fallthrough */ - case DECIMAL_RESULT: - if (table_field_type != MYSQL_TYPE_LONGLONG) - table_field_type= MYSQL_TYPE_NEWDECIMAL; - break; - case ROW_RESULT: - default: - DBUG_ASSERT(0); - } - return table_field_type; -} - - /***************************************************************************/ C_MODE_START @@ -879,8 +823,6 @@ bool Aggregator_distinct::setup(THD *thd) } else { - List<Create_field> field_list; - Create_field field_def; /* field definition */ Item *arg; DBUG_ENTER("Aggregator_distinct::setup"); /* It's legal to call setup() more than once when in a subquery */ @@ -892,8 +834,6 @@ bool Aggregator_distinct::setup(THD *thd) PS/SP. Hence all further allocations are performed in the runtime mem_root. */ - if (field_list.push_back(&field_def, thd->mem_root)) - DBUG_RETURN(TRUE); item_sum->null_value= item_sum->maybe_null= 1; item_sum->quick_group= 0; @@ -911,17 +851,8 @@ bool Aggregator_distinct::setup(THD *thd) if (always_null) DBUG_RETURN(FALSE); - enum enum_field_types field_type; - - field_type= calc_tmp_field_type(arg->field_type(), - arg->result_type()); - field_def.init_for_tmp_table(field_type, - arg->max_length, - arg->decimals, - arg->maybe_null, - arg->unsigned_flag); - - if (! (table= create_virtual_tmp_table(thd, field_list))) + Field *field= arg->make_num_distinct_aggregator_field(thd->mem_root, arg); + if (!field || !(table= create_virtual_tmp_table(thd, field))) DBUG_RETURN(TRUE); /* XXX: check that the case of CHAR(0) works OK */ @@ -1310,11 +1241,12 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table) check if the following assignments are really needed */ Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item) - :Item_sum_num(thd, item), hybrid_type(item->hybrid_type), + :Item_sum_num(thd, item), + Type_handler_hybrid_field_type(item), curr_dec_buff(item->curr_dec_buff) { /* TODO: check if the following assignments are really needed */ - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) { my_decimal2decimal(item->dec_buffs, dec_buffs); my_decimal2decimal(item->dec_buffs + 1, dec_buffs + 1); @@ -1333,7 +1265,7 @@ void Item_sum_sum::clear() { DBUG_ENTER("Item_sum_sum::clear"); null_value=1; - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) { curr_dec_buff= 0; my_decimal_set_zero(dec_buffs); @@ -1352,7 +1284,7 @@ void Item_sum_sum::fix_length_and_dec() switch (args[0]->cast_to_int_type()) { case REAL_RESULT: case STRING_RESULT: - hybrid_type= REAL_RESULT; + set_handler_by_field_type(MYSQL_TYPE_DOUBLE); sum= 0.0; break; case INT_RESULT: @@ -1365,7 +1297,7 @@ void Item_sum_sum::fix_length_and_dec() decimals, unsigned_flag); curr_dec_buff= 0; - hybrid_type= DECIMAL_RESULT; + set_handler_by_field_type(MYSQL_TYPE_NEWDECIMAL); my_decimal_set_zero(dec_buffs); break; } @@ -1373,9 +1305,9 @@ void Item_sum_sum::fix_length_and_dec() DBUG_ASSERT(0); } DBUG_PRINT("info", ("Type: %s (%d, %d)", - (hybrid_type == REAL_RESULT ? "REAL_RESULT" : - hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" : - hybrid_type == INT_RESULT ? "INT_RESULT" : + (result_type() == REAL_RESULT ? "REAL_RESULT" : + result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" : + result_type() == INT_RESULT ? "INT_RESULT" : "--ILLEGAL!!!--"), max_length, (int)decimals)); @@ -1386,7 +1318,7 @@ void Item_sum_sum::fix_length_and_dec() bool Item_sum_sum::add() { DBUG_ENTER("Item_sum_sum::add"); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) { my_decimal value; const my_decimal *val= aggr->arg_val_decimal(&value); @@ -1413,7 +1345,7 @@ longlong Item_sum_sum::val_int() DBUG_ASSERT(fixed == 1); if (aggr) aggr->endup(); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) { longlong result; my_decimal2int(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, unsigned_flag, @@ -1429,7 +1361,7 @@ double Item_sum_sum::val_real() DBUG_ASSERT(fixed == 1); if (aggr) aggr->endup(); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) my_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum); return sum; } @@ -1439,7 +1371,7 @@ String *Item_sum_sum::val_str(String *str) { if (aggr) aggr->endup(); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) return val_string_from_decimal(str); return val_string_from_real(str); } @@ -1449,7 +1381,7 @@ my_decimal *Item_sum_sum::val_decimal(my_decimal *val) { if (aggr) aggr->endup(); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) return (dec_buffs + curr_dec_buff); return val_decimal_from_real(val); } @@ -1625,7 +1557,7 @@ void Item_sum_avg::fix_length_and_dec() Item_sum_sum::fix_length_and_dec(); maybe_null=null_value=1; prec_increment= current_thd->variables.div_precincrement; - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_avg::result_type() == DECIMAL_RESULT) { int precision= args[0]->decimal_precision() + prec_increment; decimals= MY_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE); @@ -1663,11 +1595,11 @@ Field *Item_sum_avg::create_tmp_field(bool group, TABLE *table) and unpack on access. */ field= new (mem_root) - Field_string(((hybrid_type == DECIMAL_RESULT) ? + Field_string(((Item_sum_avg::result_type() == DECIMAL_RESULT) ? dec_bin_size : sizeof(double)) + sizeof(longlong), 0, name, &my_charset_bin); } - else if (hybrid_type == DECIMAL_RESULT) + else if (Item_sum_avg::result_type() == DECIMAL_RESULT) field= Field_new_decimal::create_from_item(mem_root, this); else field= new (mem_root) Field_double(max_length, maybe_null, name, decimals, @@ -1722,10 +1654,10 @@ my_decimal *Item_sum_avg::val_decimal(my_decimal *val) } /* - For non-DECIMAL hybrid_type the division will be done in + For non-DECIMAL result_type() the division will be done in Item_sum_avg::val_real(). */ - if (hybrid_type != DECIMAL_RESULT) + if (Item_sum_avg::result_type() != DECIMAL_RESULT) return val_decimal_from_real(val); sum_dec= dec_buffs + curr_dec_buff; @@ -1739,7 +1671,7 @@ String *Item_sum_avg::val_str(String *str) { if (aggr) aggr->endup(); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_avg::result_type() == DECIMAL_RESULT) return val_string_from_decimal(str); return val_string_from_real(str); } @@ -2306,7 +2238,7 @@ void Item_sum_hybrid::reset_field() void Item_sum_sum::reset_field() { DBUG_ASSERT (aggr->Aggrtype() != Aggregator::DISTINCT_AGGREGATOR); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) { my_decimal value, *arg_val= args[0]->val_decimal(&value); if (!arg_val) // Null @@ -2315,7 +2247,7 @@ void Item_sum_sum::reset_field() } else { - DBUG_ASSERT(hybrid_type == REAL_RESULT); + DBUG_ASSERT(result_type() == REAL_RESULT); double nr= args[0]->val_real(); // Nulls also return 0 float8store(result_field->ptr, nr); } @@ -2342,7 +2274,7 @@ void Item_sum_avg::reset_field() { uchar *res=result_field->ptr; DBUG_ASSERT (aggr->Aggrtype() != Aggregator::DISTINCT_AGGREGATOR); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_avg::result_type() == DECIMAL_RESULT) { longlong tmp; my_decimal value, *arg_dec= args[0]->val_decimal(&value); @@ -2396,7 +2328,7 @@ void Item_sum_bit::update_field() void Item_sum_sum::update_field() { DBUG_ASSERT (aggr->Aggrtype() != Aggregator::DISTINCT_AGGREGATOR); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_sum::result_type() == DECIMAL_RESULT) { my_decimal value, *arg_val= args[0]->val_decimal(&value); if (!args[0]->null_value) @@ -2451,7 +2383,7 @@ void Item_sum_avg::update_field() DBUG_ASSERT (aggr->Aggrtype() != Aggregator::DISTINCT_AGGREGATOR); - if (hybrid_type == DECIMAL_RESULT) + if (Item_sum_avg::result_type() == DECIMAL_RESULT) { my_decimal value, *arg_val= args[0]->val_decimal(&value); if (!args[0]->null_value) @@ -2490,7 +2422,7 @@ void Item_sum_avg::update_field() Item *Item_sum_avg::result_item(THD *thd, Field *field) { return - hybrid_type == DECIMAL_RESULT ? + Item_sum_avg::result_type() == DECIMAL_RESULT ? (Item_avg_field*) new (thd->mem_root) Item_avg_field_decimal(thd, this) : (Item_avg_field*) new (thd->mem_root) Item_avg_field_double(thd, this); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 11d2f802af7..811e9d5c59c 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -481,7 +481,10 @@ public: } virtual void make_unique() { force_copy_fields= TRUE; } Item *get_tmp_table_item(THD *thd); - virtual Field *create_tmp_field(bool group, TABLE *table); + Field *create_tmp_field(bool group, TABLE *table) + { + return Item::create_tmp_field(group, table, MY_INT32_NUM_DECIMAL_DIGITS); + } virtual bool collect_outer_ref_processor(uchar *param); bool init_sum_func_check(THD *thd); bool check_sum_func(THD *thd, Item **ref); @@ -714,15 +717,16 @@ public: String *val_str(String*str); my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return INT_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void fix_length_and_dec() { decimals=0; max_length=21; maybe_null=null_value=0; } }; -class Item_sum_sum :public Item_sum_num +class Item_sum_sum :public Item_sum_num, + public Type_handler_hybrid_field_type { protected: - Item_result hybrid_type; double sum; my_decimal dec_buffs[2]; uint curr_dec_buff; @@ -745,7 +749,12 @@ public: longlong val_int(); String *val_str(String*str); my_decimal *val_decimal(my_decimal *); - enum Item_result result_type () const { return hybrid_type; } + enum_field_types field_type() const + { return Type_handler_hybrid_field_type::field_type(); } + enum Item_result result_type () const + { return Type_handler_hybrid_field_type::result_type(); } + enum Item_result cmp_type () const + { return Type_handler_hybrid_field_type::cmp_type(); } void reset_field(); void update_field(); void no_rows_in_result() {} @@ -1084,7 +1093,6 @@ public: fixed= true; } table_map used_tables() const { return (table_map) 1L; } - Field *tmp_table_field(TABLE *) { DBUG_ASSERT(0); return NULL; } void set_result_field(Field *) { DBUG_ASSERT(0); } void save_in_result_field(bool no_conversions) { DBUG_ASSERT(0); } }; @@ -1255,6 +1263,9 @@ class Item_sum_udf_float :public Item_udf_sum double val_real(); String *val_str(String*str); my_decimal *val_decimal(my_decimal *); + enum Item_result result_type () const { return REAL_RESULT; } + enum Item_result cmp_type () const { return REAL_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } void fix_length_and_dec() { fix_num_length_and_dec(); } Item *copy_or_same(THD* thd); }; @@ -1275,6 +1286,7 @@ public: String *val_str(String*str); my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return INT_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void fix_length_and_dec() { decimals=0; max_length=21; } Item *copy_or_same(THD* thd); }; @@ -1314,6 +1326,7 @@ public: } my_decimal *val_decimal(my_decimal *dec); enum Item_result result_type () const { return STRING_RESULT; } + enum_field_types field_type() const { return string_field_type(); } void fix_length_and_dec(); Item *copy_or_same(THD* thd); }; @@ -1333,6 +1346,7 @@ public: longlong val_int(); my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return DECIMAL_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; } void fix_length_and_dec() { fix_num_length_and_dec(); } Item *copy_or_same(THD* thd); }; @@ -1468,6 +1482,8 @@ class Item_func_group_concat : public Item_sum friend int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), void* item_arg); +protected: + virtual Field *make_string_field(TABLE *table); public: Item_func_group_concat(THD *thd, Name_resolution_context *context_arg, @@ -1481,7 +1497,7 @@ public: enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} const char *func_name() const { return "group_concat"; } virtual Item_result result_type () const { return STRING_RESULT; } - virtual Field *make_string_field(TABLE *table); + virtual Item_result cmp_type () const { return STRING_RESULT; } enum_field_types field_type() const { if (too_big_for_varchar()) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 991dde632e2..16edb35c392 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1558,9 +1558,9 @@ String *Item_temporal_hybrid_func::val_str_ascii(String *str) return (String *) 0; /* Check that the returned timestamp type matches to the function type */ - DBUG_ASSERT(cached_field_type == MYSQL_TYPE_STRING || + DBUG_ASSERT(field_type() == MYSQL_TYPE_STRING || ltime.time_type == MYSQL_TIMESTAMP_NONE || - mysql_type_to_time_type(cached_field_type) == ltime.time_type); + mysql_type_to_time_type(field_type()) == ltime.time_type); return str; } @@ -2081,7 +2081,7 @@ void Item_date_add_interval::fix_length_and_dec() (This is because you can't know if the string contains a DATE, MYSQL_TIME or DATETIME argument) */ - cached_field_type= MYSQL_TYPE_STRING; + set_handler_by_field_type(MYSQL_TYPE_STRING); arg0_field_type= args[0]->field_type(); uint interval_dec= 0; if (int_type == INTERVAL_MICROSECOND || @@ -2095,25 +2095,25 @@ void Item_date_add_interval::fix_length_and_dec() arg0_field_type == MYSQL_TYPE_TIMESTAMP) { decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec); - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); } else if (arg0_field_type == MYSQL_TYPE_DATE) { if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH) - cached_field_type= arg0_field_type; + set_handler_by_field_type(arg0_field_type); else { decimals= interval_dec; - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); } } else if (arg0_field_type == MYSQL_TYPE_TIME) { decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME), interval_dec); if (int_type >= INTERVAL_DAY && int_type != INTERVAL_YEAR_MONTH) - cached_field_type= arg0_field_type; + set_handler_by_field_type(arg0_field_type); else - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); } else decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec); @@ -2126,7 +2126,7 @@ bool Item_date_add_interval::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) INTERVAL interval; if (args[0]->get_date(ltime, - cached_field_type == MYSQL_TYPE_TIME ? + field_type() == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0) || get_interval_value(args[1], int_type, &interval)) return (null_value=1); @@ -2630,20 +2630,20 @@ void Item_func_add_time::fix_length_and_dec() - Otherwise the result is MYSQL_TYPE_STRING */ - cached_field_type= MYSQL_TYPE_STRING; + set_handler_by_field_type(MYSQL_TYPE_STRING); arg0_field_type= args[0]->field_type(); if (arg0_field_type == MYSQL_TYPE_DATE || arg0_field_type == MYSQL_TYPE_DATETIME || arg0_field_type == MYSQL_TYPE_TIMESTAMP || is_date) { - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), args[1]->temporal_precision(MYSQL_TYPE_TIME)); } else if (arg0_field_type == MYSQL_TYPE_TIME) { - cached_field_type= MYSQL_TYPE_TIME; + set_handler_by_field_type(MYSQL_TYPE_TIME); decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME), args[1]->temporal_precision(MYSQL_TYPE_TIME)); } @@ -2669,7 +2669,7 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) longlong seconds; int l_sign= sign; - if (cached_field_type == MYSQL_TYPE_DATETIME) + if (Item_func_add_time::field_type() == MYSQL_TYPE_DATETIME) { // TIMESTAMP function OR the first argument is DATE/DATETIME/TIMESTAMP if (get_arg0_date(&l_time1, 0) || @@ -3149,7 +3149,7 @@ void Item_func_str_to_date::fix_length_and_dec() #endif } - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); decimals= TIME_SECOND_PART_DIGITS; if ((const_item= args[1]->const_item())) { @@ -3164,24 +3164,24 @@ void Item_func_str_to_date::fix_length_and_dec() get_date_time_result_type(format->ptr(), format->length()); switch (cached_format_type) { case DATE_ONLY: - cached_field_type= MYSQL_TYPE_DATE; + set_handler_by_field_type(MYSQL_TYPE_DATE); break; case TIME_MICROSECOND: decimals= 6; /* fall through */ case TIME_ONLY: - cached_field_type= MYSQL_TYPE_TIME; + set_handler_by_field_type(MYSQL_TYPE_TIME); break; case DATE_TIME_MICROSECOND: decimals= 6; /* fall through */ case DATE_TIME: - cached_field_type= MYSQL_TYPE_DATETIME; + set_handler_by_field_type(MYSQL_TYPE_DATETIME); break; } } } - cached_timestamp_type= mysql_type_to_time_type(cached_field_type); + cached_timestamp_type= mysql_type_to_time_type(field_type()); Item_temporal_func::fix_length_and_dec(); } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index bb840987089..175f3b06c1a 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -165,6 +165,7 @@ public: } const char *func_name() const { return "month"; } enum Item_result result_type () const { return INT_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void fix_length_and_dec() { decimals= 0; @@ -379,6 +380,7 @@ public: return (odbc_type ? "dayofweek" : "weekday"); } enum Item_result result_type () const { return INT_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void fix_length_and_dec() { decimals= 0; @@ -401,6 +403,7 @@ class Item_func_dayname :public Item_func_weekday const char *func_name() const { return "dayname"; } String *val_str(String *str); enum Item_result result_type () const { return STRING_RESULT; } + enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } void fix_length_and_dec(); bool check_partition_func_processor(uchar *int_arg) {return TRUE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -492,7 +495,6 @@ public: Item_temporal_func(THD *thd, Item *a, Item *b): Item_func(thd, a, b) {} Item_temporal_func(THD *thd, Item *a, Item *b, Item *c): Item_func(thd, a, b, c) {} enum Item_result result_type () const { return STRING_RESULT; } - enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } Item_result cmp_type() const { return TIME_RESULT; } String *val_str(String *str); longlong val_int() { return val_int_from_date(); } @@ -500,7 +502,7 @@ public: bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date) { DBUG_ASSERT(0); return 1; } my_decimal *val_decimal(my_decimal *decimal_value) { return val_decimal_from_date(decimal_value); } - Field *tmp_table_field(TABLE *table) + Field *create_field_for_create_select(THD *thd, TABLE *table) { return tmp_table_field_from_field_type(table, false, false); } int save_in_field(Field *field, bool no_conversions) { return save_date_in_field(field); } @@ -512,20 +514,20 @@ public: Abstract class for functions returning TIME, DATE, DATETIME or string values, whose data type depends on parameters and is set at fix_fields time. */ -class Item_temporal_hybrid_func: public Item_temporal_func +class Item_temporal_hybrid_func: public Item_temporal_func, + public Type_handler_hybrid_field_type { protected: - enum_field_types cached_field_type; // TIME, DATE, DATETIME or STRING String ascii_buf; // Conversion buffer public: Item_temporal_hybrid_func(THD *thd, Item *a, Item *b): Item_temporal_func(thd, a, b) {} - enum_field_types field_type() const { return cached_field_type; } - Item_result cmp_type() const - { - return cached_field_type == MYSQL_TYPE_STRING ? - STRING_RESULT : TIME_RESULT; - } + enum_field_types field_type() const + { return Type_handler_hybrid_field_type::field_type(); } + enum Item_result result_type () const + { return Type_handler_hybrid_field_type::result_type(); } + enum Item_result cmp_type () const + { return Type_handler_hybrid_field_type::cmp_type(); } CHARSET_INFO *charset_for_protocol() const { /* @@ -535,7 +537,7 @@ public: (which is fixed from @@collation_connection in fix_length_and_dec). */ DBUG_ASSERT(fixed == 1); - return cached_field_type == MYSQL_TYPE_STRING ? + return Item_temporal_hybrid_func::field_type() == MYSQL_TYPE_STRING ? collation.collation : &my_charset_bin; } /** @@ -578,6 +580,17 @@ public: }; +class Item_datetimefunc :public Item_temporal_func +{ +public: + Item_datetimefunc(THD *thd): Item_temporal_func(thd) {} + Item_datetimefunc(THD *thd, Item *a): Item_temporal_func(thd, a) {} + Item_datetimefunc(THD *thd, Item *a, Item *b, Item *c): + Item_temporal_func(thd, a, b ,c) {} + enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } +}; + + /* Abstract CURTIME function. Children should define what time zone is used */ class Item_func_curtime :public Item_timefunc @@ -662,11 +675,11 @@ public: /* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */ -class Item_func_now :public Item_temporal_func +class Item_func_now :public Item_datetimefunc { MYSQL_TIME ltime; public: - Item_func_now(THD *thd, uint dec): Item_temporal_func(thd) { decimals= dec; } + Item_func_now(THD *thd, uint dec): Item_datetimefunc(thd) { decimals= dec; } bool fix_fields(THD *, Item **); void fix_length_and_dec() { @@ -756,11 +769,11 @@ public: }; -class Item_func_from_unixtime :public Item_temporal_func +class Item_func_from_unixtime :public Item_datetimefunc { Time_zone *tz; public: - Item_func_from_unixtime(THD *thd, Item *a): Item_temporal_func(thd, a) {} + Item_func_from_unixtime(THD *thd, Item *a): Item_datetimefunc(thd, a) {} const char *func_name() const { return "from_unixtime"; } void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); @@ -781,7 +794,7 @@ class Time_zone; tables can be used during this function calculation for loading time zone descriptions. */ -class Item_func_convert_tz :public Item_temporal_func +class Item_func_convert_tz :public Item_datetimefunc { /* If time zone parameters are constants we are caching objects that @@ -793,7 +806,7 @@ class Item_func_convert_tz :public Item_temporal_func Time_zone *from_tz, *to_tz; public: Item_func_convert_tz(THD *thd, Item *a, Item *b, Item *c): - Item_temporal_func(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {} + Item_datetimefunc(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {} const char *func_name() const { return "convert_tz"; } void fix_length_and_dec(); bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index c1140946e87..ba17d2c48c3 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2603,8 +2603,7 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath) (spv= spc->find_variable(name, false))) { Item_splocal *splocal= new (thd->mem_root) - Item_splocal(thd, name, spv->offset, - spv->type, 0); + Item_splocal(thd, name, spv->offset, spv->sql_type(), 0); #ifndef DBUG_OFF if (splocal) splocal->m_sp= lex->sphead; diff --git a/sql/lex.h b/sql/lex.h index 22ff4e6d360..da5fa2de137 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -470,6 +470,7 @@ static SYMBOL symbols[] = { { "REAL", SYM(REAL)}, { "REBUILD", SYM(REBUILD_SYM)}, { "RECOVER", SYM(RECOVER_SYM)}, + { "RECURSIVE", SYM(RECURSIVE_SYM)}, { "REDO_BUFFER_SIZE", SYM(REDO_BUFFER_SIZE_SYM)}, { "REDOFILE", SYM(REDOFILE_SYM)}, { "REDUNDANT", SYM(REDUNDANT_SYM)}, diff --git a/sql/log.cc b/sql/log.cc index 6e11f4bbe5d..dc8c08bfd36 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1674,14 +1674,14 @@ static int binlog_close_connection(handlerton *hton, THD *thd) uchar *buf; size_t len=0; wsrep_write_cache_buf(cache, &buf, &len); - WSREP_WARN("binlog trx cache not empty (%lu bytes) @ connection close %lu", - len, thd->thread_id); + WSREP_WARN("binlog trx cache not empty (%lu bytes) @ connection close %lld", + len, (longlong) thd->thread_id); if (len > 0) wsrep_dump_rbr_buf(thd, buf, len); cache = cache_mngr->get_binlog_cache_log(false); wsrep_write_cache_buf(cache, &buf, &len); - WSREP_WARN("binlog stmt cache not empty (%lu bytes) @ connection close %lu", - len, thd->thread_id); + WSREP_WARN("binlog stmt cache not empty (%lu bytes) @ connection close %lld", + len, (longlong) thd->thread_id); if (len > 0) wsrep_dump_rbr_buf(thd, buf, len); } #endif /* WITH_WSREP */ @@ -6582,7 +6582,6 @@ int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate) DBUG_ENTER("MYSQL_BIN_LOG::rotate_and_purge"); bool check_purge= false; - //todo: fix the macro def and restore safe_mutex_assert_not_owner(&LOCK_log); mysql_mutex_lock(&LOCK_log); prev_binlog_id= current_binlog_id; if ((error= rotate(force_rotate, &check_purge))) @@ -9508,9 +9507,7 @@ binlog_background_thread(void *arg __attribute__((unused))) thd= new THD; thd->system_thread= SYSTEM_THREAD_BINLOG_BACKGROUND; thd->thread_stack= (char*) &thd; /* Set approximate stack start */ - mysql_mutex_lock(&LOCK_thread_count); - thd->thread_id= thread_id++; - mysql_mutex_unlock(&LOCK_thread_count); + thd->thread_id= next_thread_id(); thd->store_globals(); thd->security_ctx->skip_grants(); thd->set_command(COM_DAEMON); @@ -9597,9 +9594,8 @@ binlog_background_thread(void *arg __attribute__((unused))) THD_STAGE_INFO(thd, stage_binlog_stopping_background_thread); - mysql_mutex_lock(&LOCK_thread_count); + /* No need to use mutex as thd is not linked into other threads */ delete thd; - mysql_mutex_unlock(&LOCK_thread_count); my_thread_end(); @@ -10183,7 +10179,8 @@ IO_CACHE * get_trans_log(THD * thd) if (cache_mngr) return cache_mngr->get_binlog_cache_log(true); - WSREP_DEBUG("binlog cache not initialized, conn :%ld", thd->thread_id); + WSREP_DEBUG("binlog cache not initialized, conn: %lld", + (longlong) thd->thread_id); return NULL; } @@ -10221,7 +10218,8 @@ void thd_binlog_trx_reset(THD * thd) void thd_binlog_rollback_stmt(THD * thd) { - WSREP_DEBUG("thd_binlog_rollback_stmt :%ld", thd->thread_id); + WSREP_DEBUG("thd_binlog_rollback_stmt connection: %lld", + (longlong) thd->thread_id); binlog_cache_mngr *const cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); if (cache_mngr) diff --git a/sql/log_event.cc b/sql/log_event.cc index ea0afddafbe..b56a9e2aee3 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4438,7 +4438,8 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, } thd->enable_slow_log= thd->variables.sql_log_slow; - mysql_parse(thd, thd->query(), thd->query_length(), &parser_state); + mysql_parse(thd, thd->query(), thd->query_length(), &parser_state, + FALSE); /* Finalize server status flags after executing a statement. */ thd->update_server_status(); log_slow_statement(thd); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ced922536fc..e7d7f90d44e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -363,6 +363,7 @@ static bool volatile select_thread_in_use, signal_thread_in_use; static volatile bool ready_to_exit; static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0; static my_bool opt_short_log_format= 0, opt_silent_startup= 0; + uint kill_cached_threads; static uint wake_thread; ulong max_used_connections; @@ -377,7 +378,7 @@ static char *default_collation_name; char *default_storage_engine, *default_tmp_storage_engine; char *enforced_storage_engine=NULL; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; -static I_List<THD> thread_cache; +static I_List<CONNECT> thread_cache; static bool binlog_format_used= false; LEX_STRING opt_init_connect, opt_init_slave; mysql_cond_t COND_thread_cache; @@ -389,6 +390,7 @@ static DYNAMIC_ARRAY all_options; bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0; my_bool opt_log, debug_assert_if_crashed_table= 0, opt_help= 0; +my_bool debug_assert_on_not_freed_memory= 0; my_bool disable_log_notes; static my_bool opt_abort; ulonglong log_output_options; @@ -409,8 +411,7 @@ uint volatile global_disable_checkpoint; ulong slow_start_timeout; #endif /* - True if the bootstrap thread is running. Protected by LOCK_thread_count, - just like thread_count. + True if the bootstrap thread is running. Protected by LOCK_start_thread. Used in bootstrap() function to determine if the bootstrap thread has completed. Note, that we can't use 'thread_count' instead, since in 5.1, in presence of the Event Scheduler, there may be @@ -422,7 +423,7 @@ ulong slow_start_timeout; bootstrap either, since we want to be able to process event-related SQL commands in the init file and in --bootstrap mode. */ -bool in_bootstrap= FALSE; +bool volatile in_bootstrap= FALSE; /** @brief 'grant_option' is used to indicate if privileges needs to be checked, in which case the lock, LOCK_grant, is used @@ -556,7 +557,8 @@ ulong max_prepared_stmt_count; statements. */ ulong prepared_stmt_count=0; -ulong thread_id=1L,current_pid; +my_thread_id global_thread_id= 1; +ulong current_pid; ulong slow_launch_threads = 0; uint sync_binlog_period= 0, sync_relaylog_period= 0, sync_relayloginfo_period= 0, sync_masterinfo_period= 0; @@ -631,7 +633,7 @@ DATE_TIME_FORMAT global_date_format, global_datetime_format, global_time_format; Time_zone *default_tz; const char *mysql_real_data_home_ptr= mysql_real_data_home; -char server_version[SERVER_VERSION_LENGTH]; +char server_version[SERVER_VERSION_LENGTH], *server_version_ptr; char *mysqld_unix_port, *opt_mysql_tmpdir; ulong thread_handling; @@ -711,9 +713,34 @@ SHOW_COMP_OPTION have_openssl; /* Thread specific variables */ -pthread_key(MEM_ROOT**,THR_MALLOC); pthread_key(THD*, THR_THD); -mysql_mutex_t LOCK_thread_count, LOCK_thread_cache; + +/* + LOCK_thread_count protects the following variables: + thread_count Number of threads with THD that servers queries. + threads Linked list of active THD's. + The effect of this is that one can't unlink and + delete a THD as long as one has locked + LOCK_thread_count. + ready_to_exit + delayed_insert_threads +*/ +mysql_mutex_t LOCK_thread_count; + +/* + LOCK_start_thread is used to syncronize thread start and stop with + other threads. + + It also protects these variables: + handler_count + in_bootstrap + select_thread_in_use + slave_init_thread_running + check_temp_dir() call +*/ +mysql_mutex_t LOCK_start_thread; + +mysql_mutex_t LOCK_thread_cache; mysql_mutex_t LOCK_status, LOCK_show_status, LOCK_error_log, LOCK_short_uuid_generator, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, @@ -738,7 +765,7 @@ mysql_mutex_t LOCK_des_key_file; #endif mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; mysql_rwlock_t LOCK_system_variables_hash; -mysql_cond_t COND_thread_count; +mysql_cond_t COND_thread_count, COND_start_thread; pthread_t signal_thread; pthread_attr_t connection_attrib; mysql_mutex_t LOCK_server_started; @@ -888,6 +915,7 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages, key_LOG_INFO_lock, + key_LOCK_start_thread, key_LOCK_thread_count, key_LOCK_thread_cache, key_PARTITION_LOCK_auto_inc; PSI_mutex_key key_RELAYLOG_LOCK_index; @@ -974,6 +1002,7 @@ static PSI_mutex_info all_server_mutexes[]= { &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL}, { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0}, { &key_LOCK_slave_state, "LOCK_slave_state", 0}, + { &key_LOCK_start_thread, "LOCK_start_thread", PSI_FLAG_GLOBAL}, { &key_LOCK_binlog_state, "LOCK_binlog_state", 0}, { &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0}, { &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 0}, @@ -1015,6 +1044,7 @@ PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond, key_rpl_group_info_sleep_cond, key_TABLE_SHARE_cond, key_user_level_lock_cond, key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache, + key_COND_start_thread, key_BINLOG_COND_queue_busy; PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready, key_COND_wait_commit; @@ -1074,6 +1104,7 @@ static PSI_cond_info all_server_conds[]= { &key_COND_group_commit_orderer, "COND_group_commit_orderer", 0}, { &key_COND_prepare_ordered, "COND_prepare_ordered", 0}, { &key_COND_slave_init, "COND_slave_init", 0}, + { &key_COND_start_thread, "COND_start_thread", PSI_FLAG_GLOBAL}, { &key_COND_wait_gtid, "COND_wait_gtid", 0}, { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0} }; @@ -1200,8 +1231,13 @@ void init_net_server_extension(THD *thd) /* Activate this private extension for the mysqld server. */ thd->net.extension= & thd->m_net_server_extension; } +#else +void init_net_server_extension(THD *thd) +{ +} #endif /* EMBEDDED_LIBRARY */ + /** A log message for the error log, buffered in memory. Log messages are temporarily buffered when generated before the error log @@ -1545,8 +1581,8 @@ static void close_connections(void) #if !defined(__WIN__) DBUG_PRINT("quit", ("waiting for select thread: 0x%lx", (ulong) select_thread)); - mysql_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_start_thread); while (select_thread_in_use) { struct timespec abstime; @@ -1560,7 +1596,7 @@ static void close_connections(void) set_timespec(abstime, 2); for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++) { - error= mysql_cond_timedwait(&COND_thread_count, &LOCK_thread_count, + error= mysql_cond_timedwait(&COND_start_thread, &LOCK_start_thread, &abstime); if (error != EINTR) break; @@ -1571,7 +1607,7 @@ static void close_connections(void) #endif close_server_sock(); } - mysql_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_start_thread); #endif /* __WIN__ */ @@ -1640,7 +1676,7 @@ static void close_connections(void) while ((tmp=it++)) { DBUG_PRINT("quit",("Informing thread %ld that it's time to die", - tmp->thread_id)); + (ulong) tmp->thread_id)); /* We skip slave threads & scheduler on this first loop through. */ if (tmp->slave_thread) continue; @@ -1696,6 +1732,8 @@ static void close_connections(void) much smaller than even 2 seconds, this is only a safety fallback against stuck threads so server shutdown is not held up forever. */ + DBUG_PRINT("info", ("thread_count: %d", thread_count)); + for (int i= 0; *(volatile int32*) &thread_count && i < 1000; i++) my_sleep(20000); @@ -1707,11 +1745,9 @@ static void close_connections(void) for (;;) { - DBUG_PRINT("quit",("Locking LOCK_thread_count")); mysql_mutex_lock(&LOCK_thread_count); // For unlink from list if (!(tmp=threads.get())) { - DBUG_PRINT("quit",("Unlocking LOCK_thread_count")); mysql_mutex_unlock(&LOCK_thread_count); break; } @@ -1720,12 +1756,13 @@ static void close_connections(void) { if (global_system_variables.log_warnings) sql_print_warning(ER_DEFAULT(ER_FORCING_CLOSE),my_progname, - tmp->thread_id, + (ulong) tmp->thread_id, (tmp->main_security_ctx.user ? tmp->main_security_ctx.user : "")); close_connection(tmp,ER_SERVER_SHUTDOWN); } #endif + #ifdef WITH_WSREP /* * WSREP_TODO: @@ -1807,10 +1844,35 @@ static void close_server_sock() #endif /*EMBEDDED_LIBRARY*/ -void kill_mysql(void) +/** + Set shutdown user + + @note this function may be called by multiple threads concurrently, thus + it performs safe update of shutdown_user (first thread wins). +*/ + +static volatile char *shutdown_user; +static void set_shutdown_user(THD *thd) +{ + char user_host_buff[MAX_USER_HOST_SIZE + 1]; + char *user, *expected_shutdown_user= 0; + + make_user_name(thd, user_host_buff); + + if ((user= my_strdup(user_host_buff, MYF(0))) && + !my_atomic_casptr((void **) &shutdown_user, + (void **) &expected_shutdown_user, user)) + my_free(user); +} + + +void kill_mysql(THD *thd) { DBUG_ENTER("kill_mysql"); + if (thd) + set_shutdown_user(thd); + #if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY) abort_loop=1; // Break connection loops close_server_sock(); // Force accept to wake up @@ -1889,7 +1951,13 @@ static void __cdecl kill_server(int sig_ptr) if (sig != 0) // 0 is not a valid signal number my_sigset(sig, SIG_IGN); /* purify inspected */ if (sig == MYSQL_KILL_SIGNAL || sig == 0) - sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN),my_progname); + { + char *user= (char *) my_atomic_loadptr((void**) &shutdown_user); + sql_print_information(ER_DEFAULT(ER_NORMAL_SHUTDOWN), my_progname, + user ? user : "unknown"); + if (user) + my_free(user); + } else sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */ @@ -1961,7 +2029,8 @@ pthread_handler_t kill_server_thread(void *arg __attribute__((unused))) extern "C" sig_handler print_signal_warning(int sig) { if (global_system_variables.log_warnings) - sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id()); + sql_print_warning("Got signal %d from thread %ld", sig, + (ulong) my_thread_id()); #ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(sig,print_signal_warning); /* int. thread system calls */ #endif @@ -2051,8 +2120,6 @@ static void cleanup_tls() { if (THR_THD) (void)pthread_key_delete(THR_THD); - if (THR_MALLOC) - (void)pthread_key_delete(THR_MALLOC); } @@ -2074,6 +2141,7 @@ static void mysqld_exit(int exit_code) #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE shutdown_performance_schema(); // we do it as late as possible #endif + set_malloc_size_cb(NULL); cleanup_tls(); DBUG_LEAVE; sd_notify(0, "STATUS=MariaDB server is down"); @@ -2177,10 +2245,14 @@ void clean_up(bool print_message) logger.cleanup_end(); sys_var_end(); free_charsets(); + + /* + Signal mysqld_main() that it can exit + do the broadcast inside the lock to ensure that my_end() is not called + during broadcast() + */ mysql_mutex_lock(&LOCK_thread_count); - DBUG_PRINT("quit", ("got thread count lock")); ready_to_exit=1; - /* do the broadcast inside the lock to ensure that my_end() is not called */ mysql_cond_broadcast(&COND_thread_count); mysql_mutex_unlock(&LOCK_thread_count); @@ -2228,6 +2300,7 @@ static void clean_up_mutexes() mysql_rwlock_destroy(&LOCK_grant); mysql_mutex_destroy(&LOCK_thread_count); mysql_mutex_destroy(&LOCK_thread_cache); + mysql_mutex_destroy(&LOCK_start_thread); mysql_mutex_destroy(&LOCK_status); mysql_mutex_destroy(&LOCK_show_status); mysql_mutex_destroy(&LOCK_delayed_insert); @@ -2261,6 +2334,7 @@ static void clean_up_mutexes() mysql_mutex_destroy(&LOCK_error_messages); mysql_cond_destroy(&COND_thread_count); mysql_cond_destroy(&COND_thread_cache); + mysql_cond_destroy(&COND_start_thread); mysql_cond_destroy(&COND_flush_thread_cache); mysql_mutex_destroy(&LOCK_server_started); mysql_cond_destroy(&COND_server_started); @@ -2282,7 +2356,9 @@ static void clean_up_mutexes() static void set_ports() { } - +void close_connection(THD *thd, uint sql_errno) +{ +} #else static void set_ports() { @@ -2764,6 +2840,7 @@ static void network_init(void) @note For the connection that is doing shutdown, this is called twice */ + void close_connection(THD *thd, uint sql_errno) { DBUG_ENTER("close_connection"); @@ -2799,20 +2876,6 @@ extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused))) DBUG_VOID_RETURN; /* purecov: deadcode */ } - -/* - Cleanup THD object - - SYNOPSIS - thd_cleanup() - thd Thread handler -*/ - -void thd_cleanup(THD *thd) -{ - thd->cleanup(); -} - /* Decrease number of connections @@ -2820,43 +2883,49 @@ void thd_cleanup(THD *thd) dec_connection_count() */ -void dec_connection_count(THD *thd) +void dec_connection_count(scheduler_functions *scheduler) { -#ifdef WITH_WSREP - /* - Do not decrement when its wsrep system thread. wsrep_applier is set for - applier as well as rollbacker threads. - */ - if (thd->wsrep_applier) - return; -#endif /* WITH_WSREP */ - - DBUG_ASSERT(*thd->scheduler->connection_count > 0); mysql_mutex_lock(&LOCK_connection_count); - (*thd->scheduler->connection_count)--; + (*scheduler->connection_count)--; mysql_mutex_unlock(&LOCK_connection_count); } /* Delete THD and decrement thread counters, including thread_running + + This is mainly used to delete event threads which are not increasing + global counters. */ void delete_running_thd(THD *thd) { - mysql_mutex_lock(&LOCK_thread_count); - thd->unlink(); - mysql_mutex_unlock(&LOCK_thread_count); + thd->add_status_to_global(); + unlink_not_visible_thd(thd); delete thd; dec_thread_running(); + dec_thread_count(); +} + +/* + Decrease number of threads. Signal when it reaches 0 + + SYNOPSIS + dec_thread_count() +*/ + +void dec_thread_count(void) +{ + DBUG_ASSERT(thread_count > 0); thread_safe_decrement32(&thread_count); signal_thd_deleted(); } + /* - Send a signal to unblock close_conneciton() if there is no more - threads running with a THD attached + Send a signal to unblock close_conneciton() / rpl_slave_init_thread() + if there is no more threads running with a THD attached It's safe to check for thread_count and service_thread_count outside of a mutex as we are only interested to see if they where decremented @@ -2868,7 +2937,7 @@ void delete_running_thd(THD *thd) void signal_thd_deleted() { - if (!thread_count && ! service_thread_count) + if (!thread_count && !service_thread_count) { /* Signal close_connections() that all THD's are freed */ mysql_mutex_lock(&LOCK_thread_count); @@ -2884,9 +2953,6 @@ void signal_thd_deleted() SYNOPSIS unlink_thd() thd Thread handler - - NOTES - LOCK_thread_count is locked and left locked */ void unlink_thd(THD *thd) @@ -2894,23 +2960,18 @@ void unlink_thd(THD *thd) DBUG_ENTER("unlink_thd"); DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); - thd_cleanup(thd); - dec_connection_count(thd); - - thd->add_status_to_global(); - - mysql_mutex_lock(&LOCK_thread_count); - thd->unlink(); /* - Used by binlog_reset_master. It would be cleaner to use - DEBUG_SYNC here, but that's not possible because the THD's debug - sync feature has been shut down at this point. + Do not decrement when its wsrep system thread. wsrep_applier is set for + applier as well as rollbacker threads. */ - DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5);); - mysql_mutex_unlock(&LOCK_thread_count); + if (IF_WSREP(!thd->wsrep_applier, 1)) + dec_connection_count(thd->scheduler); + thd->cleanup(); + thd->add_status_to_global(); + unlink_not_visible_thd(thd); delete thd; - thread_safe_decrement32(&thread_count); + dec_thread_count(); DBUG_VOID_RETURN; } @@ -2934,6 +2995,7 @@ void unlink_thd(THD *thd) static bool cache_thread() { + struct timespec abstime; DBUG_ENTER("cache_thread"); mysql_mutex_lock(&LOCK_thread_cache); @@ -2952,18 +3014,46 @@ static bool cache_thread() PSI_THREAD_CALL(delete_current_thread)(); #endif +#ifndef DBUG_OFF + while (_db_is_pushed_()) + _db_pop_(); +#endif + + set_timespec(abstime, THREAD_CACHE_TIMEOUT); while (!abort_loop && ! wake_thread && ! kill_cached_threads) - mysql_cond_wait(&COND_thread_cache, &LOCK_thread_cache); + { + int error= mysql_cond_timedwait(&COND_thread_cache, &LOCK_thread_cache, + &abstime); + if (error == ETIMEDOUT || error == ETIME) + { + /* + If timeout, end thread. + If a new thread is requested (wake_thread is set), we will handle + the call, even if we got a timeout (as we are already awake and free) + */ + break; + } + } cached_thread_count--; if (kill_cached_threads) mysql_cond_signal(&COND_flush_thread_cache); if (wake_thread) { + CONNECT *connect; THD *thd; + wake_thread--; - thd= thread_cache.get(); + connect= thread_cache.get(); mysql_mutex_unlock(&LOCK_thread_cache); + if (!(thd= connect->create_thd())) + { + /* Out of resources. Free thread to get more resources */ + connect->close_and_delete(); + DBUG_RETURN(0); + } + delete connect; + thd->thread_stack= (char*) &thd; // For store_globals (void) thd->store_globals(); @@ -2986,10 +3076,7 @@ static bool cache_thread() thd->thr_create_utime= microsecond_interval_timer(); thd->start_utime= thd->thr_create_utime; - /* Link thd into list of all active threads (THD's) */ - mysql_mutex_lock(&LOCK_thread_count); - threads.append(thd); - mysql_mutex_unlock(&LOCK_thread_count); + add_to_active_threads(thd); DBUG_RETURN(1); } } @@ -3003,7 +3090,7 @@ static bool cache_thread() SYNOPSIS one_thread_per_connection_end() - thd Thread handler + thd Thread handler. This may be null if we run out of resources. put_in_cache Store thread in cache, if there is room in it Normally this is true in all cases except when we got out of resources initializing the current thread @@ -3022,12 +3109,13 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) DBUG_ENTER("one_thread_per_connection_end"); const bool wsrep_applier= IF_WSREP(thd->wsrep_applier, false); - unlink_thd(thd); + if (thd) + unlink_thd(thd); if (!wsrep_applier && put_in_cache && cache_thread()) DBUG_RETURN(0); // Thread is reused - signal_thd_deleted(); + DBUG_PRINT("info", ("killing thread")); DBUG_LEAVE; // Must match DBUG_ENTER() #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) ERR_remove_state(0); @@ -3395,7 +3483,7 @@ static void start_signal_handler(void) (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); (void) my_setstacksize(&thr_attr,my_thread_stack_size); - mysql_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_start_thread); if ((error= mysql_thread_create(key_thread_signal_hand, &signal_thread, &thr_attr, signal_hand, 0))) { @@ -3403,8 +3491,8 @@ static void start_signal_handler(void) error,errno); exit(1); } - mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); + mysql_cond_wait(&COND_start_thread, &LOCK_start_thread); + mysql_mutex_unlock(&LOCK_start_thread); (void) pthread_attr_destroy(&thr_attr); DBUG_VOID_RETURN; @@ -3454,12 +3542,12 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) signal to start_signal_handler that we are ready This works by waiting for start_signal_handler to free mutex, after which we signal it that we are ready. - At this pointer there is no other threads running, so there + At this point there is no other threads running, so there should not be any other mysql_cond_signal() calls. */ - mysql_mutex_lock(&LOCK_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); - mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_lock(&LOCK_start_thread); + mysql_cond_broadcast(&COND_start_thread); + mysql_mutex_unlock(&LOCK_start_thread); (void) pthread_sigmask(SIG_BLOCK,&set,NULL); for (;;) @@ -3760,6 +3848,7 @@ SHOW_VAR com_status_vars[]= { {"alter_server", STMT_STATUS(SQLCOM_ALTER_SERVER)}, {"alter_table", STMT_STATUS(SQLCOM_ALTER_TABLE)}, {"alter_tablespace", STMT_STATUS(SQLCOM_ALTER_TABLESPACE)}, + {"alter_user", STMT_STATUS(SQLCOM_ALTER_USER)}, {"analyze", STMT_STATUS(SQLCOM_ANALYZE)}, {"assign_to_keycache", STMT_STATUS(SQLCOM_ASSIGN_TO_KEYCACHE)}, {"begin", STMT_STATUS(SQLCOM_BEGIN)}, @@ -3816,6 +3905,7 @@ SHOW_VAR com_status_vars[]= { {"kill", STMT_STATUS(SQLCOM_KILL)}, {"load", STMT_STATUS(SQLCOM_LOAD)}, {"lock_tables", STMT_STATUS(SQLCOM_LOCK_TABLES)}, + {"multi", COM_STATUS(com_multi)}, {"optimize", STMT_STATUS(SQLCOM_OPTIMIZE)}, {"preload_keys", STMT_STATUS(SQLCOM_PRELOAD_KEYS)}, {"prepare_sql", STMT_STATUS(SQLCOM_PREPARE)}, @@ -3849,6 +3939,7 @@ SHOW_VAR com_status_vars[]= { {"show_create_proc", STMT_STATUS(SQLCOM_SHOW_CREATE_PROC)}, {"show_create_table", STMT_STATUS(SQLCOM_SHOW_CREATE)}, {"show_create_trigger", STMT_STATUS(SQLCOM_SHOW_CREATE_TRIGGER)}, + {"show_create_user", STMT_STATUS(SQLCOM_SHOW_CREATE_USER)}, {"show_databases", STMT_STATUS(SQLCOM_SHOW_DATABASES)}, {"show_engine_logs", STMT_STATUS(SQLCOM_SHOW_ENGINE_LOGS)}, {"show_engine_mutex", STMT_STATUS(SQLCOM_SHOW_ENGINE_MUTEX)}, @@ -4015,7 +4106,8 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) (longlong) thd->status_var.local_memory_used, size)); thd->status_var.local_memory_used+= size; - DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0); + DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0 || + !debug_assert_on_not_freed_memory); } } } @@ -4077,8 +4169,7 @@ static int init_common_variables() connection_errors_peer_addr= 0; my_decimal_set_zero(&decimal_zero); // set decimal_zero constant; - if (pthread_key_create(&THR_THD,NULL) || - pthread_key_create(&THR_MALLOC,NULL)) + if (pthread_key_create(&THR_THD, NULL)) { sql_print_error("Can't create thread-keys"); return 1; @@ -4095,7 +4186,7 @@ static int init_common_variables() sf_malloc_dbug_id= mariadb_dbug_id; #endif - max_system_variables.pseudo_thread_id= (ulong)~0; + max_system_variables.pseudo_thread_id= ~(my_thread_id) 0; server_start_time= flush_status_time= my_time(0); global_rpl_filter= new Rpl_filter; @@ -4248,7 +4339,7 @@ static int init_common_variables() of SQLCOM_ constants. */ compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 == - SQLCOM_END + 10); + SQLCOM_END + 11); #endif if (get_options(&remaining_argc, &remaining_argv)) @@ -4608,6 +4699,7 @@ static int init_thread_environment() DBUG_ENTER("init_thread_environment"); mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_thread_cache, &LOCK_thread_cache, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_start_thread, &LOCK_start_thread, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_show_status, &LOCK_show_status, MY_MUTEX_INIT_SLOW); mysql_mutex_init(key_LOCK_delayed_insert, @@ -4669,6 +4761,7 @@ static int init_thread_environment() mysql_rwlock_init(key_rwlock_LOCK_grant, &LOCK_grant); mysql_cond_init(key_COND_thread_count, &COND_thread_count, NULL); mysql_cond_init(key_COND_thread_cache, &COND_thread_cache, NULL); + mysql_cond_init(key_COND_start_thread, &COND_start_thread, NULL); mysql_cond_init(key_COND_flush_thread_cache, &COND_flush_thread_cache, NULL); #ifdef HAVE_REPLICATION mysql_mutex_init(key_LOCK_rpl_status, &LOCK_rpl_status, MY_MUTEX_INIT_FAST); @@ -5429,7 +5522,7 @@ static void handle_connections_methods() unireg_abort(1); // Will not return } - mysql_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_start_thread); mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL); handler_count=0; if (hPipe != INVALID_HANDLE_VALUE) @@ -5472,17 +5565,17 @@ static void handle_connections_methods() #endif while (handler_count > 0) - mysql_cond_wait(&COND_handler_count, &LOCK_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); + mysql_cond_wait(&COND_handler_count, &LOCK_start_thread); + mysql_mutex_unlock(&LOCK_start_thread); DBUG_VOID_RETURN; } void decrement_handler_count() { - mysql_mutex_lock(&LOCK_thread_count); - handler_count--; - mysql_cond_signal(&COND_handler_count); - mysql_mutex_unlock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_start_thread); + if (--handler_count == 0) + mysql_cond_signal(&COND_handler_count); + mysql_mutex_unlock(&LOCK_start_thread); my_thread_end(); } #else @@ -5949,18 +6042,10 @@ int mysqld_main(int argc, char **argv) DBUG_PRINT("quit",("Exiting main thread")); #ifndef __WIN__ -#ifdef EXTRA_DEBUG2 - sql_print_error("Before Lock_thread_count"); -#endif - WSREP_DEBUG("Before Lock_thread_count"); - mysql_mutex_lock(&LOCK_thread_count); - DBUG_PRINT("quit", ("Got thread_count mutex")); + mysql_mutex_lock(&LOCK_start_thread); select_thread_in_use=0; // For close_connections - mysql_mutex_unlock(&LOCK_thread_count); - mysql_cond_broadcast(&COND_thread_count); -#ifdef EXTRA_DEBUG2 - sql_print_error("After lock_thread_count"); -#endif + mysql_cond_broadcast(&COND_start_thread); + mysql_mutex_unlock(&LOCK_start_thread); #endif /* __WIN__ */ #ifdef HAVE_PSI_THREAD_INTERFACE @@ -5987,6 +6072,9 @@ int mysqld_main(int argc, char **argv) CloseHandle(hEventShutdown); } #endif +#if (defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)) && !defined(EMBEDDED_LIBRARY) + ERR_remove_state(0); +#endif mysqld_exit(0); return 0; } @@ -6225,7 +6313,7 @@ static void bootstrap(MYSQL_FILE *file) my_net_init(&thd->net,(st_vio*) 0, (void*) 0, MYF(0)); thd->max_client_packet_length= thd->net.max_packet; thd->security_ctx->master_access= ~(ulong)0; - thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; + thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id(); thread_count++; // Safe as only one thread running in_bootstrap= TRUE; @@ -6245,10 +6333,7 @@ static void bootstrap(MYSQL_FILE *file) /* Wait for thread to die */ mysql_mutex_lock(&LOCK_thread_count); while (in_bootstrap) - { mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); - DBUG_PRINT("quit",("One thread died (count=%u)",thread_count)); - } mysql_mutex_unlock(&LOCK_thread_count); #else thd->mysql= 0; @@ -6278,7 +6363,7 @@ static bool read_init_file(char *file_name) */ void inc_thread_created(void) { - thread_created++; + statistic_increment(thread_created, &LOCK_status); } #ifndef EMBEDDED_LIBRARY @@ -6289,18 +6374,12 @@ void inc_thread_created(void) NOTES This is only used for debugging, when starting mysqld with --thread-handling=no-threads or --one-thread - - When we enter this function, LOCK_thread_count is hold! */ -void handle_connection_in_main_thread(THD *thd) +void handle_connection_in_main_thread(CONNECT *connect) { - mysql_mutex_assert_owner(&LOCK_thread_count); - thread_cache_size=0; // Safety - threads.append(thd); - mysql_mutex_unlock(&LOCK_thread_count); - thd->start_utime= microsecond_interval_timer(); - do_handle_one_connection(thd); + thread_cache_size= 0; // Safety + do_handle_one_connection(connect); } @@ -6308,10 +6387,11 @@ void handle_connection_in_main_thread(THD *thd) Scheduler that uses one thread per connection */ -void create_thread_to_handle_connection(THD *thd) +void create_thread_to_handle_connection(CONNECT *connect) { + char error_message_buff[MYSQL_ERRMSG_SIZE]; + int error; DBUG_ENTER("create_thread_to_handle_connection"); - mysql_mutex_assert_owner(&LOCK_thread_count); /* Check if we can get thread from the cache */ if (cached_thread_count > wake_thread) @@ -6320,9 +6400,8 @@ void create_thread_to_handle_connection(THD *thd) /* Recheck condition when we have the lock */ if (cached_thread_count > wake_thread) { - mysql_mutex_unlock(&LOCK_thread_count); /* Get thread from cache */ - thread_cache.push_back(thd); + thread_cache.push_back(connect); wake_thread++; mysql_cond_signal(&COND_thread_cache); mysql_mutex_unlock(&LOCK_thread_cache); @@ -6332,46 +6411,33 @@ void create_thread_to_handle_connection(THD *thd) mysql_mutex_unlock(&LOCK_thread_cache); } - char error_message_buff[MYSQL_ERRMSG_SIZE]; /* Create new thread to handle connection */ - int error; - thread_created++; - threads.append(thd); - DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); - thd->prior_thr_create_utime= microsecond_interval_timer(); + inc_thread_created(); + DBUG_PRINT("info",(("creating thread %lu"), (ulong) connect->thread_id)); + connect->prior_thr_create_utime= microsecond_interval_timer(); + if ((error= mysql_thread_create(key_thread_one_connection, - &thd->real_id, &connection_attrib, + &connect->real_id, &connection_attrib, handle_one_connection, - (void*) thd))) + (void*) connect))) { /* purecov: begin inspected */ DBUG_PRINT("error", ("Can't create thread to handle request (error %d)", error)); - thd->killed= KILL_CONNECTION; // Safety - mysql_mutex_unlock(&LOCK_thread_count); - - mysql_mutex_lock(&LOCK_connection_count); - (*thd->scheduler->connection_count)--; - mysql_mutex_unlock(&LOCK_connection_count); - + dec_connection_count(connect->scheduler); statistic_increment(aborted_connects,&LOCK_status); statistic_increment(connection_errors_internal, &LOCK_status); - /* Can't use my_error() since store_globals has not been called. */ my_snprintf(error_message_buff, sizeof(error_message_buff), - ER_THD(thd, ER_CANT_CREATE_THREAD), error); - net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL); - close_connection(thd, ER_OUT_OF_RESOURCES); - - mysql_mutex_lock(&LOCK_thread_count); - thd->unlink(); - mysql_mutex_unlock(&LOCK_thread_count); - delete thd; - thread_safe_decrement32(&thread_count); - return; + ER_DEFAULT(ER_CANT_CREATE_THREAD), error); + connect->close_with_error(ER_CANT_CREATE_THREAD, + error_message_buff, + ER_OUT_OF_RESOURCES); + /* thread_count was incremented in create_new_thread() */ + dec_thread_count(); + DBUG_VOID_RETURN; /* purecov: end */ } - mysql_mutex_unlock(&LOCK_thread_count); DBUG_PRINT("info",("Thread created")); DBUG_VOID_RETURN; } @@ -6390,7 +6456,7 @@ void create_thread_to_handle_connection(THD *thd) @param[in,out] thd Thread handle of future thread. */ -static void create_new_thread(THD *thd) +static void create_new_thread(CONNECT *connect) { DBUG_ENTER("create_new_thread"); @@ -6401,20 +6467,19 @@ static void create_new_thread(THD *thd) mysql_mutex_lock(&LOCK_connection_count); - if (*thd->scheduler->connection_count >= - *thd->scheduler->max_connections + 1|| abort_loop) + if (*connect->scheduler->connection_count >= + *connect->scheduler->max_connections + 1|| abort_loop) { - mysql_mutex_unlock(&LOCK_connection_count); - DBUG_PRINT("error",("Too many connections")); - close_connection(thd, ER_CON_COUNT_ERROR); + + mysql_mutex_unlock(&LOCK_connection_count); statistic_increment(denied_connections, &LOCK_status); - delete thd; statistic_increment(connection_errors_max_connection, &LOCK_status); + connect->close_with_error(0, NullS, ER_CON_COUNT_ERROR); DBUG_VOID_RETURN; } - ++*thd->scheduler->connection_count; + ++*connect->scheduler->connection_count; if (connection_count + extra_connection_count > max_used_connections) max_used_connections= connection_count + extra_connection_count; @@ -6422,17 +6487,15 @@ static void create_new_thread(THD *thd) mysql_mutex_unlock(&LOCK_connection_count); thread_safe_increment32(&thread_count); + connect->thread_count_incremented= 1; - /* Start a new thread to handle connection. */ - mysql_mutex_lock(&LOCK_thread_count); /* The initialization of thread_id is done in create_embedded_thd() for the embedded library. TODO: refactor this to avoid code duplication there */ - thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - - MYSQL_CALLBACK(thd->scheduler, add_connection, (thd)); + connect->thread_id= next_thread_id(); + connect->scheduler->add_connection(connect); DBUG_VOID_RETURN; } @@ -6467,13 +6530,12 @@ void handle_connections_sockets() MYSQL_SOCKET sock= mysql_socket_invalid(); MYSQL_SOCKET new_sock= mysql_socket_invalid(); uint error_count=0; - THD *thd; + CONNECT *connect; struct sockaddr_storage cAddr; int ip_flags __attribute__((unused))=0; int socket_flags __attribute__((unused))= 0; int extra_ip_flags __attribute__((unused))=0; int flags=0,retval; - st_vio *vio_tmp; bool is_unix_sock; #ifdef HAVE_POLL int socket_count= 0; @@ -6672,58 +6734,43 @@ void handle_connections_sockets() } #endif /* HAVE_LIBWRAP */ - /* - ** Don't allow too many connections - */ + DBUG_PRINT("info", ("Creating CONNECT for new connection")); - DBUG_PRINT("info", ("Creating THD for new connection")); - if (!(thd= new THD)) + if ((connect= new CONNECT())) { - (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); - (void) mysql_socket_close(new_sock); - statistic_increment(connection_errors_internal, &LOCK_status); - continue; - } - /* Set to get io buffers to be part of THD */ - set_current_thd(thd); - - is_unix_sock= (mysql_socket_getfd(sock) == - mysql_socket_getfd(unix_sock)); + is_unix_sock= (mysql_socket_getfd(sock) == + mysql_socket_getfd(unix_sock)); - if (!(vio_tmp= - mysql_socket_vio_new(new_sock, - is_unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP, - is_unix_sock ? VIO_LOCALHOST: 0)) || - my_net_init(&thd->net, vio_tmp, thd, MYF(MY_THREAD_SPECIFIC))) - { - /* - Only delete the temporary vio if we didn't already attach it to the - NET object. The destructor in THD will delete any initialized net - structure. - */ - if (vio_tmp && thd->net.vio != vio_tmp) - vio_delete(vio_tmp); - else + if (!(connect->vio= + mysql_socket_vio_new(new_sock, + is_unix_sock ? VIO_TYPE_SOCKET : + VIO_TYPE_TCPIP, + is_unix_sock ? VIO_LOCALHOST: 0))) { - (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); - (void) mysql_socket_close(new_sock); + delete connect; + connect= 0; // Error handling below } - delete thd; + } + + if (!connect) + { + /* Connect failure */ + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_close(new_sock); + statistic_increment(aborted_connects,&LOCK_status); statistic_increment(connection_errors_internal, &LOCK_status); continue; } - init_net_server_extension(thd); if (is_unix_sock) - thd->security_ctx->host=(char*) my_localhost; + connect->host= my_localhost; if (mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock)) { - thd->extra_port= 1; - thd->scheduler= extra_thread_scheduler; + connect->extra_port= 1; + connect->scheduler= extra_thread_scheduler; } - create_new_thread(thd); - set_current_thd(0); + create_new_thread(connect); } sd_notify(0, "STOPPING=1\n" "STATUS=Shutdown in progress"); @@ -6744,7 +6791,6 @@ pthread_handler_t handle_connections_namedpipes(void *arg) { HANDLE hConnectedPipe; OVERLAPPED connectOverlapped= {0}; - THD *thd; my_thread_init(); DBUG_ENTER("handle_connections_namedpipes"); connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL); @@ -6812,25 +6858,19 @@ pthread_handler_t handle_connections_namedpipes(void *arg) hPipe=hConnectedPipe; continue; // We have to try again } - - if (!(thd = new THD)) + CONNECT *connect; + if (!(connect= new CONNECT) || + !(connect->vio= vio_new_win32pipe(hConnectedPipe))) { DisconnectNamedPipe(hConnectedPipe); CloseHandle(hConnectedPipe); + delete connect; + statistic_increment(aborted_connects,&LOCK_status); + statistic_increment(connection_errors_internal, &LOCK_status); continue; } - set_current_thd(thd); - if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) || - my_net_init(&thd->net, thd->net.vio, thd, MYF(MY_THREAD_SPECIFIC))) - { - close_connection(thd, ER_OUT_OF_RESOURCES); - delete thd; - continue; - } - /* Host is unknown */ - thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); - create_new_thread(thd); - set_current_thd(0); + connect->host= my_localhost; + create_new_thread(connect); } CloseHandle(connectOverlapped.hEvent); DBUG_LEAVE; @@ -6867,7 +6907,8 @@ pthread_handler_t handle_connections_shared_memory(void *arg) /* get enough space base-name + '_' + longest suffix we might ever send */ - if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE)))) + if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, + MYF(MY_FAE)))) goto error; if (my_security_attr_create(&sa_event, &errmsg, @@ -6933,7 +6974,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg) HANDLE event_server_wrote= 0; HANDLE event_server_read= 0; HANDLE event_conn_closed= 0; - THD *thd= 0; + CONNECT *connect= 0; p= int10_to_str(connect_number, connect_number_char, 10); /* @@ -6995,8 +7036,13 @@ pthread_handler_t handle_connections_shared_memory(void *arg) } if (abort_loop) goto errorconn; - if (!(thd= new THD)) + + if (!(connect= new CONNECT)) + { + errmsg= "Could not create CONNECT object"; goto errorconn; + } + /* Send number of connection to client */ int4store(handle_connect_map, connect_number); if (!SetEvent(event_connect_answer)) @@ -7010,24 +7056,20 @@ pthread_handler_t handle_connections_shared_memory(void *arg) errmsg= "Could not set client to read mode"; goto errorconn; } - set_current_thd(thd); - if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map, + if (!(connect->vio= vio_new_win32shared_memory(handle_client_file_map, handle_client_map, event_client_wrote, event_client_read, event_server_wrote, event_server_read, - event_conn_closed)) || - my_net_init(&thd->net, thd->net.vio, thd, MYF(MY_THREAD_SPECIFIC))) + event_conn_closed))) { - close_connection(thd, ER_OUT_OF_RESOURCES); - errmsg= 0; + errmsg= "Could not create VIO object"; goto errorconn; } - thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */ - create_new_thread(thd); + connect->host= my_localhost; /* Host is unknown */ + create_new_thread(connect); connect_number++; - set_current_thd(thd); continue; errorconn: @@ -7053,9 +7095,11 @@ errorconn: CloseHandle(event_client_read); if (event_conn_closed) CloseHandle(event_conn_closed); - delete thd; + + delete connect; + statistic_increment(aborted_connects,&LOCK_status); + statistic_increment(connection_errors_internal, &LOCK_status); } - set_current_thd(0); /* End shared memory handling */ error: @@ -7276,6 +7320,13 @@ struct my_option my_long_options[]= &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif /* HAVE_REPLICATION */ +#ifndef DBUG_OFF + {"debug-assert-on-not-freed-memory", 0, + "Assert if we found problems with memory allocation", + &debug_assert_on_not_freed_memory, + &debug_assert_on_not_freed_memory, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, + 0}, +#endif /* DBUG_OFF */ /* default-storage-engine should have "MyISAM" as def_value. Instead of initializing it here it is done in init_common_variables() due to a compiler bug in Sun Studio compiler. */ @@ -7559,8 +7610,8 @@ struct my_option my_long_options[]= 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Used with --help option for detailed help.", &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, - NO_ARG, 0, 0, 0, 0, 0, 0}, + {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_STR, + OPT_ARG, 0, 0, 0, 0, 0, 0}, {"plugin-load", OPT_PLUGIN_LOAD, "Semicolon-separated list of plugins to load, where each plugin is " "specified as ether a plugin_name=library_file pair or only a library_file. " @@ -7607,7 +7658,6 @@ struct my_option my_long_options[]= MYSQL_TO_BE_IMPLEMENTED_OPTION("slave-allow-batching"), // HAVE_REPLICATION MYSQL_COMPATIBILITY_OPTION("slave-checkpoint-period"), // HAVE_REPLICATION MYSQL_COMPATIBILITY_OPTION("slave-checkpoint-group"), // HAVE_REPLICATION - MYSQL_SUGGEST_ANALOG_OPTION("slave-parallel-workers", "--slave-parallel-threads"), // HAVE_REPLICATION MYSQL_SUGGEST_ANALOG_OPTION("slave-pending-jobs-size-max", "--slave-parallel-max-queued"), // HAVE_REPLICATION MYSQL_TO_BE_IMPLEMENTED_OPTION("disconnect-on-expired-password"), MYSQL_TO_BE_IMPLEMENTED_OPTION("sha256-password-private-key-path"), // HAVE_OPENSSL && !HAVE_YASSL @@ -8340,7 +8390,7 @@ SHOW_VAR status_vars[]= { {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS}, {"Com", (char*) com_status_vars, SHOW_ARRAY}, {"Compression", (char*) &show_net_compression, SHOW_SIMPLE_FUNC}, - {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH}, + {"Connections", (char*) &global_thread_id, SHOW_LONG_NOFLUSH}, {"Connection_errors_accept", (char*) &connection_errors_accept, SHOW_LONG}, {"Connection_errors_internal", (char*) &connection_errors_internal, SHOW_LONG}, {"Connection_errors_max_connections", (char*) &connection_errors_max_connection, SHOW_LONG}, @@ -8720,7 +8770,8 @@ static int mysql_init_variables(void) what_to_log= ~ (1L << (uint) COM_TIME); denied_connections= 0; executed_events= 0; - global_query_id= thread_id= 1L; + global_query_id= 1; + global_thread_id= 1; strnmov(server_version, MYSQL_SERVER_VERSION, sizeof(server_version)-1); threads.empty(); thread_cache.empty(); @@ -8935,12 +8986,20 @@ mysqld_get_one_option(int optid, const struct my_option *opt, char *argument) binlog_format_used= true; break; #include <sslopt-case.h> -#ifndef EMBEDDED_LIBRARY case 'V': - print_version(); - opt_abort= 1; // Abort after parsing all options - break; + if (argument) + { + strmake(server_version, argument, sizeof(server_version) - 1); + set_sys_var_value_origin(&server_version_ptr, sys_var::CONFIG); + } +#ifndef EMBEDDED_LIBRARY + else + { + print_version(); + opt_abort= 1; // Abort after parsing all options + } #endif /*EMBEDDED_LIBRARY*/ + break; case 'W': if (!argument) global_system_variables.log_warnings++; @@ -9631,6 +9690,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr) void set_server_version(void) { + if (!IS_SYSVAR_AUTOSIZE(&server_version_ptr)) + return; char *version_end= server_version+sizeof(server_version)-1; char *end= strxnmov(server_version, sizeof(server_version)-1, MYSQL_SERVER_VERSION, diff --git a/sql/mysqld.h b/sql/mysqld.h index 30120d66113..ef4a0d6a47a 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -30,6 +30,7 @@ #include "my_rdtsc.h" class THD; +class CONNECT; struct handlerton; class Time_zone; @@ -79,10 +80,10 @@ enum enum_slave_parallel_mode { }; /* Function prototypes */ -void kill_mysql(void); +void kill_mysql(THD *thd= 0); void close_connection(THD *thd, uint sql_errno= 0); -void handle_connection_in_main_thread(THD *thd); -void create_thread_to_handle_connection(THD *thd); +void handle_connection_in_main_thread(CONNECT *thd); +void create_thread_to_handle_connection(CONNECT *connect); void delete_running_thd(THD *thd); void signal_thd_deleted(); void unlink_thd(THD *thd); @@ -90,6 +91,8 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache); void flush_thread_cache(); void refresh_status(THD *thd); bool is_secure_file_path(char *path); +void dec_connection_count(scheduler_functions *scheduler); +extern void init_net_server_extension(THD *thd); extern "C" MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info; extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ; @@ -116,8 +119,9 @@ extern bool opt_disable_networking, opt_skip_show_db; extern bool opt_skip_name_resolve; extern bool opt_ignore_builtin_innodb; extern my_bool opt_character_set_client_handshake; +extern my_bool debug_assert_on_not_freed_memory; extern bool volatile abort_loop; -extern bool in_bootstrap; +extern bool volatile in_bootstrap; extern uint connection_count; extern my_bool opt_safe_user_create; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; @@ -177,7 +181,7 @@ extern char log_error_file[FN_REFLEN], *opt_tc_log_file; extern const double log_10[309]; extern ulonglong keybuff_size; extern ulonglong thd_startup_options; -extern ulong thread_id; +extern my_thread_id global_thread_id; extern ulong binlog_cache_use, binlog_cache_disk_use; extern ulong binlog_stmt_cache_use, binlog_stmt_cache_disk_use; extern ulong aborted_threads,aborted_connects; @@ -263,12 +267,6 @@ extern my_bool encrypt_tmp_disk_tables, encrypt_tmp_files; extern ulong encryption_algorithm; extern const char *encryption_algorithm_names[]; -/* - THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread, - using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr(). -*/ -extern pthread_key(MEM_ROOT**,THR_MALLOC); - #ifdef HAVE_PSI_INTERFACE #ifdef HAVE_MMAP extern PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, @@ -298,6 +296,7 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list, key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, key_rpl_group_info_sleep_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, + key_LOCK_start_thread, key_LOCK_error_messages, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc; extern PSI_mutex_key key_RELAYLOG_LOCK_index; extern PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state, @@ -329,6 +328,7 @@ extern PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond, key_relay_log_info_start_cond, key_relay_log_info_stop_cond, key_rpl_group_info_sleep_cond, key_TABLE_SHARE_cond, key_user_level_lock_cond, + key_COND_start_thread, key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache; extern PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready, key_COND_wait_commit; @@ -541,6 +541,7 @@ extern uint mysql_real_data_home_len; extern const char *mysql_real_data_home_ptr; extern ulong thread_handling; extern "C" MYSQL_PLUGIN_IMPORT char server_version[SERVER_VERSION_LENGTH]; +extern char *server_version_ptr; extern MYSQL_PLUGIN_IMPORT char mysql_real_data_home[]; extern char mysql_unpacked_real_data_home[]; extern MYSQL_PLUGIN_IMPORT struct system_variables global_system_variables; @@ -563,6 +564,7 @@ extern mysql_mutex_t LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count, LOCK_slave_init; extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count; +extern mysql_mutex_t LOCK_start_thread; #ifdef HAVE_OPENSSL extern char* des_key_file; extern mysql_mutex_t LOCK_des_key_file; @@ -571,7 +573,7 @@ extern mysql_mutex_t LOCK_server_started; extern mysql_cond_t COND_server_started; extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern mysql_rwlock_t LOCK_system_variables_hash; -extern mysql_cond_t COND_thread_count; +extern mysql_cond_t COND_thread_count, COND_start_thread; extern mysql_cond_t COND_manager; extern mysql_cond_t COND_slave_init; extern int32 thread_running; @@ -704,6 +706,16 @@ inline query_id_t get_query_id() return my_atomic_load64_explicit(&global_query_id, MY_MEMORY_ORDER_RELAXED); } +/* increment global_thread_id and return it. */ +inline __attribute__((warn_unused_result)) my_thread_id next_thread_id() +{ + return my_atomic_add64_explicit(&global_thread_id, 1, MY_MEMORY_ORDER_RELAXED); +} + +#if defined(MYSQL_DYNAMIC_PLUGIN) && defined(_WIN32) +extern "C" my_thread_id next_thread_id_noinline(); +#define next_thread_id() next_thread_id_noinline() +#endif /* TODO: Replace this with an inline function. @@ -752,7 +764,8 @@ inline void dec_thread_running() thread_safe_decrement32(&thread_running); } -void set_server_version(void); +extern void set_server_version(void); +extern void dec_thread_count(void); #if defined(MYSQL_DYNAMIC_PLUGIN) && defined(_WIN32) extern "C" THD *_current_thd_noinline(); @@ -774,6 +787,7 @@ inline int set_current_thd(THD *thd) return my_pthread_setspecific_ptr(THR_THD, thd); } + /* @todo remove, make it static in ha_maria.cc currently it's needed for sql_select.cc diff --git a/sql/net_serv.cc b/sql/net_serv.cc index d81c89fe534..f0284462206 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -121,6 +121,8 @@ extern my_bool thd_net_is_killed(); static my_bool net_write_buff(NET *, const uchar *, ulong); +my_bool net_allocate_new_packet(NET *net, void *thd, uint my_flags); + /** Init with packet info. */ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags) @@ -129,14 +131,12 @@ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags) DBUG_PRINT("enter", ("my_flags: %u", my_flags)); net->vio = vio; my_net_local_init(net); /* Set some limits */ - if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+ - NET_HEADER_SIZE + COMP_HEADER_SIZE +1, - MYF(MY_WME | my_flags)))) + + if (net_allocate_new_packet(net, thd, my_flags)) DBUG_RETURN(1); - net->buff_end=net->buff+net->max_packet; + net->error=0; net->return_status=0; net->pkt_nr=net->compress_pkt_nr=0; - net->write_pos=net->read_pos = net->buff; net->last_error[0]=0; net->compress=0; net->reading_or_writing=0; net->where_b = net->remain_in_buf=0; @@ -165,6 +165,18 @@ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags) DBUG_RETURN(0); } +my_bool net_allocate_new_packet(NET *net, void *thd, uint my_flags) +{ + DBUG_ENTER("net_allocate_new_packet"); + if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+ + NET_HEADER_SIZE + COMP_HEADER_SIZE +1, + MYF(MY_WME | my_flags)))) + DBUG_RETURN(1); + net->buff_end=net->buff+net->max_packet; + net->write_pos=net->read_pos = net->buff; + DBUG_RETURN(0); +} + void net_end(NET *net) { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ed7e9a56ae5..7169a3eda81 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -114,12 +114,11 @@ #include "sql_parse.h" // check_stack_overrun #include "sql_partition.h" // get_part_id_func, PARTITION_ITERATOR, // struct partition_info, NOT_A_PARTITION_ID -#include "sql_base.h" // free_io_cache #include "records.h" // init_read_record, end_read_record #include <m_ctype.h> #include "sql_select.h" #include "sql_statistics.h" -#include "filesort.h" // filesort_free_buffers +#include "uniques.h" #ifndef EXTRA_DEBUG #define test_rb_tree(A,B) {} @@ -1154,6 +1153,7 @@ int imerge_list_and_tree(RANGE_OPT_PARAM *param, SQL_SELECT *make_select(TABLE *head, table_map const_tables, table_map read_tables, COND *conds, + SORT_INFO *filesort, bool allow_null_cond, int *error) { @@ -1174,13 +1174,16 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables, select->head=head; select->cond= conds; - if (head->sort.io_cache) + if (filesort && my_b_inited(&filesort->io_cache)) { - select->file= *head->sort.io_cache; + /* + Hijack the filesort io_cache for make_select + SQL_SELECT will be responsible for ensuring that it's properly freed. + */ + select->file= filesort->io_cache; select->records=(ha_rows) (select->file.end_of_file/ head->file->ref_length); - my_free(head->sort.io_cache); - head->sort.io_cache=0; + my_b_clear(&filesort->io_cache); } DBUG_RETURN(select); } @@ -1393,7 +1396,6 @@ QUICK_INDEX_SORT_SELECT::~QUICK_INDEX_SORT_SELECT() delete pk_quick_select; /* It's ok to call the next two even if they are already deinitialized */ end_read_record(&read_record); - free_io_cache(head); free_root(&alloc,MYF(0)); DBUG_VOID_RETURN; } @@ -10674,7 +10676,6 @@ int read_keys_and_merge_scans(THD *thd, else { unique->reset(); - filesort_free_buffers(head, false); } DBUG_ASSERT(file->ref_length == unique->get_size()); @@ -10727,7 +10728,7 @@ int read_keys_and_merge_scans(THD *thd, /* Ok all rowids are in the Unique now. The next call will initialize - head->sort structure so it can be used to iterate through the rowids + the unique structure so it can be used to iterate through the rowids sequence. */ result= unique->get(head); @@ -10736,7 +10737,8 @@ int read_keys_and_merge_scans(THD *thd, */ if (enabled_keyread) head->disable_keyread(); - if (init_read_record(read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE)) + if (init_read_record(read_record, thd, head, (SQL_SELECT*) 0, + &unique->sort, 1 , 1, TRUE)) result= 1; DBUG_RETURN(result); @@ -10779,7 +10781,8 @@ int QUICK_INDEX_MERGE_SELECT::get_next() { result= HA_ERR_END_OF_FILE; end_read_record(&read_record); - free_io_cache(head); + // Free things used by sort early. Shouldn't be strictly necessary + unique->sort.reset(); /* All rows from Unique have been retrieved, do a clustered PK scan */ if (pk_quick_select) { @@ -10814,7 +10817,7 @@ int QUICK_INDEX_INTERSECT_SELECT::get_next() { result= HA_ERR_END_OF_FILE; end_read_record(&read_record); - free_io_cache(head); + unique->sort.reset(); // Free things early } DBUG_RETURN(result); @@ -14618,6 +14621,4 @@ void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose) } } - #endif /* !DBUG_OFF */ - diff --git a/sql/opt_range.h b/sql/opt_range.h index 0c495639db6..6970b87f6d8 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -24,9 +24,10 @@ #pragma interface /* gcc class implementation */ #endif -#include "thr_malloc.h" /* sql_memdup */ #include "records.h" /* READ_RECORD */ #include "queues.h" /* QUEUE */ +#include "filesort.h" /* SORT_INFO */ + /* It is necessary to include set_var.h instead of item.h because there are dependencies on include order for set_var.h and item.h. This @@ -1659,6 +1660,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, ha_rows records); SQL_SELECT *make_select(TABLE *head, table_map const_tables, table_map read_tables, COND *conds, + SORT_INFO* filesort, bool allow_null_cond, int *error); bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond); diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index cb356fbdf41..e53e2a9ee0d 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3955,7 +3955,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) { /* if we run out of slots or we are not using tempool */ sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid, - thd->thread_id, thd->tmp_table++); + (ulong) thd->thread_id, thd->tmp_table++); } fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME); @@ -4739,8 +4739,6 @@ int clear_sj_tmp_tables(JOIN *join) { if ((res= table->file->ha_delete_all_rows())) return res; /* purecov: inspected */ - free_io_cache(table); - filesort_free_buffers(table,0); } SJ_MATERIALIZATION_INFO *sjm; diff --git a/sql/partition_info.cc b/sql/partition_info.cc index a92c7686eaf..43a00607fe6 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -547,11 +547,11 @@ err: #define MAX_PART_NAME_SIZE 8 -char *partition_info::create_default_partition_names(uint part_no, +char *partition_info::create_default_partition_names(THD *thd, uint part_no, uint num_parts_arg, uint start_no) { - char *ptr= (char*) sql_calloc(num_parts_arg*MAX_PART_NAME_SIZE); + char *ptr= (char*) thd->calloc(num_parts_arg * MAX_PART_NAME_SIZE); char *move_ptr= ptr; uint i= 0; DBUG_ENTER("create_default_partition_names"); @@ -620,11 +620,11 @@ void partition_info::set_show_version_string(String *packet) 0 Memory allocation error */ -char *partition_info::create_default_subpartition_name(uint subpart_no, +char *partition_info::create_default_subpartition_name(THD *thd, uint subpart_no, const char *part_name) { uint size_alloc= strlen(part_name) + MAX_PART_NAME_SIZE; - char *ptr= (char*) sql_calloc(size_alloc); + char *ptr= (char*) thd->calloc(size_alloc); DBUG_ENTER("create_default_subpartition_name"); if (likely(ptr != NULL)) @@ -663,7 +663,7 @@ char *partition_info::create_default_subpartition_name(uint subpart_no, The external routine needing this code is check_partition_info */ -bool partition_info::set_up_default_partitions(handler *file, +bool partition_info::set_up_default_partitions(THD *thd, handler *file, HA_CREATE_INFO *info, uint start_no) { @@ -695,7 +695,8 @@ bool partition_info::set_up_default_partitions(handler *file, my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0)); goto end; } - if (unlikely((!(default_name= create_default_partition_names(0, num_parts, + if (unlikely((!(default_name= create_default_partition_names(thd, 0, + num_parts, start_no))))) goto end; i= 0; @@ -744,7 +745,7 @@ end: The external routine needing this code is check_partition_info */ -bool partition_info::set_up_default_subpartitions(handler *file, +bool partition_info::set_up_default_subpartitions(THD *thd, handler *file, HA_CREATE_INFO *info) { uint i, j; @@ -771,7 +772,7 @@ bool partition_info::set_up_default_subpartitions(handler *file, if (likely(subpart_elem != 0 && (!part_elem->subpartitions.push_back(subpart_elem)))) { - char *ptr= create_default_subpartition_name(j, + char *ptr= create_default_subpartition_name(thd, j, part_elem->partition_name); if (!ptr) goto end; @@ -809,7 +810,7 @@ end: this will return an error. */ -bool partition_info::set_up_defaults_for_partitioning(handler *file, +bool partition_info::set_up_defaults_for_partitioning(THD *thd, handler *file, HA_CREATE_INFO *info, uint start_no) { @@ -819,10 +820,10 @@ bool partition_info::set_up_defaults_for_partitioning(handler *file, { default_partitions_setup= TRUE; if (use_default_partitions) - DBUG_RETURN(set_up_default_partitions(file, info, start_no)); + DBUG_RETURN(set_up_default_partitions(thd, file, info, start_no)); if (is_sub_partitioned() && use_default_subpartitions) - DBUG_RETURN(set_up_default_subpartitions(file, info)); + DBUG_RETURN(set_up_default_subpartitions(thd, file, info)); } DBUG_RETURN(FALSE); } @@ -1702,7 +1703,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type, my_error(ER_SUBPARTITION_ERROR, MYF(0)); goto end; } - if (unlikely(set_up_defaults_for_partitioning(file, info, (uint)0))) + if (unlikely(set_up_defaults_for_partitioning(thd, file, info, (uint)0))) goto end; if (!(tot_partitions= get_tot_partitions())) { @@ -1940,11 +1941,11 @@ void partition_info::print_no_partition_found(TABLE *table_arg, myf errflag) FALSE Success */ -bool partition_info::set_part_expr(char *start_token, Item *item_ptr, +bool partition_info::set_part_expr(THD *thd, char *start_token, Item *item_ptr, char *end_token, bool is_subpart) { uint expr_len= end_token - start_token; - char *func_string= (char*) sql_memdup(start_token, expr_len); + char *func_string= (char*) thd->memdup(start_token, expr_len); if (!func_string) { @@ -3153,7 +3154,7 @@ part_column_list_val *partition_info::add_column_value(THD *thd) return NULL; } -bool partition_info::set_part_expr(char *start_token, Item *item_ptr, +bool partition_info::set_part_expr(THD *thd, char *start_token, Item *item_ptr, char *end_token, bool is_subpart) { (void)start_token; diff --git a/sql/partition_info.h b/sql/partition_info.h index df7010b2ab3..5181e19d568 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -307,7 +307,8 @@ public: return num_parts * (is_sub_partitioned() ? num_subparts : 1); } - bool set_up_defaults_for_partitioning(handler *file, HA_CREATE_INFO *info, + bool set_up_defaults_for_partitioning(THD *thd, handler *file, + HA_CREATE_INFO *info, uint start_no); char *find_duplicate_field(); char *find_duplicate_name(); @@ -332,7 +333,7 @@ public: void init_col_val(part_column_list_val *col_val, Item *item); int reorganize_into_single_field_col_val(THD *thd); part_column_list_val *add_column_value(THD *thd); - bool set_part_expr(char *start_token, Item *item_ptr, + bool set_part_expr(THD *thd, char *start_token, Item *item_ptr, char *end_token, bool is_subpart); static int compare_column_values(const void *a, const void *b); bool set_up_charset_field_preps(THD *thd); @@ -371,12 +372,13 @@ public: bool has_same_partitioning(partition_info *new_part_info); private: static int list_part_cmp(const void* a, const void* b); - bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info, + bool set_up_default_partitions(THD *thd, handler *file, HA_CREATE_INFO *info, uint start_no); - bool set_up_default_subpartitions(handler *file, HA_CREATE_INFO *info); - char *create_default_partition_names(uint part_no, uint num_parts, + bool set_up_default_subpartitions(THD *thd, handler *file, + HA_CREATE_INFO *info); + char *create_default_partition_names(THD *thd, uint part_no, uint num_parts, uint start_no); - char *create_default_subpartition_name(uint subpart_no, + char *create_default_subpartition_name(THD *thd, uint subpart_no, const char *part_name); bool prune_partition_bitmaps(TABLE_LIST *table_list); bool add_named_partition(const char *part_name, uint length); diff --git a/sql/procedure.h b/sql/procedure.h index a46e8cfc137..1452f33652a 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -48,7 +48,7 @@ public: virtual void set(longlong nr)=0; virtual enum_field_types field_type() const=0; void set(const char *str) { set(str,(uint) strlen(str), default_charset()); } - void make_field(Send_field *tmp_field) + void make_field(THD *thd, Send_field *tmp_field) { init_make_field(tmp_field,field_type()); } @@ -69,6 +69,7 @@ public: decimals=dec; max_length=float_length(dec); } enum Item_result result_type () const { return REAL_RESULT; } + enum Item_result cmp_type () const { return REAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } void set(double nr) { value=nr; } void set(longlong nr) { value=(double) nr; } @@ -96,6 +97,7 @@ public: Item_proc_int(THD *thd, const char *name_par): Item_proc(thd, name_par) { max_length=11; } enum Item_result result_type () const { return INT_RESULT; } + enum Item_result cmp_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } void set(double nr) { value=(longlong) nr; } void set(longlong nr) { value=nr; } @@ -115,6 +117,7 @@ public: Item_proc_string(THD *thd, const char *name_par, uint length): Item_proc(thd, name_par) { this->max_length=length; } enum Item_result result_type () const { return STRING_RESULT; } + enum Item_result cmp_type () const { return STRING_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } void set(double nr) { str_value.set_real(nr, 2, default_charset()); } void set(longlong nr) { str_value.set(nr, default_charset()); } diff --git a/sql/protocol.cc b/sql/protocol.cc index fa42915f5a9..9e528708823 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -754,7 +754,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags) char *pos; CHARSET_INFO *cs= system_charset_info; Send_field field; - item->make_field(&field); + item->make_field(thd, &field); /* Keep things compatible for old clients */ if (field.type == MYSQL_TYPE_VARCHAR) diff --git a/sql/records.cc b/sql/records.cc index ebda0ed35b0..3995bea6569 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -29,10 +29,10 @@ #include "records.h" #include "sql_priv.h" #include "records.h" -#include "filesort.h" // filesort_free_buffers #include "opt_range.h" // SQL_SELECT #include "sql_class.h" // THD #include "sql_base.h" +#include "sql_sort.h" // SORT_ADDON_FIELD static int rr_quick(READ_RECORD *info); int rr_sequential(READ_RECORD *info); @@ -182,26 +182,30 @@ bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, SQL_SELECT *select, + SORT_INFO *filesort, int use_record_cache, bool print_error, bool disable_rr_cache) { IO_CACHE *tempfile; + SORT_ADDON_FIELD *addon_field= filesort ? filesort->addon_field : 0; DBUG_ENTER("init_read_record"); bzero((char*) info,sizeof(*info)); info->thd=thd; info->table=table; info->forms= &info->table; /* Only one table */ + info->addon_field= addon_field; if ((table->s->tmp_table == INTERNAL_TMP_TABLE || table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) && - !table->sort.addon_field) + !addon_field) (void) table->file->extra(HA_EXTRA_MMAP); - if (table->sort.addon_field) + if (addon_field) { - info->rec_buf= table->sort.addon_buf; - info->ref_length= table->sort.addon_length; + info->rec_buf= (uchar*) filesort->addon_buf.str; + info->ref_length= filesort->addon_buf.length; + info->unpack= filesort->unpack; } else { @@ -213,19 +217,20 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, info->print_error=print_error; info->unlock_row= rr_unlock_row; info->ignore_not_found_rows= 0; - table->status=0; /* And it's always found */ + table->status= 0; /* Rows are always found */ + tempfile= 0; if (select && my_b_inited(&select->file)) tempfile= &select->file; - else - tempfile= table->sort.io_cache; - if (tempfile && my_b_inited(tempfile) && - !(select && select->quick)) + else if (filesort && my_b_inited(&filesort->io_cache)) + tempfile= &filesort->io_cache; + + if (tempfile && !(select && select->quick)) { DBUG_PRINT("info",("using rr_from_tempfile")); - info->read_record= (table->sort.addon_field ? + info->read_record= (addon_field ? rr_unpack_from_tempfile : rr_from_tempfile); - info->io_cache=tempfile; + info->io_cache= tempfile; reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0); info->ref_pos=table->file->ref; if (!table->file->inited) @@ -233,12 +238,12 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, DBUG_RETURN(1); /* - table->sort.addon_field is checked because if we use addon fields, + addon_field is checked because if we use addon fields, it doesn't make sense to use cache - we don't read from the table - and table->sort.io_cache is read sequentially + and filesort->io_cache is read sequentially */ if (!disable_rr_cache && - !table->sort.addon_field && + !addon_field && thd->variables.read_rnd_buff_size && !(table->file->ha_table_flags() & HA_FAST_KEY_READ) && (table->db_stat & HA_READ_ONLY || @@ -263,15 +268,15 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, DBUG_PRINT("info",("using rr_quick")); info->read_record=rr_quick; } - else if (table->sort.record_pointers) + else if (filesort && filesort->record_pointers) { DBUG_PRINT("info",("using record_pointers")); if (table->file->ha_rnd_init_with_error(0)) DBUG_RETURN(1); - info->cache_pos=table->sort.record_pointers; - info->cache_end=info->cache_pos+ - table->sort.found_records*info->ref_length; - info->read_record= (table->sort.addon_field ? + info->cache_pos= filesort->record_pointers; + info->cache_end= (info->cache_pos+ + filesort->return_rows * info->ref_length); + info->read_record= (addon_field ? rr_unpack_from_buffer : rr_from_pointers); } else @@ -288,7 +293,7 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, (use_record_cache < 0 && !(table->file->ha_table_flags() & HA_NOT_DELETE_WITH_CACHE)))) (void) table->file->extra_opt(HA_EXTRA_CACHE, - thd->variables.read_buff_size); + thd->variables.read_buff_size); } /* Condition pushdown to storage engine */ if ((table->file->ha_table_flags() & HA_CAN_TABLE_CONDITION_PUSHDOWN) && @@ -311,7 +316,6 @@ void end_read_record(READ_RECORD *info) } if (info->table) { - filesort_free_buffers(info->table,0); if (info->table->created) (void) info->table->file->extra(HA_EXTRA_NO_CACHE); if (info->read_record != rr_quick) // otherwise quick_range does it @@ -525,9 +529,8 @@ static int rr_unpack_from_tempfile(READ_RECORD *info) { if (my_b_read(info->io_cache, info->rec_buf, info->ref_length)) return -1; - TABLE *table= info->table; - (*table->sort.unpack)(table->sort.addon_field, info->rec_buf, - info->rec_buf + info->ref_length); + (*info->unpack)(info->addon_field, info->rec_buf, + info->rec_buf + info->ref_length); return 0; } @@ -577,11 +580,9 @@ static int rr_unpack_from_buffer(READ_RECORD *info) { if (info->cache_pos == info->cache_end) return -1; /* End of buffer */ - TABLE *table= info->table; - (*table->sort.unpack)(table->sort.addon_field, info->cache_pos, - info->cache_end); + (*info->unpack)(info->addon_field, info->cache_pos, + info->cache_end); info->cache_pos+= info->ref_length; - return 0; } /* cacheing of records from a database */ diff --git a/sql/records.h b/sql/records.h index a3f0b5eb084..1928acfd4f4 100644 --- a/sql/records.h +++ b/sql/records.h @@ -25,6 +25,7 @@ struct TABLE; class THD; class SQL_SELECT; class Copy_field; +class SORT_INFO; /** A context for reading through a single table using a chosen access method: @@ -60,8 +61,10 @@ struct READ_RECORD uchar *record; uchar *rec_buf; /* to read field values after filesort */ uchar *cache,*cache_pos,*cache_end,*read_positions; + struct st_sort_addon_field *addon_field; /* Pointer to the fields info */ struct st_io_cache *io_cache; bool print_error, ignore_not_found_rows; + void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *); /* SJ-Materialization runtime may need to read fields from the materialized @@ -74,7 +77,8 @@ public: }; bool init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, - SQL_SELECT *select, int use_record_cache, + SQL_SELECT *select, SORT_INFO *sort, + int use_record_cache, bool print_errors, bool disable_rr_cache); bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool print_error, uint idx, bool reverse); diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 697da6fa10e..acdedd6e0a0 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -969,10 +969,8 @@ handle_rpl_parallel_thread(void *arg) my_thread_init(); thd = new THD; thd->thread_stack = (char*)&thd; - mysql_mutex_lock(&LOCK_thread_count); - thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - threads.append(thd); - mysql_mutex_unlock(&LOCK_thread_count); + thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id(); + add_to_active_threads(thd); set_current_thd(thd); pthread_detach_this_thread(); thd->init_for_queries(); @@ -1372,10 +1370,10 @@ handle_rpl_parallel_thread(void *arg) thd->reset_db(NULL, 0); thd_proc_info(thd, "Slave worker thread exiting"); thd->temporary_tables= 0; - mysql_mutex_lock(&LOCK_thread_count); + THD_CHECK_SENTRY(thd); + unlink_not_visible_thd(thd); delete thd; - mysql_mutex_unlock(&LOCK_thread_count); mysql_mutex_lock(&rpt->LOCK_rpl_thread); rpt->running= false; diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index ff2cd74c3a7..bdf5b7dea80 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -901,6 +901,51 @@ table_def::compatible_with(THD *thd, rpl_group_info *rgi, return true; } + +/** + A wrapper to Virtual_tmp_table, to get access to its constructor, + which is protected for safety purposes (against illegal use on stack). +*/ +class Virtual_conversion_table: public Virtual_tmp_table +{ +public: + Virtual_conversion_table(THD *thd) :Virtual_tmp_table(thd) { } + /** + Add a new field into the virtual table. + @param sql_type - The real_type of the field. + @param metadata - The RBR binary log metadata for this field. + @param target_field - The field from the target table, to get extra + attributes from (e.g. typelib in case of ENUM). + */ + bool add(enum_field_types sql_type, + uint16 metadata, const Field *target_field) + { + const Type_handler *handler= Type_handler::get_handler_by_real_type(sql_type); + if (!handler) + { + sql_print_error("In RBR mode, Slave received unknown field type field %d " + " for column Name: %s.%s.%s.", + (int) sql_type, + target_field->table->s->db.str, + target_field->table->s->table_name.str, + target_field->field_name); + return true; + } + Field *tmp= handler->make_conversion_table_field(this, metadata, + target_field); + if (!tmp) + return true; + Virtual_tmp_table::add(tmp); + DBUG_PRINT("debug", ("sql_type: %d, target_field: '%s', max_length: %d, decimals: %d," + " maybe_null: %d, unsigned_flag: %d, pack_length: %u", + sql_type, target_field->field_name, + tmp->field_length, tmp->decimals(), TRUE, + tmp->flags, tmp->pack_length())); + return false; + } +}; + + /** Create a conversion table. @@ -916,8 +961,7 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi, { DBUG_ENTER("table_def::create_conversion_table"); - List<Create_field> field_list; - TABLE *conv_table= NULL; + Virtual_conversion_table *conv_table; Relay_log_info *rli= rgi->rli; /* At slave, columns may differ. So we should create @@ -925,113 +969,35 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi, conversion table. */ uint const cols_to_create= MY_MIN(target_table->s->fields, size()); + if (!(conv_table= new(thd) Virtual_conversion_table(thd)) || + conv_table->init(cols_to_create)) + goto err; for (uint col= 0 ; col < cols_to_create; ++col) { - Create_field *field_def= - (Create_field*) alloc_root(thd->mem_root, sizeof(Create_field)); - Field *target_field= target_table->field[col]; - bool unsigned_flag= 0; - if (field_list.push_back(field_def, thd->mem_root)) - DBUG_RETURN(NULL); - - uint decimals= 0; - TYPELIB* interval= NULL; - uint pack_length= 0; - uint32 max_length= - max_display_length_for_field(type(col), field_metadata(col)); - - switch(type(col)) { - int precision; - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - interval= static_cast<Field_enum*>(target_field)->typelib; - pack_length= field_metadata(col) & 0x00ff; - break; - - case MYSQL_TYPE_NEWDECIMAL: - /* - The display length of a DECIMAL type is not the same as the - length that should be supplied to make_field, so we correct - the length here. - */ - precision= field_metadata(col) >> 8; - decimals= field_metadata(col) & 0x00ff; - max_length= - my_decimal_precision_to_length(precision, decimals, FALSE); - break; - - case MYSQL_TYPE_DECIMAL: - sql_print_error("In RBR mode, Slave received incompatible DECIMAL field " - "(old-style decimal field) from Master while creating " - "conversion table. Please consider changing datatype on " - "Master to new style decimal by executing ALTER command for" - " column Name: %s.%s.%s.", - target_table->s->db.str, - target_table->s->table_name.str, - target_field->field_name); + if (conv_table->add(type(col), field_metadata(col), + target_table->field[col])) + { + DBUG_PRINT("debug", ("binlog_type: %d, metadata: %04X, target_field: '%s'" + " make_conversion_table_field() failed", + binlog_type(col), field_metadata(col), + target_table->field[col]->field_name)); goto err; - - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_GEOMETRY: - pack_length= field_metadata(col) & 0x00ff; - break; - - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: - /* - As we don't know if the integer was signed or not on the master, - assume we have same sign on master and slave. This is true when not - using conversions so it should be true also when using conversions. - */ - unsigned_flag= static_cast<Field_num*>(target_field)->unsigned_flag; - break; - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_DATETIME: - /* - As we don't know the precision of the temporal field on the master, - assume it's the same on master and slave. This is true when not - using conversions so it should be true also when using conversions. - */ - if (target_field->decimals()) - max_length+= target_field->decimals() + 1; - break; - default: - break; } - - DBUG_PRINT("debug", ("sql_type: %d, target_field: '%s', max_length: %d, decimals: %d," - " maybe_null: %d, unsigned_flag: %d, pack_length: %u", - binlog_type(col), target_field->field_name, - max_length, decimals, TRUE, unsigned_flag, - pack_length)); - field_def->init_for_tmp_table(type(col), - max_length, - decimals, - TRUE, // maybe_null - unsigned_flag, - pack_length); - field_def->charset= target_field->charset(); - field_def->interval= interval; } - conv_table= create_virtual_tmp_table(thd, field_list); + if (conv_table->open()) + goto err; // Could not allocate record buffer? -err: - if (conv_table == NULL) - { - rli->report(ERROR_LEVEL, ER_SLAVE_CANT_CREATE_CONVERSION, rgi->gtid_info(), - ER_THD(thd, ER_SLAVE_CANT_CREATE_CONVERSION), - target_table->s->db.str, - target_table->s->table_name.str); - } DBUG_RETURN(conv_table); + +err: + if (conv_table) + delete conv_table; + rli->report(ERROR_LEVEL, ER_SLAVE_CANT_CREATE_CONVERSION, rgi->gtid_info(), + ER_THD(thd, ER_SLAVE_CANT_CREATE_CONVERSION), + target_table->s->db.str, + target_table->s->table_name.str); + DBUG_RETURN(NULL); } #endif /* MYSQL_CLIENT */ diff --git a/sql/scheduler.cc b/sql/scheduler.cc index bc3166210b5..2a0138d06a8 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -22,9 +22,9 @@ #pragma implementation #endif +#include "mysqld.h" #include "sql_connect.h" // init_new_connection_handler_thread #include "scheduler.h" -#include "mysqld.h" #include "sql_class.h" #include "sql_callback.h" #include <violite.h> @@ -35,7 +35,8 @@ static bool no_threads_end(THD *thd, bool put_in_cache) { - unlink_thd(thd); + if (thd) + unlink_thd(thd); return 1; // Abort handle_one_connection } @@ -81,7 +82,9 @@ static void scheduler_wait_net_end(void) { one_thread_scheduler() or one_thread_per_connection_scheduler() in mysqld.cc, so this init function will always be called. */ -void scheduler_init() { + +void scheduler_init() +{ thr_set_lock_wait_callback(scheduler_wait_lock_begin, scheduler_wait_lock_end); thr_set_sync_wait_callback(scheduler_wait_sync_begin, @@ -118,7 +121,6 @@ void post_kill_notification(THD *thd) #ifndef EMBEDDED_LIBRARY - void one_thread_per_connection_scheduler(scheduler_functions *func, ulong *arg_max_connections, uint *arg_connection_count) @@ -132,6 +134,14 @@ void one_thread_per_connection_scheduler(scheduler_functions *func, func->end_thread= one_thread_per_connection_end; func->post_kill_notification= post_kill_notification; } +#else +bool init_new_connection_handler_thread() +{ + return 0; +} +void handle_connection_in_main_thread(CONNECT *connect) +{ +} #endif /* @@ -144,10 +154,7 @@ void one_thread_scheduler(scheduler_functions *func) func->max_threads= 1; func->max_connections= &max_connections; func->connection_count= &connection_count; -#ifndef EMBEDDED_LIBRARY func->init_new_connection_thread= init_new_connection_handler_thread; func->add_connection= handle_connection_in_main_thread; -#endif func->end_thread= no_threads_end; } - diff --git a/sql/scheduler.h b/sql/scheduler.h index f7aff377eac..71553372999 100644 --- a/sql/scheduler.h +++ b/sql/scheduler.h @@ -37,7 +37,7 @@ struct scheduler_functions ulong *max_connections; bool (*init)(void); bool (*init_new_connection_thread)(void); - void (*add_connection)(THD *thd); + void (*add_connection)(CONNECT *connect); void (*thd_wait_begin)(THD *thd, int wait_type); void (*thd_wait_end)(THD *thd); void (*post_kill_notification)(THD *thd); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 1bd87e0b393..0d168e937a9 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -1735,29 +1735,29 @@ ER_WRONG_AUTO_KEY 42000 S1009 ER_UNUSED_9 eng "You should never see it" ER_NORMAL_SHUTDOWN - cze "%s: normálnà ukonÄenÃ\n" - dan "%s: Normal nedlukning\n" - nla "%s: Normaal afgesloten \n" - eng "%s: Normal shutdown\n" - est "%s: MariaDB lõpetas\n" - fre "%s: Arrêt normal du serveur\n" - ger "%s: Normal heruntergefahren\n" - greek "%s: Φυσιολογική διαδικασία shutdown\n" - hun "%s: Normal leallitas\n" - ita "%s: Shutdown normale\n" - jpn "%s: 通常シャットダウン\n" - kor "%s: ì •ìƒì ì¸ shutdown\n" - nor "%s: Normal avslutning\n" - norwegian-ny "%s: Normal nedkopling\n" - pol "%s: Standardowe zakoÅ„czenie dziaÅ‚ania\n" - por "%s: 'Shutdown' normal\n" - rum "%s: Terminare normala\n" - rus "%s: ÐšÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð¾Ñтановка\n" - serbian "%s: Normalno gaÅ¡enje\n" - slo "%s: normálne ukonÄenie\n" - spa "%s: Apagado normal\n" - swe "%s: Normal avslutning\n" - ukr "%s: Ðормальне завершеннÑ\n" + cze "%s (%s): normálnà ukonÄenÃ\n" + dan "%s (%s): Normal nedlukning\n" + nla "%s (%s): Normaal afgesloten \n" + eng "%s (%s): Normal shutdown\n" + est "%s (%s): MariaDB lõpetas\n" + fre "%s (%s): Arrêt normal du serveur\n" + ger "%s (%s): Normal heruntergefahren\n" + greek "%s (%s): Φυσιολογική διαδικασία shutdown\n" + hun "%s (%s): Normal leallitas\n" + ita "%s (%s): Shutdown normale\n" + jpn "%s (%s): 通常シャットダウン\n" + kor "%s (%s): ì •ìƒì ì¸ shutdown\n" + nor "%s (%s): Normal avslutning\n" + norwegian-ny "%s (%s): Normal nedkopling\n" + pol "%s (%s): Standardowe zakoÅ„czenie dziaÅ‚ania\n" + por "%s (%s): 'Shutdown' normal\n" + rum "%s (%s): Terminare normala\n" + rus "%s (%s): ÐšÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð¾Ñтановка\n" + serbian "%s (%s): Normalno gaÅ¡enje\n" + slo "%s (%s): normálne ukonÄenie\n" + spa "%s (%s): Apagado normal\n" + swe "%s (%s): Normal avslutning\n" + ukr "%s (%s): Ðормальне завершеннÑ\n" ER_GOT_SIGNAL cze "%s: pÅ™ijat signal %d, konÄÃm\n" dan "%s: Fangede signal %d. Afslutter!!\n" @@ -3947,21 +3947,21 @@ ER_ERROR_DURING_CHECKPOINT swe "Fick fel %M vid CHECKPOINT" ukr "Отримано помилку %M під Ñ‡Ð°Ñ CHECKPOINT" ER_NEW_ABORTING_CONNECTION 08S01 - cze "Spojenà %ld do databáze: '%-.192s' uživatel: '%-.48s' stroj: '%-.64s' (%-.64s) bylo pÅ™eruÅ¡eno" - dan "Afbrød forbindelsen %ld til databasen '%-.192s' bruger: '%-.48s' vært: '%-.64s' (%-.64s)" - nla "Afgebroken verbinding %ld naar db: '%-.192s' gebruiker: '%-.48s' host: '%-.64s' (%-.64s)" - eng "Aborted connection %ld to db: '%-.192s' user: '%-.48s' host: '%-.64s' (%-.64s)" - est "Ühendus katkestatud %ld andmebaas: '%-.192s' kasutaja: '%-.48s' masin: '%-.64s' (%-.64s)" - fre "Connection %ld avortée vers la bd: '%-.192s' utilisateur: '%-.48s' hôte: '%-.64s' (%-.64s)" - ger "Abbruch der Verbindung %ld zur Datenbank '%-.192s'. Benutzer: '%-.48s', Host: '%-.64s' (%-.64s)" - ita "Interrotta la connessione %ld al db: ''%-.192s' utente: '%-.48s' host: '%-.64s' (%-.64s)" - jpn "接続 %ld ãŒä¸æ–ã•れã¾ã—ãŸã€‚データベース: '%-.192s' ユーザー: '%-.48s' ホスト: '%-.64s' (%-.64s)" - por "Conexão %ld abortada para banco de dados '%-.192s' - usuário '%-.48s' - 'host' '%-.64s' ('%-.64s')" - rus "Прервано Ñоединение %ld к базе данных '%-.192s' Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ '%-.48s' Ñ Ñ…Ð¾Ñта '%-.64s' (%-.64s)" - serbian "Prekinuta konekcija broj %ld ka bazi: '%-.192s' korisnik je bio: '%-.48s' a host: '%-.64s' (%-.64s)" - spa "Abortada conexión %ld para db: '%-.192s' usuario: '%-.48s' servidor: '%-.64s' (%-.64s)" - swe "Avbröt länken för trÃ¥d %ld till db '%-.192s', användare '%-.48s', host '%-.64s' (%-.64s)" - ukr "Перервано з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ %ld до бази данних: '%-.192s' кориÑтувач: '%-.48s' хоÑÑ‚: '%-.64s' (%-.64s)" + cze "Spojenà %lld do databáze: '%-.192s' uživatel: '%-.48s' stroj: '%-.64s' (%-.64s) bylo pÅ™eruÅ¡eno" + dan "Afbrød forbindelsen %lld til databasen '%-.192s' bruger: '%-.48s' vært: '%-.64s' (%-.64s)" + nla "Afgebroken verbinding %lld naar db: '%-.192s' gebruiker: '%-.48s' host: '%-.64s' (%-.64s)" + eng "Aborted connection %lld to db: '%-.192s' user: '%-.48s' host: '%-.64s' (%-.64s)" + est "Ühendus katkestatud %lld andmebaas: '%-.192s' kasutaja: '%-.48s' masin: '%-.64s' (%-.64s)" + fre "Connection %lld avortée vers la bd: '%-.192s' utilisateur: '%-.48s' hôte: '%-.64s' (%-.64s)" + ger "Abbruch der Verbindung %lld zur Datenbank '%-.192s'. Benutzer: '%-.48s', Host: '%-.64s' (%-.64s)" + ita "Interrotta la connessione %lld al db: ''%-.192s' utente: '%-.48s' host: '%-.64s' (%-.64s)" + jpn "接続 %lld ãŒä¸æ–ã•れã¾ã—ãŸã€‚データベース: '%-.192s' ユーザー: '%-.48s' ホスト: '%-.64s' (%-.64s)" + por "Conexão %lld abortada para banco de dados '%-.192s' - usuário '%-.48s' - 'host' '%-.64s' ('%-.64s')" + rus "Прервано Ñоединение %lld к базе данных '%-.192s' Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ '%-.48s' Ñ Ñ…Ð¾Ñта '%-.64s' (%-.64s)" + serbian "Prekinuta konekcija broj %lld ka bazi: '%-.192s' korisnik je bio: '%-.48s' a host: '%-.64s' (%-.64s)" + spa "Abortada conexión %lld para db: '%-.192s' usuario: '%-.48s' servidor: '%-.64s' (%-.64s)" + swe "Avbröt länken för trÃ¥d %lld till db '%-.192s', användare '%-.48s', host '%-.64s' (%-.64s)" + ukr "Перервано з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ %lld до бази данних: '%-.192s' кориÑтувач: '%-.48s' хоÑÑ‚: '%-.64s' (%-.64s)" ER_UNUSED_10 eng "You should never see it" ER_FLUSH_MASTER_BINLOG_CLOSED @@ -7139,3 +7139,18 @@ ER_KILL_QUERY_DENIED_ERROR ER_NO_EIS_FOR_FIELD eng "Engine-independent statistics are not collected for column '%s'" ukr "Ðезалежна від типу таблиці ÑтатиÑтика не збираєтьÑÑ Ð´Ð»Ñ ÑÑ‚Ð¾Ð²Ð±Ñ†Ñ '%s'" +ER_COMMULTI_BADCONTEXT 0A000 + eng "COM_MULTI can't return a result set in the given context" + ger "COM_MULTI kann im gegebenen Kontext keine Ergebnismenge zurückgeben" + ukr "COM_MULTI не може повернути результати у цьому контекÑті" +ER_BAD_COMMAND_IN_MULTI + eng "Command '%s' is not allowed for COM_MULTI" + ukr "Команда '%s' не дозволена Ð´Ð»Ñ COM_MULTI" +ER_WITH_COL_WRONG_LIST + eng "WITH column list and SELECT field list have different column counts" +ER_DUP_QUERY_NAME + eng "Duplicate query name in WITH clause" +ER_WRONG_ORDER_IN_WITH_CLAUSE + eng "The definition of the table '%s' refers to the table '%s' defined later in a non-recursive WITH clause" +ER_RECURSIVE_QUERY_IN_WITH_CLAUSE + eng "Recursive queries in WITH clause are not supported yet" diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 9077b24416b..bbe714fc5b4 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -107,7 +107,6 @@ extern "C" sig_handler handle_fatal_signal(int sig) "diagnose the problem, but since we have already crashed, \n" "something is definitely wrong and this may fail.\n\n"); - set_server_version(); my_safe_printf_stderr("Server version: %s\n", server_version); if (dflt_key_cache) diff --git a/sql/slave.cc b/sql/slave.cc index e9bcfb073b4..93506bc2ccd 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -294,9 +294,7 @@ handle_slave_init(void *arg __attribute__((unused))) my_thread_init(); thd= new THD; thd->thread_stack= (char*) &thd; /* Set approximate stack start */ - mysql_mutex_lock(&LOCK_thread_count); - thd->thread_id= thread_id++; - mysql_mutex_unlock(&LOCK_thread_count); + thd->thread_id= next_thread_id(); thd->system_thread = SYSTEM_THREAD_SLAVE_INIT; thread_safe_increment32(&service_thread_count); thd->store_globals(); @@ -310,19 +308,17 @@ handle_slave_init(void *arg __attribute__((unused))) rpl_gtid_slave_state_table_name.str, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); - - mysql_mutex_lock(&LOCK_thread_count); delete thd; - mysql_mutex_unlock(&LOCK_thread_count); thread_safe_decrement32(&service_thread_count); - signal_thd_deleted(); - my_thread_end(); - mysql_mutex_lock(&LOCK_slave_init); + /* Signal run_slave_init_thread() that we are done */ + + mysql_mutex_lock(&LOCK_start_thread); slave_init_thread_running= false; - mysql_cond_broadcast(&COND_slave_init); - mysql_mutex_unlock(&LOCK_slave_init); + mysql_cond_broadcast(&COND_start_thread); + mysql_mutex_unlock(&LOCK_start_thread); + my_thread_end(); return 0; } @@ -347,11 +343,10 @@ run_slave_init_thread() return 1; } - mysql_mutex_lock(&LOCK_slave_init); + mysql_mutex_lock(&LOCK_start_thread); while (slave_init_thread_running) - mysql_cond_wait(&COND_slave_init, &LOCK_slave_init); - mysql_mutex_unlock(&LOCK_slave_init); - + mysql_cond_wait(&COND_start_thread, &LOCK_start_thread); + mysql_mutex_unlock(&LOCK_start_thread); return 0; } @@ -3076,9 +3071,7 @@ static int init_slave_thread(THD* thd, Master_info *mi, thd->variables.log_slow_filter= global_system_variables.log_slow_filter; set_slave_thread_options(thd); thd->client_capabilities = CLIENT_LOCAL_FILES; - mysql_mutex_lock(&LOCK_thread_count); - thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - mysql_mutex_unlock(&LOCK_thread_count); + thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id(); if (thd_type == SLAVE_THD_SQL) THD_STAGE_INFO(thd, stage_waiting_for_the_next_event_in_relay_log); @@ -3970,9 +3963,7 @@ pthread_handler_t handle_slave_io(void *arg) goto err_during_init; } thd->system_thread_info.rpl_io_info= &io_info; - mysql_mutex_lock(&LOCK_thread_count); - threads.append(thd); - mysql_mutex_unlock(&LOCK_thread_count); + add_to_active_threads(thd); mi->slave_running = MYSQL_SLAVE_RUN_NOT_CONNECT; mi->abort_slave = 0; mysql_mutex_unlock(&mi->run_lock); @@ -4295,6 +4286,7 @@ err: flush_master_info(mi, TRUE, TRUE); THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit); thd->add_status_to_global(); + unlink_not_visible_thd(thd); mysql_mutex_lock(&mi->run_lock); err_during_init: @@ -4354,7 +4346,8 @@ int check_temp_dir(char* tmp_file) size_t tmp_dir_size; DBUG_ENTER("check_temp_dir"); - mysql_mutex_lock(&LOCK_thread_count); + /* This look is safe to use as this function is only called once */ + mysql_mutex_lock(&LOCK_start_thread); if (check_temp_dir_run) { result= check_temp_dir_result; @@ -4393,7 +4386,7 @@ int check_temp_dir(char* tmp_file) end: check_temp_dir_result= result; - mysql_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_start_thread); DBUG_RETURN(result); } @@ -4571,9 +4564,7 @@ pthread_handler_t handle_slave_sql(void *arg) applied. In all other cases it must be FALSE. */ thd->variables.binlog_annotate_row_events= 0; - mysql_mutex_lock(&LOCK_thread_count); - threads.append(thd); - mysql_mutex_unlock(&LOCK_thread_count); + add_to_active_threads(thd); /* We are going to set slave_running to 1. Assuming slave I/O thread is alive and connected, this is going to make Seconds_Behind_Master be 0 @@ -4882,7 +4873,9 @@ pthread_handler_t handle_slave_sql(void *arg) } THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit); thd->add_status_to_global(); + unlink_not_visible_thd(thd); mysql_mutex_lock(&rli->run_lock); + err_during_init: /* We need data_lock, at least to wake up any waiting master_pos_wait() */ mysql_mutex_lock(&rli->data_lock); @@ -4906,12 +4899,8 @@ err_during_init: to avoid unneeded position re-init */ thd->temporary_tables = 0; // remove tempation from destructor to close them - THD_CHECK_SENTRY(thd); rli->sql_driver_thd= 0; - mysql_mutex_lock(&LOCK_thread_count); thd->rgi_fake= thd->rgi_slave= NULL; - delete serial_rgi; - mysql_mutex_unlock(&LOCK_thread_count); #ifdef WITH_WSREP /* @@ -4940,10 +4929,11 @@ err_during_init: #endif /* WITH_WSREP */ /* - Note: the order of the broadcast and unlock calls below (first broadcast, then unlock) - is important. Otherwise a killer_thread can execute between the calls and - delete the mi structure leading to a crash! (see BUG#25306 for details) - */ + Note: the order of the broadcast and unlock calls below (first + broadcast, then unlock) is important. Otherwise a killer_thread can + execute between the calls and delete the mi structure leading to a + crash! (see BUG#25306 for details) + */ mysql_cond_broadcast(&rli->stop_cond); DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5);); mysql_mutex_unlock(&rli->run_lock); // tell the world we are done @@ -4960,9 +4950,13 @@ err_during_init: rpl_parallel_inactivate_pool(&global_rpl_thread_pool); mysql_mutex_unlock(&LOCK_active_mi); + /* TODO: Check if this lock is needed */ mysql_mutex_lock(&LOCK_thread_count); - delete thd; + delete serial_rgi; mysql_mutex_unlock(&LOCK_thread_count); + + THD_CHECK_SENTRY(thd); + delete thd; thread_safe_decrement32(&service_thread_count); signal_thd_deleted(); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index cb598b367e7..d58b51afc5e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -70,28 +70,6 @@ static void reset_start_time_for_sp(THD *thd) thd->set_start_time(); } -Item_result -sp_map_result_type(enum enum_field_types type) -{ - switch (type) { - case MYSQL_TYPE_BIT: - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_INT24: - return INT_RESULT; - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: - return DECIMAL_RESULT; - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - return REAL_RESULT; - default: - return STRING_RESULT; - } -} - Item::Type sp_map_item_type(enum enum_field_types type) @@ -238,6 +216,7 @@ sp_get_flags_for_command(LEX *lex) case SQLCOM_SHOW_CREATE_PROC: case SQLCOM_SHOW_CREATE_EVENT: case SQLCOM_SHOW_CREATE_TRIGGER: + case SQLCOM_SHOW_CREATE_USER: case SQLCOM_SHOW_DATABASES: case SQLCOM_SHOW_ERRORS: case SQLCOM_SHOW_EXPLAIN: @@ -305,6 +284,7 @@ sp_get_flags_for_command(LEX *lex) case SQLCOM_CREATE_USER: case SQLCOM_CREATE_ROLE: case SQLCOM_ALTER_TABLE: + case SQLCOM_ALTER_USER: case SQLCOM_GRANT: case SQLCOM_GRANT_ROLE: case SQLCOM_REVOKE: @@ -764,7 +744,7 @@ sp_head::set_stmt_end(THD *thd) static TYPELIB * -create_typelib(MEM_ROOT *mem_root, Create_field *field_def, List<String> *src) +create_typelib(MEM_ROOT *mem_root, Column_definition *field_def, List<String> *src) { TYPELIB *result= NULL; CHARSET_INFO *cs= field_def->charset; @@ -863,30 +843,56 @@ Field * sp_head::create_result_field(uint field_max_length, const char *field_name, TABLE *table) { - uint field_length; Field *field; DBUG_ENTER("sp_head::create_result_field"); - field_length= !m_return_field_def.length ? - field_max_length : m_return_field_def.length; - - field= ::make_field(table->s, /* TABLE_SHARE ptr */ - table->in_use->mem_root, - (uchar*) 0, /* field ptr */ - field_length, /* field [max] length */ - (uchar*) "", /* null ptr */ - 0, /* null bit */ - m_return_field_def.pack_flag, - m_return_field_def.sql_type, - m_return_field_def.charset, - m_return_field_def.geom_type, m_return_field_def.srid, - Field::NONE, /* unreg check */ - m_return_field_def.interval, - field_name ? field_name : (const char *) m_name.str); + /* + m_return_field_def.length is always set to the field length calculated + by the parser, according to the RETURNS clause. See prepare_create_field() + in sql_table.cc. Value examples, depending on data type: + - 11 for INT (character representation length) + - 20 for BIGINT (character representation length) + - 22 for DOUBLE (character representation length) + - N for CHAR(N) CHARACTER SET latin1 (octet length) + - 3*N for CHAR(N) CHARACTER SET utf8 (octet length) + - 8 for blob-alike data types (packed length !!!) + + field_max_length is also set according to the data type in the RETURNS + clause but can have different values depending on the execution stage: + + 1. During direct execution: + field_max_length is 0, because Item_func_sp::fix_length_and_dec() has + not been called yet, so Item_func_sp::max_length is 0 by default. + + 2a. During PREPARE: + field_max_length is 0, because Item_func_sp::fix_length_and_dec() + has not been called yet. It's called after create_result_field(). + + 2b. During EXEC: + field_max_length is set to the maximum possible octet length of the + RETURNS data type. + - N for CHAR(N) CHARACTER SET latin1 (octet length) + - 3*N for CHAR(N) CHARACTER SET utf8 (octet length) + - 255 for TINYBLOB (octet length, not packed length !!!) + + Perhaps we should refactor prepare_create_field() to set + Create_field::length to maximum octet length for BLOBs, + instead of packed length). + */ + DBUG_ASSERT(field_max_length <= m_return_field_def.length || + (current_thd->stmt_arena->is_stmt_execute() && + m_return_field_def.length == 8 && + (m_return_field_def.pack_flag & + (FIELDFLAG_BLOB|FIELDFLAG_GEOM)))); + + field= m_return_field_def.make_field(table->s, /* TABLE_SHARE ptr */ + table->in_use->mem_root, + field_name ? + field_name : + (const char *) m_name.str); field->vcol_info= m_return_field_def.vcol_info; - field->stored_in_db= m_return_field_def.stored_in_db; if (field) field->init(table); @@ -1185,7 +1191,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) /* Switch query context. This has to be done early as this is sometimes - allocated trough sql_alloc + allocated on THD::mem_root */ if (m_creation_ctx) saved_creation_ctx= m_creation_ctx->set_n_backup(thd); @@ -2149,7 +2155,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) } Send_field *out_param_info= new (thd->mem_root) Send_field(); - nctx->get_item(i)->make_field(out_param_info); + nctx->get_item(i)->make_field(thd, out_param_info); out_param_info->db_name= m_db.str; out_param_info->table_name= m_name.str; out_param_info->org_table_name= m_name.str; @@ -2292,9 +2298,9 @@ sp_head::restore_lex(THD *thd) Put the instruction on the backpatch list, associated with the label. */ int -sp_head::push_backpatch(sp_instr *i, sp_label *lab) +sp_head::push_backpatch(THD *thd, sp_instr *i, sp_label *lab) { - bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t)); + bp_t *bp= (bp_t *) thd->alloc(sizeof(bp_t)); if (!bp) return 1; @@ -2328,12 +2334,11 @@ sp_head::backpatch(sp_label *lab) } /** - Prepare an instance of Create_field for field creation (fill all necessary - attributes). + Prepare an instance of Column_definition for field creation + (fill all necessary attributes). @param[in] thd Thread handle @param[in] lex Yacc parsing context - @param[in] field_type Field type @param[out] field_def An instance of create_field to be filled @retval @@ -2344,8 +2349,7 @@ sp_head::backpatch(sp_label *lab) bool sp_head::fill_field_definition(THD *thd, LEX *lex, - enum enum_field_types field_type, - Create_field *field_def) + Column_definition *field_def) { uint unused1= 0; diff --git a/sql/sp_head.h b/sql/sp_head.h index 604190079cb..65aad1dd5a1 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -45,9 +45,6 @@ //#define TYPE_ENUM_FUNCTION 1 #define TYPE_ENUM_PROCEDURE 2 #define //TYPE_ENUM_TRIGGER 3 #define TYPE_ENUM_PROXY 4 -Item_result -sp_map_result_type(enum enum_field_types type); - Item::Type sp_map_item_type(enum enum_field_types type); @@ -181,7 +178,7 @@ public: stored_procedure_type m_type; uint m_flags; // Boolean attributes of a stored routine - Create_field m_return_field_def; /**< This is used for FUNCTIONs only. */ + Column_definition m_return_field_def; /**< This is used for FUNCTIONs only. */ const char *m_tmp_query; ///< Temporary pointer to sub query string st_sp_chistics *m_chistics; @@ -389,7 +386,7 @@ public: /// Put the instruction on the backpatch list, associated with the label. int - push_backpatch(sp_instr *, sp_label *); + push_backpatch(THD *thd, sp_instr *, sp_label *); /// Update all instruction with this label in the backpatch list to /// the current position. @@ -421,8 +418,7 @@ public: TABLE *table); bool fill_field_definition(THD *thd, LEX *lex, - enum enum_field_types field_type, - Create_field *field_def); + Column_definition *field_def); void set_info(longlong created, longlong modified, st_sp_chistics *chistics, ulonglong sql_mode); diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index faf5a2de891..9a6353c9337 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -450,7 +450,7 @@ bool sp_pcontext::find_cursor(LEX_STRING name, void sp_pcontext::retrieve_field_definitions( - List<Create_field> *field_def_lst) const + List<Column_definition> *field_def_lst) const { /* Put local/context fields in the result list. */ diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index efe9531c3a0..2a080536b8a 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -43,9 +43,6 @@ public: /// Name of the SP-variable. LEX_STRING name; - /// Field-type of the SP-variable. - enum enum_field_types type; - /// Mode of the SP-variable. enum_mode mode; @@ -60,13 +57,14 @@ public: Item *default_value; /// Full type information (field meta-data) of the SP-variable. - Create_field field_def; + Column_definition field_def; + /// Field-type of the SP-variable. + enum_field_types sql_type() const { return field_def.sql_type; } public: sp_variable(LEX_STRING _name, uint _offset) :Sql_alloc(), name(_name), - type(MYSQL_TYPE_NULL), mode(MODE_IN), offset(_offset), default_value(NULL) @@ -347,7 +345,7 @@ public: /// context and its children. /// /// @param field_def_lst[out] Container to store type information. - void retrieve_field_definitions(List<Create_field> *field_def_lst) const; + void retrieve_field_definitions(List<Column_definition> *field_def_lst) const; /// Find SP-variable by name. /// diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index b38f4a3ddad..6e724468966 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -104,7 +104,7 @@ bool sp_rcontext::alloc_arrays(THD *thd) bool sp_rcontext::init_var_table(THD *thd) { - List<Create_field> field_def_lst; + List<Column_definition> field_def_lst; if (!m_root_parsing_ctx->max_var_index()) return false; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d34f04ceb6f..241f19c75a3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -634,9 +634,6 @@ bool ROLE_GRANT_PAIR::init(MEM_ROOT *mem, char *username, char *hostname, char *rolename, bool with_admin_option) { - if (!this) - return true; - size_t uname_l = safe_strlen(username); size_t hname_l = safe_strlen(hostname); size_t rname_l = safe_strlen(rolename); @@ -1209,7 +1206,8 @@ static bool acl_load(THD *thd, TABLE_LIST *tables) (void) my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST), 20, 50, MYF(0)); if ((table= tables[HOST_TABLE].table)) // "host" table may not exist (e.g. in MySQL 5.6.7+) { - if (init_read_record(&read_record_info, thd, table, NULL, 1, 1, FALSE)) + if (init_read_record(&read_record_info, thd, table, NULL, NULL, + 1, 1, FALSE)) goto end; table->use_all_columns(); while (!(read_record_info.read_record(&read_record_info))) @@ -1264,7 +1262,7 @@ static bool acl_load(THD *thd, TABLE_LIST *tables) freeze_size(&acl_hosts); if (init_read_record(&read_record_info, thd, table=tables[USER_TABLE].table, - NULL, 1, 1, FALSE)) + NULL, NULL, 1, 1, FALSE)) goto end; table->use_all_columns(); (void) my_init_dynamic_array(&acl_users,sizeof(ACL_USER), 50, 100, MYF(0)); @@ -1526,7 +1524,7 @@ static bool acl_load(THD *thd, TABLE_LIST *tables) freeze_size(&acl_users); if (init_read_record(&read_record_info, thd, table=tables[DB_TABLE].table, - NULL, 1, 1, FALSE)) + NULL, NULL, 1, 1, FALSE)) goto end; table->use_all_columns(); (void) my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB), 50, 100, MYF(0)); @@ -1596,7 +1594,7 @@ static bool acl_load(THD *thd, TABLE_LIST *tables) if ((table= tables[PROXIES_PRIV_TABLE].table)) { if (init_read_record(&read_record_info, thd, table, - NULL, 1, 1, FALSE)) + NULL, NULL, 1, 1, FALSE)) goto end; table->use_all_columns(); while (!(read_record_info.read_record(&read_record_info))) @@ -1625,7 +1623,8 @@ static bool acl_load(THD *thd, TABLE_LIST *tables) if ((table= tables[ROLES_MAPPING_TABLE].table)) { - if (init_read_record(&read_record_info, thd, table, NULL, 1, 1, FALSE)) + if (init_read_record(&read_record_info, thd, table, NULL, NULL, 1, 1, + FALSE)) goto end; table->use_all_columns(); /* account for every role mapping */ @@ -6598,12 +6597,10 @@ bool grant_init() static bool grant_load(THD *thd, TABLE_LIST *tables) { - MEM_ROOT *memex_ptr; bool return_val= 1; TABLE *t_table, *c_table, *p_table; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; - MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, - THR_MALLOC); + MEM_ROOT *save_mem_root= thd->mem_root; ulonglong old_sql_mode= thd->variables.sql_mode; DBUG_ENTER("grant_load"); @@ -6628,15 +6625,14 @@ static bool grant_load(THD *thd, TABLE_LIST *tables) t_table->use_all_columns(); c_table->use_all_columns(); - memex_ptr= &grant_memroot; - my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr); + thd->mem_root= &grant_memroot; if (!t_table->file->ha_index_first(t_table->record[0])) { do { GRANT_TABLE *mem_check; - if (!(mem_check=new (memex_ptr) GRANT_TABLE(t_table,c_table))) + if (!(mem_check= new (&grant_memroot) GRANT_TABLE(t_table, c_table))) { /* This could only happen if we are out memory */ goto end_unlock; @@ -6681,7 +6677,7 @@ static bool grant_load(THD *thd, TABLE_LIST *tables) { GRANT_NAME *mem_check; HASH *hash; - if (!(mem_check=new (memex_ptr) GRANT_NAME(p_table, TRUE))) + if (!(mem_check= new (&grant_memroot) GRANT_NAME(p_table, TRUE))) { /* This could only happen if we are out memory */ goto end_unlock_p; @@ -6734,7 +6730,7 @@ end_unlock_p: p_table->file->ha_index_end(); end_unlock: t_table->file->ha_index_end(); - my_pthread_setspecific_ptr(THR_MALLOC, save_mem_root_ptr); + thd->mem_root= save_mem_root; end_index_init: thd->variables.sql_mode= old_sql_mode; DBUG_RETURN(return_val); @@ -7684,6 +7680,94 @@ static void add_user_option(String *grant, double value, const char *name) } } +static void add_user_parameters(String *result, ACL_USER* acl_user, + bool with_grant) +{ + result->append(STRING_WITH_LEN("@'")); + result->append(acl_user->host.hostname, acl_user->hostname_length, + system_charset_info); + result->append('\''); + + if (acl_user->plugin.str == native_password_plugin_name.str || + acl_user->plugin.str == old_password_plugin_name.str) + { + if (acl_user->auth_string.length) + { + DBUG_ASSERT(acl_user->salt_len); + result->append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '")); + result->append(acl_user->auth_string.str, acl_user->auth_string.length); + result->append('\''); + } + } + else + { + result->append(STRING_WITH_LEN(" IDENTIFIED VIA ")); + result->append(acl_user->plugin.str, acl_user->plugin.length); + if (acl_user->auth_string.length) + { + result->append(STRING_WITH_LEN(" USING '")); + result->append(acl_user->auth_string.str, acl_user->auth_string.length); + result->append('\''); + } + } + /* "show grants" SSL related stuff */ + if (acl_user->ssl_type == SSL_TYPE_ANY) + result->append(STRING_WITH_LEN(" REQUIRE SSL")); + else if (acl_user->ssl_type == SSL_TYPE_X509) + result->append(STRING_WITH_LEN(" REQUIRE X509")); + else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED) + { + int ssl_options = 0; + result->append(STRING_WITH_LEN(" REQUIRE ")); + if (acl_user->x509_issuer) + { + ssl_options++; + result->append(STRING_WITH_LEN("ISSUER \'")); + result->append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); + result->append('\''); + } + if (acl_user->x509_subject) + { + if (ssl_options++) + result->append(' '); + result->append(STRING_WITH_LEN("SUBJECT \'")); + result->append(acl_user->x509_subject,strlen(acl_user->x509_subject), + system_charset_info); + result->append('\''); + } + if (acl_user->ssl_cipher) + { + if (ssl_options++) + result->append(' '); + result->append(STRING_WITH_LEN("CIPHER '")); + result->append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher), + system_charset_info); + result->append('\''); + } + } + if (with_grant || + (acl_user->user_resource.questions || + acl_user->user_resource.updates || + acl_user->user_resource.conn_per_hour || + acl_user->user_resource.user_conn || + acl_user->user_resource.max_statement_time != 0.0)) + { + result->append(STRING_WITH_LEN(" WITH")); + if (with_grant) + result->append(STRING_WITH_LEN(" GRANT OPTION")); + add_user_option(result, acl_user->user_resource.questions, + "MAX_QUERIES_PER_HOUR", false); + add_user_option(result, acl_user->user_resource.updates, + "MAX_UPDATES_PER_HOUR", false); + add_user_option(result, acl_user->user_resource.conn_per_hour, + "MAX_CONNECTIONS_PER_HOUR", false); + add_user_option(result, acl_user->user_resource.user_conn, + "MAX_USER_CONNECTIONS", true); + add_user_option(result, acl_user->user_resource.max_statement_time, + "MAX_STATEMENT_TIME"); + } +} + static const char *command_array[]= { "SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "RELOAD", @@ -7730,6 +7814,77 @@ static bool print_grants_for_role(THD *thd, ACL_ROLE * role) } +bool mysql_show_create_user(THD *thd, LEX_USER *lex_user) +{ + const char *username = safe_str(lex_user->user.str); + const char *hostname = safe_str(lex_user->host.str); + char buff[1024]; //Show create user should not take more than 1024 bytes. + Protocol *protocol= thd->protocol; + bool error= false; + ACL_USER *acl_user; + DBUG_ENTER("mysql_show_create_user"); + + // Check if the command specifies a username or not. + if (lex_user->user.str == current_user.str) + { + username= thd->security_ctx->priv_user; + hostname= thd->security_ctx->priv_host; + } + + List<Item> field_list; + strxmov(buff, "CREATE USER for ", username, "@", hostname, NullS); + Item_string *field = new (thd->mem_root) Item_string_ascii(thd, "", 0); + if (!field) + { + my_error(ER_OUTOFMEMORY, MYF(0)); + DBUG_RETURN(true); + } + + field->name= buff; + field->max_length= sizeof(buff); + field_list.push_back(field, thd->mem_root); + if (protocol->send_result_set_metadata(&field_list, + Protocol::SEND_NUM_ROWS | + Protocol::SEND_EOF)) + DBUG_RETURN(true); + + String result(buff, sizeof(buff), system_charset_info); + result.length(0); + mysql_rwlock_rdlock(&LOCK_grant); + mysql_mutex_lock(&acl_cache->lock); + + acl_user= find_user_exact(hostname, username); + + // User not found in the internal data structures. + if (!acl_user) + { + my_error(ER_PASSWORD_NO_MATCH, MYF(0)); + error= true; + goto end; + } + + result.append("CREATE USER '"); + result.append(username); + result.append('\''); + + add_user_parameters(&result, acl_user, false); + + protocol->prepare_for_resend(); + protocol->store(result.ptr(), result.length(), result.charset()); + if (protocol->write()) + { + error= true; + } + my_eof(thd); + +end: + mysql_rwlock_unlock(&LOCK_grant); + mysql_mutex_unlock(&acl_cache->lock); + + DBUG_RETURN(error); +} + + static int show_grants_callback(ACL_USER_BASE *role, void *data) { THD *thd= (THD *)data; @@ -7739,7 +7894,6 @@ static int show_grants_callback(ACL_USER_BASE *role, void *data) return 0; } - void mysql_show_grants_get_fields(THD *thd, List<Item> *fields, const char *name) { @@ -8007,93 +8161,7 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry, global.append('\''); if (!handle_as_role) - { - ACL_USER *acl_user= (ACL_USER *)acl_entry; - - global.append (STRING_WITH_LEN("@'")); - global.append(acl_user->host.hostname, acl_user->hostname_length, - system_charset_info); - global.append ('\''); - - if (acl_user->plugin.str == native_password_plugin_name.str || - acl_user->plugin.str == old_password_plugin_name.str) - { - if (acl_user->auth_string.length) - { - DBUG_ASSERT(acl_user->salt_len); - global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '")); - global.append(acl_user->auth_string.str, acl_user->auth_string.length); - global.append('\''); - } - } - else - { - global.append(STRING_WITH_LEN(" IDENTIFIED VIA ")); - global.append(acl_user->plugin.str, acl_user->plugin.length); - if (acl_user->auth_string.length) - { - global.append(STRING_WITH_LEN(" USING '")); - global.append(acl_user->auth_string.str, acl_user->auth_string.length); - global.append('\''); - } - } - /* "show grants" SSL related stuff */ - if (acl_user->ssl_type == SSL_TYPE_ANY) - global.append(STRING_WITH_LEN(" REQUIRE SSL")); - else if (acl_user->ssl_type == SSL_TYPE_X509) - global.append(STRING_WITH_LEN(" REQUIRE X509")); - else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED) - { - int ssl_options = 0; - global.append(STRING_WITH_LEN(" REQUIRE ")); - if (acl_user->x509_issuer) - { - ssl_options++; - global.append(STRING_WITH_LEN("ISSUER \'")); - global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); - global.append('\''); - } - if (acl_user->x509_subject) - { - if (ssl_options++) - global.append(' '); - global.append(STRING_WITH_LEN("SUBJECT \'")); - global.append(acl_user->x509_subject,strlen(acl_user->x509_subject), - system_charset_info); - global.append('\''); - } - if (acl_user->ssl_cipher) - { - if (ssl_options++) - global.append(' '); - global.append(STRING_WITH_LEN("CIPHER '")); - global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher), - system_charset_info); - global.append('\''); - } - } - if ((want_access & GRANT_ACL) || - (acl_user->user_resource.questions || - acl_user->user_resource.updates || - acl_user->user_resource.conn_per_hour || - acl_user->user_resource.user_conn || - acl_user->user_resource.max_statement_time != 0.0)) - { - global.append(STRING_WITH_LEN(" WITH")); - if (want_access & GRANT_ACL) - global.append(STRING_WITH_LEN(" GRANT OPTION")); - add_user_option(&global, acl_user->user_resource.questions, - "MAX_QUERIES_PER_HOUR", false); - add_user_option(&global, acl_user->user_resource.updates, - "MAX_UPDATES_PER_HOUR", false); - add_user_option(&global, acl_user->user_resource.conn_per_hour, - "MAX_CONNECTIONS_PER_HOUR", false); - add_user_option(&global, acl_user->user_resource.user_conn, - "MAX_USER_CONNECTIONS", true); - add_user_option(&global, acl_user->user_resource.max_statement_time, - "MAX_STATEMENT_TIME"); - } - } + add_user_parameters(&global, (ACL_USER *)acl_entry, (want_access & GRANT_ACL)); protocol->prepare_for_resend(); protocol->store(global.ptr(),global.length(),global.charset()); @@ -9750,6 +9818,73 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) DBUG_RETURN(result); } +/* + Alter a user's connection and resource settings. + + SYNOPSIS + mysql_alter_user() + thd The current thread. + list The users to alter. + + RETURN + > 0 Error. Error message already sent. + 0 OK. +*/ +int mysql_alter_user(THD* thd, List<LEX_USER> &users_list) +{ + DBUG_ENTER("mysql_alter_user"); + int result= 0; + TABLE_LIST tables[TABLES_MAX]; + String wrong_users; + // The only table we're altering is the user table. + if ((result= open_grant_tables(thd, tables, TL_WRITE, Table_user))) + DBUG_RETURN(result); + + // Lock ACL data structures until we finish altering all users. + mysql_rwlock_wrlock(&LOCK_grant); + mysql_mutex_lock(&acl_cache->lock); + + LEX_USER *tmp_lex_user; + List_iterator<LEX_USER> users_list_iterator(users_list); + while ((tmp_lex_user= users_list_iterator++)) + { + LEX_USER* lex_user= get_current_user(thd, tmp_lex_user, false); + if (!lex_user || + fix_lex_user(thd, lex_user) || + replace_user_table(thd, tables[USER_TABLE].table, *lex_user,0, + false, false, true)) + { + thd->clear_error(); + append_user(thd, &wrong_users, tmp_lex_user); + result= TRUE; + continue; + } + } + + // Unlock ACL data structures. + mysql_mutex_unlock(&acl_cache->lock); + mysql_rwlock_unlock(&LOCK_grant); + + if (result) + { + // 'if exists' flag leads to warnings instead of errors. + if (thd->lex->create_info.if_exists()) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_CANNOT_USER, + ER_THD(thd, ER_CANNOT_USER), + "ALTER USER", wrong_users.c_ptr_safe()); + result= FALSE; + } + else + { + my_error(ER_CANNOT_USER, MYF(0), + "ALTER USER", + wrong_users.c_ptr_safe()); + } + } + DBUG_RETURN(result); +} /* Revoke all privileges from a list of users. @@ -10937,7 +11072,7 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, /* global privileges */ grant->privilege= sctx->master_access; - if (!sctx->priv_user) + if (!sctx->priv_user[0]) { DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); DBUG_VOID_RETURN; // it is slave @@ -11336,7 +11471,8 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, int2store(end+5, thd->client_capabilities >> 16); end[7]= data_len; DBUG_EXECUTE_IF("poison_srv_handshake_scramble_len", end[7]= -100;); - bzero(end + 8, 10); + bzero(end + 8, 6); + int4store(end + 14, thd->client_capabilities >> 32); end+= 18; /* write scramble tail */ end= (char*) memcpy(end, data + SCRAMBLE_LENGTH_323, @@ -11752,18 +11888,27 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, */ DBUG_ASSERT(net->read_pos[pkt_len] == 0); - ulong client_capabilities= uint2korr(net->read_pos); + ulonglong client_capabilities= uint2korr(net->read_pos); + compile_time_assert(sizeof(client_capabilities) >= 8); if (client_capabilities & CLIENT_PROTOCOL_41) { - if (pkt_len < 4) + if (pkt_len < 32) return packet_error; client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; + if (!(client_capabilities & CLIENT_MYSQL)) + { + // it is client with mariadb extensions + ulonglong ext_client_capabilities= + (((ulonglong)uint4korr(net->read_pos + 28)) << 32); + client_capabilities|= ext_client_capabilities; + } } /* Disable those bits which are not supported by the client. */ + compile_time_assert(sizeof(thd->client_capabilities) >= 8); thd->client_capabilities&= client_capabilities; - DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities)); + DBUG_PRINT("info", ("client capabilities: %llu", thd->client_capabilities)); if (thd->client_capabilities & CLIENT_SSL) { unsigned long errptr __attribute__((unused)); @@ -11791,8 +11936,6 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, if (client_capabilities & CLIENT_PROTOCOL_41) { - if (pkt_len < 32) - return packet_error; thd->max_client_packet_length= uint4korr(net->read_pos+4); DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8])); if (thd_init_client_charset(thd, (uint) net->read_pos[8])) @@ -12569,7 +12712,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len) } DBUG_PRINT("info", - ("Capabilities: %lu packet_length: %ld Host: '%s' " + ("Capabilities: %llu packet_length: %ld Host: '%s' " "Login user: '%s' Priv_user: '%s' Using password: %s " "Access: %lu db: '%s'", thd->client_capabilities, thd->max_client_packet_length, diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 0893504b72d..be206b1f86f 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -244,6 +244,7 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant, void mysql_show_grants_get_fields(THD *thd, List<Item> *fields, const char *name); bool mysql_show_grants(THD *thd, LEX_USER *user); +bool mysql_show_create_user(THD *thd, LEX_USER *user); int fill_schema_enabled_roles(THD *thd, TABLE_LIST *tables, COND *cond); int fill_schema_applicable_roles(THD *thd, TABLE_LIST *tables, COND *cond); void get_privilege_desc(char *to, uint max_length, ulong access); @@ -251,6 +252,7 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc); bool mysql_create_user(THD *thd, List <LEX_USER> &list, bool handle_as_role); bool mysql_drop_user(THD *thd, List <LEX_USER> &list, bool handle_as_role); bool mysql_rename_user(THD *thd, List <LEX_USER> &list); +int mysql_alter_user(THD *thd, List <LEX_USER> &list); bool mysql_revoke_all(THD *thd, List <LEX_USER> &list); void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, const char *db, const char *table); diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index f27cdcc41f2..205621c6f9f 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -131,7 +131,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, DBUG_RETURN(0); has_mdl_lock= TRUE; - share= tdc_acquire_share_shortlived(thd, table_list, GTS_TABLE); + share= tdc_acquire_share(thd, table_list, GTS_TABLE); if (share == NULL) DBUG_RETURN(0); // Can't open frm file diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 1f801a33dcd..b2bc9fc2e87 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -134,7 +134,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, } if (!(pc->f_info= - (field_info**)sql_alloc(sizeof(field_info*)*field_list.elements))) + (field_info**) thd->alloc(sizeof(field_info*) * field_list.elements))) goto err; pc->f_end = pc->f_info + field_list.elements; pc->fields = field_list; diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc index b659054a50b..e2132efc528 100644 --- a/sql/sql_audit.cc +++ b/sql/sql_audit.cc @@ -24,6 +24,7 @@ extern int finalize_audit_plugin(st_plugin_int *plugin); struct st_mysql_event_generic { + unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; unsigned int event_class; const void *event; }; @@ -32,8 +33,6 @@ unsigned long mysql_global_audit_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; static mysql_mutex_t LOCK_audit_mask; -static void event_class_dispatch(THD *, unsigned int, const void *); - static inline void set_audit_mask(unsigned long *mask, uint event_class) @@ -56,101 +55,6 @@ bool check_audit_mask(const unsigned long *lhs, } -typedef void (*audit_handler_t)(THD *thd, uint event_subtype, va_list ap); - -/** - MYSQL_AUDIT_GENERAL_CLASS handler - - @param[in] thd - @param[in] event_subtype - @param[in] error_code - @param[in] ap - -*/ - -static void general_class_handler(THD *thd, uint event_subtype, va_list ap) -{ - mysql_event_general event; - event.event_subclass= event_subtype; - event.general_error_code= va_arg(ap, int); - event.general_thread_id= thd ? thd->thread_id : 0; - event.general_time= va_arg(ap, time_t); - event.general_user= va_arg(ap, const char *); - event.general_user_length= va_arg(ap, unsigned int); - event.general_command= va_arg(ap, const char *); - event.general_command_length= va_arg(ap, unsigned int); - event.general_query= va_arg(ap, const char *); - event.general_query_length= va_arg(ap, unsigned int); - event.general_charset= va_arg(ap, struct charset_info_st *); - event.general_rows= (unsigned long long) va_arg(ap, ha_rows); - event.database= va_arg(ap, const char *); - event.database_length= va_arg(ap, unsigned int); - event.query_id= (unsigned long long) (thd ? thd->query_id : 0); - event_class_dispatch(thd, MYSQL_AUDIT_GENERAL_CLASS, &event); -} - - -static void connection_class_handler(THD *thd, uint event_subclass, va_list ap) -{ - mysql_event_connection event; - event.event_subclass= event_subclass; - event.status= va_arg(ap, int); - event.thread_id= va_arg(ap, unsigned long); - event.user= va_arg(ap, const char *); - event.user_length= va_arg(ap, unsigned int); - event.priv_user= va_arg(ap, const char *); - event.priv_user_length= va_arg(ap, unsigned int); - event.external_user= va_arg(ap, const char *); - event.external_user_length= va_arg(ap, unsigned int); - event.proxy_user= va_arg(ap, const char *); - event.proxy_user_length= va_arg(ap, unsigned int); - event.host= va_arg(ap, const char *); - event.host_length= va_arg(ap, unsigned int); - event.ip= va_arg(ap, const char *); - event.ip_length= va_arg(ap, unsigned int); - event.database= va_arg(ap, const char *); - event.database_length= va_arg(ap, unsigned int); - event_class_dispatch(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event); -} - - -static void table_class_handler(THD *thd, uint event_subclass, va_list ap) -{ - mysql_event_table event; - event.event_subclass= event_subclass; - event.read_only= va_arg(ap, int); - event.thread_id= va_arg(ap, unsigned long); - event.user= va_arg(ap, const char *); - event.priv_user= va_arg(ap, const char *); - event.priv_host= va_arg(ap, const char *); - event.external_user= va_arg(ap, const char *); - event.proxy_user= va_arg(ap, const char *); - event.host= va_arg(ap, const char *); - event.ip= va_arg(ap, const char *); - event.database= va_arg(ap, const char *); - event.database_length= va_arg(ap, unsigned int); - event.table= va_arg(ap, const char *); - event.table_length= va_arg(ap, unsigned int); - event.new_database= va_arg(ap, const char *); - event.new_database_length= va_arg(ap, unsigned int); - event.new_table= va_arg(ap, const char *); - event.new_table_length= va_arg(ap, unsigned int); - event.query_id= (unsigned long long) (thd ? thd->query_id : 0); - event_class_dispatch(thd, MYSQL_AUDIT_TABLE_CLASS, &event); -} - - -static audit_handler_t audit_handlers[] = -{ - general_class_handler, connection_class_handler, - 0,0,0,0,0,0,0,0,0,0,0,0,0, /* placeholders */ - table_class_handler -}; - -static const uint audit_handlers_count= - (sizeof(audit_handlers) / sizeof(audit_handler_t)); - - /** Acquire and lock any additional audit plugins as required @@ -207,38 +111,16 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg) void mysql_audit_acquire_plugins(THD *thd, ulong *event_class_mask) { DBUG_ENTER("mysql_audit_acquire_plugins"); - if (thd && !check_audit_mask(mysql_global_audit_mask, event_class_mask) && - check_audit_mask(thd->audit_class_mask, event_class_mask)) + DBUG_ASSERT(thd); + DBUG_ASSERT(!check_audit_mask(mysql_global_audit_mask, event_class_mask)); + + if (check_audit_mask(thd->audit_class_mask, event_class_mask)) { plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, event_class_mask); add_audit_mask(thd->audit_class_mask, event_class_mask); } DBUG_VOID_RETURN; } - - -/** - Notify the audit system of an event - - @param[in] thd - @param[in] event_class - @param[in] event_subtype - @param[in] error_code - -*/ - -void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...) -{ - va_list ap; - audit_handler_t *handlers= audit_handlers + event_class; - DBUG_ASSERT(event_class < audit_handlers_count); - unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; - set_audit_mask(event_class_mask, event_class); - mysql_audit_acquire_plugins(thd, event_class_mask); - va_start(ap, event_subtype); - (*handlers)(thd, event_subtype, ap); - va_end(ap); -} /** @@ -496,17 +378,11 @@ static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg) { const struct st_mysql_event_generic *event_generic= (const struct st_mysql_event_generic *) arg; - unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE]; st_mysql_audit *data= plugin_data(plugin, struct st_mysql_audit *); - set_audit_mask(event_class_mask, event_generic->event_class); - /* Check to see if the plugin is interested in this event */ - if (check_audit_mask(data->class_mask, event_class_mask)) - return 0; - - /* Actually notify the plugin */ - data->event_notify(thd, event_generic->event_class, event_generic->event); + if (!check_audit_mask(data->class_mask, event_generic->event_class_mask)) + data->event_notify(thd, event_generic->event_class, event_generic->event); return 0; } @@ -514,17 +390,18 @@ static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg) /** Distributes an audit event to plug-ins - + @param[in] thd + @param[in] event_class @param[in] event */ -static void event_class_dispatch(THD *thd, unsigned int event_class, - const void *event) +void mysql_audit_notify(THD *thd, uint event_class, const void *event) { struct st_mysql_event_generic event_generic; event_generic.event_class= event_class; event_generic.event= event; + set_audit_mask(event_generic.event_class_mask, event_class); /* Check if we are doing a slow global dispatch. This event occurs when thd == NULL as it is not associated with any particular thread. @@ -537,6 +414,8 @@ static void event_class_dispatch(THD *thd, unsigned int event_class, { plugin_ref *plugins, *plugins_last; + mysql_audit_acquire_plugins(thd, event_generic.event_class_mask); + /* Use the cached set of audit plugins */ plugins= (plugin_ref*) thd->audit_class_plugins.buffer; plugins_last= plugins + thd->audit_class_plugins.elements; diff --git a/sql/sql_audit.h b/sql/sql_audit.h index 68106f099cc..d6f670538cd 100644 --- a/sql/sql_audit.h +++ b/sql/sql_audit.h @@ -35,8 +35,7 @@ extern void mysql_audit_acquire_plugins(THD *thd, ulong *event_class_mask); #ifndef EMBEDDED_LIBRARY -extern void mysql_audit_notify(THD *thd, uint event_class, - uint event_subtype, ...); +extern void mysql_audit_notify(THD *thd, uint event_class, const void *event); static inline bool mysql_audit_general_enabled() { @@ -55,7 +54,7 @@ static inline bool mysql_audit_table_enabled() #else static inline void mysql_audit_notify(THD *thd, uint event_class, - uint event_subtype, ...) { } + const void *event) {} #define mysql_audit_general_enabled() 0 #define mysql_audit_connection_enabled() 0 #define mysql_audit_table_enabled() 0 @@ -94,15 +93,37 @@ void mysql_audit_general_log(THD *thd, time_t time, { if (mysql_audit_general_enabled()) { - CHARSET_INFO *clientcs= thd ? thd->variables.character_set_client - : global_system_variables.character_set_client; - const char *db= thd ? thd->db : ""; - size_t db_length= thd ? thd->db_length : 0; - - mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG, - 0, time, user, userlen, cmd, cmdlen, - query, querylen, clientcs, (ha_rows) 0, - db, db_length); + mysql_event_general event; + + event.event_subclass= MYSQL_AUDIT_GENERAL_LOG; + event.general_error_code= 0; + event.general_time= time; + event.general_user= user; + event.general_user_length= userlen; + event.general_command= cmd; + event.general_command_length= cmdlen; + event.general_query= query; + event.general_query_length= querylen; + event.general_rows= 0; + + if (thd) + { + event.general_thread_id= (unsigned long)thd->thread_id; + event.general_charset= thd->variables.character_set_client; + event.database= thd->db; + event.database_length= thd->db_length; + event.query_id= thd->query_id; + } + else + { + event.general_thread_id= 0; + event.general_charset= global_system_variables.character_set_client; + event.database= ""; + event.database_length= 0; + event.query_id= 0; + } + + mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, &event); } } @@ -124,38 +145,41 @@ void mysql_audit_general(THD *thd, uint event_subtype, { if (mysql_audit_general_enabled()) { - time_t time= my_time(0); - uint msglen= msg ? strlen(msg) : 0; - const char *user; - uint userlen; char user_buff[MAX_USER_HOST_SIZE]; - CSET_STRING query; - ha_rows rows; - const char *db; - size_t db_length; + mysql_event_general event; + + event.event_subclass= event_subtype; + event.general_error_code= error_code; + event.general_time= my_time(0); + event.general_command= msg; + event.general_command_length= safe_strlen(msg); if (thd) { - query= thd->query_string; - user= user_buff; - userlen= make_user_name(thd, user_buff); - rows= thd->get_stmt_da()->current_row_for_warning(); - db= thd->db; - db_length= thd->db_length; + event.general_user= user_buff; + event.general_user_length= make_user_name(thd, user_buff); + event.general_thread_id= (unsigned long)thd->thread_id; + event.general_query= thd->query_string.str(); + event.general_query_length= thd->query_string.length(); + event.general_charset= thd->query_string.charset(); + event.general_rows= thd->get_stmt_da()->current_row_for_warning(); + event.database= thd->db; + event.database_length= thd->db_length; + event.query_id= thd->query_id; } else { - user= 0; - userlen= 0; - rows= 0; - db= ""; - db_length= 0; + event.general_thread_id= 0; + event.general_query= NULL; + event.general_query_length= 0; + event.general_charset= &my_charset_bin; + event.general_rows= 0; + event.database= ""; + event.database_length= 0; + event.query_id= 0; } - mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype, - error_code, time, user, userlen, msg, msglen, - query.str(), query.length(), query.charset(), rows, - db, db_length); + mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, &event); } } @@ -165,19 +189,28 @@ void mysql_audit_notify_connection_connect(THD *thd) if (mysql_audit_connection_enabled()) { const Security_context *sctx= thd->security_ctx; - Diagnostics_area *da= thd->get_stmt_da(); - mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, - MYSQL_AUDIT_CONNECTION_CONNECT, - da->is_error() ? da->sql_errno() : 0, - thd->thread_id, - sctx->user, sctx->user ? strlen(sctx->user) : 0, - sctx->priv_user, strlen(sctx->priv_user), - sctx->external_user, - sctx->external_user ? strlen(sctx->external_user) : 0, - sctx->proxy_user, strlen(sctx->proxy_user), - sctx->host, sctx->host ? strlen(sctx->host) : 0, - sctx->ip, sctx->ip ? strlen(sctx->ip) : 0, - thd->db, thd->db ? strlen(thd->db) : 0); + mysql_event_connection event; + + event.event_subclass= MYSQL_AUDIT_CONNECTION_CONNECT; + event.status= thd->get_stmt_da()->is_error() ? + thd->get_stmt_da()->sql_errno() : 0; + event.thread_id= (unsigned long)thd->thread_id; + event.user= sctx->user; + event.user_length= safe_strlen(sctx->user); + event.priv_user= sctx->priv_user; + event.priv_user_length= strlen(sctx->priv_user); + event.external_user= sctx->external_user; + event.external_user_length= safe_strlen(sctx->external_user); + event.proxy_user= sctx->proxy_user; + event.proxy_user_length= strlen(sctx->proxy_user); + event.host= sctx->host; + event.host_length= safe_strlen(sctx->host); + event.ip= sctx->ip; + event.ip_length= safe_strlen(sctx->ip); + event.database= thd->db; + event.database_length= safe_strlen(thd->db); + + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event); } } @@ -187,17 +220,27 @@ void mysql_audit_notify_connection_disconnect(THD *thd, int errcode) if (mysql_audit_connection_enabled()) { const Security_context *sctx= thd->security_ctx; - mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, - MYSQL_AUDIT_CONNECTION_DISCONNECT, - errcode, thd->thread_id, - sctx->user, sctx->user ? strlen(sctx->user) : 0, - sctx->priv_user, strlen(sctx->priv_user), - sctx->external_user, - sctx->external_user ? strlen(sctx->external_user) : 0, - sctx->proxy_user, strlen(sctx->proxy_user), - sctx->host, sctx->host ? strlen(sctx->host) : 0, - sctx->ip, sctx->ip ? strlen(sctx->ip) : 0, - thd->db, thd->db ? strlen(thd->db) : 0); + mysql_event_connection event; + + event.event_subclass= MYSQL_AUDIT_CONNECTION_DISCONNECT; + event.status= errcode; + event.thread_id= (unsigned long)thd->thread_id; + event.user= sctx->user; + event.user_length= safe_strlen(sctx->user); + event.priv_user= sctx->priv_user; + event.priv_user_length= strlen(sctx->priv_user); + event.external_user= sctx->external_user; + event.external_user_length= safe_strlen(sctx->external_user); + event.proxy_user= sctx->proxy_user; + event.proxy_user_length= strlen(sctx->proxy_user); + event.host= sctx->host; + event.host_length= safe_strlen(sctx->host); + event.ip= sctx->ip; + event.ip_length= safe_strlen(sctx->ip) ; + event.database= thd->db; + event.database_length= safe_strlen(thd->db); + + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event); } } @@ -207,19 +250,28 @@ void mysql_audit_notify_connection_change_user(THD *thd) if (mysql_audit_connection_enabled()) { const Security_context *sctx= thd->security_ctx; - Diagnostics_area *da= thd->get_stmt_da(); - mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, - MYSQL_AUDIT_CONNECTION_CHANGE_USER, - da->is_error() ? da->sql_errno() : 0, - thd->thread_id, - sctx->user, sctx->user ? strlen(sctx->user) : 0, - sctx->priv_user, strlen(sctx->priv_user), - sctx->external_user, - sctx->external_user ? strlen(sctx->external_user) : 0, - sctx->proxy_user, strlen(sctx->proxy_user), - sctx->host, sctx->host ? strlen(sctx->host) : 0, - sctx->ip, sctx->ip ? strlen(sctx->ip) : 0, - thd->db, thd->db ? strlen(thd->db) : 0); + mysql_event_connection event; + + event.event_subclass= MYSQL_AUDIT_CONNECTION_CHANGE_USER; + event.status= thd->get_stmt_da()->is_error() ? + thd->get_stmt_da()->sql_errno() : 0; + event.thread_id= (unsigned long)thd->thread_id; + event.user= sctx->user; + event.user_length= safe_strlen(sctx->user); + event.priv_user= sctx->priv_user; + event.priv_user_length= strlen(sctx->priv_user); + event.external_user= sctx->external_user; + event.external_user_length= safe_strlen(sctx->external_user); + event.proxy_user= sctx->proxy_user; + event.proxy_user_length= strlen(sctx->proxy_user); + event.host= sctx->host; + event.host_length= safe_strlen(sctx->host); + event.ip= sctx->ip; + event.ip_length= safe_strlen(sctx->ip); + event.database= thd->db; + event.database_length= safe_strlen(thd->db); + + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, &event); } } @@ -229,13 +281,29 @@ void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock) if (lock != F_UNLCK && mysql_audit_table_enabled()) { const Security_context *sctx= thd->security_ctx; - mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_LOCK, - (int)(lock == F_RDLCK), (ulong)thd->thread_id, - sctx->user, sctx->priv_user, sctx->priv_host, - sctx->external_user, sctx->proxy_user, sctx->host, - sctx->ip, share->db.str, (uint)share->db.length, - share->table_name.str, (uint)share->table_name.length, - 0,0,0,0); + mysql_event_table event; + + event.event_subclass= MYSQL_AUDIT_TABLE_LOCK; + event.read_only= lock == F_RDLCK; + event.thread_id= (unsigned long)thd->thread_id; + event.user= sctx->user; + event.priv_user= sctx->priv_user; + event.priv_host= sctx->priv_host; + event.external_user= sctx->external_user; + event.proxy_user= sctx->proxy_user; + event.host= sctx->host; + event.ip= sctx->ip; + event.database= share->db.str; + event.database_length= share->db.length; + event.table= share->table_name.str; + event.table_length= share->table_name.length; + event.new_database= 0; + event.new_database_length= 0; + event.new_table= 0; + event.new_table_length= 0; + event.query_id= thd->query_id; + + mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event); } } @@ -247,13 +315,29 @@ void mysql_audit_create_table(TABLE *table) THD *thd= table->in_use; const TABLE_SHARE *share= table->s; const Security_context *sctx= thd->security_ctx; - mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_CREATE, - 0, (ulong)thd->thread_id, - sctx->user, sctx->priv_user, sctx->priv_host, - sctx->external_user, sctx->proxy_user, sctx->host, - sctx->ip, share->db.str, (uint)share->db.length, - share->table_name.str, (uint)share->table_name.length, - 0,0,0,0); + mysql_event_table event; + + event.event_subclass= MYSQL_AUDIT_TABLE_CREATE; + event.read_only= 0; + event.thread_id= (unsigned long)thd->thread_id; + event.user= sctx->user; + event.priv_user= sctx->priv_user; + event.priv_host= sctx->priv_host; + event.external_user= sctx->external_user; + event.proxy_user= sctx->proxy_user; + event.host= sctx->host; + event.ip= sctx->ip; + event.database= share->db.str; + event.database_length= share->db.length; + event.table= share->table_name.str; + event.table_length= share->table_name.length; + event.new_database= 0; + event.new_database_length= 0; + event.new_table= 0; + event.new_table_length= 0; + event.query_id= thd->query_id; + + mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event); } } @@ -263,13 +347,29 @@ void mysql_audit_drop_table(THD *thd, TABLE_LIST *table) if (mysql_audit_table_enabled()) { const Security_context *sctx= thd->security_ctx; - mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_DROP, - 0, (ulong)thd->thread_id, - sctx->user, sctx->priv_user, sctx->priv_host, - sctx->external_user, sctx->proxy_user, sctx->host, - sctx->ip, table->db, (uint)table->db_length, - table->table_name, (uint)table->table_name_length, - 0,0,0,0); + mysql_event_table event; + + event.event_subclass= MYSQL_AUDIT_TABLE_DROP; + event.read_only= 0; + event.thread_id= (unsigned long)thd->thread_id; + event.user= sctx->user; + event.priv_user= sctx->priv_user; + event.priv_host= sctx->priv_host; + event.external_user= sctx->external_user; + event.proxy_user= sctx->proxy_user; + event.host= sctx->host; + event.ip= sctx->ip; + event.database= table->db; + event.database_length= table->db_length; + event.table= table->table_name; + event.table_length= table->table_name_length; + event.new_database= 0; + event.new_database_length= 0; + event.new_table= 0; + event.new_table_length= 0; + event.query_id= thd->query_id; + + mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event); } } @@ -280,13 +380,29 @@ void mysql_audit_rename_table(THD *thd, const char *old_db, const char *old_tb, if (mysql_audit_table_enabled()) { const Security_context *sctx= thd->security_ctx; - mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_RENAME, - 0, (ulong)thd->thread_id, - sctx->user, sctx->priv_user, sctx->priv_host, - sctx->external_user, sctx->proxy_user, sctx->host, - sctx->ip, - old_db, (uint)strlen(old_db), old_tb, (uint)strlen(old_tb), - new_db, (uint)strlen(new_db), new_tb, (uint)strlen(new_tb)); + mysql_event_table event; + + event.event_subclass= MYSQL_AUDIT_TABLE_RENAME; + event.read_only= 0; + event.thread_id= (unsigned long)thd->thread_id; + event.user= sctx->user; + event.priv_user= sctx->priv_user; + event.priv_host= sctx->priv_host; + event.external_user= sctx->external_user; + event.proxy_user= sctx->proxy_user; + event.host= sctx->host; + event.ip= sctx->ip; + event.database= old_db; + event.database_length= strlen(old_db); + event.table= old_tb; + event.table_length= strlen(old_tb); + event.new_database= new_db; + event.new_database_length= strlen(new_db); + event.new_table= new_tb; + event.new_table_length= strlen(new_tb); + event.query_id= thd->query_id; + + mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event); } } @@ -296,13 +412,29 @@ void mysql_audit_alter_table(THD *thd, TABLE_LIST *table) if (mysql_audit_table_enabled()) { const Security_context *sctx= thd->security_ctx; - mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_ALTER, - 0, (ulong)thd->thread_id, - sctx->user, sctx->priv_user, sctx->priv_host, - sctx->external_user, sctx->proxy_user, sctx->host, - sctx->ip, table->db, (uint)table->db_length, - table->table_name, (uint)table->table_name_length, - 0,0,0,0); + mysql_event_table event; + + event.event_subclass= MYSQL_AUDIT_TABLE_ALTER; + event.read_only= 0; + event.thread_id= (unsigned long)thd->thread_id; + event.user= sctx->user; + event.priv_user= sctx->priv_user; + event.priv_host= sctx->priv_host; + event.external_user= sctx->external_user; + event.proxy_user= sctx->proxy_user; + event.host= sctx->host; + event.ip= sctx->ip; + event.database= table->db; + event.database_length= table->db_length; + event.table= table->table_name; + event.table_length= table->table_name_length; + event.new_database= 0; + event.new_database_length= 0; + event.new_table= 0; + event.new_table_length= 0; + event.query_id= thd->query_id; + + mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event); } } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 98c63a92a86..08509a0e2bf 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -49,6 +49,7 @@ #include "transaction.h" #include "sql_prepare.h" #include "sql_statistics.h" +#include "sql_cte.h" #include <m_ctype.h> #include <my_dir.h> #include <hash.h> @@ -348,7 +349,6 @@ void intern_close_table(TABLE *table) table->s ? table->s->table_name.str : "?", (long) table)); - free_io_cache(table); delete table->triggers; if (table->file) // Not true if placeholder (void) closefrm(table, 1); // close file @@ -358,21 +358,6 @@ void intern_close_table(TABLE *table) } -/* Free resources allocated by filesort() and read_record() */ - -void free_io_cache(TABLE *table) -{ - DBUG_ENTER("free_io_cache"); - if (table->sort.io_cache) - { - close_cached_file(table->sort.io_cache); - my_free(table->sort.io_cache); - table->sort.io_cache=0; - } - DBUG_VOID_RETURN; -} - - /** Auxiliary function which allows to kill delayed threads for particular table identified by its share. @@ -1228,7 +1213,8 @@ bool close_temporary_tables(THD *thd) */ for (; table && is_user_table(table) && - tmpkeyval(thd, table) == thd->variables.pseudo_thread_id && + (ulong) tmpkeyval(thd, table) == + (ulong) thd->variables.pseudo_thread_id && table->s->db.length == db.length() && memcmp(table->s->db.str, db.ptr(), db.length()) == 0; table= next) @@ -1810,7 +1796,6 @@ void close_temporary(TABLE *table, bool free_share, bool delete_table) DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", table->s->db.str, table->s->table_name.str)); - free_io_cache(table); closefrm(table, 0); if (delete_table) rm_temporary_table(table_type, table->s->path.str); @@ -2299,8 +2284,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) DBUG_RETURN(true); } - if (!tdc_open_view(thd, table_list, alias, key, key_length, - CHECK_METADATA_VERSION)) + if (!tdc_open_view(thd, table_list, CHECK_METADATA_VERSION)) { DBUG_ASSERT(table_list->view != 0); DBUG_RETURN(FALSE); // VIEW @@ -2418,10 +2402,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) retry_share: - share= tdc_acquire_share(thd, table_list->db, table_list->table_name, - key, key_length, - table_list->mdl_request.key.tc_hash_value(), - gts_flags, &table); + share= tdc_acquire_share(thd, table_list, gts_flags, &table); if (!share) { @@ -3271,9 +3252,6 @@ check_and_update_routine_version(THD *thd, Sroutine_hash_entry *rt, @param thd Thread handle @param table_list TABLE_LIST with db, table_name & belong_to_view - @param alias Alias name - @param cache_key Key for table definition cache - @param cache_key_length Length of cache_key @param flags Flags which modify how we open the view @todo This function is needed for special handling of views under @@ -3282,16 +3260,13 @@ check_and_update_routine_version(THD *thd, Sroutine_hash_entry *rt, @return FALSE if success, TRUE - otherwise. */ -bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, - const char *cache_key, uint cache_key_length, - uint flags) +bool tdc_open_view(THD *thd, TABLE_LIST *table_list, uint flags) { TABLE not_used; TABLE_SHARE *share; bool err= TRUE; - if (!(share= tdc_acquire_share(thd, table_list->db, table_list->table_name, - cache_key, cache_key_length, GTS_VIEW))) + if (!(share= tdc_acquire_share(thd, table_list, GTS_VIEW))) return TRUE; DBUG_ASSERT(share->is_view); @@ -3378,7 +3353,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME)))) return result; - if (!(share= tdc_acquire_share_shortlived(thd, table_list, GTS_TABLE))) + if (!(share= tdc_acquire_share(thd, table_list, GTS_TABLE))) goto end_free; DBUG_ASSERT(! share->is_view); @@ -3597,8 +3572,7 @@ Open_table_context::recover_from_failed_open() if (open_if_exists) m_thd->push_internal_handler(&no_such_table_handler); - result= !tdc_acquire_share(m_thd, m_failed_table->db, - m_failed_table->table_name, + result= !tdc_acquire_share(m_thd, m_failed_table, GTS_TABLE | GTS_FORCE_DISCOVERY | GTS_NOLOCK); if (open_if_exists) { @@ -3930,6 +3904,26 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, tables->table_name= tables->view_name.str; tables->table_name_length= tables->view_name.length; } + else if (tables->select_lex) + { + /* + Check whether 'tables' refers to a table defined in a with clause. + If so set the reference to the definition in tables->with. + */ + if (!tables->with) + tables->with= tables->select_lex->find_table_def_in_with_clauses(tables); + /* + If 'tables' is defined in a with clause set the pointer to the + specification from its definition in tables->derived. + */ + if (tables->with) + { + if (tables->set_as_with_table(thd, tables->with)) + DBUG_RETURN(1); + else + goto end; + } + } /* If this TABLE_LIST object is a placeholder for an information_schema table, create a temporary table to represent the information_schema @@ -6083,9 +6077,9 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list, } else { - item->set_name((*ref)->name, (*ref)->name_length, + item->set_name(thd, (*ref)->name, (*ref)->name_length, system_charset_info); - item->real_item()->set_name((*ref)->name, (*ref)->name_length, + item->real_item()->set_name(thd, (*ref)->name, (*ref)->name_length, system_charset_info); } } @@ -6179,9 +6173,9 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, */ if (*ref && !(*ref)->is_autogenerated_name) { - item->set_name((*ref)->name, (*ref)->name_length, + item->set_name(thd, (*ref)->name, (*ref)->name_length, system_charset_info); - item->real_item()->set_name((*ref)->name, (*ref)->name_length, + item->real_item()->set_name(thd, (*ref)->name, (*ref)->name_length, system_charset_info); } if (register_tree_change && arena) @@ -8364,7 +8358,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, temporary table. Thus in this case we can be sure that 'item' is an Item_field. */ - if (any_privileges) + if (any_privileges && !tables->is_with_table() && !tables->is_derived()) { DBUG_ASSERT((tables->field_translation == NULL && table) || tables->is_natural_join); @@ -8735,7 +8729,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values, ER_THD(thd, ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN), rfield->field_name, table->s->table_name.str); } - if ((!rfield->vcol_info || rfield->stored_in_db) && + if (rfield->stored_in_db() && (value->save_in_field(rfield, 0)) < 0 && !ignore_errors) { my_message(ER_UNKNOWN_ERROR, ER_THD(thd, ER_UNKNOWN_ERROR), MYF(0)); diff --git a/sql/sql_base.h b/sql/sql_base.h index 7407e230419..b6e135b6feb 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -267,7 +267,6 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags, uint dt_phases); bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags); int decide_logging_format(THD *thd, TABLE_LIST *tables); -void free_io_cache(TABLE *entry); void intern_close_table(TABLE *entry); void kill_delayed_threads_for_table(TDC_element *element); void close_thread_table(THD *thd, TABLE **table_ptr); @@ -305,16 +304,7 @@ void close_all_tables_for_name(THD *thd, TABLE_SHARE *share, ha_extra_function extra, TABLE *skip_table); OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild); -bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, - const char *cache_key, uint cache_key_length, uint flags); - -static inline bool tdc_open_view(THD *thd, TABLE_LIST *table_list, - const char *alias, uint flags) -{ - const char *key; - uint key_length= get_table_def_key(table_list, &key); - return tdc_open_view(thd, table_list, alias, key, key_length, flags); -} +bool tdc_open_view(THD *thd, TABLE_LIST *table_list, uint flags); TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, const char *table_name, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d2ebbc64c47..e3b70566597 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -370,16 +370,6 @@ void thd_close_connection(THD *thd) } /** - Get current THD object from thread local data - - @retval The THD object for the thread, NULL if not connection thread -*/ -THD *thd_get_current_thd() -{ - return current_thd; -} - -/** Lock data that needs protection in THD object @param thd THD object @@ -469,6 +459,16 @@ my_socket thd_get_fd(THD *thd) #endif /** + Get current THD object from thread local data + + @retval The THD object for the thread, NULL if not connection thread +*/ +THD *thd_get_current_thd() +{ + return current_thd; +} + +/** Get thread attributes for connection threads @retval Reference to thread attribute for connection threads @@ -702,12 +702,6 @@ extern "C" @param length length of buffer @param max_query_len how many chars of query to copy (0 for all) - @req LOCK_thread_count - - @note LOCK_thread_count mutex is not necessary when the function is invoked on - the currently running thread (current_thd) or if the caller in some other - way guarantees that access to thd->query is serialized. - @return Pointer to string */ @@ -953,7 +947,7 @@ THD::THD(bool is_wsrep_applier) // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; user_time.val= start_time= start_time_sec_part= 0; - start_utime= utime_after_query= prior_thr_create_utime= 0L; + start_utime= utime_after_query= 0; utime_after_lock= 0L; progress.arena= 0; progress.report_to_client= 0; @@ -1379,6 +1373,12 @@ extern "C" THD *_current_thd_noinline(void) { return my_pthread_getspecific_ptr(THD*,THR_THD); } + +extern "C" my_thread_id next_thread_id_noinline() +{ +#undef next_thread_id + return next_thread_id(); +} #endif /* @@ -1426,6 +1426,7 @@ void THD::init(void) bzero((char *) &org_status_var, sizeof(org_status_var)); start_bytes_received= 0; last_commit_gtid.seq_no= 0; + last_stmt= NULL; status_in_global= 0; #ifdef WITH_WSREP wsrep_exec_mode= wsrep_applier ? REPL_RECV : LOCAL_STATE; @@ -1630,6 +1631,10 @@ THD::~THD() THD *orig_thd= current_thd; THD_CHECK_SENTRY(this); DBUG_ENTER("~THD()"); + /* Check that we have already called thd->unlink() */ + DBUG_ASSERT(prev == 0 && next == 0); + /* This takes a long time so we should not do this under LOCK_thread_count */ + mysql_mutex_assert_not_owner(&LOCK_thread_count); /* In error cases, thd may not be current thd. We have to fix this so @@ -1701,8 +1706,9 @@ THD::~THD() if (status_var.local_memory_used != 0) { DBUG_PRINT("error", ("memory_used: %lld", status_var.local_memory_used)); - SAFEMALLOC_REPORT_MEMORY(my_thread_dbug_id()); - DBUG_ASSERT(status_var.local_memory_used == 0); + SAFEMALLOC_REPORT_MEMORY(thread_id); + DBUG_ASSERT(status_var.local_memory_used == 0 || + !debug_assert_on_not_freed_memory); } set_current_thd(orig_thd == this ? 0 : orig_thd); @@ -2047,7 +2053,7 @@ int killed_errno(killed_state killed) /* Remember the location of thread info, the structure needed for - sql_alloc() and the structure for the net buffer + the structure for the net buffer */ bool THD::store_globals() @@ -2058,8 +2064,7 @@ bool THD::store_globals() */ DBUG_ASSERT(thread_stack); - if (set_current_thd(this) || - my_pthread_setspecific_ptr(THR_MALLOC, &mem_root)) + if (set_current_thd(this)) return 1; /* mysys_var is concurrently readable by a killer thread. @@ -2112,7 +2117,6 @@ void THD::reset_globals() /* Undocking the thread specific data. */ set_current_thd(0); - my_pthread_setspecific_ptr(THR_MALLOC, NULL); net.thd= 0; } @@ -3555,7 +3559,7 @@ void Query_arena::free_items() { Item *next; DBUG_ENTER("Query_arena::free_items"); - /* This works because items are allocated with sql_alloc() */ + /* This works because items are allocated on THD::mem_root */ for (; free_list; free_list= next) { next= free_list->next; @@ -4081,7 +4085,7 @@ void Security_context::destroy() // If not pointer to constant if (host != my_localhost) { - my_free(host); + my_free((char*) host); host= NULL; } if (user != delayed_user) @@ -4344,7 +4348,7 @@ extern "C" void thd_progress_init(MYSQL_THD thd, uint max_stage) is a high level command (like ALTER TABLE) and we are not in a stored procedure */ - thd->progress.report= ((thd->client_capabilities & CLIENT_PROGRESS) && + thd->progress.report= ((thd->client_capabilities & MARIADB_CLIENT_PROGRESS) && thd->progress.report_to_client && !thd->in_sub_stmt); thd->progress.next_report_time= 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 0e23a5e5916..be652e6dd01 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -36,6 +36,7 @@ #include "violite.h" /* vio_is_connected */ #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA, THR_LOCK_INFO */ #include "thr_timer.h" +#include "thr_malloc.h" #include "sql_digest_stream.h" // sql_digest_state @@ -694,6 +695,7 @@ typedef struct system_status_var ulong com_create_tmp_table; ulong com_drop_tmp_table; ulong com_other; + ulong com_multi; ulong com_stmt_prepare; ulong com_stmt_reprepare; @@ -1184,7 +1186,8 @@ public: priv_user - The user privilege we are using. May be "" for anonymous user. ip - client IP */ - char *host, *user, *ip; + const char *host; + char *user, *ip; char priv_user[USERNAME_LENGTH]; char proxy_user[USERNAME_LENGTH + MAX_HOSTNAME + 5]; /* The host privilege we are using */ @@ -1411,7 +1414,7 @@ public: Discrete_intervals_list auto_inc_intervals_forced; ulonglong limit_found_rows; ha_rows cuted_fields, sent_row_count, examined_row_count; - ulong client_capabilities; + ulonglong client_capabilities; ulong query_plan_flags; uint in_sub_stmt; bool enable_slow_log; @@ -1962,6 +1965,13 @@ public: /* all prepared statements and cursors of this connection */ Statement_map stmt_map; + + /* Last created prepared statement */ + Statement *last_stmt; + inline void set_last_stmt(Statement *stmt) + { last_stmt= (is_error() ? NULL : stmt); } + inline void clear_last_stmt() { last_stmt= NULL; } + /* A pointer to the stack frame of handle_one_connection(), which is called first in the thread for handling a client @@ -2044,7 +2054,7 @@ public: /* Needed by MariaDB semi sync replication */ Trans_binlog_info *semisync_info; - ulong client_capabilities; /* What the client supports */ + ulonglong client_capabilities; /* What the client supports */ ulong max_client_packet_length; HASH handler_tables_hash; @@ -2086,7 +2096,7 @@ public: bool report_to_client; /* true, if we will send progress report packets to a client - (client has requested them, see CLIENT_PROGRESS; report_to_client + (client has requested them, see MARIADB_CLIENT_PROGRESS; report_to_client is true; not in sub-statement) */ bool report; @@ -4032,8 +4042,41 @@ public: { main_lex.restore_set_statement_var(); } + + /* + Reset current_linfo + Setting current_linfo to 0 needs to be done with LOCK_thread_count to + ensure that adjust_linfo_offsets doesn't use a structure that may + be deleted. + */ + inline void reset_current_linfo() + { + mysql_mutex_lock(&LOCK_thread_count); + current_linfo= 0; + mysql_mutex_unlock(&LOCK_thread_count); + } }; +inline void add_to_active_threads(THD *thd) +{ + mysql_mutex_lock(&LOCK_thread_count); + threads.append(thd); + mysql_mutex_unlock(&LOCK_thread_count); +} + +/* + This should be called when you want to delete a thd that was not + running any queries. + This function will assert if the THD was not linked. +*/ + +inline void unlink_not_visible_thd(THD *thd) +{ + thd->assert_if_linked(); + mysql_mutex_lock(&LOCK_thread_count); + thd->unlink(); + mysql_mutex_unlock(&LOCK_thread_count); +} /** A short cut for thd->get_stmt_da()->set_ok_status(). */ @@ -4891,16 +4934,19 @@ public: /* Structs used when sorting */ +struct SORT_FIELD_ATTR +{ + uint length; /* Length of sort field */ + uint suffix_length; /* Length suffix (0-4) */ +}; -typedef struct st_sort_field { + +struct SORT_FIELD: public SORT_FIELD_ATTR +{ Field *field; /* Field to sort */ Item *item; /* Item if not sorting fields */ - uint length; /* Length of sort field */ - uint suffix_length; /* Length suffix (0-4) */ - Item_result result_type; /* Type of item */ bool reverse; /* if descending sort */ - bool need_strxnfrm; /* If we have to use strxnfrm() */ -} SORT_FIELD; +}; typedef struct st_sort_buffer { @@ -4978,85 +5024,7 @@ class user_var_entry user_var_entry *get_variable(HASH *hash, LEX_STRING &name, bool create_if_not_exists); -/* - Unique -- class for unique (removing of duplicates). - Puts all values to the TREE. If the tree becomes too big, - it's dumped to the file. User can request sorted values, or - just iterate through them. In the last case tree merging is performed in - memory simultaneously with iteration, so it should be ~2-3x faster. - */ - -class Unique :public Sql_alloc -{ - DYNAMIC_ARRAY file_ptrs; - ulong max_elements; - ulonglong max_in_memory_size; - IO_CACHE file; - TREE tree; - uchar *record_pointers; - ulong filtered_out_elems; - bool flush(); - uint size; - uint full_size; - uint min_dupl_count; /* always 0 for unions, > 0 for intersections */ - bool with_counters; - - bool merge(TABLE *table, uchar *buff, bool without_last_merge); - -public: - ulong elements; - Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg, - uint size_arg, ulonglong max_in_memory_size_arg, - uint min_dupl_count_arg= 0); - ~Unique(); - ulong elements_in_tree() { return tree.elements_in_tree; } - inline bool unique_add(void *ptr) - { - DBUG_ENTER("unique_add"); - DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements)); - if (!(tree.flag & TREE_ONLY_DUPS) && - tree.elements_in_tree >= max_elements && flush()) - DBUG_RETURN(1); - DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg)); - } - - bool is_in_memory() { return (my_b_tell(&file) == 0); } - void close_for_expansion() { tree.flag= TREE_ONLY_DUPS; } - - bool get(TABLE *table); - - /* Cost of searching for an element in the tree */ - inline static double get_search_cost(ulonglong tree_elems, uint compare_factor) - { - return log((double) tree_elems) / (compare_factor * M_LN2); - } - - static double get_use_cost(uint *buffer, size_t nkeys, uint key_size, - ulonglong max_in_memory_size, uint compare_factor, - bool intersect_fl, bool *in_memory); - inline static int get_cost_calc_buff_size(size_t nkeys, uint key_size, - ulonglong max_in_memory_size) - { - register ulonglong max_elems_in_tree= - max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size); - return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree)); - } - - void reset(); - bool walk(TABLE *table, tree_walk_action action, void *walk_action_arg); - - uint get_size() const { return size; } - ulonglong get_max_in_memory_size() const { return max_in_memory_size; } - - friend int unique_write_to_file(uchar* key, element_count count, Unique *unique); - friend int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique); - - friend int unique_write_to_file_with_count(uchar* key, element_count count, - Unique *unique); - friend int unique_intersect_write_to_ptrs(uchar* key, element_count count, - Unique *unique); -}; - +class SORT_INFO; class multi_delete :public select_result_interceptor { @@ -5084,7 +5052,7 @@ public: int send_data(List<Item> &items); bool initialize_tables (JOIN *join); int do_deletes(); - int do_table_deletes(TABLE *table, bool ignore); + int do_table_deletes(TABLE *table, SORT_INFO *sort_info, bool ignore); bool send_eof(); inline ha_rows num_deleted() { @@ -5324,6 +5292,10 @@ public: Do not check that wsrep snapshot is ready before allowing this command */ #define CF_SKIP_WSREP_CHECK (1U << 2) +/** + Do not allow it for COM_MULTI batch +*/ +#define CF_NO_COM_MULTI (1U << 3) /* Inline functions */ diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h index 904578134b4..92b74bb88ab 100644 --- a/sql/sql_cmd.h +++ b/sql/sql_cmd.h @@ -93,6 +93,8 @@ enum enum_sql_command { SQLCOM_CREATE_ROLE, SQLCOM_DROP_ROLE, SQLCOM_GRANT_ROLE, SQLCOM_REVOKE_ROLE, SQLCOM_COMPOUND, SQLCOM_SHOW_GENERIC, + SQLCOM_ALTER_USER, + SQLCOM_SHOW_CREATE_USER, /* When a command is added here, be sure it's also added in mysqld.cc diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 7821b96b9bb..ea114bf40a5 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -827,14 +827,17 @@ bool thd_init_client_charset(THD *thd, uint cs_number) Initialize connection threads */ +#ifndef EMBEDDED_LIBRARY bool init_new_connection_handler_thread() { pthread_detach_this_thread(); if (my_thread_init()) { + statistic_increment(aborted_connects,&LOCK_status); statistic_increment(connection_errors_internal, &LOCK_status); return 1; } + DBUG_EXECUTE_IF("simulate_failed_connection_1", return(1); ); return 0; } @@ -850,7 +853,6 @@ bool init_new_connection_handler_thread() 1 error */ -#ifndef EMBEDDED_LIBRARY static int check_connection(THD *thd) { uint connect_errors= 0; @@ -951,6 +953,7 @@ static int check_connection(THD *thd) this is treated as a global server OOM error. TODO: remove the need for my_strdup. */ + statistic_increment(aborted_connects,&LOCK_status); statistic_increment(connection_errors_internal, &LOCK_status); return 1; /* The error is set by my_strdup(). */ } @@ -968,7 +971,7 @@ static int check_connection(THD *thd) if (thd->main_security_ctx.host) { if (thd->main_security_ctx.host != my_localhost) - thd->main_security_ctx.host[MY_MIN(strlen(thd->main_security_ctx.host), + ((char*) thd->main_security_ctx.host)[MY_MIN(strlen(thd->main_security_ctx.host), HOSTNAME_LENGTH)]= 0; thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host; } @@ -1016,6 +1019,7 @@ static int check_connection(THD *thd) Hence, there is no reason to account on OOM conditions per client IP, we count failures in the global server status instead. */ + statistic_increment(aborted_connects,&LOCK_status); statistic_increment(connection_errors_internal, &LOCK_status); return 1; /* The error is set by alloc(). */ } @@ -1054,7 +1058,8 @@ bool setup_connection_thread_globals(THD *thd) { close_connection(thd, ER_OUT_OF_RESOURCES); statistic_increment(aborted_connects,&LOCK_status); - MYSQL_CALLBACK(thd->scheduler, end_thread, (thd, 0)); + statistic_increment(connection_errors_internal, &LOCK_status); + thd->scheduler->end_thread(thd, 0); return 1; // Error } return 0; @@ -1082,7 +1087,7 @@ bool login_connection(THD *thd) int error= 0; DBUG_ENTER("login_connection"); DBUG_PRINT("info", ("login_connection called by thread %lu", - thd->thread_id)); + (ulong) thd->thread_id)); /* Use "connect_timeout" value during connection phase */ my_net_set_read_timeout(net, connect_timeout); @@ -1134,8 +1139,8 @@ void end_connection(THD *thd) { wsrep_status_t rcode= wsrep->free_connection(wsrep, thd->thread_id); if (rcode) { - WSREP_WARN("wsrep failed to free connection context: %lu, code: %d", - thd->thread_id, rcode); + WSREP_WARN("wsrep failed to free connection context: %lld code: %d", + (longlong) thd->thread_id, rcode); } } thd->wsrep_client_thread= 0; @@ -1254,11 +1259,11 @@ void prepare_new_connection_state(THD* thd) pthread_handler_t handle_one_connection(void *arg) { - THD *thd= (THD*) arg; + CONNECT *connect= (CONNECT*) arg; - mysql_thread_set_psi_id(thd->thread_id); + mysql_thread_set_psi_id(connect->thread_id); - do_handle_one_connection(thd); + do_handle_one_connection(connect); return 0; } @@ -1290,19 +1295,17 @@ bool thd_is_connection_alive(THD *thd) return FALSE; } -void do_handle_one_connection(THD *thd_arg) -{ - THD *thd= thd_arg; - - thd->thr_create_utime= microsecond_interval_timer(); - /* We need to set this because of time_out_user_resource_limits */ - thd->start_utime= thd->thr_create_utime; - if (MYSQL_CALLBACK_ELSE(thd->scheduler, init_new_connection_thread, (), 0)) +void do_handle_one_connection(CONNECT *connect) +{ + ulonglong thr_create_utime= microsecond_interval_timer(); + THD *thd; + if (connect->scheduler->init_new_connection_thread() || + !(thd= connect->create_thd())) { - close_connection(thd, ER_OUT_OF_RESOURCES); - statistic_increment(aborted_connects,&LOCK_status); - MYSQL_CALLBACK(thd->scheduler, end_thread, (thd, 0)); + scheduler_functions *scheduler= connect->scheduler; + connect->close_with_error(0, 0, ER_OUT_OF_RESOURCES); + scheduler->end_thread(0, 0); return; } @@ -1311,14 +1314,22 @@ void do_handle_one_connection(THD *thd_arg) increment slow_launch_threads counter if it took more than slow_launch_time seconds to create the thread. */ - if (thd->prior_thr_create_utime) + + if (connect->prior_thr_create_utime) { - ulong launch_time= (ulong) (thd->thr_create_utime - - thd->prior_thr_create_utime); + ulong launch_time= (ulong) (thr_create_utime - + connect->prior_thr_create_utime); if (launch_time >= slow_launch_time*1000000L) statistic_increment(slow_launch_threads, &LOCK_status); - thd->prior_thr_create_utime= 0; } + delete connect; + + /* Make THD visible in show processlist */ + add_to_active_threads(thd); + + thd->thr_create_utime= thr_create_utime; + /* We need to set this because of time_out_user_resource_limits */ + thd->start_utime= thr_create_utime; /* handle_one_connection() is normally the only way a thread would @@ -1365,7 +1376,7 @@ end_thread: if (thd->userstat_running) update_global_user_stats(thd, create_user, time(NULL)); - if (MYSQL_CALLBACK_ELSE(thd->scheduler, end_thread, (thd, 1), 0)) + if (thd->scheduler->end_thread(thd, 1)) return; // Probably no-threads /* @@ -1377,3 +1388,110 @@ end_thread: } } #endif /* EMBEDDED_LIBRARY */ + + +/* Handling of CONNECT objects */ + +/* + Close connection without error and delete the connect object + This and close_with_error are only called if we didn't manage to + create a new thd object. +*/ + +void CONNECT::close_and_delete() +{ + DBUG_ENTER("close_and_delete"); + + if (vio) + vio_close(vio); + if (thread_count_incremented) + { + /* + Normally this is handled by THD::unlink. As we haven't yet created + a THD and put it in the thread list, we have to manage counting here. + */ + dec_thread_count(); + dec_connection_count(scheduler); + } + statistic_increment(connection_errors_internal, &LOCK_status); + statistic_increment(aborted_connects,&LOCK_status); + + delete this; + DBUG_VOID_RETURN; +} + +/* + Close a connection with a possible error to the end user + Alse deletes the connection object, like close_and_delete() +*/ + +void CONNECT::close_with_error(uint sql_errno, + const char *message, uint close_error) +{ + THD *thd= create_thd(); + if (thd) + { + if (sql_errno) + net_send_error(thd, sql_errno, message, NULL); + close_connection(thd, close_error); + delete thd; + set_current_thd(0); + if (thread_count_incremented) + { + dec_thread_count(); + dec_connection_count(scheduler); + } + delete this; + statistic_increment(connection_errors_internal, &LOCK_status); + statistic_increment(aborted_connects,&LOCK_status); + } + else + { + /* + Out of memory; We can't generate an error, just close the connection + close_and_delete() will increment statistics. + */ + close_and_delete(); + } +} + + +CONNECT::~CONNECT() +{ + if (vio) + vio_delete(vio); +} + +/* Create a THD based on a CONNECT object */ + +THD *CONNECT::create_thd() +{ + my_bool res; + THD *thd; + DBUG_ENTER("create_thd"); + + DBUG_EXECUTE_IF("simulate_failed_connection_2", DBUG_RETURN(0); ); + + if (!(thd= new THD)) + DBUG_RETURN(0); + + set_current_thd(thd); + res= my_net_init(&thd->net, vio, thd, MYF(MY_THREAD_SPECIFIC)); + vio= 0; // Vio now handled by thd + + if (res) + { + delete thd; + set_current_thd(0); + DBUG_RETURN(0); + } + + init_net_server_extension(thd); + + thd->security_ctx->host= host; + thd->extra_port= extra_port; + thd->scheduler= scheduler; + thd->thread_id= thd->variables.pseudo_thread_id= thread_id; + thd->real_id= real_id; + DBUG_RETURN(thd); +} diff --git a/sql/sql_connect.h b/sql/sql_connect.h index bab171606ba..22a12e845c7 100644 --- a/sql/sql_connect.h +++ b/sql/sql_connect.h @@ -19,8 +19,43 @@ #include "my_sys.h" /* pthread_handler_t */ #include "mysql_com.h" /* enum_server_command */ #include "structs.h" +#include <mysql/psi/mysql_socket.h> #include <hash.h> +/* + Object to hold connect information to be given to the newly created thread +*/ + +struct scheduler_functions; + +class CONNECT : public ilink { +public: + /* To be copied to THD */ + Vio *vio; /* Copied to THD with my_net_init() */ + const char *host; + scheduler_functions *scheduler; + my_thread_id thread_id; + pthread_t real_id; + bool extra_port; + + /* Own variables */ + bool thread_count_incremented; + ulonglong prior_thr_create_utime; + + CONNECT() + :vio(0), host(0), scheduler(thread_scheduler), thread_id(0), real_id(0), + extra_port(0), + thread_count_incremented(0), prior_thr_create_utime(0) + { + }; + ~CONNECT(); + void close_and_delete(); + void close_with_error(uint sql_errno, + const char *message, uint close_error); + THD *create_thd(); +}; + + class THD; typedef struct st_lex_user LEX_USER; typedef struct user_conn USER_CONN; @@ -37,7 +72,7 @@ void free_global_index_stats(void); void free_global_client_stats(void); pthread_handler_t handle_one_connection(void *arg); -void do_handle_one_connection(THD *thd_arg); +void do_handle_one_connection(CONNECT *connect); bool init_new_connection_handler_thread(); void reset_mqh(LEX_USER *lu, bool get_them); bool check_mqh(THD *thd, uint check_command); diff --git a/sql/sql_const.h b/sql/sql_const.h index 76e47bd278b..31ee4603dc9 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -235,6 +235,8 @@ that does not respond to "initial server greeting" timely */ #define CONNECT_TIMEOUT 10 + /* Wait 5 minutes before removing thread from thread cache */ +#define THREAD_CACHE_TIMEOUT 5*60 /* The following can also be changed from the command line */ #define DEFAULT_CONCURRENCY 10 diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc new file mode 100644 index 00000000000..1203a4ce0c8 --- /dev/null +++ b/sql/sql_cte.cc @@ -0,0 +1,601 @@ +#include "sql_class.h" +#include "sql_lex.h" +#include "sql_cte.h" +#include "sql_view.h" // for make_valid_column_names +#include "sql_parse.h" + + +/** + @brief + Check dependencies between tables defined in a list of with clauses + + @param + with_clauses_list Pointer to the first clause in the list + + @details + The procedure just calls the method With_clause::check_dependencies + for each member of the given list. + + @retval + false on success + true on failure +*/ + +bool check_dependencies_in_with_clauses(With_clause *with_clauses_list) +{ + for (With_clause *with_clause= with_clauses_list; + with_clause; + with_clause= with_clause->next_with_clause) + { + if (with_clause->check_dependencies()) + return true; + } + return false; +} + + +/** + @brief + Check dependencies between tables defined in this with clause + + @details + The method performs the following actions for this with clause: + + 1. Test for definitions of the tables with the same name. + 2. For each table T defined in this with clause look for tables + from the same with clause that are used in the query that + specifies T and set the dependencies of T on these tables + in dependency_map. + 3. Build the transitive closure of the above direct dependencies + to find out all recursive definitions. + 4. If this with clause is not specified as recursive then + for each with table T defined in this with clause check whether + it is used in any definition that follows the definition of T. + + @retval + true if an error is reported + false otherwise +*/ + +bool With_clause::check_dependencies() +{ + if (dependencies_are_checked) + return false; + /* + Look for for definitions with the same query name. + When found report an error and return true immediately. + For each table T defined in this with clause look for all other tables from + the same with with clause that are used in the specification of T. + For each such table set the dependency bit in the dependency map of + with element for T. + */ + for (With_element *with_elem= first_elem; + with_elem != NULL; + with_elem= with_elem->next_elem) + { + for (With_element *elem= first_elem; + elem != with_elem; + elem= elem->next_elem) + { + if (my_strcasecmp(system_charset_info, with_elem->query_name->str, + elem->query_name->str) == 0) + { + my_error(ER_DUP_QUERY_NAME, MYF(0), with_elem->query_name->str); + return true; + } + } + with_elem->check_dependencies_in_unit(with_elem->spec); + } + /* Build the transitive closure of the direct dependencies found above */ + for (With_element *with_elem= first_elem; + with_elem != NULL; + with_elem= with_elem->next_elem) + { + table_map with_elem_map= with_elem->get_elem_map(); + for (With_element *elem= first_elem; elem != NULL; elem= elem->next_elem) + { + if (elem->dependency_map & with_elem_map) + elem->dependency_map |= with_elem->dependency_map; + } + } + + /* + Mark those elements where tables are defined with direct or indirect recursion. + Report an error when recursion (direct or indirect) is used to define a table. + */ + for (With_element *with_elem= first_elem; + with_elem != NULL; + with_elem= with_elem->next_elem) + { + if (with_elem->dependency_map & with_elem->get_elem_map()) + with_elem->is_recursive= true; + } + for (With_element *with_elem= first_elem; + with_elem != NULL; + with_elem= with_elem->next_elem) + { + if (with_elem->is_recursive) + { + my_error(ER_RECURSIVE_QUERY_IN_WITH_CLAUSE, MYF(0), + with_elem->query_name->str); + return true; + } + } + + if (!with_recursive) + { + /* + For each with table T defined in this with clause check whether + it is used in any definition that follows the definition of T. + */ + for (With_element *with_elem= first_elem; + with_elem != NULL; + with_elem= with_elem->next_elem) + { + With_element *checked_elem= with_elem->next_elem; + for (uint i = with_elem->number+1; + i < elements; + i++, checked_elem= checked_elem->next_elem) + { + if (with_elem->check_dependency_on(checked_elem)) + { + my_error(ER_WRONG_ORDER_IN_WITH_CLAUSE, MYF(0), + with_elem->query_name->str, checked_elem->query_name->str); + return true; + } + } + } + } + + dependencies_are_checked= true; + return false; +} + + +/** + @brief + Check dependencies on the sibling with tables used in the given unit + + @param unit The unit where the siblings are to be searched for + + @details + The method recursively looks through all from lists encountered + the given unit. If it finds a reference to a table that is + defined in the same with clause to which this element belongs + the method set the bit of dependency on this table in the + dependency_map of this element. +*/ + +void With_element::check_dependencies_in_unit(st_select_lex_unit *unit) +{ + st_select_lex *sl= unit->first_select(); + for (; sl; sl= sl->next_select()) + { + for (TABLE_LIST *tbl= sl->table_list.first; tbl; tbl= tbl->next_local) + { + if (!tbl->with) + tbl->with= owner->find_table_def(tbl); + if (!tbl->with && tbl->select_lex) + tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl); + if (tbl->with && tbl->with->owner== this->owner) + set_dependency_on(tbl->with); + } + st_select_lex_unit *inner_unit= sl->first_inner_unit(); + for (; inner_unit; inner_unit= inner_unit->next_unit()) + check_dependencies_in_unit(inner_unit); + } +} + + +/** + @brief + Search for the definition of a table among the elements of this with clause + + @param table The reference to the table that is looked for + + @details + The function looks through the elements of this with clause trying to find + the definition of the given table. When it encounters the element with + the same query name as the table's name it returns this element. If no + such definitions are found the function returns NULL. + + @retval + found with element if the search succeeded + NULL - otherwise +*/ + +With_element *With_clause::find_table_def(TABLE_LIST *table) +{ + for (With_element *with_elem= first_elem; + with_elem != NULL; + with_elem= with_elem->next_elem) + { + if (my_strcasecmp(system_charset_info, with_elem->query_name->str, table->table_name) == 0) + { + return with_elem; + } + } + return NULL; +} + + +/** + @brief + Perform context analysis for all unreferenced tables defined in with clause + + @param thd The context of the statement containing this with clause + + @details + For each unreferenced table T defined in this with clause the method + calls the method With_element::prepare_unreferenced that performs + context analysis of the element with the definition of T. + + @retval + false If context analysis does not report any error + true Otherwise +*/ + +bool With_clause::prepare_unreferenced_elements(THD *thd) +{ + for (With_element *with_elem= first_elem; + with_elem != NULL; + with_elem= with_elem->next_elem) + { + if (!with_elem->is_referenced() && with_elem->prepare_unreferenced(thd)) + return true; + } + + return false; +} + + +/** + @brief + Save the specification of the given with table as a string + + @param thd The context of the statement containing this with element + @param spec_start The beginning of the specification in the input string + @param spec_end The end of the specification in the input string + + @details + The method creates for a string copy of the specification used in this element. + The method is called when the element is parsed. The copy may be used to + create clones of the specification whenever they are needed. + + @retval + false on success + true on failure +*/ + +bool With_element::set_unparsed_spec(THD *thd, char *spec_start, char *spec_end) +{ + unparsed_spec.length= spec_end - spec_start; + unparsed_spec.str= (char*) thd->memdup(spec_start, unparsed_spec.length+1); + unparsed_spec.str[unparsed_spec.length]= '\0'; + + if (!unparsed_spec.str) + { + my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), + static_cast<int>(unparsed_spec.length)); + return true; + } + return false; +} + + +/** + @brief + Create a clone of the specification for the given with table + + @param thd The context of the statement containing this with element + @param with_table The reference to the table defined in this element for which + the clone is created. + + @details + The method creates a clone of the specification used in this element. + The clone is created for the given reference to the table defined by + this element. + The clone is created when the string with the specification saved in + unparsed_spec is fed into the parser as an input string. The parsing + this string a unit object representing the specification is build. + A chain of all table references occurred in the specification is also + formed. + The method includes the new unit and its sub-unit into hierarchy of + the units of the main query. I also insert the constructed chain of the + table references into the chain of all table references of the main query. + + @note + Clones is created only for not first references to tables defined in + the with clause. They are necessary for merged specifications because + the optimizer handles any such specification as independent on the others. + When a table defined in the with clause is materialized in a temporary table + one could do without specification clones. However in this case they + are created as well, because currently different table references to a + the same temporary table cannot share the same definition structure. + + @retval + pointer to the built clone if succeeds + NULL - otherwise +*/ + +st_select_lex_unit *With_element::clone_parsed_spec(THD *thd, + TABLE_LIST *with_table) +{ + LEX *lex; + st_select_lex_unit *res= NULL; + Query_arena backup; + Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup); + + if (!(lex= (LEX*) new(thd->mem_root) st_lex_local)) + { + if (arena) + thd->restore_active_arena(arena, &backup); + return res; + } + LEX *old_lex= thd->lex; + thd->lex= lex; + + bool parse_status= false; + Parser_state parser_state; + TABLE_LIST *spec_tables; + TABLE_LIST *spec_tables_tail; + st_select_lex *with_select; + + if (parser_state.init(thd, unparsed_spec.str, unparsed_spec.length)) + goto err; + lex_start(thd); + with_select= &lex->select_lex; + with_select->select_number= ++thd->select_number; + parse_status= parse_sql(thd, &parser_state, 0); + if (parse_status) + goto err; + spec_tables= lex->query_tables; + spec_tables_tail= 0; + for (TABLE_LIST *tbl= spec_tables; + tbl; + tbl= tbl->next_global) + { + tbl->grant.privilege= with_table->grant.privilege; + spec_tables_tail= tbl; + } + if (spec_tables) + { + if (with_table->next_global) + { + spec_tables_tail->next_global= with_table->next_global; + with_table->next_global->prev_global= &spec_tables_tail->next_global; + } + else + { + old_lex->query_tables_last= &spec_tables_tail->next_global; + } + spec_tables->prev_global= &with_table->next_global; + with_table->next_global= spec_tables; + } + res= &lex->unit; + + lex->unit.include_down(with_table->select_lex); + lex->unit.set_slave(with_select); + old_lex->all_selects_list= + (st_select_lex*) (lex->all_selects_list-> + insert_chain_before( + (st_select_lex_node **) &(old_lex->all_selects_list), + with_select)); + lex_end(lex); +err: + if (arena) + thd->restore_active_arena(arena, &backup); + thd->lex= old_lex; + return res; +} + + +/** + @brief + Rename columns of the unit derived from the spec of this with element + @param thd The context of the statement containing the with element + @param unit The specification of the with element or its clone + + @details + The method assumes that the parameter unit is either specification itself + of this with element or a clone of this specification. The looks through + the column list in this with element. It reports an error if the cardinality + of this list differs from the cardinality of select lists in 'unit'. + Otherwise it renames the columns of the first select list and sets the flag + unit->column_list_is_processed to true preventing renaming columns for the + second time. + + @retval + true if an error was reported + false otherwise +*/ + +bool +With_element::rename_columns_of_derived_unit(THD *thd, + st_select_lex_unit *unit) +{ + if (unit->columns_are_renamed) + return false; + + st_select_lex *select= unit->first_select(); + + if (column_list.elements) // The column list is optional + { + List_iterator_fast<Item> it(select->item_list); + List_iterator_fast<LEX_STRING> nm(column_list); + Item *item; + LEX_STRING *name; + + if (column_list.elements != select->item_list.elements) + { + my_error(ER_WITH_COL_WRONG_LIST, MYF(0)); + return true; + } + /* Rename the columns of the first select in the unit */ + while ((item= it++, name= nm++)) + { + item->set_name(thd, name->str, (uint) name->length, system_charset_info); + item->is_autogenerated_name= false; + } + } + + make_valid_column_names(thd, select->item_list); + + unit->columns_are_renamed= true; + + return false; +} + + +/** + @brief + Perform context analysis the definition of an unreferenced table + + @param thd The context of the statement containing this with element + + @details + The method assumes that this with element contains the definition + of a table that is not used anywhere. In this case one has to check + that context conditions are met. + + @retval + true if an error was reported + false otherwise +*/ + +bool With_element::prepare_unreferenced(THD *thd) +{ + bool rc= false; + st_select_lex *first_sl= spec->first_select(); + + /* Prevent name resolution for field references out of with elements */ + for (st_select_lex *sl= first_sl; + sl; + sl= sl->next_select()) + sl->context.outer_context= 0; + + thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; + if (!spec->prepared && + (spec->prepare(thd, 0, 0) || + rename_columns_of_derived_unit(thd, spec) || + check_duplicate_names(thd, first_sl->item_list, 1))) + rc= true; + + thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED; + return rc; +} + + +/** + @brief + Search for the definition of the given table referred in this select node + + @param table reference to the table whose definition is searched for + + @details + The method looks for the definition the table whose reference is occurred + in the FROM list of this select node. First it searches for it in the + with clause attached to the unit this select node belongs to. If such a + definition is not found there the embedding units are looked through. + + @retval + pointer to the found definition if the search has been successful + NULL - otherwise +*/ + +With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table) +{ + With_element *found= NULL; + for (st_select_lex *sl= this; + sl; + sl= sl->master_unit()->outer_select()) + { + With_clause *with_clause=sl->get_with_clause(); + if (with_clause && (found= with_clause->find_table_def(table))) + return found; + } + return found; +} + + +/** + @brief + Set the specifying unit in this reference to a with table + + @details + The method assumes that the given element with_elem defines the table T + this table reference refers to. + If this is the first reference to T the method just sets its specification + in the field 'derived' as the unit that yields T. Otherwise the method + first creates a clone specification and sets rather this clone in this field. + + @retval + false on success + true on failure +*/ + +bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem) +{ + with= with_elem; + if (!with_elem->is_referenced()) + derived= with_elem->spec; + else + { + if(!(derived= with_elem->clone_parsed_spec(thd, this))) + return true; + derived->with_element= with_elem; + } + with_elem->inc_references(); + return false; +} + + +/** + @brief + Print this with clause + + @param str Where to print to + @param query_type The mode of printing + + @details + The method prints a string representation of this clause in the + string str. The parameter query_type specifies the mode of printing. +*/ + +void With_clause::print(String *str, enum_query_type query_type) +{ + str->append(STRING_WITH_LEN("WITH ")); + if (with_recursive) + str->append(STRING_WITH_LEN("RECURSIVE ")); + for (With_element *with_elem= first_elem; + with_elem != NULL; + with_elem= with_elem->next_elem) + { + with_elem->print(str, query_type); + if (with_elem != first_elem) + str->append(", "); + } +} + + +/** + @brief + Print this with element + + @param str Where to print to + @param query_type The mode of printing + + @details + The method prints a string representation of this with element in the + string str. The parameter query_type specifies the mode of printing. +*/ + +void With_element::print(String *str, enum_query_type query_type) +{ + str->append(query_name); + str->append(STRING_WITH_LEN(" AS ")); + str->append('('); + spec->print(str, query_type); + str->append(')'); +} + diff --git a/sql/sql_cte.h b/sql/sql_cte.h new file mode 100644 index 00000000000..0cbc9247af9 --- /dev/null +++ b/sql/sql_cte.h @@ -0,0 +1,178 @@ +#ifndef SQL_CTE_INCLUDED +#define SQL_CTE_INCLUDED +#include "sql_list.h" +#include "sql_lex.h" + +class With_clause; + +/** + @class With_clause + @brief Set of with_elements + + It has a reference to the first with element from this with clause. + This reference allows to navigate through all the elements of the with clause. + It contains a reference to the unit to which this with clause is attached. + It also contains a flag saying whether this with clause was specified as recursive. +*/ + +class With_element : public Sql_alloc +{ +private: + With_clause *owner; // with clause this object belongs to + With_element *next_elem; // next element in the with clause + uint number; // number of the element in the with clause (starting from 0) + /* + The map dependency_map has 1 in the i-th position if the query that + specifies this element contains a reference to the element number i + in the query FROM list. + */ + table_map elem_map; // The map where with only one 1 set in this->number + table_map dependency_map; + /* + Total number of references to this element in the FROM lists of + the queries that are in the scope of the element (including + subqueries and specifications of other with elements). + */ + uint references; + /* + Unparsed specification of the query that specifies this element. + It used to build clones of the specification if they are needed. + */ + LEX_STRING unparsed_spec; + + /* Return the map where 1 is set only in the position for this element */ + table_map get_elem_map() { return 1 << number; } + +public: + /* + The name of the table introduced by this with elememt. The name + can be used in FROM lists of the queries in the scope of the element. + */ + LEX_STRING *query_name; + /* + Optional list of column names to name the columns of the table introduced + by this with element. It is used in the case when the names are not + inherited from the query that specified the table. Otherwise the list is + always empty. + */ + List <LEX_STRING> column_list; + /* The query that specifies the table introduced by this with element */ + st_select_lex_unit *spec; + /* + Set to true is recursion is used (directly or indirectly) + for the definition of this element + */ + bool is_recursive; + + With_element(LEX_STRING *name, + List <LEX_STRING> list, + st_select_lex_unit *unit) + : next_elem(NULL), dependency_map(0), references(0), + query_name(name), column_list(list), spec(unit), + is_recursive(false) {} + + void check_dependencies_in_unit(st_select_lex_unit *unit); + + void set_dependency_on(With_element *with_elem) + { dependency_map|= with_elem->get_elem_map(); } + + bool check_dependency_on(With_element *with_elem) + { return dependency_map & with_elem->get_elem_map(); } + + bool set_unparsed_spec(THD *thd, char *spec_start, char *spec_end); + + st_select_lex_unit *clone_parsed_spec(THD *thd, TABLE_LIST *with_table); + + bool is_referenced() { return references != 0; } + + void inc_references() { references++; } + + bool rename_columns_of_derived_unit(THD *thd, st_select_lex_unit *unit); + + bool prepare_unreferenced(THD *thd); + + void print(String *str, enum_query_type query_type); + + friend class With_clause; +}; + + +/** + @class With_element + @brief Definition of a CTE table + + It contains a reference to the name of the table introduced by this with element, + and a reference to the unit that specificies this table. Also it contains + a reference to the with clause to which this element belongs to. +*/ + +class With_clause : public Sql_alloc +{ +private: + st_select_lex_unit *owner; // the unit this with clause attached to + With_element *first_elem; // the first definition in this with clause + With_element **last_next; // here is set the link for the next added element + uint elements; // number of the elements/defintions in this with clauses + /* + The with clause immediately containing this with clause if there is any, + otherwise NULL. Now used only at parsing. + */ + With_clause *embedding_with_clause; + /* + The next with the clause of the chain of with clauses encountered + in the current statement + */ + With_clause *next_with_clause; + /* Set to true if dependencies between with elements have been checked */ + bool dependencies_are_checked; + +public: + /* If true the specifier RECURSIVE is present in the with clause */ + bool with_recursive; + + With_clause(bool recursive_fl, With_clause *emb_with_clause) + : owner(NULL), first_elem(NULL), elements(0), + embedding_with_clause(emb_with_clause), next_with_clause(NULL), + dependencies_are_checked(false), + with_recursive(recursive_fl) + { last_next= &first_elem; } + + /* Add a new element to the current with clause */ + bool add_with_element(With_element *elem) + { + elem->owner= this; + elem->number= elements; + owner= elem->spec; + owner->with_element= elem; + *last_next= elem; + last_next= &elem->next_elem; + elements++; + return false; + } + + /* Add this with clause to the list of with clauses used in the statement */ + void add_to_list(With_clause ** &last_next) + { + *last_next= this; + last_next= &this->next_with_clause; + } + + With_clause *pop() { return embedding_with_clause; } + + bool check_dependencies(); + + With_element *find_table_def(TABLE_LIST *table); + + With_element *find_table_def_in_with_clauses(TABLE_LIST *table); + + bool prepare_unreferenced_elements(THD *thd); + + void print(String *str, enum_query_type query_type); + + friend + bool check_dependencies_in_with_clauses(With_clause *with_clauses_list); + +}; + + +#endif /* SQL_CTE_INCLUDED */ diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index a8c5569ba4a..7ecce8a8da3 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -277,7 +277,7 @@ int Materialized_cursor::send_result_set_metadata( { Send_field send_field; Item_ident *ident= static_cast<Item_ident *>(item_dst); - item_org->make_field(&send_field); + item_org->make_field(thd, &send_field); ident->db_name= thd->strdup(send_field.db_name); ident->table_name= thd->strdup(send_field.table_name); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f49a053918b..42e7f6c3569 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -40,6 +40,8 @@ #include "sql_statistics.h" #include "transaction.h" #include "records.h" // init_read_record, +#include "filesort.h" +#include "uniques.h" #include "sql_derived.h" // mysql_handle_list_of_derived // end_read_record #include "sql_partition.h" // make_used_partitions_str @@ -227,10 +229,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, int error, loc_error; TABLE *table; SQL_SELECT *select=0; + SORT_INFO *file_sort= 0; READ_RECORD info; bool using_limit=limit != HA_POS_ERROR; bool transactional_table, safe_update, const_cond; bool const_cond_result; + bool return_error= 0; ha_rows deleted= 0; bool reverse= FALSE; ORDER *order= (ORDER *) ((order_list && order_list->elements) ? @@ -405,7 +409,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, table->covering_keys.clear_all(); table->quick_keys.clear_all(); // Can't use 'only index' - select=make_select(table, 0, 0, conds, 0, &error); + select=make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); if (error) DBUG_RETURN(TRUE); if ((select && select->check_quick(thd, safe_update, limit)) || !limit) @@ -486,32 +490,21 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (query_plan.using_filesort) { - ha_rows examined_rows; - ha_rows found_rows; uint length= 0; SORT_FIELD *sortorder; { DBUG_ASSERT(query_plan.index == MAX_KEY); - table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL | - MY_THREAD_SPECIFIC)); Filesort_tracker *fs_tracker= thd->lex->explain->get_upd_del_plan()->filesort_tracker; if (!(sortorder= make_unireg_sortorder(thd, order, &length, NULL)) || - (table->sort.found_records= filesort(thd, table, sortorder, length, - select, HA_POS_ERROR, - true, - &examined_rows, &found_rows, - fs_tracker)) - == HA_POS_ERROR) - { - delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); - DBUG_RETURN(TRUE); - } - thd->inc_examined_row_count(examined_rows); + !(file_sort= filesort(thd, table, sortorder, length, + select, HA_POS_ERROR, + true, + fs_tracker))) + goto got_error; + thd->inc_examined_row_count(file_sort->examined_rows); /* Filesort has already found and selected the rows we want to delete, so we don't need the where clause @@ -524,24 +517,16 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, /* If quick select is used, initialize it before retrieving rows. */ if (select && select->quick && select->quick->reset()) - { - delete select; - free_underlaid_joins(thd, select_lex); - DBUG_RETURN(TRUE); - } + goto got_error; if (query_plan.index == MAX_KEY || (select && select->quick)) - error= init_read_record(&info, thd, table, select, 1, 1, FALSE); + error= init_read_record(&info, thd, table, select, file_sort, 1, 1, FALSE); else error= init_read_record_idx(&info, thd, table, 1, query_plan.index, reverse); if (error) - { - delete select; - free_underlaid_joins(thd, select_lex); - DBUG_RETURN(TRUE); - } - + goto got_error; + init_ftfuncs(thd, select_lex, 1); THD_STAGE_INFO(thd, stage_updating); @@ -697,8 +682,6 @@ cleanup: } DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table); - - free_underlaid_joins(thd, select_lex); if (error < 0 || (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error)) { @@ -711,6 +694,8 @@ cleanup: my_ok(thd, deleted); DBUG_PRINT("info",("%ld records deleted",(long) deleted)); } + delete file_sort; + free_underlaid_joins(thd, select_lex); DBUG_RETURN(error >= 0 || thd->is_error()); /* Special exits */ @@ -729,9 +714,16 @@ send_nothing_and_leave: */ delete select; + delete file_sort; free_underlaid_joins(thd, select_lex); //table->set_keyread(false); - DBUG_RETURN((thd->is_error() || thd->killed) ? 1 : 0); + + DBUG_ASSERT(!return_error || thd->is_error() || thd->killed); + DBUG_RETURN((return_error || thd->is_error() || thd->killed) ? 1 : 0); + +got_error: + return_error= 1; + goto send_nothing_and_leave; } @@ -1183,7 +1175,8 @@ int multi_delete::do_deletes() if (tempfiles[counter]->get(table)) DBUG_RETURN(1); - local_error= do_table_deletes(table, thd->lex->ignore); + local_error= do_table_deletes(table, &tempfiles[counter]->sort, + thd->lex->ignore); if (thd->killed && !local_error) DBUG_RETURN(1); @@ -1213,14 +1206,15 @@ int multi_delete::do_deletes() @retval 1 Triggers or handler reported error. @retval -1 End of file from handler. */ -int multi_delete::do_table_deletes(TABLE *table, bool ignore) +int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info, + bool ignore) { int local_error= 0; READ_RECORD info; ha_rows last_deleted= deleted; DBUG_ENTER("do_deletes_for_table"); - if (init_read_record(&info, thd, table, NULL, 0, 1, FALSE)) + if (init_read_record(&info, thd, table, NULL, sort_info, 0, 1, FALSE)) DBUG_RETURN(1); /* diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 67e7b6115a3..1ef83b3bf1f 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -30,6 +30,7 @@ #include "sql_base.h" #include "sql_view.h" // check_duplicate_names #include "sql_acl.h" // SELECT_ACL +#include "sql_cte.h" typedef bool (*dt_processor)(THD *thd, LEX *lex, TABLE_LIST *derived); @@ -670,8 +671,11 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) // st_select_lex_unit::prepare correctly work for single select if ((res= unit->prepare(thd, derived->derived_result, 0))) goto exit; + if (derived->with && + (res= derived->with->rename_columns_of_derived_unit(thd, unit))) + goto exit; lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED; - if ((res= check_duplicate_names(unit->types, 0))) + if ((res= check_duplicate_names(thd, unit->types, 0))) goto exit; /* diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 8b3e6724c76..dae5127cbf8 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -862,6 +862,12 @@ void Explain_select::print_explain_json(Explain_query *query, writer->add_member("const_condition"); write_item(writer, exec_const_cond); } + if (outer_ref_cond) + { + writer->add_member("outer_ref_condition"); + write_item(writer, outer_ref_cond); + } + /* we do not print HAVING which always evaluates to TRUE */ if (having || (having_value == Item::COND_FALSE)) { diff --git a/sql/sql_explain.h b/sql/sql_explain.h index 6a3e6c25a61..844773c4a47 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -232,9 +232,10 @@ public: /* Expensive constant condition */ Item *exec_const_cond; + Item *outer_ref_cond; /* HAVING condition */ - COND *having; + Item *having; Item::cond_result having_value; /* Global join attributes. In tabular form, they are printed on the first row */ diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 662fa33dc9f..e8ade81062b 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -31,7 +31,7 @@ then do { handler_items=concat(handler_items, free_list); free_list=0; } But !!! do_command calls free_root at the end of every query and frees up - all the sql_alloc'ed memory. It's harder to work around... + all the memory allocated on THD::mem_root. It's harder to work around... */ /* diff --git a/sql/sql_help.cc b/sql/sql_help.cc index a0e836da203..a50b90fc111 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -194,7 +194,8 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields, DBUG_ENTER("search_topics"); /* Should never happen. As this is part of help, we can ignore this */ - if (init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE)) + if (init_read_record(&read_record_info, thd, topics, select, NULL, 1, 0, + FALSE)) DBUG_RETURN(0); while (!read_record_info.read_record(&read_record_info)) @@ -229,14 +230,16 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields, 2 found more then one topic matching the mask */ -int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields, +int search_keyword(THD *thd, TABLE *keywords, + struct st_find_field *find_fields, SQL_SELECT *select, int *key_id) { int count= 0; READ_RECORD read_record_info; DBUG_ENTER("search_keyword"); /* Should never happen. As this is part of help, we can ignore this */ - if (init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE)) + if (init_read_record(&read_record_info, thd, keywords, select, NULL, 1, 0, + FALSE)) DBUG_RETURN(0); while (!read_record_info.read_record(&read_record_info) && count<2) @@ -370,7 +373,8 @@ int search_categories(THD *thd, TABLE *categories, DBUG_ENTER("search_categories"); /* Should never happen. As this is part of help, we can ignore this */ - if (init_read_record(&read_record_info, thd, categories, select,1,0,FALSE)) + if (init_read_record(&read_record_info, thd, categories, select, NULL, + 1, 0, FALSE)) DBUG_RETURN(0); while (!read_record_info.read_record(&read_record_info)) { @@ -406,7 +410,8 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname, DBUG_ENTER("get_all_items_for_category"); /* Should never happen. As this is part of help, we can ignore this */ - if (init_read_record(&read_record_info, thd, items, select,1,0,FALSE)) + if (init_read_record(&read_record_info, thd, items, select, NULL, 1, 0, + FALSE)) DBUG_VOID_RETURN; while (!read_record_info.read_record(&read_record_info)) @@ -608,7 +613,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, /* Assume that no indexes cover all required fields */ table->covering_keys.clear_all(); - SQL_SELECT *res= make_select(table, 0, 0, cond, 0, error); + SQL_SELECT *res= make_select(table, 0, 0, cond, 0, 0, error); if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) || (res && res->quick && res->quick->reset())) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f8a755c8d5e..9817b882bdd 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1506,7 +1506,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, { for (Field **vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++) { - if ((*vfield_ptr)->stored_in_db) + if ((*vfield_ptr)->vcol_info->stored_in_db) { thd->lex->unit.insert_table_with_stored_vcol= table; break; @@ -2068,6 +2068,7 @@ public: delayed_lock= global_system_variables.low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE; mysql_mutex_unlock(&LOCK_thread_count); + thread_safe_increment32(&thread_count); DBUG_VOID_RETURN; } ~Delayed_insert() @@ -2081,17 +2082,24 @@ public: close_thread_tables(&thd); thd.mdl_context.release_transactional_locks(); } - mysql_mutex_lock(&LOCK_thread_count); mysql_mutex_destroy(&mutex); mysql_cond_destroy(&cond); mysql_cond_destroy(&cond_client); + + /* + We could use unlink_not_visible_threads() here, but as + delayed_insert_threads also needs to be protected by + the LOCK_thread_count mutex, we open code this. + */ + mysql_mutex_lock(&LOCK_thread_count); thd.unlink(); // Must be unlinked under lock - my_free(thd.query()); - thd.security_ctx->user= thd.security_ctx->host=0; delayed_insert_threads--; mysql_mutex_unlock(&LOCK_thread_count); - thread_safe_decrement32(&thread_count); - mysql_cond_broadcast(&COND_thread_count); /* Tell main we are ready */ + + my_free(thd.query()); + thd.security_ctx->user= 0; + thd.security_ctx->host= 0; + dec_thread_count(); } /* The following is for checking when we can delete ourselves */ @@ -2226,8 +2234,6 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, if (!(di= new Delayed_insert(thd->lex->current_select))) goto end_create; - thread_safe_increment32(&thread_count); - /* Annotating delayed inserts is not supported. */ @@ -2803,15 +2809,13 @@ pthread_handler_t handle_delayed_insert(void *arg) pthread_detach_this_thread(); /* Add thread to THD list so that's it's visible in 'show processlist' */ - mysql_mutex_lock(&LOCK_thread_count); - thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; + thd->thread_id= thd->variables.pseudo_thread_id= next_thread_id(); thd->set_current_time(); - threads.append(thd); + add_to_active_threads(thd); if (abort_loop) thd->killed= KILL_CONNECTION; else thd->reset_killed(); - mysql_mutex_unlock(&LOCK_thread_count); mysql_thread_set_psi_id(thd->thread_id); @@ -3892,8 +3896,8 @@ void select_insert::abort_result_set() { Field *Item::create_field_for_create_select(THD *thd, TABLE *table) { Field *def_field, *tmp_field; - return create_tmp_field(thd, table, this, type(), - (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0); + return ::create_tmp_field(thd, table, this, type(), + (Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0); } @@ -4341,8 +4345,9 @@ bool select_create::send_eof() mysql_mutex_lock(&thd->LOCK_wsrep_thd); if (thd->wsrep_conflict_state != NO_CONFLICT) { - WSREP_DEBUG("select_create commit failed, thd: %lu err: %d %s", - thd->thread_id, thd->wsrep_conflict_state, thd->query()); + WSREP_DEBUG("select_create commit failed, thd: %lld err: %d %s", + (longlong) thd->thread_id, thd->wsrep_conflict_state, + thd->query()); mysql_mutex_unlock(&thd->LOCK_wsrep_thd); abort_result_set(); DBUG_RETURN(true); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 31fc5f9712c..65257c9b2ce 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -29,6 +29,7 @@ #include "sp_head.h" #include "sp.h" #include "sql_select.h" +#include "sql_cte.h" static int lex_one_token(YYSTYPE *yylval, THD *thd); @@ -668,11 +669,15 @@ void lex_start(THD *thd) /* 'parent_lex' is used in init_query() so it must be before it. */ lex->select_lex.parent_lex= lex; lex->select_lex.init_query(); + lex->curr_with_clause= 0; + lex->with_clauses_list= 0; + lex->with_clauses_list_last_next= &lex->with_clauses_list; lex->value_list.empty(); lex->update_list.empty(); lex->set_var_list.empty(); lex->param_list.empty(); lex->view_list.empty(); + lex->with_column_list.empty(); lex->with_persistent_for_clause= FALSE; lex->column_list= NULL; lex->index_list= NULL; @@ -703,7 +708,6 @@ void lex_start(THD *thd) lex->parsing_options.reset(); lex->empty_field_list_on_rset= 0; lex->select_lex.select_number= 1; - lex->length=0; lex->part_info= 0; lex->select_lex.in_sum_expr=0; lex->select_lex.ftfunc_list_alloc.empty(); @@ -1407,28 +1411,22 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) if (use_mb(cs)) { result_state= IDENT_QUOTED; - if (my_mbcharlen(cs, lip->yyGetLast()) > 1) + int char_length= my_charlen(cs, lip->get_ptr() - 1, + lip->get_end_of_query()); + if (char_length <= 0) { - int l = my_ismbchar(cs, - lip->get_ptr() -1, - lip->get_end_of_query()); - if (l == 0) { - state = MY_LEX_CHAR; - continue; - } - lip->skip_binary(l - 1); + state= MY_LEX_CHAR; + continue; } + lip->skip_binary(char_length - 1); + while (ident_map[c=lip->yyGet()]) { - if (my_mbcharlen(cs, c) > 1) - { - int l; - if ((l = my_ismbchar(cs, - lip->get_ptr() -1, - lip->get_end_of_query())) == 0) - break; - lip->skip_binary(l-1); - } + char_length= my_charlen(cs, lip->get_ptr() - 1, + lip->get_end_of_query()); + if (char_length <= 0) + break; + lip->skip_binary(char_length - 1); } } else @@ -1569,15 +1567,11 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) result_state= IDENT_QUOTED; while (ident_map[c=lip->yyGet()]) { - if (my_mbcharlen(cs, c) > 1) - { - int l; - if ((l = my_ismbchar(cs, - lip->get_ptr() -1, - lip->get_end_of_query())) == 0) - break; - lip->skip_binary(l-1); - } + int char_length= my_charlen(cs, lip->get_ptr() - 1, + lip->get_end_of_query()); + if (char_length <= 0) + break; + lip->skip_binary(char_length - 1); } } else @@ -1605,8 +1599,9 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) char quote_char= c; // Used char while ((c=lip->yyGet())) { - int var_length; - if ((var_length= my_mbcharlen(cs, c)) == 1) + int var_length= my_charlen(cs, lip->get_ptr() - 1, + lip->get_end_of_query()); + if (var_length == 1) { if (c == quote_char) { @@ -1618,11 +1613,9 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) } } #ifdef USE_MB - else if (use_mb(cs)) + else if (var_length > 1) { - if ((var_length= my_ismbchar(cs, lip->get_ptr() - 1, - lip->get_end_of_query()))) - lip->skip_binary(var_length-1); + lip->skip_binary(var_length - 1); } #endif } @@ -2077,6 +2070,9 @@ void st_select_lex_unit::init_query() found_rows_for_union= 0; insert_table_with_stored_vcol= 0; derived= 0; + with_clause= 0; + with_element= 0; + columns_are_renamed= false; } void st_select_lex::init_query() @@ -2260,6 +2256,37 @@ void st_select_lex_node::fast_exclude() } +/** + @brief + Insert a new chain of nodes into another chain before a particular link + + @param in/out + ptr_pos_to_insert the address of the chain pointer pointing to the link + before which the subchain has to be inserted + @param + end_chain_node the last link of the subchain to be inserted + + @details + The method inserts the chain of nodes starting from this node and ending + with the node nd_chain_node into another chain of nodes before the node + pointed to by *ptr_pos_to_insert. + It is assumed that ptr_pos_to_insert belongs to the chain where we insert. + So it must be updated. + + @retval + The method returns the pointer to the first link of the inserted chain +*/ + +st_select_lex_node *st_select_lex_node:: insert_chain_before( + st_select_lex_node **ptr_pos_to_insert, + st_select_lex_node *end_chain_node) +{ + end_chain_node->link_next= *ptr_pos_to_insert; + (*ptr_pos_to_insert)->link_prev= &end_chain_node->link_next; + this->link_prev= ptr_pos_to_insert; + return this; +} + /* Exclude a node from the tree lex structure, but leave it in the global list of nodes. @@ -2649,6 +2676,8 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) void st_select_lex_unit::print(String *str, enum_query_type query_type) { bool union_all= !union_distinct; + if (with_clause) + with_clause->print(str, query_type); for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) { if (sl != first_select()) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6ec112cc038..c64ed6b8d5c 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -48,6 +48,8 @@ class Item_func_match; class File_parser; class Key_part_spec; struct sql_digest_state; +class With_clause; + #define ALLOC_ROOT_SET 1024 @@ -178,6 +180,7 @@ const LEX_STRING sp_data_access_name[]= #define DERIVED_SUBQUERY 1 #define DERIVED_VIEW 2 +#define DERIVED_WITH 4 enum enum_view_create_mode { @@ -496,10 +499,6 @@ public: enum sub_select_type linkage; bool no_table_names_allowed; /* used for global order by */ - static void *operator new(size_t size) throw () - { - return sql_alloc(size); - } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } @@ -544,7 +543,9 @@ public: List<String> *partition_names= 0, LEX_STRING *option= 0); virtual void set_lock_for_tables(thr_lock_type lock_type) {} - + void set_slave(st_select_lex_node *slave_arg) { slave= slave_arg; } + st_select_lex_node *insert_chain_before(st_select_lex_node **ptr_pos_to_insert, + st_select_lex_node *end_chain_node); friend class st_select_lex_unit; friend bool mysql_new_select(LEX *lex, bool move_down); friend bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, @@ -642,6 +643,10 @@ public: derived tables/views handling. */ TABLE_LIST *derived; + /* With clause attached to this unit (if any) */ + With_clause *with_clause; + /* With element where this unit is used as the specification (if any) */ + With_element *with_element; /* thread handler */ THD *thd; /* @@ -650,7 +655,7 @@ public: */ st_select_lex *fake_select_lex; /** - SELECT_LEX that stores LIMIT and OFFSET for UNION ALL when no + SELECT_LEX that stores LIMIT and OFFSET for UNION ALL when noq fake_select_lex is used. */ st_select_lex *saved_fake_select_lex; @@ -666,12 +671,15 @@ public: */ TABLE *insert_table_with_stored_vcol; + bool columns_are_renamed; + void init_query(); st_select_lex* outer_select(); st_select_lex* first_select() { return reinterpret_cast<st_select_lex*>(slave); } + void set_with_clause(With_clause *with_cl) { with_clause= with_cl; } st_select_lex_unit* next_unit() { return reinterpret_cast<st_select_lex_unit*>(next); @@ -1066,6 +1074,19 @@ public: void set_non_agg_field_used(bool val) { m_non_agg_field_used= val; } void set_agg_func_used(bool val) { m_agg_func_used= val; } + void set_with_clause(With_clause *with_clause) + { + master_unit()->with_clause= with_clause; + } + With_clause *get_with_clause() + { + return master_unit()->with_clause; + } + With_element *get_with_element() + { + return master_unit()->with_element; + } + With_element *find_table_def_in_with_clauses(TABLE_LIST *table); private: bool m_non_agg_field_used; @@ -2413,12 +2434,20 @@ struct LEX: public Query_tables_list SELECT_LEX *current_select; /* list of all SELECT_LEX */ SELECT_LEX *all_selects_list; - + /* current with clause in parsing if any, otherwise 0*/ + With_clause *curr_with_clause; + /* pointer to the first with clause in the current statemant */ + With_clause *with_clauses_list; + /* + (*with_clauses_list_last_next) contains a pointer to the last + with clause in the current statement + */ + With_clause **with_clauses_list_last_next; + /* Query Plan Footprint of a currently running select */ Explain_query *explain; // type information - char *length,*dec; CHARSET_INFO *charset; LEX_STRING name; @@ -2480,6 +2509,7 @@ public: List<Item_func_set_user_var> set_var_list; // in-query assignment list List<Item_param> param_list; List<LEX_STRING> view_list; // view list (list of field names in view) + List<LEX_STRING> with_column_list; // list of column names in with_list_element List<LEX_STRING> *column_list; // list of column names (in ANALYZE) List<LEX_STRING> *index_list; // list of index names (in ANALYZE) /* @@ -2499,7 +2529,7 @@ public: SQL_I_List<ORDER> proc_list; SQL_I_List<TABLE_LIST> auxiliary_table_list, save_list; - Create_field *last_field; + Column_definition *last_field; Item_sum *in_sum_func; udf_func udf; HA_CHECK_OPT check_opt; // check/repair options @@ -2877,8 +2907,8 @@ public: bool is_analyze, bool *printed_anything); void restore_set_statement_var(); - void init_last_field(Create_field *field, const char *name, CHARSET_INFO *cs); - void set_last_field_type(enum enum_field_types type); + void init_last_field(Column_definition *field, const char *name, CHARSET_INFO *cs); + void set_last_field_type(const Lex_field_type_st &type); bool set_bincmp(CHARSET_INFO *cs, bool bin); // Check if "KEY IF NOT EXISTS name" used outside of ALTER context bool check_add_key(DDL_options_st ddl) diff --git a/sql/sql_list.h b/sql/sql_list.h index 6f01b64df70..113af35bad7 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -22,7 +22,8 @@ #include "my_sys.h" /* alloc_root, TRASH, MY_WME, MY_FAE, MY_ALLOW_ZERO_PTR */ #include "m_string.h" /* bfill */ -#include "thr_malloc.h" /* sql_alloc */ + +THD *thd_get_current_thd(); /* mysql standard class memory allocator */ @@ -31,11 +32,11 @@ class Sql_alloc public: static void *operator new(size_t size) throw () { - return sql_alloc(size); + return thd_alloc(thd_get_current_thd(), size); } static void *operator new[](size_t size) throw () { - return sql_alloc(size); + return thd_alloc(thd_get_current_thd(), size); } static void *operator new[](size_t size, MEM_ROOT *mem_root) throw () { return alloc_root(mem_root, size); } @@ -649,6 +650,10 @@ struct ilink if (next) next->prev=prev; prev=0 ; next=0; } + inline void assert_if_linked() + { + DBUG_ASSERT(prev != 0 && next != 0); + } virtual ~ilink() { unlink(); } /*lint -e1740 */ }; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index e102066c0bc..d43eb884abd 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -86,7 +86,7 @@ public: CHARSET_INFO *read_charset; LOAD_FILE_IO_CACHE cache; - READ_INFO(File file,uint tot_length,CHARSET_INFO *cs, + READ_INFO(THD *thd, File file, uint tot_length, CHARSET_INFO *cs, String &field_term,String &line_start,String &line_term, String &enclosed,int escape,bool get_it_from_net, bool is_fifo); ~READ_INFO(); @@ -306,7 +306,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { for (Field **vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++) { - if ((*vfield_ptr)->stored_in_db) + if ((*vfield_ptr)->vcol_info->stored_in_db) { thd->lex->unit.insert_table_with_stored_vcol= table; break; @@ -440,7 +440,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, !(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))) ? (*escaped)[0] : INT_MAX; - READ_INFO read_info(file,tot_length, + READ_INFO read_info(thd, file, tot_length, ex->cs ? ex->cs : thd->variables.collation_database, *field_term,*ex->line_start, *ex->line_term, *enclosed, info.escape_char, read_file_from_client, is_fifo); @@ -1337,7 +1337,7 @@ READ_INFO::unescape(char chr) */ -READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, +READ_INFO::READ_INFO(THD *thd, File file_par, uint tot_length, CHARSET_INFO *cs, String &field_term, String &line_start, String &line_term, String &enclosed_par, int escape, bool get_it_from_net, bool is_fifo) @@ -1384,7 +1384,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, /* Set of a stack for unget if long terminators */ uint length= MY_MAX(cs->mbmaxlen, MY_MAX(field_term_length, line_term_length)) + 1; set_if_bigger(length,line_start.length()); - stack=stack_pos=(int*) sql_alloc(sizeof(int)*length); + stack= stack_pos= (int*) thd->alloc(sizeof(int) * length); if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(MY_THREAD_SPECIFIC)))) error=1; /* purecov: inspected */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6fcb549f097..7c50e4ed680 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -92,6 +92,7 @@ #include "transaction.h" #include "sql_audit.h" #include "sql_prepare.h" +#include "sql_cte.h" #include "debug_sync.h" #include "probes_mysql.h" #include "set_var.h" @@ -110,7 +111,7 @@ #include "wsrep_thd.h" static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, - Parser_state *parser_state); + Parser_state *parser_state, bool is_next_command); /** @defgroup Runtime_Environment Runtime Environment @@ -134,38 +135,263 @@ static bool check_rename_table(THD *, TABLE_LIST *, TABLE_LIST *); const char *any_db="*any*"; // Special symbol for check_access -const LEX_STRING command_name[]={ - { C_STRING_WITH_LEN("Sleep") }, - { C_STRING_WITH_LEN("Quit") }, - { C_STRING_WITH_LEN("Init DB") }, - { C_STRING_WITH_LEN("Query") }, - { C_STRING_WITH_LEN("Field List") }, - { C_STRING_WITH_LEN("Create DB") }, - { C_STRING_WITH_LEN("Drop DB") }, - { C_STRING_WITH_LEN("Refresh") }, - { C_STRING_WITH_LEN("Shutdown") }, - { C_STRING_WITH_LEN("Statistics") }, - { C_STRING_WITH_LEN("Processlist") }, - { C_STRING_WITH_LEN("Connect") }, - { C_STRING_WITH_LEN("Kill") }, - { C_STRING_WITH_LEN("Debug") }, - { C_STRING_WITH_LEN("Ping") }, - { C_STRING_WITH_LEN("Time") }, - { C_STRING_WITH_LEN("Delayed insert") }, - { C_STRING_WITH_LEN("Change user") }, - { C_STRING_WITH_LEN("Binlog Dump") }, - { C_STRING_WITH_LEN("Table Dump") }, - { C_STRING_WITH_LEN("Connect Out") }, - { C_STRING_WITH_LEN("Register Slave") }, - { C_STRING_WITH_LEN("Prepare") }, - { C_STRING_WITH_LEN("Execute") }, - { C_STRING_WITH_LEN("Long Data") }, - { C_STRING_WITH_LEN("Close stmt") }, - { C_STRING_WITH_LEN("Reset stmt") }, - { C_STRING_WITH_LEN("Set option") }, - { C_STRING_WITH_LEN("Fetch") }, - { C_STRING_WITH_LEN("Daemon") }, - { C_STRING_WITH_LEN("Error") } // Last command number +const LEX_STRING command_name[257]={ + { C_STRING_WITH_LEN("Sleep") }, //0 + { C_STRING_WITH_LEN("Quit") }, //1 + { C_STRING_WITH_LEN("Init DB") }, //2 + { C_STRING_WITH_LEN("Query") }, //3 + { C_STRING_WITH_LEN("Field List") }, //4 + { C_STRING_WITH_LEN("Create DB") }, //5 + { C_STRING_WITH_LEN("Drop DB") }, //6 + { C_STRING_WITH_LEN("Refresh") }, //7 + { C_STRING_WITH_LEN("Shutdown") }, //8 + { C_STRING_WITH_LEN("Statistics") }, //9 + { C_STRING_WITH_LEN("Processlist") }, //10 + { C_STRING_WITH_LEN("Connect") }, //11 + { C_STRING_WITH_LEN("Kill") }, //12 + { C_STRING_WITH_LEN("Debug") }, //13 + { C_STRING_WITH_LEN("Ping") }, //14 + { C_STRING_WITH_LEN("Time") }, //15 + { C_STRING_WITH_LEN("Delayed insert") }, //16 + { C_STRING_WITH_LEN("Change user") }, //17 + { C_STRING_WITH_LEN("Binlog Dump") }, //18 + { C_STRING_WITH_LEN("Table Dump") }, //19 + { C_STRING_WITH_LEN("Connect Out") }, //20 + { C_STRING_WITH_LEN("Register Slave") }, //21 + { C_STRING_WITH_LEN("Prepare") }, //22 + { C_STRING_WITH_LEN("Execute") }, //23 + { C_STRING_WITH_LEN("Long Data") }, //24 + { C_STRING_WITH_LEN("Close stmt") }, //25 + { C_STRING_WITH_LEN("Reset stmt") }, //26 + { C_STRING_WITH_LEN("Set option") }, //27 + { C_STRING_WITH_LEN("Fetch") }, //28 + { C_STRING_WITH_LEN("Daemon") }, //29 + { 0, 0 }, //30 + { 0, 0 }, //31 + { 0, 0 }, //32 + { 0, 0 }, //33 + { 0, 0 }, //34 + { 0, 0 }, //35 + { 0, 0 }, //36 + { 0, 0 }, //37 + { 0, 0 }, //38 + { 0, 0 }, //39 + { 0, 0 }, //40 + { 0, 0 }, //41 + { 0, 0 }, //42 + { 0, 0 }, //43 + { 0, 0 }, //44 + { 0, 0 }, //45 + { 0, 0 }, //46 + { 0, 0 }, //47 + { 0, 0 }, //48 + { 0, 0 }, //49 + { 0, 0 }, //50 + { 0, 0 }, //51 + { 0, 0 }, //52 + { 0, 0 }, //53 + { 0, 0 }, //54 + { 0, 0 }, //55 + { 0, 0 }, //56 + { 0, 0 }, //57 + { 0, 0 }, //58 + { 0, 0 }, //59 + { 0, 0 }, //60 + { 0, 0 }, //61 + { 0, 0 }, //62 + { 0, 0 }, //63 + { 0, 0 }, //64 + { 0, 0 }, //65 + { 0, 0 }, //66 + { 0, 0 }, //67 + { 0, 0 }, //68 + { 0, 0 }, //69 + { 0, 0 }, //70 + { 0, 0 }, //71 + { 0, 0 }, //72 + { 0, 0 }, //73 + { 0, 0 }, //74 + { 0, 0 }, //75 + { 0, 0 }, //76 + { 0, 0 }, //77 + { 0, 0 }, //78 + { 0, 0 }, //79 + { 0, 0 }, //80 + { 0, 0 }, //81 + { 0, 0 }, //82 + { 0, 0 }, //83 + { 0, 0 }, //84 + { 0, 0 }, //85 + { 0, 0 }, //86 + { 0, 0 }, //87 + { 0, 0 }, //88 + { 0, 0 }, //89 + { 0, 0 }, //90 + { 0, 0 }, //91 + { 0, 0 }, //92 + { 0, 0 }, //93 + { 0, 0 }, //94 + { 0, 0 }, //95 + { 0, 0 }, //96 + { 0, 0 }, //97 + { 0, 0 }, //98 + { 0, 0 }, //99 + { 0, 0 }, //100 + { 0, 0 }, //101 + { 0, 0 }, //102 + { 0, 0 }, //103 + { 0, 0 }, //104 + { 0, 0 }, //105 + { 0, 0 }, //106 + { 0, 0 }, //107 + { 0, 0 }, //108 + { 0, 0 }, //109 + { 0, 0 }, //110 + { 0, 0 }, //111 + { 0, 0 }, //112 + { 0, 0 }, //113 + { 0, 0 }, //114 + { 0, 0 }, //115 + { 0, 0 }, //116 + { 0, 0 }, //117 + { 0, 0 }, //118 + { 0, 0 }, //119 + { 0, 0 }, //120 + { 0, 0 }, //121 + { 0, 0 }, //122 + { 0, 0 }, //123 + { 0, 0 }, //124 + { 0, 0 }, //125 + { 0, 0 }, //126 + { 0, 0 }, //127 + { 0, 0 }, //128 + { 0, 0 }, //129 + { 0, 0 }, //130 + { 0, 0 }, //131 + { 0, 0 }, //132 + { 0, 0 }, //133 + { 0, 0 }, //134 + { 0, 0 }, //135 + { 0, 0 }, //136 + { 0, 0 }, //137 + { 0, 0 }, //138 + { 0, 0 }, //139 + { 0, 0 }, //140 + { 0, 0 }, //141 + { 0, 0 }, //142 + { 0, 0 }, //143 + { 0, 0 }, //144 + { 0, 0 }, //145 + { 0, 0 }, //146 + { 0, 0 }, //147 + { 0, 0 }, //148 + { 0, 0 }, //149 + { 0, 0 }, //150 + { 0, 0 }, //151 + { 0, 0 }, //152 + { 0, 0 }, //153 + { 0, 0 }, //154 + { 0, 0 }, //155 + { 0, 0 }, //156 + { 0, 0 }, //157 + { 0, 0 }, //158 + { 0, 0 }, //159 + { 0, 0 }, //160 + { 0, 0 }, //161 + { 0, 0 }, //162 + { 0, 0 }, //163 + { 0, 0 }, //164 + { 0, 0 }, //165 + { 0, 0 }, //166 + { 0, 0 }, //167 + { 0, 0 }, //168 + { 0, 0 }, //169 + { 0, 0 }, //170 + { 0, 0 }, //171 + { 0, 0 }, //172 + { 0, 0 }, //173 + { 0, 0 }, //174 + { 0, 0 }, //175 + { 0, 0 }, //176 + { 0, 0 }, //177 + { 0, 0 }, //178 + { 0, 0 }, //179 + { 0, 0 }, //180 + { 0, 0 }, //181 + { 0, 0 }, //182 + { 0, 0 }, //183 + { 0, 0 }, //184 + { 0, 0 }, //185 + { 0, 0 }, //186 + { 0, 0 }, //187 + { 0, 0 }, //188 + { 0, 0 }, //189 + { 0, 0 }, //190 + { 0, 0 }, //191 + { 0, 0 }, //192 + { 0, 0 }, //193 + { 0, 0 }, //194 + { 0, 0 }, //195 + { 0, 0 }, //196 + { 0, 0 }, //197 + { 0, 0 }, //198 + { 0, 0 }, //199 + { 0, 0 }, //200 + { 0, 0 }, //201 + { 0, 0 }, //202 + { 0, 0 }, //203 + { 0, 0 }, //204 + { 0, 0 }, //205 + { 0, 0 }, //206 + { 0, 0 }, //207 + { 0, 0 }, //208 + { 0, 0 }, //209 + { 0, 0 }, //210 + { 0, 0 }, //211 + { 0, 0 }, //212 + { 0, 0 }, //213 + { 0, 0 }, //214 + { 0, 0 }, //215 + { 0, 0 }, //216 + { 0, 0 }, //217 + { 0, 0 }, //218 + { 0, 0 }, //219 + { 0, 0 }, //220 + { 0, 0 }, //221 + { 0, 0 }, //222 + { 0, 0 }, //223 + { 0, 0 }, //224 + { 0, 0 }, //225 + { 0, 0 }, //226 + { 0, 0 }, //227 + { 0, 0 }, //228 + { 0, 0 }, //229 + { 0, 0 }, //230 + { 0, 0 }, //231 + { 0, 0 }, //232 + { 0, 0 }, //233 + { 0, 0 }, //234 + { 0, 0 }, //235 + { 0, 0 }, //236 + { 0, 0 }, //237 + { 0, 0 }, //238 + { 0, 0 }, //239 + { 0, 0 }, //240 + { 0, 0 }, //241 + { 0, 0 }, //242 + { 0, 0 }, //243 + { 0, 0 }, //244 + { 0, 0 }, //245 + { 0, 0 }, //246 + { 0, 0 }, //247 + { 0, 0 }, //248 + { 0, 0 }, //249 + { 0, 0 }, //250 + { 0, 0 }, //251 + { 0, 0 }, //252 + { 0, 0 }, //253 + { C_STRING_WITH_LEN("Com_multi") }, //254 + { C_STRING_WITH_LEN("Error") } // Last command number 255 }; const char *xa_state_names[]={ @@ -267,7 +493,7 @@ void init_update_queries(void) memset(server_command_flags, 0, sizeof(server_command_flags)); server_command_flags[COM_STATISTICS]= CF_SKIP_QUERY_ID | CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK; - server_command_flags[COM_PING]= CF_SKIP_QUERY_ID | CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK; + server_command_flags[COM_PING]= CF_SKIP_QUERY_ID | CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK | CF_NO_COM_MULTI; server_command_flags[COM_QUIT]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_PROCESS_INFO]= CF_SKIP_WSREP_CHECK; @@ -276,6 +502,10 @@ void init_update_queries(void) server_command_flags[COM_SLEEP]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_TIME]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_END]= CF_SKIP_WSREP_CHECK; + for (uint i= COM_MDB_GAP_BEG; i <= COM_MDB_GAP_END; i++) + { + server_command_flags[i]= CF_SKIP_WSREP_CHECK; + } /* COM_QUERY, COM_SET_OPTION and COM_STMT_XXX are allowed to pass the early @@ -288,6 +518,7 @@ void init_update_queries(void) server_command_flags[COM_STMT_RESET]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK; server_command_flags[COM_STMT_EXECUTE]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_STMT_SEND_LONG_DATA]= CF_SKIP_WSREP_CHECK; + server_command_flags[COM_MULTI]= CF_SKIP_WSREP_CHECK | CF_NO_COM_MULTI; /* Initialize the sql command flags array. */ memset(sql_command_flags, 0, sizeof(sql_command_flags)); @@ -415,6 +646,7 @@ void init_update_queries(void) sql_command_flags[SQLCOM_SHOW_EXPLAIN]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_GRANTS]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CREATE_USER]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND; @@ -436,6 +668,7 @@ void init_update_queries(void) sql_command_flags[SQLCOM_CREATE_USER]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_RENAME_USER]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_DROP_USER]= CF_CHANGES_DATA; + sql_command_flags[SQLCOM_ALTER_USER]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_CREATE_ROLE]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_GRANT]= CF_CHANGES_DATA; sql_command_flags[SQLCOM_GRANT_ROLE]= CF_CHANGES_DATA; @@ -492,6 +725,7 @@ void init_update_queries(void) sql_command_flags[SQLCOM_CHECKSUM]= CF_REPORT_PROGRESS; sql_command_flags[SQLCOM_CREATE_USER]|= CF_AUTO_COMMIT_TRANS; + sql_command_flags[SQLCOM_ALTER_USER]|= CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_DROP_USER]|= CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_RENAME_USER]|= CF_AUTO_COMMIT_TRANS; sql_command_flags[SQLCOM_CREATE_ROLE]|= CF_AUTO_COMMIT_TRANS; @@ -585,6 +819,7 @@ void init_update_queries(void) sql_command_flags[SQLCOM_ALTER_EVENT]|= CF_DISALLOW_IN_RO_TRANS; sql_command_flags[SQLCOM_DROP_EVENT]|= CF_DISALLOW_IN_RO_TRANS; sql_command_flags[SQLCOM_CREATE_USER]|= CF_DISALLOW_IN_RO_TRANS; + sql_command_flags[SQLCOM_ALTER_USER]|= CF_DISALLOW_IN_RO_TRANS; sql_command_flags[SQLCOM_RENAME_USER]|= CF_DISALLOW_IN_RO_TRANS; sql_command_flags[SQLCOM_DROP_USER]|= CF_DISALLOW_IN_RO_TRANS; sql_command_flags[SQLCOM_CREATE_SERVER]|= CF_DISALLOW_IN_RO_TRANS; @@ -635,7 +870,7 @@ void execute_init_command(THD *thd, LEX_STRING *init_command, mysql_rwlock_t *var_lock) { Vio* save_vio; - ulong save_client_capabilities; + ulonglong save_client_capabilities; mysql_rwlock_rdlock(var_lock); if (!init_command->length) @@ -667,7 +902,7 @@ void execute_init_command(THD *thd, LEX_STRING *init_command, */ save_vio= thd->net.vio; thd->net.vio= 0; - dispatch_command(COM_QUERY, thd, buf, len); + dispatch_command(COM_QUERY, thd, buf, len, FALSE, FALSE); thd->client_capabilities= save_client_capabilities; thd->net.vio= save_vio; @@ -785,7 +1020,7 @@ static void handle_bootstrap_impl(THD *thd) break; } - mysql_parse(thd, thd->query(), length, &parser_state); + mysql_parse(thd, thd->query(), length, &parser_state, FALSE); bootstrap_error= thd->is_error(); thd->protocol->end_statement(); @@ -842,12 +1077,13 @@ end: delete thd; #ifndef EMBEDDED_LIBRARY - thread_safe_decrement32(&thread_count); + DBUG_ASSERT(thread_count == 1); in_bootstrap= FALSE; - - mysql_mutex_lock(&LOCK_thread_count); - mysql_cond_broadcast(&COND_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); + /* + dec_thread_count will signal bootstrap() function that we have ended as + thread_count will become 0. + */ + dec_thread_count(); my_thread_end(); pthread_exit(0); #endif @@ -856,7 +1092,7 @@ end: } -/* This works because items are allocated with sql_alloc() */ +/* This works because items are allocated on THD::mem_root */ void free_items(Item *item) { @@ -871,7 +1107,7 @@ void free_items(Item *item) } /** - This works because items are allocated with sql_alloc(). + This works because items are allocated on THD::mem_root. @note The function also handles null pointers (empty list). */ void cleanup_items(Item *item) @@ -882,6 +1118,23 @@ void cleanup_items(Item *item) DBUG_VOID_RETURN; } +static enum enum_server_command fetch_command(THD *thd, char *packet) +{ + enum enum_server_command + command= (enum enum_server_command) (uchar) packet[0]; + NET *net= &thd->net; + DBUG_ENTER("fetch_command"); + + if (command >= COM_END || + (command >= COM_MDB_GAP_BEG && command <= COM_MDB_GAP_END)) + command= COM_END; // Wrong command + + DBUG_PRINT("info",("Command on %s = %d (%s)", + vio_description(net->vio), command, + command_name[command].str)); + DBUG_RETURN(command); +} + #ifndef EMBEDDED_LIBRARY @@ -952,7 +1205,6 @@ bool do_command(THD *thd) if(!thd->skip_wait_timeout) my_net_set_read_timeout(net, thd->variables.net_wait_timeout); - /* XXX: this code is here only to clear possible errors of init_connect. Consider moving to init_connect() instead. @@ -1071,14 +1323,8 @@ bool do_command(THD *thd) /* Do not rely on my_net_read, extra safety against programming errors. */ packet[packet_length]= '\0'; /* safety */ - command= (enum enum_server_command) (uchar) packet[0]; - if (command >= COM_END) - command= COM_END; // Wrong command - - DBUG_PRINT("info",("Command on %s = %d (%s)", - vio_description(net->vio), command, - command_name[command].str)); + command= fetch_command(thd, packet); #ifdef WITH_WSREP /* @@ -1104,7 +1350,8 @@ bool do_command(THD *thd) DBUG_ASSERT(packet_length); DBUG_ASSERT(!thd->apc_target.is_enabled()); - return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1)); + return_value= dispatch_command(command, thd, packet+1, + (uint) (packet_length-1), FALSE, FALSE); #ifdef WITH_WSREP if (WSREP(thd)) { @@ -1122,7 +1369,7 @@ bool do_command(THD *thd) my_charset_latin1.csname); } return_value= dispatch_command(command, thd, thd->wsrep_retry_query, - thd->wsrep_retry_query_len); + thd->wsrep_retry_query_len, FALSE, FALSE); thd->variables.character_set_client = current_charset; } @@ -1214,6 +1461,44 @@ static my_bool deny_updates_if_read_only_option(THD *thd, /** + check COM_MULTI packet + + @param thd thread handle + @param packet pointer on the packet of commands + @param packet_length length of this packet + + @retval 0 - Error + @retval # - Number of commands in the batch +*/ + +uint maria_multi_check(THD *thd, char *packet, uint packet_length) +{ + uint counter= 0; + DBUG_ENTER("maria_multi_check"); + while (packet_length) + { + // length of command + 3 bytes where that length was stored + uint subpacket_length= (uint3korr(packet) + 3); + DBUG_PRINT("info", ("sub-packet length: %d command: %x", + subpacket_length, packet[3])); + + if (subpacket_length == 3 || + subpacket_length > packet_length) + { + my_message(ER_UNKNOWN_COM_ERROR, ER_THD(thd, ER_UNKNOWN_COM_ERROR), + MYF(0)); + DBUG_RETURN(0); + } + + counter++; + packet+= subpacket_length; + packet_length-= subpacket_length; + } + DBUG_RETURN(counter); +} + + +/** Perform one connection-level (COM_XXXX) command. @param command type of command to perform @@ -1222,6 +1507,8 @@ static my_bool deny_updates_if_read_only_option(THD *thd, @param packet_length length of packet + 1 (to show that data is null-terminated) except for COM_SLEEP, where it can be zero. + @param is_com_multi recursive call from COM_MULTI + @param is_next_command there will be more command in the COM_MULTI batch @todo set thd->lex->sql_command to SQLCOM_END here. @@ -1235,15 +1522,24 @@ static my_bool deny_updates_if_read_only_option(THD *thd, COM_QUIT/COM_SHUTDOWN */ bool dispatch_command(enum enum_server_command command, THD *thd, - char* packet, uint packet_length) + char* packet, uint packet_length, bool is_com_multi, + bool is_next_command) { NET *net= &thd->net; bool error= 0; bool do_end_of_statement= true; DBUG_ENTER("dispatch_command"); - DBUG_PRINT("info", ("command: %d", command)); + DBUG_PRINT("info", ("command: %d %s", command, + (command_name[command].str != 0 ? + command_name[command].str : + "<?>"))); + bool drop_more_results= 0; - inc_thread_running(); + if (!is_com_multi) + inc_thread_running(); + + /* keep it withing 1 byte */ + compile_time_assert(COM_END == 255); #ifdef WITH_WSREP if (WSREP(thd)) @@ -1333,6 +1629,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, beginning of each command. */ thd->server_status&= ~SERVER_STATUS_CLEAR_SET; + if (is_next_command) + { + drop_more_results= !MY_TEST(thd->server_status & + SERVER_MORE_RESULTS_EXISTS); + thd->server_status|= SERVER_MORE_RESULTS_EXISTS; + } + switch (command) { case COM_INIT_DB: { @@ -1481,9 +1784,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; if (WSREP_ON) - wsrep_mysql_parse(thd, thd->query(), thd->query_length(), &parser_state); + wsrep_mysql_parse(thd, thd->query(), thd->query_length(), &parser_state, + is_next_command); else - mysql_parse(thd, thd->query(), thd->query_length(), &parser_state); + mysql_parse(thd, thd->query(), thd->query_length(), &parser_state, + is_next_command); while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) && ! thd->is_error()) @@ -1568,9 +1873,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* TODO: set thd->lex->sql_command to SQLCOM_END here */ if (WSREP_ON) - wsrep_mysql_parse(thd, beginning_of_next_stmt, length, &parser_state); + wsrep_mysql_parse(thd, beginning_of_next_stmt, length, &parser_state, + is_next_command); else - mysql_parse(thd, beginning_of_next_stmt, length, &parser_state); + mysql_parse(thd, beginning_of_next_stmt, length, &parser_state, + is_next_command); } @@ -1622,6 +1929,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } packet= arg_end + 1; thd->reset_for_next_command(); + // thd->reset_for_next_command reset state => restore it + if (is_next_command) + thd->server_status|= SERVER_MORE_RESULTS_EXISTS; lex_start(thd); /* Must be before we init the table list. */ if (lower_case_table_names) @@ -1803,7 +2113,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_PRINT("quit",("Got shutdown command for level %u", level)); general_log_print(thd, command, NullS); my_eof(thd); - kill_mysql(); + kill_mysql(thd); error=TRUE; break; } @@ -1900,6 +2210,66 @@ bool dispatch_command(enum enum_server_command command, THD *thd, general_log_print(thd, command, NullS); my_eof(thd); break; + case COM_MULTI: + { + uint counter; + uint current_com= 0; + DBUG_ASSERT(!is_com_multi); + if (!(thd->client_capabilities & CLIENT_MULTI_RESULTS)) + { + /* The client does not support multiple result sets being sent back */ + my_error(ER_COMMULTI_BADCONTEXT, MYF(0)); + break; + } + + if (!(counter= maria_multi_check(thd, packet, packet_length))) + break; + + { + /* We have to store next length because it will be destroyed by '\0' */ + uint next_subpacket_length= uint3korr(packet); + unsigned char *readbuff= net->buff; + + if (net_allocate_new_packet(net, thd, MYF(0))) + break; + + while (packet_length) + { + current_com++; + uint subpacket_length= next_subpacket_length + 3; + if (subpacket_length < packet_length) + next_subpacket_length= uint3korr(packet + subpacket_length); + /* safety like in do_command() */ + packet[subpacket_length]= '\0'; + + enum enum_server_command subcommand= fetch_command(thd, (packet + 3)); + + if (server_command_flags[subcommand] & CF_NO_COM_MULTI) + { + my_error(ER_BAD_COMMAND_IN_MULTI, MYF(0), command_name[subcommand]); + goto com_multi_end; + } + + if (dispatch_command(subcommand, thd, packet + (1 + 3), + subpacket_length - (1 + 3), TRUE, + (current_com != counter))) + { + DBUG_ASSERT(thd->is_error()); + goto com_multi_end; + } + + DBUG_ASSERT(subpacket_length <= packet_length); + packet+= subpacket_length; + packet_length-= subpacket_length; + } + +com_multi_end: + /* release old buffer */ + DBUG_ASSERT(net->buff == net->write_pos); // nothing to send + my_free(readbuff); + } + break; + } case COM_SLEEP: case COM_CONNECT: // Impossible here case COM_TIME: // Impossible from client @@ -1936,9 +2306,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd_proc_info(thd, "updating status"); /* Finalize server status flags after executing a command. */ thd->update_server_status(); - thd->protocol->end_statement(); - query_cache_end_of_result(thd); + if (command != COM_MULTI) + { + thd->protocol->end_statement(); + query_cache_end_of_result(thd); + } } + if (drop_more_results) + thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; if (!thd->is_error() && !thd->killed_errno()) mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0); @@ -1962,8 +2337,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->m_statement_psi= NULL; thd->m_digest= NULL; - dec_thread_running(); - thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory + if (!is_com_multi) + { + dec_thread_running(); + thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory + } free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); #if defined(ENABLED_PROFILING) @@ -2098,7 +2476,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, { DBUG_RETURN(1); } - schema_select_lex= new SELECT_LEX(); + schema_select_lex= new (thd->mem_root) SELECT_LEX(); db.str= schema_select_lex->db= lex->select_lex.db; schema_select_lex->table_list.first= NULL; db.length= strlen(db.str); @@ -2121,7 +2499,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, #else DBUG_ASSERT(table_ident); TABLE_LIST **query_tables_last= lex->query_tables_last; - schema_select_lex= new SELECT_LEX(); + schema_select_lex= new (thd->mem_root) SELECT_LEX(); /* 'parent_lex' is used in init_query() so it must be before it. */ schema_select_lex->parent_lex= lex; schema_select_lex->init_query(); @@ -2828,7 +3206,8 @@ mysql_execute_command(THD *thd) thd->mdl_context.release_transactional_locks(); if (commit_failed) { - WSREP_DEBUG("implicit commit failed, MDL released: %lu", thd->thread_id); + WSREP_DEBUG("implicit commit failed, MDL released: %lld", + (longlong) thd->thread_id); goto error; } } @@ -4635,6 +5014,7 @@ end_with_restore_list: my_ok(thd); break; } + case SQLCOM_ALTER_USER: case SQLCOM_RENAME_USER: { if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) && @@ -4642,7 +5022,11 @@ end_with_restore_list: break; /* Conditionally writes to binlog */ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) - if (!(res= mysql_rename_user(thd, lex->users_list))) + if (lex->sql_command == SQLCOM_ALTER_USER) + res= mysql_alter_user(thd, lex->users_list); + else + res= mysql_rename_user(thd, lex->users_list); + if (!res) my_ok(thd); break; } @@ -4927,7 +5311,7 @@ end_with_restore_list: #ifndef EMBEDDED_LIBRARY if (check_global_access(thd,SHUTDOWN_ACL)) goto error; - kill_mysql(); + kill_mysql(thd); my_ok(thd); #else my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server"); @@ -4935,6 +5319,7 @@ end_with_restore_list: break; #ifndef NO_EMBEDDED_ACCESS_CHECKS + case SQLCOM_SHOW_CREATE_USER: case SQLCOM_SHOW_GRANTS: { LEX_USER *grant_user= lex->grant_user; @@ -4951,7 +5336,10 @@ end_with_restore_list: grant_user->user.str == current_user_and_current_role.str || !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 0)) { - res = mysql_show_grants(thd, grant_user); + if (lex->sql_command == SQLCOM_SHOW_GRANTS) + res = mysql_show_grants(thd, grant_user); + else + res = mysql_show_create_user(thd, grant_user); } break; } @@ -4988,7 +5376,8 @@ end_with_restore_list: if (trans_begin(thd, lex->start_transaction_opt)) { thd->mdl_context.release_transactional_locks(); - WSREP_DEBUG("BEGIN failed, MDL released: %lu", thd->thread_id); + WSREP_DEBUG("BEGIN failed, MDL released: %lld", + (longlong) thd->thread_id); goto error; } my_ok(thd); @@ -5007,7 +5396,8 @@ end_with_restore_list: thd->mdl_context.release_transactional_locks(); if (commit_failed) { - WSREP_DEBUG("COMMIT failed, MDL released: %lu", thd->thread_id); + WSREP_DEBUG("COMMIT failed, MDL released: %lld", + (longlong) thd->thread_id); goto error; } /* Begin transaction with the same isolation level. */ @@ -5054,7 +5444,8 @@ end_with_restore_list: if (rollback_failed) { - WSREP_DEBUG("rollback failed, MDL released: %lu", thd->thread_id); + WSREP_DEBUG("rollback failed, MDL released: %lld", + (longlong) thd->thread_id); goto error; } /* Begin transaction with the same isolation level. */ @@ -5544,7 +5935,8 @@ end_with_restore_list: thd->mdl_context.release_transactional_locks(); if (commit_failed) { - WSREP_DEBUG("XA commit failed, MDL released: %lu", thd->thread_id); + WSREP_DEBUG("XA commit failed, MDL released: %lld", + (longlong) thd->thread_id); goto error; } /* @@ -5562,7 +5954,8 @@ end_with_restore_list: thd->mdl_context.release_transactional_locks(); if (rollback_failed) { - WSREP_DEBUG("XA rollback failed, MDL released: %lu", thd->thread_id); + WSREP_DEBUG("XA rollback failed, MDL released: %lld", + (longlong) thd->thread_id); goto error; } /* @@ -5799,8 +6192,8 @@ finish: ! thd->in_active_multi_stmt_transaction() && thd->mdl_context.has_transactional_locks()) { - WSREP_DEBUG("Forcing release of transactional locks for thd %lu", - thd->thread_id); + WSREP_DEBUG("Forcing release of transactional locks for thd: %lld", + (longlong) thd->thread_id); thd->mdl_context.release_transactional_locks(); } #endif /* WITH_WSREP */ @@ -5822,6 +6215,9 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) new (thd->mem_root) Item_int(thd, (ulonglong) thd->variables.select_limit); } + if (check_dependencies_in_with_clauses(lex->with_clauses_list)) + return 1; + if (!(res= open_and_lock_tables(thd, all_tables, TRUE, 0))) { if (lex->describe) @@ -7085,7 +7481,7 @@ void create_select_for_variable(const char *var_name) if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_str))) { end= strxmov(buff, "@@session.", var_name, NullS); - var->set_name(buff, end-buff, system_charset_info); + var->set_name(thd, buff, end-buff, system_charset_info); add_item_to_list(thd, var); } DBUG_VOID_RETURN; @@ -7104,7 +7500,7 @@ void mysql_init_multi_delete(LEX *lex) } static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, - Parser_state *parser_state) + Parser_state *parser_state, bool is_next_command) { #ifdef WITH_WSREP bool is_autocommit= @@ -7123,7 +7519,7 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(), thd->query_length()); } - mysql_parse(thd, rawbuf, length, parser_state); + mysql_parse(thd, rawbuf, length, parser_state, is_next_command); if (WSREP(thd)) { /* wsrep BF abort in query exec phase */ @@ -7166,10 +7562,11 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, } else { - WSREP_DEBUG("%s, thd: %lu is_AC: %d, retry: %lu - %lu SQL: %s", + WSREP_DEBUG("%s, thd: %lld is_AC: %d, retry: %lu - %lu SQL: %s", (thd->wsrep_conflict_state == ABORTED) ? "BF Aborted" : "cert failure", - thd->thread_id, is_autocommit, thd->wsrep_retry_counter, + (longlong) thd->thread_id, is_autocommit, + thd->wsrep_retry_counter, thd->variables.wsrep_retry_autocommit, thd->query()); my_error(ER_LOCK_DEADLOCK, MYF(0), "wsrep aborted transaction"); thd->killed= NOT_KILLED; @@ -7220,10 +7617,11 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, @param length Length of the query text @param[out] found_semicolon For multi queries, position of the character of the next query in the query text. + @param is_next_command there will be more command in the COM_MULTI batch */ void mysql_parse(THD *thd, char *rawbuf, uint length, - Parser_state *parser_state) + Parser_state *parser_state, bool is_next_command) { int error __attribute__((unused)); DBUG_ENTER("mysql_parse"); @@ -7247,6 +7645,8 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, */ lex_start(thd); thd->reset_for_next_command(); + if (is_next_command) + thd->server_status|= SERVER_MORE_RESULTS_EXISTS; if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0) { @@ -7280,7 +7680,6 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, and Query_log_event::print() would give ';;' output). This also helps display only the current query in SHOW PROCESSLIST. - Note that we don't need LOCK_thread_count to modify query_length. */ if (found_semicolon && (ulong) (found_semicolon - thd->query())) thd->set_query_inner(thd->query(), @@ -7379,13 +7778,6 @@ bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length) #endif -/** Store position for column in ALTER TABLE .. ADD column. */ - -void store_position_for_column(const char *name) -{ - current_thd->lex->last_field->after=(char*) (name); -} - bool add_proc_to_list(THD* thd, Item *item) { diff --git a/sql/sql_parse.h b/sql/sql_parse.h index c3c47567cf5..53a9ed3b24c 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -35,6 +35,7 @@ enum enum_mysql_completiontype { extern "C" int test_if_data_home_dir(const char *dir); int error_if_data_home_dir(const char *path, const char *what); +my_bool net_allocate_new_packet(NET *net, void *thd, uint my_flags); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables); @@ -87,7 +88,7 @@ bool is_log_table_write_query(enum enum_sql_command command); bool alloc_query(THD *thd, const char *packet, uint packet_length); void mysql_init_select(LEX *lex); void mysql_parse(THD *thd, char *rawbuf, uint length, - Parser_state *parser_state); + Parser_state *parser_state, bool is_com_multi); bool mysql_new_select(LEX *lex, bool move_down); void create_select_for_variable(const char *var_name); void create_table_set_open_action_and_adjust_tables(LEX *lex); @@ -99,7 +100,8 @@ int mysql_execute_command(THD *thd); bool do_command(THD *thd); void do_handle_bootstrap(THD *thd); bool dispatch_command(enum enum_server_command command, THD *thd, - char* packet, uint packet_length); + char* packet, uint packet_length, + bool is_com_multi, bool is_next_command); void log_slow_statement(THD *thd); bool append_file_to_dir(THD *thd, const char **filename_ptr, const char *table_name); @@ -115,7 +117,6 @@ bool add_proc_to_list(THD *thd, Item *item); bool push_new_name_resolution_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op); -void store_position_for_column(const char *name); void init_update_queries(void); bool check_simple_select(); Item *normalize_cond(THD *thd, Item *cond); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 16588871fd8..832f218fb51 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -255,7 +255,7 @@ static bool is_name_in_list(char *name, List<char> list_names) FALSE Success */ -bool partition_default_handling(TABLE *table, partition_info *part_info, +bool partition_default_handling(THD *thd, TABLE *table, partition_info *part_info, bool is_create_table_ind, const char *normalized_path) { @@ -283,7 +283,7 @@ bool partition_default_handling(TABLE *table, partition_info *part_info, part_info->num_subparts= num_parts / part_info->num_parts; } } - part_info->set_up_defaults_for_partitioning(table->file, + part_info->set_up_defaults_for_partitioning(thd, table->file, NULL, 0U); DBUG_RETURN(FALSE); } @@ -455,7 +455,7 @@ int get_part_for_delete(const uchar *buf, const uchar *rec0, function. */ -static bool set_up_field_array(TABLE *table, +static bool set_up_field_array(THD *thd, TABLE *table, bool is_sub_part) { Field **ptr, *field, **field_array; @@ -492,7 +492,7 @@ static bool set_up_field_array(TABLE *table, DBUG_RETURN(result); } size_field_array= (num_fields+1)*sizeof(Field*); - field_array= (Field**)sql_calloc(size_field_array); + field_array= (Field**) thd->calloc(size_field_array); if (unlikely(!field_array)) { mem_alloc_error(size_field_array); @@ -617,7 +617,7 @@ static bool create_full_part_field_array(THD *thd, TABLE *table, num_part_fields++; } size_field_array= (num_part_fields+1)*sizeof(Field*); - field_array= (Field**)sql_calloc(size_field_array); + field_array= (Field**) thd->calloc(size_field_array); if (unlikely(!field_array)) { mem_alloc_error(size_field_array); @@ -804,7 +804,7 @@ static void clear_field_flag(TABLE *table) */ -static bool handle_list_of_fields(List_iterator<char> it, +static bool handle_list_of_fields(THD *thd, List_iterator<char> it, TABLE *table, partition_info *part_info, bool is_sub_part) @@ -865,7 +865,7 @@ static bool handle_list_of_fields(List_iterator<char> it, } } } - result= set_up_field_array(table, is_sub_part); + result= set_up_field_array(thd, table, is_sub_part); end: DBUG_RETURN(result); } @@ -1034,7 +1034,7 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, if ((!is_sub_part) && (error= check_signed_flag(part_info))) goto end; - result= set_up_field_array(table, is_sub_part); + result= set_up_field_array(thd, table, is_sub_part); end: end_lex_with_single_table(thd, table, old_lex); #if !defined(DBUG_OFF) @@ -1622,7 +1622,7 @@ bool fix_partition_func(THD *thd, TABLE *table, if (!is_create_table_ind || thd->lex->sql_command != SQLCOM_CREATE_TABLE) { - if (partition_default_handling(table, part_info, + if (partition_default_handling(thd, table, part_info, is_create_table_ind, table->s->normalized_path.str)) { @@ -1641,7 +1641,7 @@ bool fix_partition_func(THD *thd, TABLE *table, if (part_info->list_of_subpart_fields) { List_iterator<char> it(part_info->subpart_field_list); - if (unlikely(handle_list_of_fields(it, table, part_info, TRUE))) + if (unlikely(handle_list_of_fields(thd, it, table, part_info, TRUE))) goto end; } else @@ -1668,7 +1668,7 @@ bool fix_partition_func(THD *thd, TABLE *table, if (part_info->list_of_part_fields) { List_iterator<char> it(part_info->part_field_list); - if (unlikely(handle_list_of_fields(it, table, part_info, FALSE))) + if (unlikely(handle_list_of_fields(thd, it, table, part_info, FALSE))) goto end; } else @@ -1690,7 +1690,7 @@ bool fix_partition_func(THD *thd, TABLE *table, if (part_info->column_list) { List_iterator<char> it(part_info->part_field_list); - if (unlikely(handle_list_of_fields(it, table, part_info, FALSE))) + if (unlikely(handle_list_of_fields(thd, it, table, part_info, FALSE))) goto end; } else @@ -2468,7 +2468,7 @@ static int add_key_with_algorithm(File fptr, partition_info *part_info, common queries. */ -char *generate_partition_syntax(partition_info *part_info, +char *generate_partition_syntax(THD *thd, partition_info *part_info, uint *buf_length, bool use_sql_alloc, bool show_partition_options, @@ -2642,7 +2642,7 @@ char *generate_partition_syntax(partition_info *part_info, goto close_file; *buf_length= (uint)buffer_length; if (use_sql_alloc) - buf= (char*) sql_alloc(*buf_length+1); + buf= (char*) thd->alloc(*buf_length + 1); else buf= (char*) my_malloc(*buf_length+1, MYF(MY_WME)); if (!buf) @@ -4976,7 +4976,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, } alt_part_info->part_type= tab_part_info->part_type; alt_part_info->subpart_type= tab_part_info->subpart_type; - if (alt_part_info->set_up_defaults_for_partitioning(table->file, 0, + if (alt_part_info->set_up_defaults_for_partitioning(thd, table->file, 0, tab_part_info->num_parts)) { goto err; @@ -5395,7 +5395,8 @@ state of p1. DBUG_ASSERT(!alt_part_info->use_default_partitions); /* We specified partitions explicitly so don't use defaults anymore. */ tab_part_info->use_default_partitions= FALSE; - if (alt_part_info->set_up_defaults_for_partitioning(table->file, 0, 0)) + if (alt_part_info->set_up_defaults_for_partitioning(thd, table->file, 0, + 0)) { goto err; } diff --git a/sql/sql_partition.h b/sql/sql_partition.h index b560c53562d..dd352b60120 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -262,7 +262,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, Alter_table_ctx *alter_ctx, bool *partition_changed, bool *fast_alter_table); -char *generate_partition_syntax(partition_info *part_info, +char *generate_partition_syntax(THD *thd, partition_info *part_info, uint *buf_length, bool use_sql_alloc, bool show_partition_options, HA_CREATE_INFO *create_info, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 0158ab7d206..dbe19674cf2 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1796,7 +1796,8 @@ static void plugin_load(MEM_ROOT *tmp_root) goto end; } - if (init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE)) + if (init_read_record(&read_record_info, new_thd, table, NULL, NULL, 1, 0, + FALSE)) { sql_print_error("Could not initialize init_read_record; Plugins not " "loaded"); @@ -2152,7 +2153,8 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, */ unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = { MYSQL_AUDIT_GENERAL_CLASSMASK }; - mysql_audit_acquire_plugins(thd, event_class_mask); + if (mysql_audit_general_enabled()) + mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); error= plugin_add(thd->mem_root, name, &dl, REPORT_TO_USER); @@ -2282,7 +2284,8 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, */ unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE] = { MYSQL_AUDIT_GENERAL_CLASSMASK }; - mysql_audit_acquire_plugins(thd, event_class_mask); + if (mysql_audit_general_enabled()) + mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 0db1daa378e..8e5ab71288d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -102,6 +102,7 @@ When one supplies long data for a placeholder: #include "sql_acl.h" // *_ACL #include "sql_derived.h" // mysql_derived_prepare, // mysql_handle_derived +#include "sql_cte.h" #include "sql_cursor.h" #include "sql_show.h" #include "sql_repl.h" @@ -326,8 +327,14 @@ find_prepared_statement(THD *thd, ulong id) To strictly separate namespaces of SQL prepared statements and C API prepared statements find() will return 0 if there is a named prepared statement with such id. + + LAST_STMT_ID is special value which mean last prepared statement ID + (it was made for COM_MULTI to allow prepare and execute a statement + in the same command but usage is not limited by COM_MULTI only). */ - Statement *stmt= thd->stmt_map.find(id); + Statement *stmt= ((id == LAST_STMT_ID) ? + thd->last_stmt : + thd->stmt_map.find(id)); if (stmt == 0 || stmt->type() != Query_arena::PREPARED_STATEMENT) return NULL; @@ -721,54 +728,44 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, case MYSQL_TYPE_TINY: param->set_param_func= set_param_tiny; param->item_type= Item::INT_ITEM; - param->item_result_type= INT_RESULT; break; case MYSQL_TYPE_SHORT: param->set_param_func= set_param_short; param->item_type= Item::INT_ITEM; - param->item_result_type= INT_RESULT; break; case MYSQL_TYPE_LONG: param->set_param_func= set_param_int32; param->item_type= Item::INT_ITEM; - param->item_result_type= INT_RESULT; break; case MYSQL_TYPE_LONGLONG: param->set_param_func= set_param_int64; param->item_type= Item::INT_ITEM; - param->item_result_type= INT_RESULT; break; case MYSQL_TYPE_FLOAT: param->set_param_func= set_param_float; param->item_type= Item::REAL_ITEM; - param->item_result_type= REAL_RESULT; break; case MYSQL_TYPE_DOUBLE: param->set_param_func= set_param_double; param->item_type= Item::REAL_ITEM; - param->item_result_type= REAL_RESULT; break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: param->set_param_func= set_param_decimal; param->item_type= Item::DECIMAL_ITEM; - param->item_result_type= DECIMAL_RESULT; break; case MYSQL_TYPE_TIME: param->set_param_func= set_param_time; param->item_type= Item::STRING_ITEM; - param->item_result_type= STRING_RESULT; break; case MYSQL_TYPE_DATE: param->set_param_func= set_param_date; param->item_type= Item::STRING_ITEM; - param->item_result_type= STRING_RESULT; break; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: param->set_param_func= set_param_datetime; param->item_type= Item::STRING_ITEM; - param->item_result_type= STRING_RESULT; break; case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: @@ -781,7 +778,6 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, DBUG_ASSERT(thd->variables.character_set_client); param->value.cs_info.final_character_set_of_str_value= &my_charset_bin; param->item_type= Item::STRING_ITEM; - param->item_result_type= STRING_RESULT; break; default: /* @@ -811,10 +807,9 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, charset of connection, so we have to set it later. */ param->item_type= Item::STRING_ITEM; - param->item_result_type= STRING_RESULT; } } - param->param_type= (enum enum_field_types) param_type; + param->set_handler_by_field_type((enum enum_field_types) param_type); } #ifndef EMBEDDED_LIBRARY @@ -826,8 +821,8 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, */ inline bool is_param_long_data_type(Item_param *param) { - return ((param->param_type >= MYSQL_TYPE_TINY_BLOB) && - (param->param_type <= MYSQL_TYPE_STRING)); + return ((param->field_type() >= MYSQL_TYPE_TINY_BLOB) && + (param->field_type() <= MYSQL_TYPE_STRING)); } @@ -1216,7 +1211,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt, the parameter's members that might be needed further (e.g. value.cs_info.character_set_client is used in the query_val_str()). */ - setup_one_conversion_function(thd, param, param->param_type); + setup_one_conversion_function(thd, param, param->field_type()); if (param->set_from_user_var(thd, entry)) DBUG_RETURN(1); @@ -1512,6 +1507,8 @@ static int mysql_test_select(Prepared_statement *stmt, lex->select_lex.context.resolve_in_select_list= TRUE; ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; + if (check_dependencies_in_with_clauses(lex->with_clauses_list)) + goto error; if (tables) { if (check_table_access(thd, privilege, tables, FALSE, UINT_MAX, FALSE)) @@ -2585,7 +2582,10 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) { /* Statement map deletes statement on erase */ thd->stmt_map.erase(stmt); + thd->clear_last_stmt(); } + else + thd->set_last_stmt(stmt); thd->protocol= save_protocol; @@ -3171,6 +3171,9 @@ void mysqld_stmt_close(THD *thd, char *packet) stmt->deallocate(); general_log_print(thd, thd->get_command(), NullS); + if (thd->last_stmt == stmt) + thd->clear_last_stmt(); + DBUG_VOID_RETURN; } @@ -3433,7 +3436,8 @@ end: Prepared_statement::Prepared_statement(THD *thd_arg) :Statement(NULL, &main_mem_root, - STMT_INITIALIZED, ++thd_arg->statement_id_counter), + STMT_INITIALIZED, + ((++thd_arg->statement_id_counter) & STMT_ID_MASK)), thd(thd_arg), result(thd_arg), param_array(0), @@ -3909,8 +3913,9 @@ reexecute: switch (thd->wsrep_conflict_state) { case CERT_FAILURE: - WSREP_DEBUG("PS execute fail for CERT_FAILURE: thd: %ld err: %d", - thd->thread_id, thd->get_stmt_da()->sql_errno() ); + WSREP_DEBUG("PS execute fail for CERT_FAILURE: thd: %lld err: %d", + (longlong) thd->thread_id, + thd->get_stmt_da()->sql_errno() ); thd->wsrep_conflict_state = NO_CONFLICT; break; diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h index b468ac1bf9b..aec4ac40036 100644 --- a/sql/sql_prepare.h +++ b/sql/sql_prepare.h @@ -18,6 +18,10 @@ #include "sql_error.h" + +#define LAST_STMT_ID 0xFFFFFFFF +#define STMT_ID_MASK 0x7FFFFFFF + class THD; struct LEX; diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 4d62f72f571..cc56daacf3e 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -320,11 +320,11 @@ /* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */ #define UNDEF_POS (-1) +#endif /* !MYSQL_CLIENT */ + /* BINLOG_DUMP options */ #define BINLOG_DUMP_NON_BLOCK 1 -#endif /* !MYSQL_CLIENT */ - #define BINLOG_SEND_ANNOTATE_ROWS_EVENT 2 #ifndef MYSQL_CLIENT diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index 48f7987daf5..a169823e25e 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -124,7 +124,7 @@ int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table) NullS, NullS, field_info->field_name); if (field) { - field->set_name(field_info->old_name, + field->set_name(thd, field_info->old_name, (uint) strlen(field_info->old_name), system_charset_info); if (add_item_to_list(thd, field)) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 572d08399d5..c9e2b3a586d 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2181,9 +2181,7 @@ static int init_binlog_sender(binlog_send_info *info, linfo->pos= *pos; // note: publish that we use file, before we open it - mysql_mutex_lock(&LOCK_thread_count); thd->current_linfo= linfo; - mysql_mutex_unlock(&LOCK_thread_count); if (check_start_offset(info, linfo->log_file_name, *pos)) return 1; @@ -2922,9 +2920,7 @@ err: mysql_file_close(file, MYF(MY_WME)); } - mysql_mutex_lock(&LOCK_thread_count); - thd->current_linfo = 0; - mysql_mutex_unlock(&LOCK_thread_count); + thd->reset_current_linfo(); thd->variables.max_allowed_packet= old_max_allowed_packet; delete info->fdev; @@ -3379,10 +3375,8 @@ err: SYNOPSIS kill_zombie_dump_threads() slave_server_id the slave's server id - */ - void kill_zombie_dump_threads(uint32 slave_server_id) { mysql_mutex_lock(&LOCK_thread_count); @@ -3946,9 +3940,7 @@ bool mysql_show_binlog_events(THD* thd) goto err; } - mysql_mutex_lock(&LOCK_thread_count); - thd->current_linfo = &linfo; - mysql_mutex_unlock(&LOCK_thread_count); + thd->current_linfo= &linfo; if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0) goto err; @@ -4080,9 +4072,7 @@ err: else my_eof(thd); - mysql_mutex_lock(&LOCK_thread_count); - thd->current_linfo = 0; - mysql_mutex_unlock(&LOCK_thread_count); + thd->reset_current_linfo(); thd->variables.max_allowed_packet= old_max_allowed_packet; DBUG_RETURN(ret); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e83f63d1070..c1916aae58a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -53,6 +53,7 @@ #include "log_slow.h" #include "sql_derived.h" #include "sql_statistics.h" +#include "sql_cte.h" #include "debug_sync.h" // DEBUG_SYNC #include <m_ctype.h> @@ -115,12 +116,6 @@ static int join_tab_cmp(const void *dummy, const void* ptr1, const void* ptr2); static int join_tab_cmp_straight(const void *dummy, const void* ptr1, const void* ptr2); static int join_tab_cmp_embedded_first(const void *emb, const void* ptr1, const void *ptr2); C_MODE_END -/* - TODO: 'find_best' is here only temporarily until 'greedy_search' is - tested and approved. -*/ -static bool find_best(JOIN *join,table_map rest_tables,uint index, - double record_count,double read_time, uint use_cond_selectivity); static uint cache_record_length(JOIN *join,uint index); bool get_best_combination(JOIN *join); static store_key *get_store_key(THD *thd, @@ -834,6 +829,10 @@ JOIN::prepare(Item ***rref_pointer_array, DBUG_RETURN(-1); /* purecov: inspected */ thd->lex->allow_sum_func= save_allow_sum_func; } + + With_clause *with_clause=select_lex->get_with_clause(); + if (with_clause && with_clause->prepare_unreferenced_elements(thd)) + DBUG_RETURN(1); int res= check_and_do_in_subquery_rewrites(this); @@ -1436,7 +1435,7 @@ JOIN::optimize_inner() } select= make_select(*table, const_table_map, - const_table_map, conds, 1, &error); + const_table_map, conds, (SORT_INFO*) 0, 1, &error); if (error) { /* purecov: inspected */ error= -1; /* purecov: inspected */ @@ -2374,15 +2373,11 @@ JOIN::reinit() { exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE); exec_tmp_table1->file->ha_delete_all_rows(); - free_io_cache(exec_tmp_table1); - filesort_free_buffers(exec_tmp_table1,0); } if (exec_tmp_table2) { exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE); exec_tmp_table2->file->ha_delete_all_rows(); - free_io_cache(exec_tmp_table2); - filesort_free_buffers(exec_tmp_table2,0); } clear_sj_tmp_tables(this); if (items0) @@ -3199,12 +3194,12 @@ void JOIN::exec_inner() DBUG_VOID_RETURN; sortorder= curr_join->sortorder; if (curr_join->const_tables != curr_join->table_count && - !curr_join->join_tab[curr_join->const_tables].table->sort.io_cache) + !curr_join->join_tab[curr_join->const_tables].filesort) { /* - If no IO cache exists for the first table then we are using an - INDEX SCAN and no filesort. Thus we should not remove the sorted - attribute on the INDEX SCAN. + If no filesort for the first table then we are using an + INDEX SCAN. Thus we should not remove the sorted attribute + on the INDEX SCAN. */ skip_sort_order= 1; } @@ -4101,6 +4096,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, select= make_select(s->table, found_const_table_map, found_const_table_map, *s->on_expr_ref ? *s->on_expr_ref : join->conds, + (SORT_INFO*) 0, 1, &error); if (!select) goto error; @@ -6602,10 +6598,6 @@ static void choose_initial_table_order(JOIN *join) the query @param join_tables set of the tables in the query - @todo - 'MAX_TABLES+2' denotes the old implementation of find_best before - the greedy version. Will be removed when greedy_search is approved. - @retval FALSE ok @retval @@ -6668,27 +6660,13 @@ choose_plan(JOIN *join, table_map join_tables) } else { - if (search_depth == MAX_TABLES+2) - { /* - TODO: 'MAX_TABLES+2' denotes the old implementation of find_best before - the greedy version. Will be removed when greedy_search is approved. - */ - join->best_read= DBL_MAX; - if (find_best(join, join_tables, join->const_tables, 1.0, 0.0, - use_cond_selectivity)) - { - DBUG_RETURN(TRUE); - } - } - else - { - if (search_depth == 0) - /* Automatically determine a reasonable value for 'search_depth' */ - search_depth= determine_search_depth(join); - if (greedy_search(join, join_tables, search_depth, prune_level, - use_cond_selectivity)) - DBUG_RETURN(TRUE); - } + DBUG_ASSERT(search_depth <= MAX_TABLES + 1); + if (search_depth == 0) + /* Automatically determine a reasonable value for 'search_depth' */ + search_depth= determine_search_depth(join); + if (greedy_search(join, join_tables, search_depth, prune_level, + use_cond_selectivity)) + DBUG_RETURN(TRUE); } /* @@ -7990,105 +7968,6 @@ best_extension_by_limited_search(JOIN *join, /** - @todo - - TODO: this function is here only temporarily until 'greedy_search' is - tested and accepted. - - RETURN VALUES - FALSE ok - TRUE Fatal error -*/ -static bool -find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, - double read_time, uint use_cond_selectivity) -{ - DBUG_ENTER("find_best"); - THD *thd= join->thd; - if (thd->check_killed()) - DBUG_RETURN(TRUE); - if (!rest_tables) - { - DBUG_PRINT("best",("read_time: %g record_count: %g",read_time, - record_count)); - - read_time+=record_count/(double) TIME_FOR_COMPARE; - if (join->sort_by_table && - join->sort_by_table != - join->positions[join->const_tables].table->table) - read_time+=record_count; // We have to make a temp table - if (read_time < join->best_read) - { - memcpy((uchar*) join->best_positions,(uchar*) join->positions, - sizeof(POSITION)*idx); - join->best_read= read_time - 0.001; - } - DBUG_RETURN(FALSE); - } - if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read) - DBUG_RETURN(FALSE); /* Found better before */ - - JOIN_TAB *s; - double best_record_count=DBL_MAX,best_read_time=DBL_MAX; - bool disable_jbuf= join->thd->variables.join_cache_level == 0; - for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++) - { - table_map real_table_bit=s->table->map; - if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) && - (!idx|| !check_interleaving_with_nj(s))) - { - double records, best; - POSITION loose_scan_pos; - best_access_path(join, s, rest_tables, idx, disable_jbuf, record_count, - join->positions + idx, &loose_scan_pos); - records= join->positions[idx].records_read; - best= join->positions[idx].read_time; - /* - Go to the next level only if there hasn't been a better key on - this level! This will cut down the search for a lot simple cases! - */ - double current_record_count=record_count*records; - double current_read_time=read_time+best; - advance_sj_state(join, rest_tables, idx, ¤t_record_count, - ¤t_read_time, &loose_scan_pos); - - double pushdown_cond_selectivity= 1.0; - if (use_cond_selectivity > 1) - pushdown_cond_selectivity= table_cond_selectivity(join, idx, s, - rest_tables & - ~real_table_bit); - join->positions[idx].cond_selectivity= pushdown_cond_selectivity; - double partial_join_cardinality= current_record_count * - pushdown_cond_selectivity; - - if (best_record_count > partial_join_cardinality || - best_read_time > current_read_time || - (idx == join->const_tables && s->table == join->sort_by_table)) - { - if (best_record_count >= partial_join_cardinality && - best_read_time >= current_read_time && - (!(s->key_dependent & rest_tables) || records < 2.0)) - { - best_record_count= partial_join_cardinality; - best_read_time=current_read_time; - } - swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); - if (find_best(join,rest_tables & ~real_table_bit,idx+1, - partial_join_cardinality,current_read_time, - use_cond_selectivity)) - DBUG_RETURN(TRUE); - swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); - } - restore_prev_nj_state(s); - restore_prev_sj_state(rest_tables, s, idx); - if (join->select_options & SELECT_STRAIGHT_JOIN) - break; // Don't test all combinations - } - } - DBUG_RETURN(FALSE); -} - - -/** Find how much space the prevous read not const tables takes in cache. */ @@ -9166,13 +9045,21 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table) /* Reuse TABLE * and JOIN_TAB if already allocated by a previous call to this function through JOIN::exec (may happen for sub-queries). + + psergey-todo: here, save the pointer for original join_tabs. */ - if (!parent->join_tab_reexec && - !(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)))) - DBUG_RETURN(TRUE); /* purecov: inspected */ + if (!(join_tab= parent->join_tab_reexec)) + { + if (!(join_tab= parent->join_tab_reexec= + (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)))) + DBUG_RETURN(TRUE); /* purecov: inspected */ + } + else + { + /* Free memory used by previous allocations */ + delete join_tab->filesort; + } - // psergey-todo: here, save the pointer for original join_tabs. - join_tab= parent->join_tab_reexec; table= &parent->table_reexec[0]; parent->table_reexec[0]= temp_table; table_count= top_join_tab_count= 1; @@ -11535,13 +11422,16 @@ bool error_if_full_join(JOIN *join) void JOIN_TAB::cleanup() { DBUG_ENTER("JOIN_TAB::cleanup"); - DBUG_PRINT("enter", ("table %s.%s", + DBUG_PRINT("enter", ("tab: %p table %s.%s", + this, (table ? table->s->db.str : "?"), (table ? table->s->table_name.str : "?"))); delete select; select= 0; delete quick; quick= 0; + delete filesort; + filesort= 0; if (cache) { cache->free(); @@ -11940,8 +11830,8 @@ void JOIN::cleanup(bool full) JOIN_TAB *first_tab= first_top_level_tab(this, WITHOUT_CONST_TABLES); if (first_tab->table) { - free_io_cache(first_tab->table); - filesort_free_buffers(first_tab->table, full); + delete first_tab->filesort; + first_tab->filesort= 0; } } if (full) @@ -12490,9 +12380,9 @@ static void clear_tables(JOIN *join) class COND_CMP :public ilink { public: - static void *operator new(size_t size) + static void *operator new(size_t size, MEM_ROOT *mem_root) { - return (void*) sql_alloc((uint) size); + return alloc_root(mem_root, size); } static void operator delete(void *ptr __attribute__((unused)), size_t size __attribute__((unused))) @@ -14112,7 +14002,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list, { cond->marker=1; COND_CMP *tmp2; - if ((tmp2=new COND_CMP(and_father,func))) + if ((tmp2= new (thd->mem_root) COND_CMP(and_father, func))) save_list->push_back(tmp2); } /* @@ -14144,7 +14034,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list, thd->change_item_tree(args + 1, value); cond->marker=1; COND_CMP *tmp2; - if ((tmp2=new COND_CMP(and_father,func))) + if ((tmp2=new (thd->mem_root) COND_CMP(and_father, func))) save_list->push_back(tmp2); } if (functype != Item_func::LIKE_FUNC) @@ -15783,7 +15673,6 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field, else if (org_field->type() == FIELD_TYPE_DOUBLE) ((Field_double *) new_field)->not_fixed= TRUE; new_field->vcol_info= 0; - new_field->stored_in_db= TRUE; new_field->cond_selectivity= 1.0; new_field->next_equal_field= NULL; new_field->option_list= NULL; @@ -15792,76 +15681,49 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field, return new_field; } -/** - Create field for temporary table using type of given item. - - @param thd Thread handler - @param item Item to create a field for - @param table Temporary table - @param copy_func If set and item is a function, store copy of - item in this array - @param modify_item 1 if item->result_field should point to new - item. This is relevent for how fill_record() - is going to work: - If modify_item is 1 then fill_record() will - update the record in the original table. - If modify_item is 0 then fill_record() will - update the temporary table - - @retval - 0 on error - @retval - new_created field -*/ -static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, - Item ***copy_func, bool modify_item) +Field *Item::create_tmp_field(bool group, TABLE *table, uint convert_int_length) { - bool maybe_null= item->maybe_null; Field *UNINIT_VAR(new_field); - MEM_ROOT *mem_root= thd->mem_root; + MEM_ROOT *mem_root= table->in_use->mem_root; - switch (item->result_type()) { + switch (cmp_type()) { case REAL_RESULT: new_field= new (mem_root) - Field_double(item->max_length, maybe_null, - item->name, item->decimals, TRUE); + Field_double(max_length, maybe_null, name, decimals, TRUE); break; case INT_RESULT: /* Select an integer type with the minimal fit precision. - MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign. - Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into - Field_long : make them Field_longlong. + convert_int_length is sign inclusive, don't consider the sign. */ - if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1)) - new_field=new (mem_root) - Field_longlong(item->max_length, maybe_null, - item->name, item->unsigned_flag); + if (max_char_length() > convert_int_length) + new_field= new (mem_root) + Field_longlong(max_char_length(), maybe_null, name, unsigned_flag); else - new_field=new (mem_root) - Field_long(item->max_length, maybe_null, item->name, - item->unsigned_flag); + new_field= new (mem_root) + Field_long(max_char_length(), maybe_null, name, unsigned_flag); + break; + case TIME_RESULT: + new_field= tmp_table_field_from_field_type(table, true, false); break; case STRING_RESULT: - DBUG_ASSERT(item->collation.collation); + DBUG_ASSERT(collation.collation); /* - DATE/TIME and GEOMETRY fields have STRING_RESULT result type. + GEOMETRY fields have STRING_RESULT result type. To preserve type they needed to be handled separately. */ - if (item->cmp_type() == TIME_RESULT || - item->field_type() == MYSQL_TYPE_GEOMETRY) - new_field= item->tmp_table_field_from_field_type(table, true, false); + if (field_type() == MYSQL_TYPE_GEOMETRY) + new_field= tmp_table_field_from_field_type(table, true, false); else - new_field= item->make_string_field(table); - new_field->set_derivation(item->collation.derivation); + new_field= make_string_field(table); + new_field->set_derivation(collation.derivation); break; case DECIMAL_RESULT: - new_field= Field_new_decimal::create_from_item(mem_root, item); + new_field= Field_new_decimal::create_from_item(mem_root, this); break; case ROW_RESULT: - default: // This case should never be choosen DBUG_ASSERT(0); new_field= 0; @@ -15869,6 +15731,41 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, } if (new_field) new_field->init(table); + return new_field; +} + + + +/** + Create field for temporary table using type of given item. + + @param thd Thread handler + @param item Item to create a field for + @param table Temporary table + @param copy_func If set and item is a function, store copy of + item in this array + @param modify_item 1 if item->result_field should point to new + item. This is relevent for how fill_record() + is going to work: + If modify_item is 1 then fill_record() will + update the record in the original table. + If modify_item is 0 then fill_record() will + update the temporary table + @param convert_blob_length If >0 create a varstring(convert_blob_length) + field instead of blob. + + @retval + 0 on error + @retval + new_created field +*/ + +static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, + Item ***copy_func, bool modify_item) +{ + Field *UNINIT_VAR(new_field); + DBUG_ASSERT(thd == table->in_use); + new_field= item->Item::create_tmp_field(false, table); if (copy_func && item->real_item()->is_result_field()) *((*copy_func)++) = item; // Save for copy_funcs @@ -15960,8 +15857,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, switch (type) { case Item::SUM_FUNC_ITEM: { - Item_sum *item_sum=(Item_sum*) item; - result= item_sum->create_tmp_field(group, table); + result= item->create_tmp_field(group, table); if (!result) my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); return result; @@ -16103,9 +15999,9 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, a tmp_set bitmap to be used by things like filesort. */ -void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) +void +setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps, uint field_count) { - uint field_count= table->s->fields; uint bitmap_size= bitmap_buffer_size(field_count); DBUG_ASSERT(table->s->vfields == 0 && table->def_vcol_set == 0); @@ -16129,6 +16025,13 @@ void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) } +void +setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) +{ + setup_tmp_table_column_bitmaps(table, bitmaps, table->s->fields); +} + + /** Create a temp table according to a field list. @@ -16216,7 +16119,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, { /* if we run out of slots or we are not using tempool */ sprintf(path, "%s%lx_%lx_%x", tmp_file_prefix,current_pid, - thd->thread_id, thd->tmp_table++); + (ulong) thd->thread_id, thd->tmp_table++); } /* @@ -17013,141 +16916,108 @@ err: /****************************************************************************/ -/** - Create a reduced TABLE object with properly set up Field list from a - list of field definitions. - - The created table doesn't have a table handler associated with - it, has no keys, no group/distinct, no copy_funcs array. - The sole purpose of this TABLE object is to use the power of Field - class to read/write data to/from table->record[0]. Then one can store - the record in any container (RB tree, hash, etc). - The table is created in THD mem_root, so are the table's fields. - Consequently, if you don't BLOB fields, you don't need to free it. - - @param thd connection handle - @param field_list list of column definitions +void *Virtual_tmp_table::operator new(size_t size, THD *thd) throw() +{ + return (Virtual_tmp_table *) alloc_root(thd->mem_root, size); +} - @return - 0 if out of memory, TABLE object in case of success -*/ -TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list) +bool Virtual_tmp_table::init(uint field_count) { - uint field_count= field_list.elements; - uint blob_count= 0; - Field **field; - Create_field *cdef; /* column definition */ - uint record_length= 0; - uint null_count= 0; /* number of columns which may be null */ - uint null_pack_length; /* NULL representation array length */ uint *blob_field; uchar *bitmaps; - TABLE *table; - TABLE_SHARE *share; - - if (!multi_alloc_root(thd->mem_root, - &table, sizeof(*table), - &share, sizeof(*share), + if (!multi_alloc_root(in_use->mem_root, + &s, sizeof(*s), &field, (field_count + 1) * sizeof(Field*), - &blob_field, (field_count+1) *sizeof(uint), - &bitmaps, bitmap_buffer_size(field_count)*5, + &blob_field, (field_count + 1) * sizeof(uint), + &bitmaps, bitmap_buffer_size(field_count) * 5, NullS)) - return 0; + return true; + bzero(s, sizeof(*s)); + s->blob_field= blob_field; + setup_tmp_table_column_bitmaps(this, bitmaps, field_count); + m_alloced_field_count= field_count; + return false; +}; - bzero(table, sizeof(*table)); - bzero(share, sizeof(*share)); - table->field= field; - table->s= share; - table->temp_pool_slot= MY_BIT_NONE; - share->blob_field= blob_field; - share->fields= field_count; - setup_tmp_table_column_bitmaps(table, bitmaps); +bool Virtual_tmp_table::add(List<Column_definition> &field_list) +{ /* Create all fields and calculate the total length of record */ - List_iterator_fast<Create_field> it(field_list); - while ((cdef= it++)) - { - *field= make_field(share, thd->mem_root, 0, cdef->length, - (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0), - f_maybe_null(cdef->pack_flag) ? 1 : 0, - cdef->pack_flag, cdef->sql_type, cdef->charset, - cdef->geom_type, cdef->srid, cdef->unireg_check, - cdef->interval, cdef->field_name); - if (!*field) - goto error; - (*field)->init(table); - record_length+= (*field)->pack_length(); - if (! ((*field)->flags & NOT_NULL_FLAG)) - null_count++; - - if ((*field)->flags & BLOB_FLAG) - share->blob_field[blob_count++]= (uint) (field - table->field); - - field++; + Column_definition *cdef; /* column definition */ + List_iterator_fast<Column_definition> it(field_list); + for ( ; (cdef= it++); ) + { + Field *tmp; + if (!(tmp= cdef->make_field(s, in_use->mem_root, 0, + (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0), + f_maybe_null(cdef->pack_flag) ? 1 : 0, + cdef->field_name))) + return true; + add(tmp); } - *field= NULL; /* mark the end of the list */ - share->blob_field[blob_count]= 0; /* mark the end of the list */ - share->blob_fields= blob_count; + return false; +} - null_pack_length= (null_count + 7)/8; - share->reclength= record_length + null_pack_length; - share->rec_buff_length= ALIGN_SIZE(share->reclength + 1); - table->record[0]= (uchar*) thd->alloc(share->rec_buff_length); - if (!table->record[0]) - goto error; - if (null_pack_length) - { - table->null_flags= (uchar*) table->record[0]; - share->null_fields= null_count; - share->null_bytes= share->null_bytes_for_compare= null_pack_length; - } +void Virtual_tmp_table::setup_field_pointers() +{ + uchar *null_pos= record[0]; + uchar *field_pos= null_pos + s->null_bytes; + uint null_bit= 1; - table->in_use= thd; /* field->reset() may access table->in_use */ + for (Field **cur_ptr= field; *cur_ptr; ++cur_ptr) { - /* Set up field pointers */ - uchar *null_pos= table->record[0]; - uchar *field_pos= null_pos + share->null_bytes; - uint null_bit= 1; - - for (field= table->field; *field; ++field) + Field *cur_field= *cur_ptr; + if ((cur_field->flags & NOT_NULL_FLAG)) + cur_field->move_field(field_pos); + else { - Field *cur_field= *field; - if ((cur_field->flags & NOT_NULL_FLAG)) - cur_field->move_field(field_pos); - else + cur_field->move_field(field_pos, (uchar*) null_pos, null_bit); + null_bit<<= 1; + if (null_bit == (uint)1 << 8) { - cur_field->move_field(field_pos, (uchar*) null_pos, null_bit); - null_bit<<= 1; - if (null_bit == (uint)1 << 8) - { - ++null_pos; - null_bit= 1; - } + ++null_pos; + null_bit= 1; } - if (cur_field->type() == MYSQL_TYPE_BIT && - cur_field->key_type() == HA_KEYTYPE_BIT) + } + if (cur_field->type() == MYSQL_TYPE_BIT && + cur_field->key_type() == HA_KEYTYPE_BIT) + { + /* This is a Field_bit since key_type is HA_KEYTYPE_BIT */ + static_cast<Field_bit*>(cur_field)->set_bit_ptr(null_pos, null_bit); + null_bit+= cur_field->field_length & 7; + if (null_bit > 7) { - /* This is a Field_bit since key_type is HA_KEYTYPE_BIT */ - static_cast<Field_bit*>(cur_field)->set_bit_ptr(null_pos, null_bit); - null_bit+= cur_field->field_length & 7; - if (null_bit > 7) - { - null_pos++; - null_bit-= 8; - } + null_pos++; + null_bit-= 8; } - cur_field->reset(); - - field_pos+= cur_field->pack_length(); } + cur_field->reset(); + field_pos+= cur_field->pack_length(); } - return table; -error: - for (field= table->field; *field; ++field) - delete *field; /* just invokes field destructor */ - return 0; +} + + +bool Virtual_tmp_table::open() +{ + // Make sure that we added all the fields we planned to: + DBUG_ASSERT(s->fields == m_alloced_field_count); + field[s->fields]= NULL; // mark the end of the list + s->blob_field[s->blob_fields]= 0; // mark the end of the list + + uint null_pack_length= (s->null_fields + 7) / 8; // NULL-bit array length + s->reclength+= null_pack_length; + s->rec_buff_length= ALIGN_SIZE(s->reclength + 1); + if (!(record[0]= (uchar*) in_use->alloc(s->rec_buff_length))) + return true; + if (null_pack_length) + { + null_flags= (uchar*) record[0]; + s->null_bytes= s->null_bytes_for_compare= null_pack_length; + } + setup_field_pointers(); + return false; } @@ -17703,7 +17573,6 @@ free_tmp_table(THD *thd, TABLE *entry) /* free blobs */ for (Field **ptr=entry->field ; *ptr ; ptr++) (*ptr)->free(); - free_io_cache(entry); if (entry->temp_pool_slot != MY_BIT_NONE) bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot); @@ -19166,7 +19035,7 @@ int join_init_read_record(JOIN_TAB *tab) if (!tab->preread_init_done && tab->preread_init()) return 1; if (init_read_record(&tab->read_record, tab->join->thd, tab->table, - tab->select,1,1, FALSE)) + tab->select, tab->filesort, 1,1, FALSE)) return 1; return (*tab->read_record.read_record)(&tab->read_record); } @@ -19184,7 +19053,7 @@ join_read_record_no_init(JOIN_TAB *tab) save_copy_end= tab->read_record.copy_field_end; init_read_record(&tab->read_record, tab->join->thd, tab->table, - tab->select,1,1, FALSE); + tab->select, tab->filesort, 1, 1, FALSE); tab->read_record.copy_field= save_copy; tab->read_record.copy_field_end= save_copy_end; @@ -19429,11 +19298,9 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), TABLE *table=jt->table; join->select_options ^= OPTION_FOUND_ROWS; - if (table->sort.record_pointers || - (table->sort.io_cache && my_b_inited(table->sort.io_cache))) + if (jt->filesort) // If filesort was used { - /* Using filesort */ - join->send_records= table->sort.found_records; + join->send_records= jt->filesort->found_rows; } else { @@ -21163,8 +21030,7 @@ use_filesort: 'join' is modified to use this index. - If no index, create with filesort() an index file that can be used to retrieve rows in order (should be done with 'read_record'). - The sorted data is stored in tab->table and will be freed when calling - free_io_cache(tab->table). + The sorted data is stored in tab->filesort RETURN VALUES 0 ok @@ -21177,15 +21043,12 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by) { - uint length= 0; - ha_rows examined_rows; - ha_rows found_rows; - ha_rows filesort_retval= HA_POS_ERROR; + uint length; TABLE *table; SQL_SELECT *select; JOIN_TAB *tab; - int err= 0; bool quick_created= FALSE; + SORT_INFO *file_sort= 0; DBUG_ENTER("create_sort_index"); if (join->table_count == join->const_tables) @@ -21270,15 +21133,19 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, } tab->update_explain_data(join->const_tables); + /* + Calculate length of join->order as this may be longer than 'order', + which may come from 'group by'. This is needed as join->sortorder is + used both for grouping and ordering. + */ + length= 0; for (ORDER *ord= join->order; ord; ord= ord->next) length++; - if (!(join->sortorder= + + if (!(join->sortorder= make_unireg_sortorder(thd, order, &length, join->sortorder))) goto err; /* purecov: inspected */ - table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), - MYF(MY_WME | MY_ZEROFILL| - MY_THREAD_SPECIFIC)); table->status=0; // May be wrong if quick_select if (!tab->preread_init_done && tab->preread_init()) @@ -21322,12 +21189,18 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, if (table->s->tmp_table) table->file->info(HA_STATUS_VARIABLE); // Get record count - filesort_retval= filesort(thd, table, join->sortorder, length, - select, filesort_limit, 0, - &examined_rows, &found_rows, - join->explain->ops_tracker.report_sorting(thd)); - table->sort.found_records= filesort_retval; - tab->records= join->select_options & OPTION_FOUND_ROWS ? found_rows : filesort_retval; + file_sort= filesort(thd, table, join->sortorder, length, + select, filesort_limit, 0, + join->explain->ops_tracker.report_sorting(thd)); + DBUG_ASSERT(tab->filesort == 0); + tab->filesort= file_sort; + tab->records= 0; + if (file_sort) + { + tab->records= join->select_options & OPTION_FOUND_ROWS ? + file_sort->found_rows : file_sort->return_rows; + tab->join->join_examined_rows+= file_sort->examined_rows; + } if (quick_created) { @@ -21350,12 +21223,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, tab->type=JT_ALL; // Read with normal read_record tab->read_first_record= join_init_read_record; tab->table->file->ha_index_or_rnd_end(); - - if (err) - goto err; - tab->join->join_examined_rows+= examined_rows; - DBUG_RETURN(filesort_retval == HA_POS_ERROR); + DBUG_RETURN(file_sort == 0); err: DBUG_RETURN(-1); } @@ -21478,7 +21347,6 @@ remove_duplicates(JOIN *join, TABLE *table, List<Item> &fields, Item *having) if (thd->killed == ABORT_QUERY) thd->reset_killed(); - free_io_cache(table); // Safety table->file->info(HA_STATUS_VARIABLE); if (table->s->db_type() == heap_hton || (!table->s->blob_fields && @@ -22983,7 +22851,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, str.length(0); str.extra_allocation(1024); item->print(&str, QT_ORDINARY); - item_field->name= sql_strmake(str.ptr(),str.length()); + item_field->name= thd->strmake(str.ptr(),str.length()); } #endif } @@ -23245,8 +23113,8 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) } join_tab->set_select_cond(cond, __LINE__); } - else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0, - &error))) + else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, + (SORT_INFO*) 0, 0, &error))) join_tab->set_select_cond(cond, __LINE__); DBUG_RETURN(error ? TRUE : FALSE); @@ -24306,9 +24174,8 @@ int JOIN::save_explain_data_intern(Explain_query *output, bool need_tmp_table, /* There should be no attempts to save query plans for merged selects */ DBUG_ASSERT(!join->select_lex->master_unit()->derived || - join->select_lex->master_unit()->derived->is_materialized_derived()); - - explain= NULL; + join->select_lex->master_unit()->derived->is_materialized_derived() || + join->select_lex->master_unit()->derived->is_with_table()); /* Don't log this into the slow query log */ @@ -24366,6 +24233,7 @@ int JOIN::save_explain_data_intern(Explain_query *output, bool need_tmp_table, xpl_sel->using_filesort= true; xpl_sel->exec_const_cond= exec_const_cond; + xpl_sel->outer_ref_cond= outer_ref_cond; if (tmp_having) xpl_sel->having= tmp_having; else @@ -24817,11 +24685,19 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str, } else if (derived) { - // A derived table - str->append('('); - derived->print(str, query_type); - str->append(')'); - cmp_name= ""; // Force printing of alias + if (!derived->derived->is_with_table()) + { + // A derived table + str->append('('); + derived->print(str, query_type); + str->append(')'); + cmp_name= ""; // Force printing of alias + } + else + { + append_identifier(thd, str, table_name, table_name_length); + cmp_name= table_name; + } } else { diff --git a/sql/sql_select.h b/sql/sql_select.h index 3a0baf03c26..87de9316c3a 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -32,6 +32,7 @@ #include "sql_array.h" /* Array */ #include "records.h" /* READ_RECORD */ #include "opt_range.h" /* SQL_SELECT, QUICK_SELECT_I */ +#include "filesort.h" /* Values in optimize */ #define KEY_OPTIMIZE_EXISTS 1 @@ -236,6 +237,7 @@ typedef struct st_join_table { For join tabs that are inside an SJM bush: root of the bush */ st_join_table *bush_root_tab; + SORT_INFO *filesort; /* TRUE <=> This join_tab is inside an SJM bush and is the last leaf tab here */ bool last_leaf_in_bush; @@ -1859,7 +1861,180 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, All methods presume that there is at least one field to change. */ -TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list); + +class Virtual_tmp_table: public TABLE +{ + /** + Destruct collected fields. This method is called on errors only, + when we could not make the virtual temporary table completely, + e.g. when some of the fields could not be created or added. + + This is needed to avoid memory leaks, as some fields can be BLOB + variants and thus can have String onboard. Strings must be destructed + as they store data not the heap (not on MEM_ROOT). + */ + void destruct_fields() + { + for (uint i= 0; i < s->fields; i++) + delete field[i]; // to invoke the field destructor + s->fields= 0; // safety + } + +protected: + /** + The number of the fields that are going to be in the table. + We remember the number of the fields at init() time, and + at open() we check that all of the fields were really added. + */ + uint m_alloced_field_count; + + /** + Setup field pointers and null-bit pointers. + */ + void setup_field_pointers(); + +public: + /** + Create a new empty virtual temporary table on the thread mem_root. + After creation, the caller must: + - call init() + - populate the table with new fields using add(). + - call open(). + @param thd - Current thread. + */ + static void *operator new(size_t size, THD *thd) throw(); + + Virtual_tmp_table(THD *thd) + { + bzero(this, sizeof(*this)); + temp_pool_slot= MY_BIT_NONE; + in_use= thd; + } + + ~Virtual_tmp_table() + { + destruct_fields(); + } + + /** + Allocate components for the given number of fields. + - fields[] + - s->blob_fields[], + - bitmaps: def_read_set, def_write_set, tmp_set, eq_join_set, cond_set. + @param field_count - The number of fields we plan to add to the table. + @returns false - on success. + @returns true - on error. + */ + bool init(uint field_count); + + /** + Add one Field to the end of the field array, update members: + s->reclength, s->fields, s->blob_fields, s->null_fuelds. + */ + bool add(Field *new_field) + { + DBUG_ASSERT(s->fields < m_alloced_field_count); + new_field->init(this); + field[s->fields]= new_field; + s->reclength+= new_field->pack_length(); + if (!(new_field->flags & NOT_NULL_FLAG)) + s->null_fields++; + if (new_field->flags & BLOB_FLAG) + { + // Note, s->blob_fields was incremented in Field_blob::Field_blob + DBUG_ASSERT(s->blob_fields); + DBUG_ASSERT(s->blob_fields <= m_alloced_field_count); + s->blob_field[s->blob_fields - 1]= s->fields; + } + s->fields++; + return false; + } + + /** + Add fields from a Column_definition list + @returns false - on success. + @returns true - on error. + */ + bool add(List<Column_definition> &field_list); + + /** + Open a virtual table for read/write: + - Setup end markers in TABLE::field and TABLE_SHARE::blob_fields, + - Allocate a buffer in TABLE::record[0]. + - Set field pointers (Field::ptr, Field::null_pos, Field::null_bit) to + the allocated record. + This method is called when all of the fields have been added to the table. + After calling this method the table is ready for read and write operations. + @return false - on success + @return true - on error (e.g. could not allocate the record buffer). + */ + bool open(); +}; + + +/** + Create a reduced TABLE object with properly set up Field list from a + list of field definitions. + + The created table doesn't have a table handler associated with + it, has no keys, no group/distinct, no copy_funcs array. + The sole purpose of this TABLE object is to use the power of Field + class to read/write data to/from table->record[0]. Then one can store + the record in any container (RB tree, hash, etc). + The table is created in THD mem_root, so are the table's fields. + Consequently, if you don't BLOB fields, you don't need to free it. + + @param thd connection handle + @param field_list list of column definitions + + @return + 0 if out of memory, or a + TABLE object ready for read and write in case of success +*/ + +inline TABLE * +create_virtual_tmp_table(THD *thd, List<Column_definition> &field_list) +{ + Virtual_tmp_table *table; + if (!(table= new(thd) Virtual_tmp_table(thd))) + return NULL; + if (table->init(field_list.elements) || + table->add(field_list) || + table->open()) + { + delete table; + return NULL; + } + return table; +} + + +/** + Create a new virtual temporary table consisting of a single field. + SUM(DISTINCT expr) and similar numeric aggregate functions use this. + @param thd - Current thread + @param field - The field that will be added into the table. + @return NULL - On error. + @return !NULL - A pointer to the created table that is ready + for read and write. +*/ +inline TABLE * +create_virtual_tmp_table(THD *thd, Field *field) +{ + Virtual_tmp_table *table; + DBUG_ASSERT(field); + if (!(table= new(thd) Virtual_tmp_table(thd))) + return NULL; + if (table->init(1) || + table->add(field) || + table->open()) + { + delete table; + return NULL; + } + return table; +} + int test_if_item_cache_changed(List<Cached_item> &list); int join_init_read_record(JOIN_TAB *tab); diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 0138c3e5a3b..196c138c04d 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -205,8 +205,8 @@ static bool servers_load(THD *thd, TABLE_LIST *tables) free_root(&mem, MYF(0)); init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); - if (init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, - FALSE)) + if (init_read_record(&read_record_info,thd,table=tables[0].table, NULL, NULL, + 1,0, FALSE)) DBUG_RETURN(1); while (!(read_record_info.read_record(&read_record_info))) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4a30b68bbc0..00881adff1d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -39,7 +39,6 @@ #include "tztime.h" // struct Time_zone #include "sql_acl.h" // TABLE_ACLS, check_grant, DB_ACLS, acl_get, // check_grant_db -#include "filesort.h" // filesort_free_buffers #include "sp.h" #include "sp_head.h" #include "sp_pcontext.h" @@ -1431,14 +1430,13 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) static const char *require_quotes(const char *name, uint name_length) { - uint length; bool pure_digit= TRUE; const char *end= name + name_length; for (; name < end ; name++) { uchar chr= (uchar) *name; - length= my_mbcharlen(system_charset_info, chr); + int length= my_charlen(system_charset_info, name, end); if (length == 1 && !system_charset_info->ident_map[chr]) return name; if (length == 1 && (chr < '0' || chr > '9')) @@ -1496,24 +1494,25 @@ append_identifier(THD *thd, String *packet, const char *name, uint length) if (packet->append("e_char, 1, quote_charset)) return true; - for (name_end= name+length ; name < name_end ; name+= length) + for (name_end= name+length ; name < name_end ; ) { uchar chr= (uchar) *name; - length= my_mbcharlen(system_charset_info, chr); + int char_length= my_charlen(system_charset_info, name, name_end); /* - my_mbcharlen can return 0 on a wrong multibyte + charlen can return 0 and negative numbers on a wrong multibyte sequence. It is possible when upgrading from 4.0, and identifier contains some accented characters. The manual says it does not work. So we'll just - change length to 1 not to hang in the endless loop. + change char_length to 1 not to hang in the endless loop. */ - if (!length) - length= 1; - if (length == 1 && chr == (uchar) quote_char && + if (char_length <= 0) + char_length= 1; + if (char_length == 1 && chr == (uchar) quote_char && packet->append("e_char, 1, quote_charset)) return true; - if (packet->append(name, length, system_charset_info)) + if (packet->append(name, char_length, system_charset_info)) return true; + name+= char_length; } return packet->append("e_char, 1, quote_charset); } @@ -1889,7 +1888,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, field->vcol_info->expr_str.length, system_charset_info); packet->append(STRING_WITH_LEN(")")); - if (field->stored_in_db) + if (field->vcol_info->stored_in_db) packet->append(STRING_WITH_LEN(" PERSISTENT")); else packet->append(STRING_WITH_LEN(" VIRTUAL")); @@ -2168,7 +2167,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, char *part_syntax; String comment_start; table->part_info->set_show_version_string(&comment_start); - if ((part_syntax= generate_partition_syntax(table->part_info, + if ((part_syntax= generate_partition_syntax(thd, table->part_info, &part_syntax_len, FALSE, show_table_options, @@ -4490,7 +4489,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, goto end; } - share= tdc_acquire_share_shortlived(thd, &table_list, GTS_TABLE | GTS_VIEW); + share= tdc_acquire_share(thd, &table_list, GTS_TABLE | GTS_VIEW); if (!share) { res= 0; @@ -5402,7 +5401,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, table->field[17]->store(type.ptr(), type.length(), cs); if (field->vcol_info) { - if (field->stored_in_db) + if (field->vcol_info->stored_in_db) table->field[17]->store(STRING_WITH_LEN("PERSISTENT"), cs); else table->field[17]->store(STRING_WITH_LEN("VIRTUAL"), cs); @@ -5685,7 +5684,6 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, if (sp) { Field *field; - Create_field *field_def; String tmp_string; if (routine_type == TYPE_ENUM_FUNCTION) { @@ -5697,14 +5695,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, get_field(thd->mem_root, proc_table->field[MYSQL_PROC_MYSQL_TYPE], &tmp_string); table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs); - field_def= &sp->m_return_field_def; - field= make_field(&share, thd->mem_root, - (uchar*) 0, field_def->length, - (uchar*) "", 0, field_def->pack_flag, - field_def->sql_type, field_def->charset, - field_def->geom_type, field_def->srid, Field::NONE, - field_def->interval, ""); - + field= sp->m_return_field_def.make_field(&share, thd->mem_root, ""); field->table= &tbl; tbl.in_use= thd; store_column_type(table, field, cs, 6); @@ -5723,7 +5714,6 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, { const char *tmp_buff; sp_variable *spvar= spcont->find_variable(i); - field_def= &spvar->field_def; switch (spvar->mode) { case sp_variable::MODE_IN: tmp_buff= "IN"; @@ -5752,12 +5742,8 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, &tmp_string); table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs); - field= make_field(&share, thd->mem_root, (uchar*) 0, field_def->length, - (uchar*) "", 0, field_def->pack_flag, - field_def->sql_type, field_def->charset, - field_def->geom_type, field_def->srid, Field::NONE, - field_def->interval, spvar->name.str); - + field= spvar->field_def.make_field(&share, thd->mem_root, + spvar->name.str); field->table= &tbl; tbl.in_use= thd; store_column_type(table, field, cs, 6); @@ -5844,18 +5830,11 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, TABLE_SHARE share; TABLE tbl; Field *field; - Create_field *field_def= &sp->m_return_field_def; bzero((char*) &tbl, sizeof(TABLE)); (void) build_table_filename(path, sizeof(path), "", "", "", 0); init_tmp_table_share(thd, &share, "", 0, "", path); - field= make_field(&share, thd->mem_root, (uchar*) 0, - field_def->length, - (uchar*) "", 0, field_def->pack_flag, - field_def->sql_type, field_def->charset, - field_def->geom_type, field_def->srid, Field::NONE, - field_def->interval, ""); - + field= sp->m_return_field_def.make_field(&share, thd->mem_root, ""); field->table= &tbl; tbl.in_use= thd; store_column_type(table, field, cs, 5); @@ -7508,7 +7487,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) item->max_length+= 1; if (item->decimals > 0) item->max_length+= 1; - item->set_name(fields_info->field_name, + item->set_name(thd, fields_info->field_name, strlen(fields_info->field_name), cs); break; case MYSQL_TYPE_TINY_BLOB: @@ -7531,7 +7510,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) { DBUG_RETURN(0); } - item->set_name(fields_info->field_name, + item->set_name(thd, fields_info->field_name, strlen(fields_info->field_name), cs); break; } @@ -7591,7 +7570,7 @@ static int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) Item_field(thd, context, NullS, NullS, field_info->field_name); if (field) { - field->set_name(field_info->old_name, + field->set_name(thd, field_info->old_name, strlen(field_info->old_name), system_charset_info); if (add_item_to_list(thd, field)) @@ -7626,7 +7605,7 @@ int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) buffer.append(lex->wild->ptr()); buffer.append(')'); } - field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + field->set_name(thd, buffer.ptr(), buffer.length(), system_charset_info); } return 0; } @@ -7653,15 +7632,15 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) NullS, NullS, field_info->field_name); if (add_item_to_list(thd, field)) return 1; - field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + field->set_name(thd, buffer.ptr(), buffer.length(), system_charset_info); if (thd->lex->verbose) { - field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + field->set_name(thd, buffer.ptr(), buffer.length(), system_charset_info); field_info= &schema_table->fields_info[3]; field= new (thd->mem_root) Item_field(thd, context, NullS, NullS, field_info->field_name); if (add_item_to_list(thd, field)) return 1; - field->set_name(field_info->old_name, strlen(field_info->old_name), + field->set_name(thd, field_info->old_name, strlen(field_info->old_name), system_charset_info); } return 0; @@ -7686,7 +7665,7 @@ int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) NullS, NullS, field_info->field_name); if (field) { - field->set_name(field_info->old_name, + field->set_name(thd, field_info->old_name, strlen(field_info->old_name), system_charset_info); if (add_item_to_list(thd, field)) @@ -7711,7 +7690,7 @@ int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) NullS, NullS, field_info->field_name); if (field) { - field->set_name(field_info->old_name, + field->set_name(thd, field_info->old_name, strlen(field_info->old_name), system_charset_info); if (add_item_to_list(thd, field)) @@ -7736,7 +7715,7 @@ int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) NullS, NullS, field_info->field_name); if (field) { - field->set_name(field_info->old_name, + field->set_name(thd, field_info->old_name, strlen(field_info->old_name), system_charset_info); if (add_item_to_list(thd, field)) @@ -8090,8 +8069,6 @@ bool get_schema_tables_result(JOIN *join, table_list->table->file->extra(HA_EXTRA_NO_CACHE); table_list->table->file->extra(HA_EXTRA_RESET_STATE); table_list->table->file->ha_delete_all_rows(); - free_io_cache(table_list->table); - filesort_free_buffers(table_list->table,1); table_list->table->null_row= 0; } else diff --git a/sql/sql_sort.h b/sql/sql_sort.h index d30ddfb6eec..6c97ad7e9ab 100644 --- a/sql/sql_sort.h +++ b/sql/sql_sort.h @@ -16,15 +16,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "m_string.h" /* memset */ -#include "my_global.h" /* uchar */ #include "my_base.h" /* ha_rows */ #include "my_sys.h" /* qsort2_cmp */ #include "queues.h" typedef struct st_buffpek BUFFPEK; -typedef struct st_sort_field SORT_FIELD; +struct SORT_FIELD; class Field; struct TABLE; @@ -71,7 +69,6 @@ public: uint rec_length; // Length of sorted records. uint sort_length; // Length of sorted columns. uint ref_length; // Length of record ref. - uint addon_length; // Length of added packed fields. uint res_length; // Length of records in final sorted file/buffer. uint max_keys_per_buffer; // Max keys / buffer. uint min_dupl_count; @@ -81,6 +78,8 @@ public: SORT_FIELD *local_sortorder; SORT_FIELD *end; SORT_ADDON_FIELD *addon_field; // Descriptors for companion fields. + LEX_STRING addon_buf; // Buffer & length of added packed fields. + uchar *unique_buff; bool not_killable; char* tmp_buffer; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 28e76ae43f1..f6811b020eb 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -28,6 +28,7 @@ #include "key.h" #include "sql_statistics.h" #include "opt_range.h" +#include "uniques.h" #include "my_atomic.h" /* @@ -1656,7 +1657,7 @@ public: bool is_single_comp_pk; - Index_prefix_calc(TABLE *table, KEY *key_info) + Index_prefix_calc(THD *thd, TABLE *table, KEY *key_info) : index_table(table), index_info(key_info) { uint i; @@ -1677,7 +1678,7 @@ public: } if ((calc_state= - (Prefix_calc_state *) sql_alloc(sizeof(Prefix_calc_state)*key_parts))) + (Prefix_calc_state *) thd->alloc(sizeof(Prefix_calc_state)*key_parts))) { uint keyno= key_info-table->key_info; for (i= 0, state= calc_state; i < key_parts; i++, state++) @@ -1691,7 +1692,8 @@ public: break; if (!(state->last_prefix= - new Cached_item_field(key_info->key_part[i].field))) + new (thd->mem_root) Cached_item_field(thd, + key_info->key_part[i].field))) break; state->entry_count= state->prefix_count= 0; prefixes++; @@ -2475,7 +2477,7 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index) if (key_info->flags & HA_FULLTEXT) DBUG_RETURN(rc); - Index_prefix_calc index_prefix_calc(table, key_info); + Index_prefix_calc index_prefix_calc(thd, table, key_info); DEBUG_SYNC(table->in_use, "statistics_collection_start1"); DEBUG_SYNC(table->in_use, "statistics_collection_start2"); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dfce503e314..dad51139af3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -63,7 +63,8 @@ const char *primary_key_name="PRIMARY"; static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end); -static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); +static char *make_unique_key_name(THD *thd, const char *field_name, KEY *start, + KEY *end); static int copy_data_between_tables(THD *thd, TABLE *from,TABLE *to, List<Create_field> &create, bool ignore, uint order_num, ORDER *order, @@ -71,7 +72,7 @@ static int copy_data_between_tables(THD *thd, TABLE *from,TABLE *to, Alter_info::enum_enable_or_disable keys_onoff, Alter_table_ctx *alter_ctx); -static bool prepare_blob_field(THD *thd, Create_field *sql_field); +static bool prepare_blob_field(THD *thd, Column_definition *sql_field); static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *, uint *, handler *, KEY **, uint *, int); static uint blob_length_by_type(enum_field_types type); @@ -89,7 +90,7 @@ static char* add_identifier(THD* thd, char *to_p, const char * end_p, { uint res; uint errors; - const char *conv_name; + const char *conv_name, *conv_name_end; char tmp_name[FN_REFLEN]; char conv_string[FN_REFLEN]; int quote; @@ -110,11 +111,13 @@ static char* add_identifier(THD* thd, char *to_p, const char * end_p, { DBUG_PRINT("error", ("strconvert of '%s' failed with %u (errors: %u)", conv_name, res, errors)); conv_name= name; + conv_name_end= name + name_len; } else { DBUG_PRINT("info", ("conv '%s' -> '%s'", conv_name, conv_string)); conv_name= conv_string; + conv_name_end= conv_string + res; } quote = thd ? get_quote_char_for_identifier(thd, conv_name, res - 1) : '"'; @@ -124,8 +127,8 @@ static char* add_identifier(THD* thd, char *to_p, const char * end_p, *(to_p++)= (char) quote; while (*conv_name && (end_p - to_p - 1) > 0) { - uint length= my_mbcharlen(system_charset_info, *conv_name); - if (!length) + int length= my_charlen(system_charset_info, conv_name, conv_name_end); + if (length <= 0) length= 1; if (length == 1 && *conv_name == (char) quote) { @@ -572,7 +575,7 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen) DBUG_ENTER("build_tmptable_filename"); char *p= strnmov(buff, mysql_tmpdir, bufflen); - my_snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x", + my_snprintf(p, bufflen - (p - buff), "/%s%lx_%llx_%x", tmp_file_prefix, current_pid, thd->thread_id, thd->tmp_table++); @@ -1813,7 +1816,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) partition_info *part_info= lpt->table->part_info; if (part_info) { - if (!(part_syntax_buf= generate_partition_syntax(part_info, + if (!(part_syntax_buf= generate_partition_syntax(lpt->thd, part_info, &syntax_len, TRUE, TRUE, lpt->create_info, @@ -1896,7 +1899,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) { TABLE_SHARE *share= lpt->table->s; char *tmp_part_syntax_str; - if (!(part_syntax_buf= generate_partition_syntax(part_info, + if (!(part_syntax_buf= generate_partition_syntax(lpt->thd, part_info, &syntax_len, TRUE, TRUE, lpt->create_info, @@ -2875,7 +2878,7 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval, 1 Error */ -int prepare_create_field(Create_field *sql_field, +int prepare_create_field(Column_definition *sql_field, uint *blob_columns, longlong table_flags) { @@ -3491,7 +3494,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->flags= dup_field->flags; sql_field->interval= dup_field->interval; sql_field->vcol_info= dup_field->vcol_info; - sql_field->stored_in_db= dup_field->stored_in_db; it2.remove(); // Remove first (create) definition select_field_pos--; break; @@ -3533,14 +3535,14 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, (virtual fields) and update their offset later (see the next loop). */ - if (sql_field->stored_in_db) + if (sql_field->stored_in_db()) record_offset+= sql_field->pack_length; } /* Update virtual fields' offset*/ it.rewind(); while ((sql_field=it++)) { - if (!sql_field->stored_in_db) + if (!sql_field->stored_in_db()) { sql_field->offset= record_offset; record_offset+= sql_field->pack_length; @@ -3893,7 +3895,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } } #endif - if (!sql_field->stored_in_db) + if (!sql_field->stored_in_db()) { /* Key fields must always be physically stored. */ my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0)); @@ -4052,7 +4054,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, primary_key=1; } else if (!(key_name= key->name.str)) - key_name=make_unique_key_name(sql_field->field_name, + key_name=make_unique_key_name(thd, sql_field->field_name, *key_info_buffer, key_info); if (check_if_keyname_exists(key_name, *key_info_buffer, key_info)) { @@ -4261,7 +4263,7 @@ static void set_table_default_charset(THD *thd, In this case the error is given */ -static bool prepare_blob_field(THD *thd, Create_field *sql_field) +static bool prepare_blob_field(THD *thd, Column_definition *sql_field) { DBUG_ENTER("prepare_blob_field"); @@ -4320,7 +4322,7 @@ static bool prepare_blob_field(THD *thd, Create_field *sql_field) */ -void sp_prepare_create_field(THD *thd, Create_field *sql_field) +void sp_prepare_create_field(THD *thd, Column_definition *sql_field) { if (sql_field->sql_type == MYSQL_TYPE_SET || sql_field->sql_type == MYSQL_TYPE_ENUM) @@ -4502,7 +4504,7 @@ handler *mysql_create_frm_image(THD *thd, We reverse the partitioning parser and generate a standard format for syntax stored in frm file. */ - if (!(part_syntax_buf= generate_partition_syntax(part_info, + if (!(part_syntax_buf= generate_partition_syntax(thd, part_info, &syntax_len, TRUE, TRUE, create_info, @@ -5094,7 +5096,7 @@ check_if_keyname_exists(const char *name, KEY *start, KEY *end) static char * -make_unique_key_name(const char *field_name,KEY *start,KEY *end) +make_unique_key_name(THD *thd, const char *field_name,KEY *start,KEY *end) { char buff[MAX_FIELD_NAME],*buff_end; @@ -5112,7 +5114,7 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end) *buff_end= '_'; int10_to_str(i, buff_end+1, 10); if (!check_if_keyname_exists(buff,start,end)) - return sql_strdup(buff); + return thd->strdup(buff); } return (char*) "not_specified"; // Should never happen } @@ -6272,7 +6274,7 @@ static bool fill_alter_inplace_info(THD *thd, is stored or is used in the partitioning expression. */ if (field->vcol_info && - (field->stored_in_db || field->vcol_info->is_in_partitioning_expr())) + (field->stored_in_db() || field->vcol_info->is_in_partitioning_expr())) { if (is_equal == IS_EQUAL_NO || !field->vcol_info->is_equal(new_field->vcol_info)) @@ -6371,11 +6373,10 @@ static bool fill_alter_inplace_info(THD *thd, DBUG_ASSERT(ha_alter_info->handler_flags & Alter_inplace_info::ADD_COLUMN); if (new_field->vcol_info && - (new_field->stored_in_db || new_field->vcol_info->is_in_partitioning_expr())) + (new_field->stored_in_db() || new_field->vcol_info->is_in_partitioning_expr())) { ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL; } - break; } } @@ -7438,7 +7439,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, of the list for now. Their positions will be corrected later. */ new_create_list.push_back(def, thd->mem_root); - if (field->stored_in_db != def->stored_in_db) + if (field->stored_in_db() != def->stored_in_db()) { my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN, MYF(0)); goto err; @@ -9350,15 +9351,14 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, int error= 1; Copy_field *copy= NULL, *copy_end; ha_rows found_count= 0, delete_count= 0; - uint length= 0; SORT_FIELD *sortorder; + SORT_INFO *file_sort= 0; READ_RECORD info; TABLE_LIST tables; List<Item> fields; List<Item> all_fields; - ha_rows examined_rows; - ha_rows found_rows; bool auto_increment_field_copied= 0; + bool init_read_record_done= 0; ulonglong save_sql_mode= thd->variables.sql_mode; ulonglong prev_insert_id, time_to_report_progress; Field **dfield_ptr= to->default_field; @@ -9441,9 +9441,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, } else { - from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL | - MY_THREAD_SPECIFIC)); + uint length= 0; bzero((char *) &tables, sizeof(tables)); tables.table= from; tables.alias= tables.table_name= from->s->table_name.str; @@ -9455,12 +9453,10 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, fields, all_fields, order) || !(sortorder= make_unireg_sortorder(thd, order, &length, NULL)) || - (from->sort.found_records= filesort(thd, from, sortorder, length, - NULL, HA_POS_ERROR, - true, - &examined_rows, &found_rows, - &dummy_tracker)) == - HA_POS_ERROR) + !(file_sort= filesort(thd, from, sortorder, length, + NULL, HA_POS_ERROR, + true, + &dummy_tracker))) goto err; } thd_progress_next_stage(thd); @@ -9470,8 +9466,10 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, /* Tell handler that we have values for all columns in the to table */ to->use_all_columns(); to->mark_virtual_columns_for_write(TRUE); - if (init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE)) + if (init_read_record(&info, thd, from, (SQL_SELECT *) 0, file_sort, 1, 1, + FALSE)) goto err; + init_read_record_done= 1; if (ignore && !alter_ctx->fk_error_if_delete_row) to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); @@ -9586,9 +9584,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, found_count++; thd->get_stmt_da()->inc_current_row_for_warning(); } - end_read_record(&info); - free_io_cache(from); - delete [] copy; THD_STAGE_INFO(thd, stage_enabling_keys); thd_progress_next_stage(thd); @@ -9609,6 +9604,12 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, error= 1; err: + /* Free resources */ + if (init_read_record_done) + end_read_record(&info); + delete [] copy; + delete file_sort; + thd->variables.sql_mode= save_sql_mode; thd->abort_on_warning= 0; *copied= found_count; diff --git a/sql/sql_table.h b/sql/sql_table.h index a8124177840..109da541a28 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -23,6 +23,7 @@ class Alter_info; class Alter_table_ctx; +class Column_definition; class Create_field; struct TABLE_LIST; class THD; @@ -249,8 +250,8 @@ bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length, bool quick_rm_table(THD *thd, handlerton *base, const char *db, const char *table_name, uint flags); void close_cached_table(THD *thd, TABLE *table); -void sp_prepare_create_field(THD *thd, Create_field *sql_field); -int prepare_create_field(Create_field *sql_field, +void sp_prepare_create_field(THD *thd, Column_definition *sql_field); +int prepare_create_field(Column_definition *sql_field, uint *blob_columns, longlong table_flags); CHARSET_INFO* get_sql_field_charset(Create_field *sql_field, diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 8e7525893eb..642cf208908 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -88,7 +88,7 @@ static my_bool print_cached_tables_callback(TDC_element *element, THD *in_use= entry->in_use; printf("%-14.14s %-32s%6ld%8ld%6d %s\n", entry->s->db.str, entry->s->table_name.str, element->version, - in_use ? in_use->thread_id : 0, + in_use ? (long) in_use->thread_id : (long) 0, entry->db_stat ? 1 : 0, in_use ? lock_descriptions[(int)entry->reginfo.lock_type] : "Not in use"); diff --git a/sql/sql_test.h b/sql/sql_test.h index 3c1ee188eeb..867582a9569 100644 --- a/sql/sql_test.h +++ b/sql/sql_test.h @@ -22,7 +22,7 @@ class JOIN; struct TABLE_LIST; typedef class Item COND; typedef class st_select_lex SELECT_LEX; -typedef struct st_sort_field SORT_FIELD; +struct SORT_FIELD; #ifndef DBUG_OFF void print_where(COND *cond,const char *info, enum_query_type query_type); diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 7d52419ae18..d85664568a1 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -16,6 +16,9 @@ #include "sql_type.h" #include "sql_const.h" +#include "sql_class.h" +#include "item.h" +#include "log.h" static Type_handler_tiny type_handler_tiny; static Type_handler_short type_handler_short; @@ -27,9 +30,13 @@ static Type_handler_bit type_handler_bit; static Type_handler_float type_handler_float; static Type_handler_double type_handler_double; static Type_handler_time type_handler_time; +static Type_handler_time2 type_handler_time2; static Type_handler_date type_handler_date; +static Type_handler_newdate type_handler_newdate; static Type_handler_datetime type_handler_datetime; +static Type_handler_datetime2 type_handler_datetime2; static Type_handler_timestamp type_handler_timestamp; +static Type_handler_timestamp2 type_handler_timestamp2; static Type_handler_olddecimal type_handler_olddecimal; static Type_handler_newdecimal type_handler_newdecimal; static Type_handler_null type_handler_null; @@ -39,7 +46,11 @@ static Type_handler_tiny_blob type_handler_tiny_blob; static Type_handler_medium_blob type_handler_medium_blob; static Type_handler_long_blob type_handler_long_blob; static Type_handler_blob type_handler_blob; +#ifdef HAVE_SPATIAL static Type_handler_geometry type_handler_geometry; +#endif +static Type_handler_enum type_handler_enum; +static Type_handler_set type_handler_set; /** @@ -111,8 +122,7 @@ Type_handler_hybrid_field_type::Type_handler_hybrid_field_type() const Type_handler * -Type_handler_hybrid_field_type::get_handler_by_field_type(enum_field_types type) - const +Type_handler::get_handler_by_field_type(enum_field_types type) { switch (type) { case MYSQL_TYPE_DECIMAL: return &type_handler_olddecimal; @@ -127,7 +137,7 @@ Type_handler_hybrid_field_type::get_handler_by_field_type(enum_field_types type) case MYSQL_TYPE_FLOAT: return &type_handler_float; case MYSQL_TYPE_DOUBLE: return &type_handler_double; case MYSQL_TYPE_NULL: return &type_handler_null; - case MYSQL_TYPE_VARCHAR: return &type_handler_varchar; + case MYSQL_TYPE_VARCHAR: return &type_handler_varchar; case MYSQL_TYPE_TINY_BLOB: return &type_handler_tiny_blob; case MYSQL_TYPE_MEDIUM_BLOB: return &type_handler_medium_blob; case MYSQL_TYPE_LONG_BLOB: return &type_handler_long_blob; @@ -136,17 +146,497 @@ Type_handler_hybrid_field_type::get_handler_by_field_type(enum_field_types type) case MYSQL_TYPE_STRING: return &type_handler_string; case MYSQL_TYPE_ENUM: return &type_handler_varchar; // Map to VARCHAR case MYSQL_TYPE_SET: return &type_handler_varchar; // Map to VARCHAR - case MYSQL_TYPE_GEOMETRY: return &type_handler_geometry; + case MYSQL_TYPE_GEOMETRY: +#ifdef HAVE_SPATIAL + return &type_handler_geometry; +#else + return NULL; +#endif + case MYSQL_TYPE_TIMESTAMP: return &type_handler_timestamp2;// Map to timestamp2 + case MYSQL_TYPE_TIMESTAMP2: return &type_handler_timestamp2; + case MYSQL_TYPE_DATE: return &type_handler_newdate; // Map to newdate + case MYSQL_TYPE_TIME: return &type_handler_time2; // Map to time2 + case MYSQL_TYPE_TIME2: return &type_handler_time2; + case MYSQL_TYPE_DATETIME: return &type_handler_datetime2; // Map to datetime2 + case MYSQL_TYPE_DATETIME2: return &type_handler_datetime2; + case MYSQL_TYPE_NEWDATE: + /* + NEWDATE is actually a real_type(), not a field_type(), + but it's used around the code in field_type() context. + We should probably clean up the code not to use MYSQL_TYPE_NEWDATE + in field_type() context and add DBUG_ASSERT(0) here. + */ + return &type_handler_newdate; + }; + DBUG_ASSERT(0); + return &type_handler_string; +} + + +const Type_handler * +Type_handler::get_handler_by_real_type(enum_field_types type) +{ + switch (type) { + case MYSQL_TYPE_DECIMAL: return &type_handler_olddecimal; + case MYSQL_TYPE_NEWDECIMAL: return &type_handler_newdecimal; + case MYSQL_TYPE_TINY: return &type_handler_tiny; + case MYSQL_TYPE_SHORT: return &type_handler_short; + case MYSQL_TYPE_LONG: return &type_handler_long; + case MYSQL_TYPE_LONGLONG: return &type_handler_longlong; + case MYSQL_TYPE_INT24: return &type_handler_int24; + case MYSQL_TYPE_YEAR: return &type_handler_year; + case MYSQL_TYPE_BIT: return &type_handler_bit; + case MYSQL_TYPE_FLOAT: return &type_handler_float; + case MYSQL_TYPE_DOUBLE: return &type_handler_double; + case MYSQL_TYPE_NULL: return &type_handler_null; + case MYSQL_TYPE_VARCHAR: return &type_handler_varchar; + case MYSQL_TYPE_TINY_BLOB: return &type_handler_tiny_blob; + case MYSQL_TYPE_MEDIUM_BLOB: return &type_handler_medium_blob; + case MYSQL_TYPE_LONG_BLOB: return &type_handler_long_blob; + case MYSQL_TYPE_BLOB: return &type_handler_blob; + case MYSQL_TYPE_VAR_STRING: + /* + VAR_STRING is actually a field_type(), not a real_type(), + but it's used around the code in real_type() context. + We should clean up the code and add DBUG_ASSERT(0) here. + */ + return &type_handler_string; + case MYSQL_TYPE_STRING: return &type_handler_string; + case MYSQL_TYPE_ENUM: return &type_handler_enum; + case MYSQL_TYPE_SET: return &type_handler_set; + case MYSQL_TYPE_GEOMETRY: +#ifdef HAVE_SPATIAL + return &type_handler_geometry; +#else + return NULL; +#endif case MYSQL_TYPE_TIMESTAMP: return &type_handler_timestamp; - case MYSQL_TYPE_TIMESTAMP2: return &type_handler_timestamp; + case MYSQL_TYPE_TIMESTAMP2: return &type_handler_timestamp2; case MYSQL_TYPE_DATE: return &type_handler_date; case MYSQL_TYPE_TIME: return &type_handler_time; - case MYSQL_TYPE_TIME2: return &type_handler_time; + case MYSQL_TYPE_TIME2: return &type_handler_time2; case MYSQL_TYPE_DATETIME: return &type_handler_datetime; - case MYSQL_TYPE_DATETIME2: return &type_handler_datetime; - case MYSQL_TYPE_NEWDATE: return &type_handler_date; + case MYSQL_TYPE_DATETIME2: return &type_handler_datetime2; + case MYSQL_TYPE_NEWDATE: return &type_handler_newdate; }; DBUG_ASSERT(0); return &type_handler_string; } + +/** + Create a DOUBLE field by default. +*/ +Field * +Type_handler::make_num_distinct_aggregator_field(MEM_ROOT *mem_root, + const Item *item) const +{ + return new(mem_root) + Field_double(NULL, item->max_length, + (uchar *) (item->maybe_null ? "" : 0), + item->maybe_null ? 1 : 0, Field::NONE, + item->name, item->decimals, 0, item->unsigned_flag); +} + + +Field * +Type_handler_float::make_num_distinct_aggregator_field(MEM_ROOT *mem_root, + const Item *item) + const +{ + return new(mem_root) + Field_float(NULL, item->max_length, + (uchar *) (item->maybe_null ? "" : 0), + item->maybe_null ? 1 : 0, Field::NONE, + item->name, item->decimals, 0, item->unsigned_flag); +} + + +Field * +Type_handler_decimal_result::make_num_distinct_aggregator_field( + MEM_ROOT *mem_root, + const Item *item) + const +{ + DBUG_ASSERT(item->decimals <= DECIMAL_MAX_SCALE); + return new (mem_root) + Field_new_decimal(NULL, item->max_length, + (uchar *) (item->maybe_null ? "" : 0), + item->maybe_null ? 1 : 0, Field::NONE, + item->name, item->decimals, 0, item->unsigned_flag); +} + + +Field * +Type_handler_int_result::make_num_distinct_aggregator_field(MEM_ROOT *mem_root, + const Item *item) + const +{ + /** + Make a longlong field for all INT-alike types. It could create + smaller fields for TINYINT, SMALLINT, MEDIUMINT, INT though. + */ + return new(mem_root) + Field_longlong(NULL, item->max_length, + (uchar *) (item->maybe_null ? "" : 0), + item->maybe_null ? 1 : 0, Field::NONE, + item->name, 0, item->unsigned_flag); +} + + +/***********************************************************************/ + +#define TMPNAME "" + +Field *Type_handler_tiny::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + /* + As we don't know if the integer was signed or not on the master, + assume we have same sign on master and slave. This is true when not + using conversions so it should be true also when using conversions. + */ + bool unsigned_flag= ((Field_num*) target)->unsigned_flag; + return new (table->in_use->mem_root) + Field_tiny(NULL, 4 /*max_length*/, (uchar *) "", 1, Field::NONE, + TMPNAME, 0/*zerofill*/, unsigned_flag); +} + + +Field *Type_handler_short::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + bool unsigned_flag= ((Field_num*) target)->unsigned_flag; + return new (table->in_use->mem_root) + Field_short(NULL, 6 /*max_length*/, (uchar *) "", 1, Field::NONE, + TMPNAME, 0/*zerofill*/, unsigned_flag); +} + + +Field *Type_handler_int24::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + bool unsigned_flag= ((Field_num*) target)->unsigned_flag; + return new (table->in_use->mem_root) + Field_medium(NULL, 9 /*max_length*/, (uchar *) "", 1, Field::NONE, + TMPNAME, 0/*zerofill*/, unsigned_flag); +} + + +Field *Type_handler_long::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + bool unsigned_flag= ((Field_num*) target)->unsigned_flag; + return new (table->in_use->mem_root) + Field_long(NULL, 11 /*max_length*/, (uchar *) "", 1, Field::NONE, + TMPNAME, 0/*zerofill*/, unsigned_flag); +} + + +Field *Type_handler_longlong::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + bool unsigned_flag= ((Field_num*) target)->unsigned_flag; + return new (table->in_use->mem_root) + Field_longlong(NULL, 20 /*max_length*/,(uchar *) "", 1, Field::NONE, + TMPNAME, 0/*zerofill*/, unsigned_flag); +} + + + +Field *Type_handler_float::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new (table->in_use->mem_root) + Field_float(NULL, 12 /*max_length*/, (uchar *) "", 1, Field::NONE, + TMPNAME, 0/*dec*/, 0/*zerofill*/, 0/*unsigned_flag*/); +} + + +Field *Type_handler_double::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new (table->in_use->mem_root) + Field_double(NULL, 22 /*max_length*/, (uchar *) "", 1, Field::NONE, + TMPNAME, 0/*dec*/, 0/*zerofill*/, 0/*unsigned_flag*/); +} + + +Field *Type_handler_newdecimal::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + int precision= metadata >> 8; + uint decimals= metadata & 0x00ff; + uint32 max_length= my_decimal_precision_to_length(precision, decimals, false); + DBUG_ASSERT(decimals <= DECIMAL_MAX_SCALE); + return new (table->in_use->mem_root) + Field_new_decimal(NULL, max_length, (uchar *) "", 1, Field::NONE, + TMPNAME, decimals, 0/*zerofill*/, 0/*unsigned*/); +} + + +Field *Type_handler_olddecimal::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + sql_print_error("In RBR mode, Slave received incompatible DECIMAL field " + "(old-style decimal field) from Master while creating " + "conversion table. Please consider changing datatype on " + "Master to new style decimal by executing ALTER command for" + " column Name: %s.%s.%s.", + target->table->s->db.str, + target->table->s->table_name.str, + target->field_name); + return NULL; +} + + +Field *Type_handler_year::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_year(NULL, 4, (uchar *) "", 1, Field::NONE, TMPNAME); +} + + +Field *Type_handler_null::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_null(NULL, 0, Field::NONE, TMPNAME, target->charset()); +} + + +Field *Type_handler_timestamp::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new_Field_timestamp(table->in_use->mem_root, NULL, (uchar *) "", 1, + Field::NONE, TMPNAME, table->s, target->decimals()); +} + + +Field *Type_handler_timestamp2::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_timestampf(NULL, (uchar *) "", 1, Field::NONE, + TMPNAME, table->s, metadata); +} + + +Field *Type_handler_newdate::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_newdate(NULL, (uchar *) "", 1, Field::NONE, TMPNAME); +} + + +Field *Type_handler_date::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_date(NULL, (uchar *) "", 1, Field::NONE, TMPNAME); +} + + +Field *Type_handler_time::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new_Field_time(table->in_use->mem_root, NULL, (uchar *) "", 1, + Field::NONE, TMPNAME, target->decimals()); +} + + +Field *Type_handler_time2::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_timef(NULL, (uchar *) "", 1, Field::NONE, TMPNAME, metadata); +} + + +Field *Type_handler_datetime::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new_Field_datetime(table->in_use->mem_root, NULL, (uchar *) "", 1, + Field::NONE, TMPNAME, target->decimals()); +} + + +Field *Type_handler_datetime2::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_datetimef(NULL, (uchar *) "", 1, + Field::NONE, TMPNAME, metadata); +} + + +Field *Type_handler_bit::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + DBUG_ASSERT((metadata & 0xff) <= 7); + uint32 max_length= 8 * (metadata >> 8U) + (metadata & 0x00ff); + return new(table->in_use->mem_root) + Field_bit_as_char(NULL, max_length, (uchar *) "", 1, + Field::NONE, TMPNAME); +} + + +Field *Type_handler_string::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + /* This is taken from Field_string::unpack. */ + uint32 max_length= (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff); + return new(table->in_use->mem_root) + Field_string(NULL, max_length, (uchar *) "", 1, + Field::NONE, TMPNAME, target->charset()); +} + + +Field *Type_handler_varchar::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_varstring(NULL, metadata, HA_VARCHAR_PACKLENGTH(metadata), + (uchar *) "", 1, Field::NONE, TMPNAME, + table->s, target->charset()); +} + + +Field *Type_handler_tiny_blob::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_blob(NULL, (uchar *) "", 1, Field::NONE, TMPNAME, + table->s, 1, target->charset()); +} + + +Field *Type_handler_blob::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_blob(NULL, (uchar *) "", 1, Field::NONE, TMPNAME, + table->s, 2, target->charset()); +} + + +Field *Type_handler_medium_blob::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_blob(NULL, (uchar *) "", 1, Field::NONE, TMPNAME, + table->s, 3, target->charset()); +} + + +Field *Type_handler_long_blob::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + return new(table->in_use->mem_root) + Field_blob(NULL, (uchar *) "", 1, Field::NONE, TMPNAME, + table->s, 4, target->charset()); +} + + +#ifdef HAVE_SPATIAL +Field *Type_handler_geometry::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + DBUG_ASSERT(target->type() == MYSQL_TYPE_GEOMETRY); + /* + We do not do not update feature_gis statistics here: + status_var_increment(target->table->in_use->status_var.feature_gis); + as this is only a temporary field. + The statistics was already incremented when "target" was created. + */ + return new(table->in_use->mem_root) + Field_geom(NULL, (uchar *) "", 1, Field::NONE, TMPNAME, table->s, 4, + ((const Field_geom*) target)->geom_type, + ((const Field_geom*) target)->srid); +} +#endif + +Field *Type_handler_enum::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + DBUG_ASSERT(target->type() == MYSQL_TYPE_STRING); + DBUG_ASSERT(target->real_type() == MYSQL_TYPE_ENUM); + return new(table->in_use->mem_root) + Field_enum(NULL, target->field_length, + (uchar *) "", 1, Field::NONE, TMPNAME, + metadata & 0x00ff/*pack_length()*/, + ((const Field_enum*) target)->typelib, target->charset()); +} + + +Field *Type_handler_set::make_conversion_table_field(TABLE *table, + uint metadata, + const Field *target) + const +{ + DBUG_ASSERT(target->type() == MYSQL_TYPE_STRING); + DBUG_ASSERT(target->real_type() == MYSQL_TYPE_SET); + return new(table->in_use->mem_root) + Field_set(NULL, target->field_length, + (uchar *) "", 1, Field::NONE, TMPNAME, + metadata & 0x00ff/*pack_length()*/, + ((const Field_enum*) target)->typelib, target->charset()); +} diff --git a/sql/sql_type.h b/sql/sql_type.h index f5a42e8d97d..596c338720e 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -23,12 +23,26 @@ #include "mysqld.h" +class Field; +class Item; +class Type_std_attributes; +class Sort_param; +struct TABLE; +struct SORT_FIELD_ATTR; + class Type_handler { protected: const Type_handler *string_type_handler(uint max_octet_length) const; + void make_sort_key_longlong(uchar *to, + bool maybe_null, bool null_value, + bool unsigned_flag, + longlong value) const; public: + static const Type_handler *get_handler_by_field_type(enum_field_types type); + static const Type_handler *get_handler_by_real_type(enum_field_types type); virtual enum_field_types field_type() const= 0; + virtual enum_field_types real_field_type() const { return field_type(); } virtual Item_result result_type() const= 0; virtual Item_result cmp_type() const= 0; virtual const Type_handler* @@ -36,6 +50,48 @@ public: CHARSET_INFO *cs) const { return this; } virtual ~Type_handler() {} + /** + Makes a temporary table Field to handle numeric aggregate functions, + e.g. SUM(DISTINCT expr), AVG(DISTINCT expr), etc. + */ + virtual Field *make_num_distinct_aggregator_field(MEM_ROOT *, + const Item *) const; + /** + Makes a temporary table Field to handle RBR replication type conversion. + @param TABLE - The conversion table the field is going to be added to. + It's used to access to table->in_use->mem_root, + to create the new field on the table memory root, + as well as to increment statistics in table->share + (e.g. table->s->blob_count). + @param metadata - Metadata from the binary log. + @param target - The field in the target table on the slave. + + Note, the data types of "target" and of "this" are not necessarily + always the same, in general case it's possible that: + this->field_type() != target->field_type() + and/or + this->real_type( ) != target->real_type() + + This method decodes metadata according to this->real_type() + and creates a new field also according to this->real_type(). + + In some cases it lurks into "target", to get some extra information, e.g.: + - unsigned_flag for numeric fields + - charset() for string fields + - typelib and field_length for SET and ENUM + - geom_type and srid for GEOMETRY + This information is not available in the binary log, so + we assume that these fields are the same on the master and on the slave. + */ + virtual Field *make_conversion_table_field(TABLE *TABLE, + uint metadata, + const Field *target) const= 0; + virtual void make_sort_key(uchar *to, Item *item, + const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const= 0; + virtual void sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const= 0; }; @@ -47,6 +103,11 @@ public: Item_result result_type() const { return REAL_RESULT; } Item_result cmp_type() const { return REAL_RESULT; } virtual ~Type_handler_real_result() {} + void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const; + void sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const; }; @@ -56,6 +117,12 @@ public: Item_result result_type() const { return DECIMAL_RESULT; } Item_result cmp_type() const { return DECIMAL_RESULT; } virtual ~Type_handler_decimal_result() {}; + Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const; + void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const; + void sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const; }; @@ -65,6 +132,12 @@ public: Item_result result_type() const { return INT_RESULT; } Item_result cmp_type() const { return INT_RESULT; } virtual ~Type_handler_int_result() {} + Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const; + void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const; + void sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const; }; @@ -74,6 +147,11 @@ public: Item_result result_type() const { return STRING_RESULT; } Item_result cmp_type() const { return TIME_RESULT; } virtual ~Type_handler_temporal_result() {} + void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const; + void sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const; }; @@ -86,6 +164,11 @@ public: const Type_handler * type_handler_adjusted_to_max_octet_length(uint max_octet_length, CHARSET_INFO *cs) const; + void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const; + void sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const; }; @@ -114,6 +197,8 @@ class Type_handler_tiny: public Type_handler_int_result public: virtual ~Type_handler_tiny() {} enum_field_types field_type() const { return MYSQL_TYPE_TINY; } + Field *make_conversion_table_field(TABLE *TABLE, uint metadata, + const Field *target) const; }; @@ -122,6 +207,8 @@ class Type_handler_short: public Type_handler_int_result public: virtual ~Type_handler_short() {} enum_field_types field_type() const { return MYSQL_TYPE_SHORT; } + Field *make_conversion_table_field(TABLE *TABLE, uint metadata, + const Field *target) const; }; @@ -130,6 +217,8 @@ class Type_handler_long: public Type_handler_int_result public: virtual ~Type_handler_long() {} enum_field_types field_type() const { return MYSQL_TYPE_LONG; } + Field *make_conversion_table_field(TABLE *TABLE, uint metadata, + const Field *target) const; }; @@ -138,6 +227,8 @@ class Type_handler_longlong: public Type_handler_int_result public: virtual ~Type_handler_longlong() {} enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } + Field *make_conversion_table_field(TABLE *TABLE, uint metadata, + const Field *target) const; }; @@ -146,6 +237,8 @@ class Type_handler_int24: public Type_handler_int_result public: virtual ~Type_handler_int24() {} enum_field_types field_type() const { return MYSQL_TYPE_INT24; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -154,6 +247,8 @@ class Type_handler_year: public Type_handler_int_result public: virtual ~Type_handler_year() {} enum_field_types field_type() const { return MYSQL_TYPE_YEAR; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -162,6 +257,8 @@ class Type_handler_bit: public Type_handler_int_result public: virtual ~Type_handler_bit() {} enum_field_types field_type() const { return MYSQL_TYPE_BIT; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -170,6 +267,9 @@ class Type_handler_float: public Type_handler_real_result public: virtual ~Type_handler_float() {} enum_field_types field_type() const { return MYSQL_TYPE_FLOAT; } + Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const; + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -178,6 +278,8 @@ class Type_handler_double: public Type_handler_real_result public: virtual ~Type_handler_double() {} enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -186,6 +288,19 @@ class Type_handler_time: public Type_handler_temporal_result public: virtual ~Type_handler_time() {} enum_field_types field_type() const { return MYSQL_TYPE_TIME; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; +}; + + +class Type_handler_time2: public Type_handler_temporal_result +{ +public: + virtual ~Type_handler_time2() {} + enum_field_types field_type() const { return MYSQL_TYPE_TIME; } + enum_field_types real_field_type() const { return MYSQL_TYPE_TIME2; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -194,6 +309,18 @@ class Type_handler_date: public Type_handler_temporal_result public: virtual ~Type_handler_date() {} enum_field_types field_type() const { return MYSQL_TYPE_DATE; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; +}; + + +class Type_handler_newdate: public Type_handler_temporal_result +{ +public: + virtual ~Type_handler_newdate() {} + enum_field_types field_type() const { return MYSQL_TYPE_DATE; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -202,6 +329,19 @@ class Type_handler_datetime: public Type_handler_temporal_result public: virtual ~Type_handler_datetime() {} enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; +}; + + +class Type_handler_datetime2: public Type_handler_temporal_result +{ +public: + virtual ~Type_handler_datetime2() {} + enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } + enum_field_types real_field_type() const { return MYSQL_TYPE_DATETIME2; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -210,6 +350,19 @@ class Type_handler_timestamp: public Type_handler_temporal_result public: virtual ~Type_handler_timestamp() {} enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; +}; + + +class Type_handler_timestamp2: public Type_handler_temporal_result +{ +public: + virtual ~Type_handler_timestamp2() {} + enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; } + enum_field_types real_field_type() const { return MYSQL_TYPE_TIMESTAMP2; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -218,6 +371,8 @@ class Type_handler_olddecimal: public Type_handler_decimal_result public: virtual ~Type_handler_olddecimal() {} enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -226,6 +381,8 @@ class Type_handler_newdecimal: public Type_handler_decimal_result public: virtual ~Type_handler_newdecimal() {} enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -234,6 +391,8 @@ class Type_handler_null: public Type_handler_string_result public: virtual ~Type_handler_null() {} enum_field_types field_type() const { return MYSQL_TYPE_NULL; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -242,6 +401,8 @@ class Type_handler_string: public Type_handler_string_result public: virtual ~Type_handler_string() {} enum_field_types field_type() const { return MYSQL_TYPE_STRING; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -250,6 +411,8 @@ class Type_handler_varchar: public Type_handler_string_result public: virtual ~Type_handler_varchar() {} enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -258,6 +421,8 @@ class Type_handler_tiny_blob: public Type_handler_string_result public: virtual ~Type_handler_tiny_blob() {} enum_field_types field_type() const { return MYSQL_TYPE_TINY_BLOB; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -266,6 +431,8 @@ class Type_handler_medium_blob: public Type_handler_string_result public: virtual ~Type_handler_medium_blob() {} enum_field_types field_type() const { return MYSQL_TYPE_MEDIUM_BLOB; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -274,6 +441,8 @@ class Type_handler_long_blob: public Type_handler_string_result public: virtual ~Type_handler_long_blob() {} enum_field_types field_type() const { return MYSQL_TYPE_LONG_BLOB; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -282,14 +451,42 @@ class Type_handler_blob: public Type_handler_string_result public: virtual ~Type_handler_blob() {} enum_field_types field_type() const { return MYSQL_TYPE_BLOB; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; +#ifdef HAVE_SPATIAL class Type_handler_geometry: public Type_handler_string_result { public: virtual ~Type_handler_geometry() {} enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; +}; +#endif + + +class Type_handler_enum: public Type_handler_string_result +{ +public: + virtual ~Type_handler_enum() {} + enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } + virtual enum_field_types real_field_type() const { return MYSQL_TYPE_ENUM; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; +}; + + +class Type_handler_set: public Type_handler_string_result +{ +public: + virtual ~Type_handler_set() {} + enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } + virtual enum_field_types real_field_type() const { return MYSQL_TYPE_SET; } + Field *make_conversion_table_field(TABLE *, uint metadata, + const Field *target) const; }; @@ -306,9 +503,11 @@ class Type_handler_hybrid_field_type: public Type_handler { const Type_handler *m_type_handler; const Type_handler *get_handler_by_result_type(Item_result type) const; - const Type_handler *get_handler_by_field_type(enum_field_types type) const; public: Type_handler_hybrid_field_type(); + Type_handler_hybrid_field_type(const Type_handler *handler) + :m_type_handler(handler) + { } Type_handler_hybrid_field_type(enum_field_types type) :m_type_handler(get_handler_by_field_type(type)) { } @@ -316,8 +515,16 @@ public: :m_type_handler(other->m_type_handler) { } enum_field_types field_type() const { return m_type_handler->field_type(); } + enum_field_types real_field_type() const + { + return m_type_handler->real_field_type(); + } Item_result result_type() const { return m_type_handler->result_type(); } Item_result cmp_type() const { return m_type_handler->cmp_type(); } + void set_handler(const Type_handler *other) + { + m_type_handler= other; + } const Type_handler *set_handler_by_result_type(Item_result type) { return (m_type_handler= get_handler_by_result_type(type)); @@ -335,6 +542,10 @@ public: { return (m_type_handler= get_handler_by_field_type(type)); } + const Type_handler *set_handler_by_real_type(enum_field_types type) + { + return (m_type_handler= get_handler_by_real_type(type)); + } const Type_handler * type_handler_adjusted_to_max_octet_length(uint max_octet_length, CHARSET_INFO *cs) const @@ -343,6 +554,42 @@ public: m_type_handler->type_handler_adjusted_to_max_octet_length(max_octet_length, cs); } + Field *make_num_distinct_aggregator_field(MEM_ROOT *mem_root, + const Item *item) const + { + return m_type_handler->make_num_distinct_aggregator_field(mem_root, item); + } + Field *make_conversion_table_field(TABLE *table, uint metadata, + const Field *target) const + { + return m_type_handler->make_conversion_table_field(table, metadata, target); + } + void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, + Sort_param *param) const + { + m_type_handler->make_sort_key(to, item, sort_field, param); + } + void sortlength(THD *thd, + const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const + { + m_type_handler->sortlength(thd, item, attr); + } + }; + +/** + This class is used for Item_type_holder, which preserves real_type. +*/ +class Type_handler_hybrid_real_field_type: + public Type_handler_hybrid_field_type +{ +public: + Type_handler_hybrid_real_field_type(enum_field_types type) + :Type_handler_hybrid_field_type(get_handler_by_real_type(type)) + { } +}; + + #endif /* SQL_TYPE_H_INCLUDED */ diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 0b294b5af8c..502bc88c489 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -180,7 +180,8 @@ void udf_init() } table= tables.table; - if (init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE)) + if (init_read_record(&read_record_info, new_thd, table, NULL, NULL, 1, 0, + FALSE)) { sql_print_error("Could not initialize init_read_record; udf's not " "loaded"); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 8145cec5f25..5685c90850a 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -173,7 +173,8 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types, /** - Reset and empty the temporary table that stores the materialized query result. + Reset and empty the temporary table that stores the materialized query + result. @note The cleanup performed here is exactly the same as for the two temp tables of JOIN - exec_tmp_table_[1 | 2]. @@ -183,8 +184,6 @@ void select_union::cleanup() { table->file->extra(HA_EXTRA_RESET_STATE); table->file->ha_delete_all_rows(); - free_io_cache(table); - filesort_free_buffers(table,0); } @@ -534,7 +533,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, while ((type= tp++)) { - if (type->result_type() == STRING_RESULT && + if (type->cmp_type() == STRING_RESULT && type->collation.derivation == DERIVATION_NONE) { my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION"); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 43038ba9321..61c16a905fe 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -270,6 +270,7 @@ int mysql_update(THD *thd, key_map old_covering_keys; TABLE *table; SQL_SELECT *select= NULL; + SORT_INFO *file_sort= 0; READ_RECORD info; SELECT_LEX *select_lex= &thd->lex->select_lex; ulonglong id; @@ -420,7 +421,7 @@ int mysql_update(THD *thd, table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); set_statistics_for_table(thd, table); - select= make_select(table, 0, 0, conds, 0, &error); + select= make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); if (error || !limit || thd->is_error() || (select && select->check_quick(thd, safe_update, limit))) { @@ -558,26 +559,18 @@ int mysql_update(THD *thd, */ uint length= 0; SORT_FIELD *sortorder; - ha_rows examined_rows; - ha_rows found_rows; - table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL | - MY_THREAD_SPECIFIC)); Filesort_tracker *fs_tracker= thd->lex->explain->get_upd_del_plan()->filesort_tracker; if (!(sortorder=make_unireg_sortorder(thd, order, &length, NULL)) || - (table->sort.found_records= filesort(thd, table, sortorder, length, - select, limit, - true, - &examined_rows, &found_rows, - fs_tracker)) - == HA_POS_ERROR) - { + !(file_sort= filesort(thd, table, sortorder, length, + select, limit, + true, + fs_tracker))) goto err; - } - thd->inc_examined_row_count(examined_rows); + thd->inc_examined_row_count(file_sort->examined_rows); + /* Filesort has already found and selected the rows we want to update, so we don't need the where clause @@ -618,7 +611,7 @@ int mysql_update(THD *thd, */ if (query_plan.index == MAX_KEY || (select && select->quick)) - error= init_read_record(&info, thd, table, select, 0, 1, FALSE); + error= init_read_record(&info, thd, table, select, NULL, 0, 1, FALSE); else error= init_read_record_idx(&info, thd, table, 1, query_plan.index, reverse); @@ -662,8 +655,9 @@ int mysql_update(THD *thd, else { /* - Don't try unlocking the row if skip_record reported an error since in - this case the transaction might have been rolled back already. + Don't try unlocking the row if skip_record reported an + error since in this case the transaction might have been + rolled back already. */ if (error < 0) { @@ -712,7 +706,7 @@ int mysql_update(THD *thd, if (select && select->quick && select->quick->reset()) goto err; table->file->try_semi_consistent_read(1); - if (init_read_record(&info, thd, table, select, 0, 1, FALSE)) + if (init_read_record(&info, thd, table, select, file_sort, 0, 1, FALSE)) goto err; updated= found= 0; @@ -1020,6 +1014,7 @@ int mysql_update(THD *thd, } DBUG_ASSERT(transactional_table || !updated || thd->transaction.stmt.modified_non_trans_table); free_underlaid_joins(thd, select_lex); + delete file_sort; /* If LAST_INSERT_ID(X) was used, report X */ id= thd->arg_of_last_insert_id_function ? @@ -1053,6 +1048,7 @@ int mysql_update(THD *thd, err: delete select; + delete file_sort; free_underlaid_joins(thd, select_lex); table->disable_keyread(); thd->abort_on_warning= 0; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 5604ffd5bee..41fd5b78f04 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -58,7 +58,7 @@ static int mysql_register_view(THD *, TABLE_LIST *, enum_view_create_mode); NAME_LEN, it is truncated. */ -static void make_unique_view_field_name(Item *target, +static void make_unique_view_field_name(THD *thd, Item *target, List<Item> &item_list, Item *last_element) { @@ -96,7 +96,7 @@ static void make_unique_view_field_name(Item *target, } target->orig_name= target->name; - target->set_name(buff, name_len, system_charset_info); + target->set_name(thd, buff, name_len, system_charset_info); } @@ -123,7 +123,7 @@ static void make_unique_view_field_name(Item *target, isn't allowed */ -bool check_duplicate_names(List<Item> &item_list, bool gen_unique_view_name) +bool check_duplicate_names(THD *thd, List<Item> &item_list, bool gen_unique_view_name) { Item *item; List_iterator_fast<Item> it(item_list); @@ -144,9 +144,9 @@ bool check_duplicate_names(List<Item> &item_list, bool gen_unique_view_name) if (!gen_unique_view_name) goto err; if (item->is_autogenerated_name) - make_unique_view_field_name(item, item_list, item); + make_unique_view_field_name(thd, item, item_list, item); else if (check->is_autogenerated_name) - make_unique_view_field_name(check, item_list, item); + make_unique_view_field_name(thd, check, item_list, item); else goto err; } @@ -167,7 +167,7 @@ err: @param item_list List of Items which should be checked */ -static void make_valid_column_names(List<Item> &item_list) +void make_valid_column_names(THD *thd, List<Item> &item_list) { Item *item; uint name_len; @@ -181,7 +181,7 @@ static void make_valid_column_names(List<Item> &item_list) continue; name_len= my_snprintf(buff, NAME_LEN, "Name_exp_%u", column_no); item->orig_name= item->name; - item->set_name(buff, name_len, system_charset_info); + item->set_name(thd, buff, name_len, system_charset_info); } DBUG_VOID_RETURN; @@ -215,7 +215,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) TABLE_LIST decoy; memcpy (&decoy, view, sizeof (TABLE_LIST)); - if (tdc_open_view(thd, &decoy, decoy.alias, OPEN_VIEW_NO_PARSE)) + if (tdc_open_view(thd, &decoy, OPEN_VIEW_NO_PARSE)) return TRUE; if (!lex->definer) @@ -539,16 +539,16 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } while ((item= it++, name= nm++)) { - item->set_name(name->str, (uint) name->length, system_charset_info); + item->set_name(thd, name->str, (uint) name->length, system_charset_info); item->is_autogenerated_name= FALSE; } } /* Check if the auto generated column names are conforming. */ for (sl= select_lex; sl; sl= sl->next_select()) - make_valid_column_names(sl->item_list); + make_valid_column_names(thd, sl->item_list); - if (check_duplicate_names(select_lex->item_list, 1)) + if (check_duplicate_names(thd, select_lex->item_list, 1)) { res= TRUE; goto err; diff --git a/sql/sql_view.h b/sql/sql_view.h index ce83dc656ad..b9eb92198f8 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -51,12 +51,17 @@ int view_repair(THD *thd, TABLE_LIST *view, HA_CHECK_OPT *check_opt); extern TYPELIB updatable_views_with_limit_typelib; -bool check_duplicate_names(List<Item>& item_list, bool gen_unique_view_names); +bool check_duplicate_names(THD *thd, List<Item>& item_list, + bool gen_unique_view_names); bool mysql_rename_view(THD *thd, const char *new_db, const char *new_name, TABLE_LIST *view); +void make_valid_column_names(THD *thd, List<Item> &item_list); + #define VIEW_ANY_ACL (SELECT_ACL | UPDATE_ACL | INSERT_ACL | DELETE_ACL) extern const LEX_STRING view_type; +void make_valid_column_names(List<Item> &item_list); + #endif /* SQL_VIEW_INCLUDED */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 24dc3c44b0f..1870b3f719f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -54,6 +54,7 @@ #include "sql_handler.h" // Sql_cmd_handler_* #include "sql_signal.h" #include "sql_get_diagnostics.h" // Sql_cmd_get_diagnostics +#include "sql_cte.h" #include "event_parse_data.h" #include "create_options.h" #include <myisam.h> @@ -346,7 +347,7 @@ int case_stmt_action_when(LEX *lex, Item *when, bool simple) */ return !MY_TEST(i) || - sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)) || + sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)) || sp->add_cont_backpatch(i) || sp->add_instr(i); } @@ -380,7 +381,7 @@ int case_stmt_action_then(LEX *lex) (jump from instruction 4 to 12, 7 to 12 ... in the example) */ - return sp->push_backpatch(i, ctx->last_label()); + return sp->push_backpatch(lex->thd, i, ctx->last_label()); } static bool @@ -464,7 +465,8 @@ set_local_variable(THD *thd, sp_variable *spv, Item *val) sp_set= new (thd->mem_root) sp_instr_set(lex->sphead->instructions(), lex->spcont, - spv->offset, it, spv->type, lex, TRUE); + spv->offset, it, spv->sql_type(), + lex, TRUE); return (sp_set == NULL || lex->sphead->add_instr(sp_set)); } @@ -563,7 +565,8 @@ create_item_for_sp_var(THD *thd, LEX_STRING name, sp_variable *spvar, len_in_q= end_in_q - start_in_q; item= new (thd->mem_root) - Item_splocal(thd, name, spvar->offset, spvar->type, pos_in_q, len_in_q); + Item_splocal(thd, name, spvar->offset, spvar->sql_type(), + pos_in_q, len_in_q); #ifndef DBUG_OFF if (item) @@ -882,7 +885,7 @@ static void add_key_to_list(LEX *lex, LEX_STRING *field_name, lex->alter_info.key_list.push_back(key, mem_root); } -void LEX::init_last_field(Create_field *field, const char *field_name, +void LEX::init_last_field(Column_definition *field, const char *field_name, CHARSET_INFO *cs) { last_field= field; @@ -890,28 +893,25 @@ void LEX::init_last_field(Create_field *field, const char *field_name, field->field_name= field_name; /* reset LEX fields that are used in Create_field::set_and_check() */ - length= 0; - dec= 0; charset= cs; } -void LEX::set_last_field_type(enum enum_field_types field_type) +void LEX::set_last_field_type(const Lex_field_type_st &type) { - last_field->sql_type= field_type; - last_field->create_if_not_exists= check_exists; + last_field->sql_type= type.field_type(); last_field->charset= charset; - if (length) + if (type.length()) { int err; - last_field->length= my_strtoll10(length, NULL, &err); + last_field->length= my_strtoll10(type.length(), NULL, &err); if (err) last_field->length= ~0ULL; // safety } else last_field->length= 0; - last_field->decimals= dec ? (uint)atoi(dec) : 0; + last_field->decimals= type.dec() ? (uint)atoi(type.dec()) : 0; } bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) @@ -953,8 +953,13 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) LEX_SYMBOL symbol; struct sys_var_with_base variable; struct { int vars, conds, hndlrs, curs; } spblock; + Lex_length_and_dec_st Lex_length_and_dec; + Lex_cast_type_st Lex_cast_type; + Lex_field_type_st Lex_field_type; + Lex_dyncol_type_st Lex_dyncol_type; /* pointers */ + Create_field *create_field; CHARSET_INFO *charset; Condition_information_item *cond_info_item; DYNCALL_CREATE_DEF *dyncol_def; @@ -976,6 +981,7 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) TABLE_LIST *table_list; Table_ident *table; char *simple_string; + const char *const_simple_string; chooser_compare_func_creator boolfunc2creator; class my_var *myvar; class sp_condition_value *spcondvalue; @@ -983,13 +989,14 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) class sp_label *splabel; class sp_name *spname; class sp_variable *spvar; + class With_clause *with_clause; + handlerton *db_type; st_select_lex *select_lex; struct p_elem_val *p_elem_value; udf_func *udf; /* enums */ - enum Cast_target cast_type; enum Condition_information_item::Name cond_info_item_name; enum enum_diag_condition_item_name diag_condition_item_name; enum Diagnostics_information::Which_area diag_area; @@ -1023,10 +1030,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 160 shift/reduce conflicts. + Currently there are 121 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 162 +%expect 121 /* Comments for TOKENS. @@ -1481,6 +1488,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token REAL /* SQL-2003-R */ %token REBUILD_SYM %token RECOVER_SYM +%token RECURSIVE_SYM %token REDOFILE_SYM %token REDO_BUFFER_SIZE_SYM %token REDUNDANT_SYM @@ -1730,11 +1738,22 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <simple_string> remember_name remember_end opt_db remember_tok_start wild_and_where + field_length opt_field_length opt_field_length_default_1 + +%type <const_simple_string> + opt_place %type <string> text_string hex_or_bin_String opt_gconcat_separator -%type <field_type> type_with_opt_collate int_type real_type field_type +%type <field_type> int_type real_type + +%type <Lex_field_type> type_with_opt_collate field_type + +%type <Lex_dyncol_type> opt_dyncol_type dyncol_type + numeric_dyncol_type temporal_dyncol_type string_dyncol_type + +%type <create_field> field_spec column_def %type <geom_type> spatial_type @@ -1748,12 +1767,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_natural_language_mode opt_query_expansion opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt - optional_flush_tables_arguments opt_dyncol_type dyncol_type + optional_flush_tables_arguments opt_time_precision kill_type kill_option int_num opt_default_time_precision case_stmt_body opt_bin_mod opt_if_exists_table_element opt_if_not_exists_table_element opt_into opt_procedure_clause + opt_recursive %type <object_ddl_options> create_or_replace @@ -1852,7 +1872,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <ha_rkey_mode> handler_rkey_mode -%type <cast_type> cast_type +%type <Lex_cast_type> cast_type cast_type_numeric cast_type_temporal + +%type <Lex_length_and_dec> precision opt_precision float_options %type <symbol> keyword keyword_sp @@ -1898,7 +1920,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); persistent_column_stat_spec persistent_index_stat_spec table_column_list table_index_list table_index_name check start checksum - field_list field_list_item field_spec kill column_def key_def + field_list field_list_item kill key_def keycache_list keycache_list_or_parts assign_to_keycache assign_to_keycache_parts preload_list preload_list_or_parts preload_keys preload_keys_parts @@ -1906,13 +1928,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_limit_clause delete_limit_clause fields opt_values values procedure_list procedure_list2 procedure_item field_def handler opt_generated_always - opt_precision opt_ignore opt_column opt_restrict + opt_ignore opt_column opt_restrict grant revoke set lock unlock string_list field_options field_option field_opt_list opt_binary table_lock_list table_lock ref_list opt_match_clause opt_on_update_delete use opt_delete_options opt_delete_option varchar nchar nvarchar opt_outer table_list table_name table_alias_ref_list table_alias_ref - opt_place opt_attribute opt_attribute_list attribute column_list column_list_id opt_column_list grant_privileges grant_ident grant_list grant_option object_privilege object_privilege_list user_list user_and_role_list @@ -1925,9 +1946,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild union_clause union_list - precision subselect_start opt_and charset + subselect_start opt_and charset subselect_end select_var_list select_var_list_init help - field_length opt_field_length opt_extended_describe shutdown opt_format_json prepare prepare_src execute deallocate @@ -1955,6 +1975,7 @@ END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt %type <NONE> sp_proc_stmt_statement sp_proc_stmt_return + sp_proc_stmt_in_returns_clause %type <NONE> sp_proc_stmt_compound_ok %type <NONE> sp_proc_stmt_if %type <NONE> sp_labeled_control sp_unlabeled_control @@ -1995,6 +2016,10 @@ END_OF_INPUT THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM ROLE_SYM +%type <with_clause> opt_with_clause with_clause + +%type <lex_str_ptr> query_name + %% @@ -2559,6 +2584,7 @@ create: } view_or_trigger_or_sp_or_event { } | create_or_replace USER opt_if_not_exists clear_privileges grant_list + opt_require_clause opt_resource_options { if (Lex->set_command_with_check(SQLCOM_CREATE_USER, $1 | $3)) MYSQL_YYABORT; @@ -2958,9 +2984,7 @@ sp_param_name_and_type: LEX *lex= Lex; sp_variable *spvar= $<spvar>2; - spvar->type= $3; - if (lex->sphead->fill_field_definition(thd, lex, $3, - lex->last_field)) + if (lex->sphead->fill_field_definition(thd, lex, lex->last_field)) { MYSQL_YYABORT; } @@ -3055,7 +3079,6 @@ sp_decl: LEX *lex= Lex; sp_pcontext *pctx= lex->spcont; uint num_vars= pctx->context_var_count(); - enum enum_field_types var_type= $4; Item *dflt_value_item= $5; if (!dflt_value_item) @@ -3078,11 +3101,10 @@ sp_decl: if (!last) spvar->field_def= *lex->last_field; - spvar->type= var_type; spvar->default_value= dflt_value_item; spvar->field_def.field_name= spvar->name.str; - if (lex->sphead->fill_field_definition(thd, lex, var_type, + if (lex->sphead->fill_field_definition(thd, lex, &spvar->field_def)) { MYSQL_YYABORT; @@ -3097,7 +3119,7 @@ sp_decl: pctx, var_idx, dflt_value_item, - var_type, + $4.field_type(), lex, last)); if (is == NULL || @@ -3147,10 +3169,10 @@ sp_decl: /* For continue handlers, mark end of handler scope. */ if ($2 == sp_handler::CONTINUE && - sp->push_backpatch(i, ctx->last_label())) + sp->push_backpatch(thd, i, ctx->last_label())) MYSQL_YYABORT; - if (sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0))) + if (sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0))) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt @@ -3175,7 +3197,7 @@ sp_decl: sp_instr_hreturn(sp->instructions(), ctx); if (i == NULL || sp->add_instr(i) || - sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */ + sp->push_backpatch(thd, i, lex->spcont->last_label())) /* Block end */ MYSQL_YYABORT; } lex->sphead->backpatch(hlab); @@ -3682,18 +3704,31 @@ sp_opt_default: | DEFAULT expr { $$ = $2; } ; -sp_proc_stmt: - sp_proc_stmt_statement - | sp_proc_stmt_return +/* + ps_proc_stmt_in_returns_clause is a statement that is allowed + in the RETURNS clause of a stored function definition directly, + without the BEGIN..END block. + It should not include any syntax structures starting with '(', to avoid + shift/reduce conflicts with the rule "field_type" and its sub-rules + that scan an optional length, like CHAR(1) or YEAR(4). + See MDEV-9166. +*/ +sp_proc_stmt_in_returns_clause: + sp_proc_stmt_return | sp_labeled_block | sp_unlabeled_block | sp_labeled_control + | sp_proc_stmt_compound_ok + ; + +sp_proc_stmt: + sp_proc_stmt_in_returns_clause + | sp_proc_stmt_statement | sp_proc_stmt_leave | sp_proc_stmt_iterate | sp_proc_stmt_open | sp_proc_stmt_fetch | sp_proc_stmt_close - | sp_proc_stmt_compound_ok ; sp_proc_stmt_compound_ok: @@ -3847,7 +3882,7 @@ sp_proc_stmt_leave: i= new (lex->thd->mem_root) sp_instr_jump(ip, ctx); if (i == NULL) MYSQL_YYABORT; - sp->push_backpatch(i, lab); /* Jumping forward */ + sp->push_backpatch(thd, i, lab); /* Jumping forward */ sp->add_instr(i); } } @@ -4024,7 +4059,7 @@ sp_if: sp_instr_jump_if_not *i= new (lex->thd->mem_root) sp_instr_jump_if_not(ip, ctx, $2, lex); if (i == NULL || - sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)) || + sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)) || sp->add_cont_backpatch(i) || sp->add_instr(i)) MYSQL_YYABORT; @@ -4041,7 +4076,7 @@ sp_if: sp->add_instr(i)) MYSQL_YYABORT; sp->backpatch(ctx->pop_label()); - sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)); + sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)); } sp_elseifs { @@ -4332,7 +4367,7 @@ while_body: sp_instr_jump_if_not(ip, lex->spcont, $1, lex); if (i == NULL || /* Jumping forward */ - sp->push_backpatch(i, lex->spcont->last_label()) || + sp->push_backpatch(thd, i, lex->spcont->last_label()) || sp->new_cont_backpatch(i) || sp->add_instr(i)) MYSQL_YYABORT; @@ -5090,7 +5125,7 @@ part_func: '(' remember_name part_func_expr remember_end ')' { partition_info *part_info= Lex->part_info; - if (part_info->set_part_expr($2+1, $3, $4, FALSE)) + if (part_info->set_part_expr(thd, $2 + 1, $3, $4, FALSE)) { MYSQL_YYABORT; } part_info->num_columns= 1; part_info->column_list= FALSE; @@ -5100,7 +5135,7 @@ part_func: sub_part_func: '(' remember_name part_func_expr remember_end ')' { - if (Lex->part_info->set_part_expr($2+1, $3, $4, TRUE)) + if (Lex->part_info->set_part_expr(thd, $2 + 1, $3, $4, TRUE)) { MYSQL_YYABORT; } } ; @@ -6043,13 +6078,13 @@ field_list: ; field_list_item: - column_def + column_def { } | key_def ; column_def: - field_spec opt_check_constraint - | field_spec references + field_spec opt_check_constraint { $$= $1; } + | field_spec references { $$= $1; } ; key_def: @@ -6171,21 +6206,23 @@ field_spec: MYSQL_YYABORT; lex->init_last_field(f, $1.str, NULL); + $<create_field>$= f; } field_type { Lex->set_last_field_type($3); } field_def { LEX *lex=Lex; - Create_field *f= lex->last_field; + $$= $<create_field>2; - if (f->check(thd)) + if ($$->check(thd)) MYSQL_YYABORT; - lex->alter_info.create_list.push_back(f, thd->mem_root); + lex->alter_info.create_list.push_back($$, thd->mem_root); - if (f->flags & PRI_KEY_FLAG) + $$->create_if_not_exists= Lex->check_exists; + if ($$->flags & PRI_KEY_FLAG) add_key_to_list(lex, &$1, Key::PRIMARY, Lex->check_exists); - else if (f->flags & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) + else if ($$->flags & UNIQUE_KEY_FLAG) add_key_to_list(lex, &$1, Key::UNIQUE, Lex->check_exists); } ; @@ -6231,13 +6268,13 @@ vcol_attribute: UNIQUE_SYM { LEX *lex=Lex; - lex->last_field->flags|= UNIQUE_FLAG; + lex->last_field->flags|= UNIQUE_KEY_FLAG; lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; } | UNIQUE_SYM KEY_SYM { LEX *lex=Lex; - lex->last_field->flags|= UNIQUE_FLAG; + lex->last_field->flags|= UNIQUE_KEY_FLAG; lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; } | COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; } @@ -6277,15 +6314,15 @@ virtual_column_func: ; field_type: - int_type opt_field_length field_options { $$=$1; } - | real_type opt_precision field_options { $$=$1; } + int_type opt_field_length field_options { $$.set($1, $2); } + | real_type opt_precision field_options { $$.set($1, $2); } | FLOAT_SYM float_options field_options { - $$=MYSQL_TYPE_FLOAT; - if (Lex->length && !Lex->dec) + $$.set(MYSQL_TYPE_FLOAT, $2); + if ($2.length() && !$2.dec()) { int err; - ulonglong tmp_length= my_strtoll10(Lex->length, NULL, &err); + ulonglong tmp_length= my_strtoll10($2.length(), NULL, &err); if (err || tmp_length > PRECISION_FOR_DOUBLE) { my_error(ER_WRONG_FIELD_SPEC, MYF(0), @@ -6293,80 +6330,57 @@ field_type: MYSQL_YYABORT; } else if (tmp_length > PRECISION_FOR_FLOAT) - $$= MYSQL_TYPE_DOUBLE; - Lex->length= 0; + $$.set(MYSQL_TYPE_DOUBLE); + else + $$.set(MYSQL_TYPE_FLOAT); } } - | BIT_SYM - { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_BIT; - } - | BIT_SYM field_length + | BIT_SYM opt_field_length_default_1 { - $$=MYSQL_TYPE_BIT; + $$.set(MYSQL_TYPE_BIT, $2); } | BOOL_SYM { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_TINY; + $$.set(MYSQL_TYPE_TINY, "1"); } | BOOLEAN_SYM { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_TINY; - } - | char field_length opt_binary - { - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_TINY, "1"); } - | char opt_binary + | char opt_field_length_default_1 opt_binary { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); } - | nchar field_length opt_bin_mod + | nchar opt_field_length_default_1 opt_bin_mod { - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); bincmp_collation(national_charset_info, $3); } - | nchar opt_bin_mod + | BINARY opt_field_length_default_1 { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_STRING; - bincmp_collation(national_charset_info, $2); - } - | BINARY field_length - { - Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_STRING; - } - | BINARY - { - Lex->length= (char*) "1"; Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); } | varchar field_length opt_binary { - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); } | nvarchar field_length opt_bin_mod { - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); bincmp_collation(national_charset_info, $3); } | VARBINARY field_length { Lex->charset=&my_charset_bin; - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); } | YEAR_SYM opt_field_length field_options { - if (Lex->length) + if ($2) { errno= 0; - ulong length= strtoul(Lex->length, NULL, 10); + ulong length= strtoul($2, NULL, 10); if (errno == 0 && length <= MAX_FIELD_BLOBLENGTH && length != 4) { char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1]; @@ -6377,18 +6391,18 @@ field_type: buff, "YEAR(4)"); } } - $$=MYSQL_TYPE_YEAR; + $$.set(MYSQL_TYPE_YEAR, $2); } | DATE_SYM - { $$=MYSQL_TYPE_DATE; } + { $$.set(MYSQL_TYPE_DATE); } | TIME_SYM opt_field_length - { $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME; } + { $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME, $2); } | TIMESTAMP opt_field_length { if (thd->variables.sql_mode & MODE_MAXDB) - $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME; + $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); else { /* @@ -6397,29 +6411,29 @@ field_type: */ if (!opt_explicit_defaults_for_timestamp) Lex->last_field->flags|= NOT_NULL_FLAG; - $$= opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2 - : MYSQL_TYPE_TIMESTAMP; + $$.set(opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2 + : MYSQL_TYPE_TIMESTAMP, $2); } } | DATETIME opt_field_length - { $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME; } + { $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); } | TINYBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_TINY_BLOB; + $$.set(MYSQL_TYPE_TINY_BLOB); } | BLOB_SYM opt_field_length { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_BLOB; + $$.set(MYSQL_TYPE_BLOB, $2); } | spatial_type float_options srid_option { #ifdef HAVE_SPATIAL Lex->charset=&my_charset_bin; Lex->last_field->geom_type= $1; - $$=MYSQL_TYPE_GEOMETRY; + $$.set(MYSQL_TYPE_GEOMETRY, $2); #else my_error(ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, sym_group_geom.needed_define); @@ -6429,57 +6443,52 @@ field_type: | MEDIUMBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_MEDIUM_BLOB; + $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONGBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_LONG_BLOB; + $$.set(MYSQL_TYPE_LONG_BLOB); } | LONG_SYM VARBINARY { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_MEDIUM_BLOB; + $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONG_SYM varchar opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | TINYTEXT opt_binary - { $$=MYSQL_TYPE_TINY_BLOB; } + { $$.set(MYSQL_TYPE_TINY_BLOB); } | TEXT_SYM opt_field_length opt_binary - { $$=MYSQL_TYPE_BLOB; } + { $$.set(MYSQL_TYPE_BLOB, $2); } | MEDIUMTEXT opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONGTEXT opt_binary - { $$=MYSQL_TYPE_LONG_BLOB; } + { $$.set(MYSQL_TYPE_LONG_BLOB); } | DECIMAL_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | NUMERIC_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | FIXED_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | ENUM '(' string_list ')' opt_binary - { $$=MYSQL_TYPE_ENUM; } + { $$.set(MYSQL_TYPE_ENUM); } | SET '(' string_list ')' opt_binary - { $$=MYSQL_TYPE_SET; } + { $$.set(MYSQL_TYPE_SET); } | LONG_SYM opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | SERIAL_SYM { - $$=MYSQL_TYPE_LONGLONG; + $$.set(MYSQL_TYPE_LONGLONG); Lex->last_field->flags|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | - UNIQUE_FLAG); + UNIQUE_KEY_FLAG); } ; spatial_type: GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } | GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } - | POINT_SYM - { - Lex->length= const_cast<char*>(STRINGIFY_ARG - (MAX_LEN_GEOM_POINT_FIELD)); - $$= Field::GEOM_POINT; - } + | POINT_SYM { $$= Field::GEOM_POINT; } | MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } | LINESTRING { $$= Field::GEOM_LINESTRING; } | MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; } @@ -6540,21 +6549,13 @@ srid_option: ; float_options: - /* empty */ - { Lex->dec=Lex->length= (char*)0; } - | field_length - { Lex->dec= (char*)0; } - | precision - {} + /* empty */ { $$.set(0, 0); } + | field_length { $$.set($1, 0); } + | precision { $$= $1; } ; precision: - '(' NUM ',' NUM ')' - { - LEX *lex=Lex; - lex->length=$2.str; - lex->dec=$4.str; - } + '(' NUM ',' NUM ')' { $$.set($2.str, $4.str); } ; field_options: @@ -6574,19 +6575,22 @@ field_option: ; field_length: - '(' LONG_NUM ')' { Lex->length= $2.str; } - | '(' ULONGLONG_NUM ')' { Lex->length= $2.str; } - | '(' DECIMAL_NUM ')' { Lex->length= $2.str; } - | '(' NUM ')' { Lex->length= $2.str; }; + '(' LONG_NUM ')' { $$= $2.str; } + | '(' ULONGLONG_NUM ')' { $$= $2.str; } + | '(' DECIMAL_NUM ')' { $$= $2.str; } + | '(' NUM ')' { $$= $2.str; }; opt_field_length: - /* empty */ { Lex->length=(char*) 0; /* use default length */ } - | field_length { } - ; + /* empty */ { $$= (char*) 0; /* use default length */ } + | field_length { $$= $1; } + +opt_field_length_default_1: + /* empty */ { $$= (char*) "1"; } + | field_length { $$= $1; } opt_precision: - /* empty */ {} - | precision {} + /* empty */ { $$.set(0, 0); } + | precision { $$= $1; } ; opt_attribute: @@ -6614,7 +6618,7 @@ attribute: | SERIAL_SYM DEFAULT VALUE_SYM { LEX *lex=Lex; - lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG; + lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_KEY_FLAG; lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; } | opt_primary KEY_SYM @@ -6626,7 +6630,7 @@ attribute: | UNIQUE_SYM { LEX *lex=Lex; - lex->last_field->flags|= UNIQUE_FLAG; + lex->last_field->flags|= UNIQUE_KEY_FLAG; lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; } | UNIQUE_SYM KEY_SYM @@ -7347,6 +7351,13 @@ alter: lex->sql_command= SQLCOM_ALTER_SERVER; lex->server_options.reset($3); } OPTIONS_SYM '(' server_options_list ')' { } + /* ALTER USER foo is allowed for MySQL compatibility. */ + | ALTER opt_if_exists USER clear_privileges grant_list + opt_require_clause opt_resource_options + { + Lex->create_info.set($2); + Lex->sql_command= SQLCOM_ALTER_USER; + } ; ev_alter_on_schedule_completion: @@ -7634,6 +7645,7 @@ alter_list_item: add_column column_def opt_place { Lex->create_last_non_select_table= Lex->last_table(); + $2->after= $3; } | ADD key_def { @@ -7650,14 +7662,16 @@ alter_list_item: { Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN; Lex->create_last_non_select_table= Lex->last_table(); - Lex->last_field->change= $4.str; + $5->change= $4.str; + $5->after= $6; } | MODIFY_SYM opt_column opt_if_exists_table_element field_spec opt_place { Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN; Lex->create_last_non_select_table= Lex->last_table(); - Lex->last_field->change= Lex->last_field->field_name; + $4->change= $4->field_name; + $4->after= $5; } | DROP opt_column opt_if_exists_table_element field_ident opt_restrict { @@ -7870,15 +7884,15 @@ opt_restrict: ; opt_place: - /* empty */ {} + /* empty */ { $$= NULL; } | AFTER_SYM ident { - store_position_for_column($2.str); + $$= $2.str; Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER; } | FIRST_SYM { - store_position_for_column(first_keyword); + $$= first_keyword; Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER; } ; @@ -8452,10 +8466,11 @@ opt_ignore_leaves: select: - select_init + opt_with_clause select_init { LEX *lex= Lex; lex->sql_command= SQLCOM_SELECT; + lex->current_select->set_with_clause($1); } ; @@ -8722,11 +8737,11 @@ select_item: MYSQL_YYABORT; } $2->is_autogenerated_name= FALSE; - $2->set_name($4.str, $4.length, system_charset_info); + $2->set_name(thd, $4.str, $4.length, system_charset_info); } else if (!$2->name) { - $2->set_name($1, (uint) ($3 - $1), thd->charset()); + $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); } } ; @@ -9187,92 +9202,44 @@ all_or_any: opt_dyncol_type: /* empty */ { - LEX *lex= Lex; - $$= DYN_COL_NULL; /* automatic type */ - lex->charset= NULL; - lex->length= lex->dec= 0; + $$.set(DYN_COL_NULL); /* automatic type */ + Lex->charset= NULL; } | AS dyncol_type { $$= $2; } ; dyncol_type: - INT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_INT; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | UNSIGNED INT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_UINT; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | DOUBLE_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | REAL - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | FLOAT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | DECIMAL_SYM float_options - { - $$= DYN_COL_DECIMAL; - Lex->charset= NULL; - } - | char + numeric_dyncol_type { $$= $1; Lex->charset= NULL; } + | temporal_dyncol_type { $$= $1; Lex->charset= NULL; } + | string_dyncol_type { $$= $1; } + ; + +numeric_dyncol_type: + INT_SYM { $$.set(DYN_COL_INT); } + | UNSIGNED INT_SYM { $$.set(DYN_COL_UINT); } + | DOUBLE_SYM { $$.set(DYN_COL_DOUBLE); } + | REAL { $$.set(DYN_COL_DOUBLE); } + | FLOAT_SYM { $$.set(DYN_COL_DOUBLE); } + | DECIMAL_SYM float_options { $$.set(DYN_COL_DECIMAL, $2); } + ; + +temporal_dyncol_type: + DATE_SYM { $$.set(DYN_COL_DATE); } + | TIME_SYM opt_field_length { $$.set(DYN_COL_TIME, 0, $2); } + | DATETIME opt_field_length { $$.set(DYN_COL_DATETIME, 0, $2); } + ; + +string_dyncol_type: + char { Lex->charset= thd->variables.collation_connection; } opt_binary { - LEX *lex= Lex; - $$= DYN_COL_STRING; - lex->length= lex->dec= 0; + $$.set(DYN_COL_STRING); } | nchar { - LEX *lex= Lex; - $$= DYN_COL_STRING; - lex->charset= national_charset_info; - lex->length= lex->dec= 0; - } - | DATE_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DATE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | TIME_SYM opt_field_length - { - LEX *lex= Lex; - $$= DYN_COL_TIME; - lex->charset= NULL; - lex->dec= lex->length; - lex->length= 0; - } - | DATETIME opt_field_length - { - LEX *lex= Lex; - $$= DYN_COL_DATETIME; - lex->charset= NULL; - lex->dec= lex->length; - lex->length= 0; + $$.set(DYN_COL_STRING); + Lex->charset= national_charset_info; } ; @@ -9286,14 +9253,14 @@ dyncall_create_element: MYSQL_YYABORT; $$->key= $1; $$->value= $3; - $$->type= (DYNAMIC_COLUMN_TYPE)$4; + $$->type= (DYNAMIC_COLUMN_TYPE)$4.dyncol_type(); $$->cs= lex->charset; - if (lex->length) - $$->len= strtoul(lex->length, NULL, 10); + if ($4.length()) + $$->len= strtoul($4.length(), NULL, 10); else $$->len= 0; - if (lex->dec) - $$->frac= strtoul(lex->dec, NULL, 10); + if ($4.dec()) + $$->frac= strtoul($4.dec(), NULL, 10); else $$->len= 0; } @@ -9434,7 +9401,7 @@ simple_expr: | CAST_SYM '(' expr AS cast_type ')' { LEX *lex= Lex; - $$= create_func_cast(thd, $3, $5, lex->length, lex->dec, + $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(), lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -9447,7 +9414,7 @@ simple_expr: } | CONVERT_SYM '(' expr ',' cast_type ')' { - $$= create_func_cast(thd, $3, $5, Lex->length, Lex->dec, + $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(), Lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -9887,8 +9854,8 @@ function_call_nonkeyword: COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')' { LEX *lex= Lex; - $$= create_func_dyncol_get(thd, $3, $5, $7, - lex->length, lex->dec, + $$= create_func_dyncol_get(thd, $3, $5, $7.type(), + $7.length(), $7.dec(), lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -10028,7 +9995,7 @@ function_call_conflict: if (!(i1= get_system_var(thd, OPT_SESSION, name, null_lex_str))) MYSQL_YYABORT; - i1->set_name((const char *) + i1->set_name(thd, (const char *) STRING_WITH_LEN("@@default_week_format"), system_charset_info); $$= new (thd->mem_root) Item_func_week(thd, $3, i1); @@ -10315,7 +10282,7 @@ udf_expr: if ($4.str) { $2->is_autogenerated_name= FALSE; - $2->set_name($4.str, $4.length, system_charset_info); + $2->set_name(thd, $4.str, $4.length, system_charset_info); } /* A field has to have its proper name in order for name @@ -10325,7 +10292,7 @@ udf_expr: */ else if ($2->type() != Item::FIELD_ITEM && $2->type() != Item::REF_ITEM /* For HAVING */ ) - $2->set_name($1, (uint) ($3 - $1), thd->charset()); + $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); $$= $2; } ; @@ -10577,43 +10544,35 @@ in_sum_expr: cast_type: BINARY opt_field_length - { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; } + { $$.set(ITEM_CAST_CHAR, $2); Lex->charset= &my_charset_bin; } | CHAR_SYM opt_field_length { Lex->charset= thd->variables.collation_connection; } opt_binary - { $$=ITEM_CAST_CHAR; Lex->dec= 0; } + { $$.set(ITEM_CAST_CHAR, $2); } | NCHAR_SYM opt_field_length - { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; } - | INT_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | SIGNED_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | SIGNED_SYM INT_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | UNSIGNED - { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | UNSIGNED INT_SYM - { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | DATE_SYM - { $$=ITEM_CAST_DATE; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | TIME_SYM opt_field_length - { - $$=ITEM_CAST_TIME; - LEX *lex= Lex; - lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0; - } - | DATETIME opt_field_length { - $$=ITEM_CAST_DATETIME; - LEX *lex= Lex; - lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0; - } - | DECIMAL_SYM float_options - { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; } - | DOUBLE_SYM - { Lex->charset= NULL; Lex->length= Lex->dec= 0;} - opt_precision - { $$=ITEM_CAST_DOUBLE; } + Lex->charset= national_charset_info; + $$.set(ITEM_CAST_CHAR, $2, 0); + } + | cast_type_numeric { $$= $1; Lex->charset= NULL; } + | cast_type_temporal { $$= $1; Lex->charset= NULL; } + ; + +cast_type_numeric: + INT_SYM { $$.set(ITEM_CAST_SIGNED_INT); } + | SIGNED_SYM { $$.set(ITEM_CAST_SIGNED_INT); } + | SIGNED_SYM INT_SYM { $$.set(ITEM_CAST_SIGNED_INT); } + | UNSIGNED { $$.set(ITEM_CAST_UNSIGNED_INT); } + | UNSIGNED INT_SYM { $$.set(ITEM_CAST_UNSIGNED_INT); } + | DECIMAL_SYM float_options { $$.set(ITEM_CAST_DECIMAL, $2); } + | DOUBLE_SYM opt_precision { $$.set(ITEM_CAST_DOUBLE, $2); } + ; + +cast_type_temporal: + DATE_SYM { $$.set(ITEM_CAST_DATE); } + | TIME_SYM opt_field_length { $$.set(ITEM_CAST_TIME, 0, $2); } + | DATETIME opt_field_length { $$.set(ITEM_CAST_DATETIME, 0, $2); } + ; opt_expr_list: /* empty */ { $$= NULL; } @@ -10937,20 +10896,20 @@ table_factor: and our parser. Possibly this rule could be replaced by our query_expression_body. */ - | '(' get_select_lex select_derived_union ')' opt_table_alias + | '('opt_with_clause get_select_lex select_derived_union ')' opt_table_alias { - /* Use $2 instead of Lex->current_select as derived table will + /* Use $3 instead of Lex->current_select as derived table will alter value of Lex->current_select. */ - if (!($3 || $5) && $2->embedding && - !$2->embedding->nested_join->join_list.elements) + if (!($4 || $6) && $3->embedding && + !$3->embedding->nested_join->join_list.elements) { - /* we have a derived table ($3 == NULL) but no alias, + /* we have a derived table ($4 == NULL) but no alias, Since we are nested in further parentheses so we can pass NULL to the outer level parentheses Permits parsing of "((((select ...))) as xyz)" */ $$= 0; } - else if (!$3) + else if (!$4) { /* Handle case of derived table, alias may be NULL if there are no outer parentheses, add_table_to_list() will throw @@ -10958,12 +10917,13 @@ table_factor: LEX *lex=Lex; SELECT_LEX *sel= lex->current_select; SELECT_LEX_UNIT *unit= sel->master_unit(); + unit->set_with_clause($2); lex->current_select= sel= unit->outer_select(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); if (ti == NULL) MYSQL_YYABORT; if (!($$= sel->add_table_to_list(lex->thd, - ti, $5, 0, + ti, $6, 0, TL_READ, MDL_SHARED_READ))) MYSQL_YYABORT; @@ -10971,11 +10931,11 @@ table_factor: lex->pop_context(); lex->nest_level--; } - /*else if (($3->select_lex && - $3->select_lex->master_unit()->is_union() && - ($3->select_lex->master_unit()->first_select() == - $3->select_lex || !$3->lifted)) || $5)*/ - else if ($5 != NULL) + /*else if (($4->select_lex && + $4->select_lex->master_unit()->is_union() && + ($4->select_lex->master_unit()->first_select() == + $4->select_lex || !$4->lifted)) || $6)*/ + else if ($6 != NULL) { /* Tables with or without joins within parentheses cannot @@ -10988,7 +10948,7 @@ table_factor: { /* nested join: FROM (t1 JOIN t2 ...), nest_level is the same as in the outer query */ - $$= $3; + $$= $4; } /* Fields in derived table can be used in upper select in @@ -11576,7 +11536,7 @@ limit_option: if (spc && (spv = spc->find_variable($1, false))) { splocal= new (thd->mem_root) - Item_splocal(thd, $1, spv->offset, spv->type, + Item_splocal(thd, $1, spv->offset, spv->sql_type(), lip->get_tok_start() - lex->sphead->m_tmp_query, lip->get_ptr() - lip->get_tok_start()); if (splocal == NULL) @@ -11762,7 +11722,7 @@ procedure_item: if (add_proc_to_list(thd, $2)) MYSQL_YYABORT; if (!$2->name) - $2->set_name($1, (uint) ($3 - $1), thd->charset()); + $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); } ; @@ -11816,7 +11776,7 @@ select_outvar: MYSQL_YYABORT; } $$ = Lex->result ? (new (thd->mem_root) - my_var_sp($1, t->offset, t->type, + my_var_sp($1, t->offset, t->sql_type(), Lex->sphead)) : NULL; } @@ -12826,6 +12786,18 @@ show_param: lex->sql_command= SQLCOM_SHOW_CREATE_TRIGGER; lex->spname= $3; } + | CREATE USER + { + Lex->sql_command= SQLCOM_SHOW_CREATE_USER; + if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER)))) + MYSQL_YYABORT; + Lex->grant_user->user= current_user; + } + | CREATE USER user + { + Lex->sql_command= SQLCOM_SHOW_CREATE_USER; + Lex->grant_user= $3; + } | PROCEDURE_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; @@ -13489,7 +13461,7 @@ load_data_set_elem: if (lex->update_list.push_back($1, thd->mem_root) || lex->value_list.push_back($4, thd->mem_root)) MYSQL_YYABORT; - $4->set_name_no_truncate($3, (uint) ($5 - $3), thd->charset()); + $4->set_name_no_truncate(thd, $3, (uint) ($5 - $3), thd->charset()); } ; @@ -13775,8 +13747,93 @@ temporal_literal: ; +opt_with_clause: + /*empty */ { $$= 0; } + | with_clause + { + $$= $1; + Lex->derived_tables|= DERIVED_WITH; + } + ; + + +with_clause: + WITH opt_recursive + { + With_clause *with_clause= + new With_clause($2, Lex->curr_with_clause); + if (with_clause == NULL) + MYSQL_YYABORT; + Lex->curr_with_clause= with_clause; + with_clause->add_to_list(Lex->with_clauses_list_last_next); + } + with_list + { + $$= Lex->curr_with_clause; + Lex->curr_with_clause= Lex->curr_with_clause->pop(); + } + ; + + +opt_recursive: + /*empty*/ { $$= 0; } + | RECURSIVE_SYM { $$= 1; } + ; + + +with_list: + with_list_element + | with_list ',' with_list_element + ; + + +with_list_element: + query_name + opt_with_column_list + AS '(' remember_name subselect remember_end ')' + { + With_element *elem= new With_element($1, Lex->with_column_list, $6->master_unit()); + if (elem == NULL || Lex->curr_with_clause->add_with_element(elem)) + MYSQL_YYABORT; + Lex->with_column_list.empty(); + if (elem->set_unparsed_spec(thd, $5+1, $7)) + MYSQL_YYABORT; + } + ; + + +opt_with_column_list: + /* empty */ + {} + | '(' with_column_list ')' + ; + + +with_column_list: + ident + { + Lex->with_column_list.push_back((LEX_STRING*) + thd->memdup(&$1, sizeof(LEX_STRING))); + } + | with_column_list ',' ident + { + Lex->with_column_list.push_back((LEX_STRING*) + thd->memdup(&$3, sizeof(LEX_STRING))); + } + ; + + +query_name: + ident + { + $$= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING)); + if ($$ == NULL) + MYSQL_YYABORT; + } + ; + /********************************************************************** ** Creating different items. **********************************************************************/ @@ -13832,7 +13889,7 @@ simple_ident: Item_splocal *splocal; splocal= new (thd->mem_root) - Item_splocal(thd, $1, spv->offset, spv->type, + Item_splocal(thd, $1, spv->offset, spv->sql_type(), lip->get_tok_start_prev() - lex->sphead->m_tmp_query, lip->get_tok_end() - lip->get_tok_start_prev()); if (splocal == NULL) @@ -14265,6 +14322,7 @@ keyword: | ASCII_SYM {} | BACKUP_SYM {} | BEGIN_SYM {} + | BINLOG_SYM {} | BYTE_SYM {} | CACHE_SYM {} | CHARSET {} @@ -14348,7 +14406,6 @@ keyword_sp: | AUTO_SYM {} | AVG_ROW_LENGTH {} | AVG_SYM {} - | BINLOG_SYM {} | BIT_SYM {} | BLOCK_SYM {} | BOOL_SYM {} @@ -15401,14 +15458,14 @@ grant: grant_command: grant_privileges ON opt_table grant_ident TO_SYM grant_list - require_clause grant_options + opt_require_clause opt_grant_options { LEX *lex= Lex; lex->sql_command= SQLCOM_GRANT; lex->type= 0; } | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list - require_clause grant_options + opt_require_clause opt_grant_options { LEX *lex= Lex; if (lex->columns.elements) @@ -15420,7 +15477,7 @@ grant_command: lex->type= TYPE_ENUM_FUNCTION; } | grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list - require_clause grant_options + opt_require_clause opt_grant_options { LEX *lex= Lex; if (lex->columns.elements) @@ -15780,7 +15837,7 @@ column_list_id: } ; -require_clause: +opt_require_clause: /* empty */ | REQUIRE_SYM require_list { @@ -15800,24 +15857,8 @@ require_clause: } ; -grant_options: - /* empty */ {} - | WITH grant_option_list - ; - -opt_grant_option: - /* empty */ {} - | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;} - ; - -grant_option_list: - grant_option_list grant_option {} - | grant_option {} - ; - -grant_option: - GRANT OPTION { Lex->grant |= GRANT_ACL;} - | MAX_QUERIES_PER_HOUR ulong_num +resource_option: + MAX_QUERIES_PER_HOUR ulong_num { LEX *lex=Lex; lex->mqh.questions=$2; @@ -15849,6 +15890,37 @@ grant_option: } ; +resource_option_list: + resource_option_list resource_option {} + | resource_option {} + ; + +opt_resource_options: + /* empty */ {} + | WITH resource_option_list + ; + + +opt_grant_options: + /* empty */ {} + | WITH grant_option_list {} + ; + +opt_grant_option: + /* empty */ {} + | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;} + ; + +grant_option_list: + grant_option_list grant_option {} + | grant_option {} + ; + +grant_option: + GRANT OPTION { Lex->grant |= GRANT_ACL;} + | resource_option {} + ; + begin: BEGIN_SYM { @@ -16044,9 +16116,10 @@ query_expression_body: /* Corresponds to <query expression> in the SQL:2003 standard. */ subselect: - subselect_start query_expression_body subselect_end + subselect_start opt_with_clause query_expression_body subselect_end { - $$= $2; + $3->set_with_clause($2); + $$= $3; } ; @@ -16273,7 +16346,7 @@ view_select: lex->parsing_options.allows_derived= FALSE; lex->create_view_select.str= (char *) YYLIP->get_cpp_ptr(); } - view_select_aux view_check_option + opt_with_clause view_select_aux view_check_option { LEX *lex= Lex; uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str; @@ -16285,6 +16358,7 @@ view_select: lex->parsing_options.allows_select_into= TRUE; lex->parsing_options.allows_select_procedure= TRUE; lex->parsing_options.allows_derived= TRUE; + lex->current_select->set_with_clause($2); } ; @@ -16450,8 +16524,7 @@ sf_tail: } type_with_opt_collate /* $11 */ { /* $12 */ - if (Lex->sphead->fill_field_definition(thd, Lex, $11, - Lex->last_field)) + if (Lex->sphead->fill_field_definition(thd, Lex, Lex->last_field)) MYSQL_YYABORT; } sp_c_chistics /* $13 */ @@ -16461,7 +16534,7 @@ sf_tail: lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); } - sp_proc_stmt /* $15 */ + sp_proc_stmt_in_returns_clause /* $15 */ { LEX *lex= thd->lex; sp_head *sp= lex->sphead; diff --git a/sql/structs.h b/sql/structs.h index c1c832d07ec..e51f3e0fe3a 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -557,4 +557,74 @@ public: }; +struct Lex_length_and_dec_st +{ +private: + const char *m_length; + const char *m_dec; +public: + void set(const char *length, const char *dec) + { + m_length= length; + m_dec= dec; + } + const char *length() const { return m_length; } + const char *dec() const { return m_dec; } +}; + + +struct Lex_field_type_st: public Lex_length_and_dec_st +{ +private: + enum_field_types m_type; + void set(enum_field_types type, const char *length, const char *dec) + { + m_type= type; + Lex_length_and_dec_st::set(length, dec); + } +public: + void set(enum_field_types type, Lex_length_and_dec_st length_and_dec) + { + m_type= type; + Lex_length_and_dec_st::operator=(length_and_dec); + } + void set(enum_field_types type, const char *length) + { + set(type, length, 0); + } + void set(enum_field_types type) + { + set(type, 0, 0); + } + enum_field_types field_type() const { return m_type; } +}; + + +struct Lex_dyncol_type_st: public Lex_length_and_dec_st +{ +private: + int m_type; // enum_dynamic_column_type is not visible here, so use int +public: + void set(int type, const char *length, const char *dec) + { + m_type= type; + Lex_length_and_dec_st::set(length, dec); + } + void set(int type, Lex_length_and_dec_st length_and_dec) + { + m_type= type; + Lex_length_and_dec_st::operator=(length_and_dec); + } + void set(int type, const char *length) + { + set(type, length, 0); + } + void set(int type) + { + set(type, 0, 0); + } + int dyncol_type() const { return m_type; } +}; + + #endif /* STRUCTS_INCLUDED */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index e3ff327404f..9d871703bfe 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -283,7 +283,7 @@ static Sys_var_long Sys_pfs_events_stages_history_size( /** Variable performance_schema_max_statement_classes. The default number of statement classes is the sum of: - - COM_END for all regular "statement/com/...", + - (COM_END - mariadb gap) for all regular "statement/com/...", - 1 for "statement/com/new_packet", for unknown enum_server_command - 1 for "statement/com/Error", for invalid enum_server_command - SQLCOM_END for all regular "statement/sql/...", @@ -295,7 +295,8 @@ static Sys_var_ulong Sys_pfs_max_statement_classes( "Maximum number of statement instruments.", PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_statement_class_sizing), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256), - DEFAULT((ulong) SQLCOM_END + (ulong) COM_END + 4), + DEFAULT((ulong) SQLCOM_END + + (ulong) (COM_END -(COM_MDB_GAP_END - COM_MDB_GAP_BEG + 1)) + 4), BLOCK_SIZE(1)); static Sys_var_long Sys_pfs_events_statements_history_long_size( @@ -1450,16 +1451,11 @@ static Sys_var_ulong Sys_metadata_locks_hash_instances( VALID_RANGE(1, 1024), DEFAULT(8), BLOCK_SIZE(1)); -/* - "pseudo_thread_id" variable used in the test suite to detect 32/64bit - systems. If you change it to something else then ulong then fix the tests - in mysql-test/include/have_32bit.inc and have_64bit.inc. -*/ -static Sys_var_ulong Sys_pseudo_thread_id( +static Sys_var_ulonglong Sys_pseudo_thread_id( "pseudo_thread_id", "This variable is for internal server use", SESSION_ONLY(pseudo_thread_id), - NO_CMD_LINE, VALID_RANGE(0, ULONG_MAX), DEFAULT(0), + NO_CMD_LINE, VALID_RANGE(0, ULONGLONG_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_has_super)); @@ -1861,6 +1857,15 @@ static Sys_var_ulong Sys_slave_parallel_threads( NOT_IN_BINLOG, ON_CHECK(check_slave_parallel_threads), ON_UPDATE(fix_slave_parallel_threads)); +/* Alias for @@slave_parallel_threads to match what MySQL 5.7 uses. */ +static Sys_var_ulong Sys_slave_parallel_workers( + "slave_parallel_workers", + "Alias for slave_parallel_threads", + GLOBAL_VAR(opt_slave_parallel_threads), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0,16383), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(check_slave_parallel_threads), + ON_UPDATE(fix_slave_parallel_threads)); + static bool check_slave_domain_parallel_threads(sys_var *self, THD *thd, set_var *var) @@ -2341,17 +2346,6 @@ static Sys_var_ulong Sys_optimizer_use_condition_selectivity( SESSION_VAR(optimizer_use_condition_selectivity), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, 5), DEFAULT(1), BLOCK_SIZE(1)); -/** Warns about deprecated value 63 */ -static bool fix_optimizer_search_depth(sys_var *self, THD *thd, - enum_var_type type) -{ - SV *sv= type == OPT_GLOBAL ? &global_system_variables : &thd->variables; - if (sv->optimizer_search_depth == MAX_TABLES+2) - WARN_DEPRECATED(thd, 10, 2, "optimizer-search-depth=63", - "a search depth less than 63"); - return false; -} - static Sys_var_ulong Sys_optimizer_search_depth( "optimizer_search_depth", "Maximum depth of search performed by the query optimizer. Values " @@ -2359,13 +2353,10 @@ static Sys_var_ulong Sys_optimizer_search_depth( "query plans, but take longer to compile a query. Values smaller " "than the number of tables in a relation result in faster " "optimization, but may produce very bad query plans. If set to 0, " - "the system will automatically pick a reasonable value; if set to " - "63, the optimizer will switch to the original find_best search. " - "NOTE: The value 63 and its associated behaviour is deprecated", + "the system will automatically pick a reasonable value", SESSION_VAR(optimizer_search_depth), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, MAX_TABLES+2), DEFAULT(MAX_TABLES+1), BLOCK_SIZE(1), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(fix_optimizer_search_depth)); + VALID_RANGE(0, MAX_TABLES+1), DEFAULT(MAX_TABLES+1), BLOCK_SIZE(1), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0)); /* this is used in the sigsegv handler */ export const char *optimizer_switch_names[]= @@ -3216,9 +3207,9 @@ static Sys_var_ulong Sys_table_cache_size( static Sys_var_ulong Sys_thread_cache_size( "thread_cache_size", - "How many threads we should keep in a cache for reuse", + "How many threads we should keep in a cache for reuse. These are freed after 5 minutes of idle time", GLOBAL_VAR(thread_cache_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, 16384), DEFAULT(0), BLOCK_SIZE(1)); + VALID_RANGE(0, 16384), DEFAULT(256), BLOCK_SIZE(1)); #ifdef HAVE_POOL_OF_THREADS static bool fix_tp_max_threads(sys_var *, THD *, enum_var_type) @@ -3395,7 +3386,6 @@ static Sys_var_mybool Sys_timed_mutexes( NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), ON_UPDATE(NULL), DEPRECATED("")); -static char *server_version_ptr; static Sys_var_charptr Sys_version( "version", "Server version", READ_ONLY GLOBAL_VAR(server_version_ptr), @@ -3544,7 +3534,8 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type) { thd->variables.option_bits&= ~OPTION_AUTOCOMMIT; thd->mdl_context.release_transactional_locks(); - WSREP_DEBUG("autocommit, MDL TRX lock released: %lu", thd->thread_id); + WSREP_DEBUG("autocommit, MDL TRX lock released: %lld", + (longlong) thd->thread_id); return true; } /* diff --git a/sql/table.cc b/sql/table.cc index a90eb2eee15..07e2876f5ba 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -40,6 +40,7 @@ #include "discover.h" #include "mdl.h" // MDL_wait_for_graph_visitor #include "sql_view.h" +#include "rpl_filter.h" /* INFORMATION_SCHEMA name */ LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")}; @@ -62,6 +63,8 @@ LEX_STRING SLOW_LOG_NAME= {C_STRING_WITH_LEN("slow_log")}; */ LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") }; +static int64 last_table_id; + /* Functions defined in this file */ static void fix_type_pointers(const char ***array, TYPELIB *point_to_type, @@ -316,7 +319,8 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, share->normalized_path.length= path_length; share->table_category= get_table_category(& share->db, & share->table_name); share->open_errno= ENOENT; - share->cached_row_logging_check= -1; + /* The following will be fixed in open_table_from_share */ + share->cached_row_logging_check= 1; init_sql_alloc(&share->stats_cb.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); @@ -325,7 +329,16 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, &share->LOCK_share, MY_MUTEX_INIT_SLOW); mysql_mutex_init(key_TABLE_SHARE_LOCK_ha_data, &share->LOCK_ha_data, MY_MUTEX_INIT_FAST); - tdc_assign_new_table_id(share); + + /* + There is one reserved number that cannot be used. Remember to + change this when 6-byte global table id's are introduced. + */ + do + { + share->table_map_id= my_atomic_add64_explicit(&last_table_id, 1, + MY_MEMORY_ORDER_RELAXED); + } while (unlikely(share->table_map_id == ~0UL)); } DBUG_RETURN(share); } @@ -381,7 +394,7 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, share->path.length= share->normalized_path.length= strlen(path); share->frm_version= FRM_VER_TRUE_VARCHAR; - share->cached_row_logging_check= -1; + share->cached_row_logging_check= 0; // No row logging /* table_map_id is also used for MERGE tables to suppress repeated @@ -948,12 +961,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, plugin_ref se_plugin= 0; keyinfo= &first_keyinfo; share->ext_key_parts= 0; - MEM_ROOT **root_ptr, *old_root; + MEM_ROOT *old_root= thd->mem_root; DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image"); - root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); - old_root= *root_ptr; - *root_ptr= &share->mem_root; + thd->mem_root= &share->mem_root; if (write && write_frm_image(frm_image, frm_length)) goto err; @@ -1675,7 +1686,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, reg_field->field_index= i; reg_field->comment=comment; reg_field->vcol_info= vcol_info; - reg_field->stored_in_db= fld_stored_in_db; + if (vcol_info) + reg_field->vcol_info->stored_in_db= fld_stored_in_db; + else + DBUG_ASSERT(fld_stored_in_db == true); if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) { null_bits_are_used= 1; @@ -1698,7 +1712,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (use_hash && my_hash_insert(&share->name_hash, (uchar*) field_ptr)) goto err; - if (!reg_field->stored_in_db) + if (!reg_field->stored_in_db()) { share->stored_fields--; if (share->stored_rec_length>=recpos) @@ -2084,7 +2098,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->db_plugin= se_plugin; share->error= OPEN_FRM_OK; thd->status_var.opened_shares++; - *root_ptr= old_root; + thd->mem_root= old_root; DBUG_RETURN(0); err: @@ -2097,7 +2111,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (!thd->is_error()) open_table_error(share, OPEN_FRM_CORRUPTED, share->open_errno); - *root_ptr= old_root; + thd->mem_root= old_root; DBUG_RETURN(HA_ERR_NOT_A_TABLE); } @@ -2526,6 +2540,10 @@ bool unpack_vcol_info_from_frm(THD *thd, /* From now on use vcol_info generated by the parser. */ field->vcol_info= vcol_storage.vcol_info; + /* copy the stored_in_db property, the parser doesn't generate it */ + field->vcol_info->stored_in_db= + table->s->field[field->field_index]->vcol_info->stored_in_db; + /* Validate the Item tree. */ if (fix_vcol_expr(thd, table, field)) { @@ -2969,6 +2987,9 @@ partititon_err: outparam->no_replicate= FALSE; } + if (outparam->no_replicate || !binlog_filter->db_ok(outparam->s->db.str)) + outparam->s->cached_row_logging_check= 0; // No row based replication + /* Increment the opened_tables counter, only when open flags set. */ if (db_stat) thd->status_var.opened_tables++; @@ -6154,7 +6175,7 @@ void TABLE::mark_virtual_columns_for_write(bool insert_fl) tmp_vfield= *vfield_ptr; if (bitmap_is_set(write_set, tmp_vfield->field_index)) bitmap_updated= mark_virtual_col(tmp_vfield); - else if (tmp_vfield->stored_in_db) + else if (tmp_vfield->vcol_info->stored_in_db) { bool mark_fl= insert_fl; if (!mark_fl) @@ -6888,13 +6909,15 @@ int update_virtual_fields(THD *thd, TABLE *table, for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++) { vfield= (*vfield_ptr); - DBUG_ASSERT(vfield->vcol_info && vfield->vcol_info->expr_item); + Virtual_column_info *vcol_info= vfield->vcol_info; + DBUG_ASSERT(vcol_info); + DBUG_ASSERT(vcol_info->expr_item); if ((bitmap_is_set(table->vcol_set, vfield->field_index) && - (vcol_update_mode == VCOL_UPDATE_FOR_WRITE || !vfield->stored_in_db)) || + (vcol_update_mode == VCOL_UPDATE_FOR_WRITE || !vcol_info->stored_in_db)) || vcol_update_mode == VCOL_UPDATE_ALL) { /* Compute the actual value of the virtual fields */ - error= vfield->vcol_info->expr_item->save_in_field(vfield, 0); + error= vcol_info->expr_item->save_in_field(vfield, 0); DBUG_PRINT("info", ("field '%s' - updated", vfield->field_name)); } else @@ -7258,7 +7281,9 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) */ if (is_merged_derived()) { - if (is_view() || unit->prepared) + if (is_view() || + (unit->prepared && + !(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW))) create_field_translation(thd); } @@ -7400,6 +7425,11 @@ void TABLE_LIST::set_lock_type(THD *thd, enum thr_lock_type lock) } } +bool TABLE_LIST::is_with_table() +{ + return derived && derived->with_element; +} + uint TABLE_SHARE::actual_n_key_parts(THD *thd) { return use_ext_keys && diff --git a/sql/table.h b/sql/table.h index 023d5e542b8..1c461d96097 100644 --- a/sql/table.h +++ b/sql/table.h @@ -48,6 +48,7 @@ class ACL_internal_schema_access; class ACL_internal_table_access; class Field; class Table_statistics; +class With_element; class TDC_element; /* @@ -321,55 +322,6 @@ enum enum_vcol_update_mode VCOL_UPDATE_ALL }; -class Filesort_info -{ - /// Buffer for sorting keys. - Filesort_buffer filesort_buffer; - -public: - IO_CACHE *io_cache; /* If sorted through filesort */ - uchar *buffpek; /* Buffer for buffpek structures */ - uint buffpek_len; /* Max number of buffpeks in the buffer */ - uchar *addon_buf; /* Pointer to a buffer if sorted with fields */ - size_t addon_length; /* Length of the buffer */ - struct st_sort_addon_field *addon_field; /* Pointer to the fields info */ - void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *); /* To unpack back */ - uchar *record_pointers; /* If sorted in memory */ - ha_rows found_records; /* How many records in sort */ - - /** Sort filesort_buffer */ - void sort_buffer(Sort_param *param, uint count) - { filesort_buffer.sort_buffer(param, count); } - - /** - Accessors for Filesort_buffer (which @c). - */ - uchar *get_record_buffer(uint idx) - { return filesort_buffer.get_record_buffer(idx); } - - uchar **get_sort_keys() - { return filesort_buffer.get_sort_keys(); } - - uchar **alloc_sort_buffer(uint num_records, uint record_length) - { return filesort_buffer.alloc_sort_buffer(num_records, record_length); } - - bool check_sort_buffer_properties(uint num_records, uint record_length) - { - return filesort_buffer.check_sort_buffer_properties(num_records, - record_length); - } - - void free_sort_buffer() - { filesort_buffer.free_sort_buffer(); } - - void init_record_pointers() - { filesort_buffer.init_record_pointers(); } - - size_t sort_buffer_size() const - { return filesort_buffer.sort_buffer_size(); } -}; - - class Field_blob; class Table_triggers_list; @@ -490,9 +442,6 @@ TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name); -struct TABLE_share; -struct All_share_tables; - typedef struct st_table_field_type { LEX_STRING name; @@ -1059,7 +1008,7 @@ private: One should use methods of I_P_List template instead. */ TABLE *share_all_next, **share_all_prev; - friend struct All_share_tables; + friend class TDC_element; public: @@ -1305,7 +1254,6 @@ public: */ Blob_mem_storage *blob_storage; GRANT_INFO grant; - Filesort_info sort; /* The arena which the items for expressions from the table definition are associated with. @@ -1466,19 +1414,6 @@ struct TABLE_share }; -struct All_share_tables -{ - static inline TABLE **next_ptr(TABLE *l) - { - return &l->share_all_next; - } - static inline TABLE ***prev_ptr(TABLE *l) - { - return &l->share_all_prev; - } -}; - - enum enum_schema_table_state { NOT_PROCESSED= 0, @@ -1897,6 +1832,7 @@ struct TABLE_LIST derived tables. Use TABLE_LIST::is_anonymous_derived_table(). */ st_select_lex_unit *derived; /* SELECT_LEX_UNIT of derived table */ + With_element *with; /* With element of with_table */ ST_SCHEMA_TABLE *schema_table; /* Information_schema table */ st_select_lex *schema_select_lex; /* @@ -2261,6 +2197,7 @@ struct TABLE_LIST { return (derived_type & DTYPE_TABLE); } + bool is_with_table(); inline void set_view() { derived_type= DTYPE_VIEW; @@ -2301,6 +2238,7 @@ struct TABLE_LIST { derived_type|= DTYPE_MULTITABLE; } + bool set_as_with_table(THD *thd, With_element *with_elem); void reset_const_table(); bool handle_derived(LEX *lex, uint phases); diff --git a/sql/table_cache.cc b/sql/table_cache.cc index 2dd368a1945..b6c1e32b350 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -67,7 +67,6 @@ I_P_List <TDC_element, I_P_List_fast_push_back<TDC_element> > unused_shares; static int64 tdc_version; /* Increments on each reload */ -static int64 last_table_id; static bool tdc_inited; static int32 tc_count; /**< Number of TABLE objects in table cache. */ @@ -599,13 +598,14 @@ void tdc_unlock_share(TDC_element *element) # Share for table */ -TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db, const char *table_name, - const char *key, uint key_length, - my_hash_value_type hash_value, uint flags, +TABLE_SHARE *tdc_acquire_share(THD *thd, TABLE_LIST *tl, uint flags, TABLE **out_table) { TABLE_SHARE *share; TDC_element *element; + const char *key; + uint key_length= get_table_def_key(tl, &key); + my_hash_value_type hash_value= tl->mdl_request.key.tc_hash_value(); bool was_unused; DBUG_ENTER("tdc_acquire_share"); @@ -629,7 +629,7 @@ retry: lf_hash_search_unpin(thd->tdc_hash_pins); DBUG_ASSERT(element); - if (!(share= alloc_table_share(db, table_name, key, key_length))) + if (!(share= alloc_table_share(tl->db, tl->table_name, key, key_length))) { lf_hash_delete(&tdc_hash, thd->tdc_hash_pins, key, key_length); DBUG_RETURN(0); @@ -841,7 +841,7 @@ bool tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type, const char *db, const char *table_name, bool kill_delayed_threads) { - I_P_List <TABLE, TABLE_share> purge_tables; + TDC_element::TABLE_list purge_tables; TABLE *table; TDC_element *element; uint my_refs= 1; @@ -1091,56 +1091,3 @@ int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument, } return res; } - - -/* - Function to assign a new table map id to a table share. - - PARAMETERS - - share - Pointer to table share structure - - DESCRIPTION - - We are intentionally not checking that share->mutex is locked - since this function should only be called when opening a table - share and before it is entered into the table definition cache - (meaning that it cannot be fetched by another thread, even - accidentally). - - PRE-CONDITION(S) - - share is non-NULL - last_table_id_lock initialized (tdc_inited) - - POST-CONDITION(S) - - share->table_map_id is given a value that with a high certainty is - not used by any other table (the only case where a table id can be - reused is on wrap-around, which means more than 4 billion table - share opens have been executed while one table was open all the - time). - - share->table_map_id is not ~0UL. -*/ - -void tdc_assign_new_table_id(TABLE_SHARE *share) -{ - ulong tid; - DBUG_ENTER("assign_new_table_id"); - DBUG_ASSERT(share); - DBUG_ASSERT(tdc_inited); - - /* - There is one reserved number that cannot be used. Remember to - change this when 6-byte global table id's are introduced. - */ - do - { - tid= my_atomic_add64_explicit(&last_table_id, 1, MY_MEMORY_ORDER_RELAXED); - } while (unlikely(tid == ~0UL)); - - share->table_map_id= tid; - DBUG_PRINT("info", ("table_id= %lu", share->table_map_id)); - DBUG_VOID_RETURN; -} diff --git a/sql/table_cache.h b/sql/table_cache.h index 2c5b0fc45a2..2efc535c425 100644 --- a/sql/table_cache.h +++ b/sql/table_cache.h @@ -31,7 +31,9 @@ public: TABLE_SHARE *share; typedef I_P_List <TABLE, TABLE_share> TABLE_list; - typedef I_P_List <TABLE, All_share_tables> All_share_tables_list; + typedef I_P_List <TABLE, I_P_List_adapter<TABLE, &TABLE::share_all_next, + &TABLE::share_all_prev> > + All_share_tables_list; /** Protects ref_count, m_flush_tickets, all_tables, free_tables, flushed, all_tables_refs. @@ -205,11 +207,8 @@ extern void tdc_purge(bool all); extern TDC_element *tdc_lock_share(THD *thd, const char *db, const char *table_name); extern void tdc_unlock_share(TDC_element *element); -extern TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db, - const char *table_name, - const char *key, uint key_length, - my_hash_value_type hash_value, - uint flags, TABLE **out_table); +extern TABLE_SHARE *tdc_acquire_share(THD *thd, TABLE_LIST *tl, uint flags, + TABLE **out_table= 0); extern void tdc_release_share(TABLE_SHARE *share); extern bool tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type, const char *db, const char *table_name, @@ -220,7 +219,6 @@ extern int tdc_wait_for_old_version(THD *thd, const char *db, ulong refresh_version= ULONG_MAX); extern ulong tdc_refresh_version(void); extern ulong tdc_increment_refresh_version(void); -extern void tdc_assign_new_table_id(TABLE_SHARE *share); extern int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument, bool no_dups= false); @@ -249,50 +247,3 @@ inline uint tdc_create_key(char *key, const char *db, const char *table_name) return (uint) (strmake(strmake(key, db, NAME_LEN) + 1, table_name, NAME_LEN) - key + 1); } - -/** - Convenience helper: call tdc_acquire_share() without out_table. -*/ - -static inline TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db, - const char *table_name, - const char *key, - uint key_length, uint flags) -{ - return tdc_acquire_share(thd, db, table_name, key, key_length, - my_hash_sort(&my_charset_bin, (uchar*) key, - key_length), flags, 0); -} - - -/** - Convenience helper: call tdc_acquire_share() without precomputed cache key. -*/ - -static inline TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db, - const char *table_name, uint flags) -{ - char key[MAX_DBKEY_LENGTH]; - uint key_length; - key_length= tdc_create_key(key, db, table_name); - return tdc_acquire_share(thd, db, table_name, key, key_length, flags); -} - - -/** - Convenience helper: call tdc_acquire_share() reusing the MDL cache key. - - @note lifetime of the returned TABLE_SHARE is limited by the - lifetime of the TABLE_LIST object!!! -*/ - -uint get_table_def_key(const TABLE_LIST *table_list, const char **key); - -static inline TABLE_SHARE *tdc_acquire_share_shortlived(THD *thd, TABLE_LIST *tl, - uint flags) -{ - const char *key; - uint key_length= get_table_def_key(tl, &key); - return tdc_acquire_share(thd, tl->db, tl->table_name, key, key_length, - tl->mdl_request.key.tc_hash_value(), flags, 0); -} diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index b82d29e51f4..cbed769a424 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -66,56 +66,7 @@ void init_sql_alloc(MEM_ROOT *mem_root, uint block_size, uint pre_alloc, } -#ifndef MYSQL_CLIENT -void *sql_alloc(size_t Size) -{ - MEM_ROOT *root= *my_pthread_getspecific_ptr(MEM_ROOT**,THR_MALLOC); - return alloc_root(root,Size); -} -#endif - - -void *sql_calloc(size_t size) -{ - void *ptr; - if ((ptr=sql_alloc(size))) - bzero(ptr,size); - return ptr; -} - - -char *sql_strdup(const char *str) -{ - size_t len= strlen(str)+1; - char *pos; - if ((pos= (char*) sql_alloc(len))) - memcpy(pos,str,len); - return pos; -} - - -char *sql_strmake(const char *str, size_t len) -{ - char *pos; - if ((pos= (char*) sql_alloc(len+1))) - { - memcpy(pos,str,len); - pos[len]=0; - } - return pos; -} - - -void* sql_memdup(const void *ptr, size_t len) -{ - void *pos; - if ((pos= sql_alloc(len))) - memcpy(pos,ptr,len); - return pos; -} - - -char *sql_strmake_with_convert(const char *str, size_t arg_length, +char *sql_strmake_with_convert(THD *thd, const char *str, size_t arg_length, CHARSET_INFO *from_cs, size_t max_res_length, CHARSET_INFO *to_cs, size_t *result_length) @@ -125,7 +76,7 @@ char *sql_strmake_with_convert(const char *str, size_t arg_length, max_res_length--; // Reserve place for end null set_if_smaller(new_length, max_res_length); - if (!(pos= (char*) sql_alloc(new_length+1))) + if (!(pos= (char*) thd->alloc(new_length + 1))) return pos; // Error if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin)) diff --git a/sql/thr_malloc.h b/sql/thr_malloc.h index 0b17c5cdaf1..fc23c87c9fd 100644 --- a/sql/thr_malloc.h +++ b/sql/thr_malloc.h @@ -22,12 +22,7 @@ typedef struct st_mem_root MEM_ROOT; void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size, myf my_flags); -void *sql_alloc(size_t); -void *sql_calloc(size_t); -char *sql_strdup(const char *str); -char *sql_strmake(const char *str, size_t len); -void *sql_memdup(const void * ptr, size_t size); -char *sql_strmake_with_convert(const char *str, size_t arg_length, +char *sql_strmake_with_convert(THD *thd, const char *str, size_t arg_length, CHARSET_INFO *from_cs, size_t max_res_length, CHARSET_INFO *to_cs, size_t *result_length); diff --git a/sql/threadpool.h b/sql/threadpool.h index 7b62d2cb70a..7ddc661565f 100644 --- a/sql/threadpool.h +++ b/sql/threadpool.h @@ -27,10 +27,9 @@ extern uint threadpool_oversubscribe; /* Maximum active threads in group */ /* Common thread pool routines, suitable for different implementations */ -extern void threadpool_cleanup_connection(THD *thd); extern void threadpool_remove_connection(THD *thd); extern int threadpool_process_request(THD *thd); -extern int threadpool_add_connection(THD *thd); +extern THD* threadpool_add_connection(CONNECT *connect, void *scheduled_data); /* Functions used by scheduler. @@ -38,7 +37,7 @@ extern int threadpool_add_connection(THD *thd); threadpool_unix.cc or threadpool_win.cc */ extern bool tp_init(); -extern void tp_add_connection(THD*); +extern void tp_add_connection(CONNECT *); extern void tp_wait_begin(THD *, int); extern void tp_wait_end(THD*); extern void tp_post_kill_notification(THD *thd); diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc index 5bcea767aae..2cfa3473222 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -87,7 +87,6 @@ struct Worker_thread_context #endif pthread_setspecific(THR_KEY_mysys,mysys_var); pthread_setspecific(THR_THD, 0); - pthread_setspecific(THR_MALLOC, 0); } }; @@ -95,7 +94,7 @@ struct Worker_thread_context /* Attach/associate the connection with the OS thread, */ -static bool thread_attach(THD* thd) +static void thread_attach(THD* thd) { pthread_setspecific(THR_KEY_mysys,thd->mysys_var); thd->thread_stack=(char*)&thd; @@ -104,13 +103,14 @@ static bool thread_attach(THD* thd) if (PSI_server) PSI_server->set_thread(thd->event_scheduler.m_psi); #endif - return 0; } -int threadpool_add_connection(THD *thd) +THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data) { - int retval=1; + THD *thd= NULL; + int error=1; + Worker_thread_context worker_context; worker_context.save(); @@ -121,13 +121,29 @@ int threadpool_add_connection(THD *thd) pthread_setspecific(THR_KEY_mysys, 0); my_thread_init(); - thd->mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys); - if (!thd->mysys_var) + st_my_thread_var* mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys); + if (!mysys_var ||!(thd= connect->create_thd())) { /* Out of memory? */ + connect->close_and_delete(); + if (mysys_var) + { +#ifdef HAVE_PSI_INTERFACE + /* + current PSI is still from worker thread. + Set to 0, to avoid premature cleanup by my_thread_end + */ + if (PSI_server) PSI_server->set_thread(0); +#endif + my_thread_end(); + } worker_context.restore(); - return 1; + return NULL; } + delete connect; + add_to_active_threads(thd); + thd->mysys_var= mysys_var; + thd->event_scheduler.data= scheduler_data; /* Create new PSI thread for use with the THD. */ #ifdef HAVE_PSI_INTERFACE @@ -158,28 +174,19 @@ int threadpool_add_connection(THD *thd) */ if (thd_is_connection_alive(thd)) { - retval= 0; + error= 0; thd->net.reading_or_writing= 1; thd->skip_wait_timeout= true; } } } + if (error) + { + threadpool_remove_connection(thd); + thd= NULL; + } worker_context.restore(); - return retval; -} - -/* - threadpool_cleanup_connection() does the bulk of connection shutdown work. - Usually called from threadpool_remove_connection(), but rarely it might - be called also in the main polling thread if connection initialization fails. -*/ -void threadpool_cleanup_connection(THD *thd) -{ - thd->net.reading_or_writing = 0; - end_connection(thd); - close_connection(thd, 0); - unlink_thd(thd); - mysql_cond_broadcast(&COND_thread_count); + return thd; } @@ -189,7 +196,12 @@ void threadpool_remove_connection(THD *thd) worker_context.save(); thread_attach(thd); - threadpool_cleanup_connection(thd); + thd->net.reading_or_writing = 0; + end_connection(thd); + close_connection(thd, 0); + unlink_thd(thd); + mysql_cond_broadcast(&COND_thread_count); + /* Free resources associated with this connection: mysys thread_var and PSI thread. @@ -222,7 +234,8 @@ int threadpool_process_request(THD *thd) /* - In the loop below, the flow is essentially the copy of thead-per-connections + In the loop below, the flow is essentially the copy of + thead-per-connections logic, see do_handle_one_connection() in sql_connect.c The goal is to execute a single query, thus the loop is normally executed @@ -261,18 +274,31 @@ end: } + +/* Dummy functions, do nothing */ + +static bool tp_init_new_connection_thread() +{ + return 0; +} + +static bool tp_end_thread(THD *, bool) +{ + return 0; +} + static scheduler_functions tp_scheduler_functions= { 0, // max_threads NULL, NULL, tp_init, // init - NULL, // init_new_connection_thread + tp_init_new_connection_thread, // init_new_connection_thread tp_add_connection, // add_connection tp_wait_begin, // thd_wait_begin tp_wait_end, // thd_wait_end post_kill_notification, // post_kill_notification - NULL, // end_thread + tp_end_thread, // Dummy function tp_end // end }; diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc index 89a2036cb10..91b392eb766 100644 --- a/sql/threadpool_unix.cc +++ b/sql/threadpool_unix.cc @@ -116,6 +116,7 @@ struct connection_t connection_t *next_in_queue; connection_t **prev_in_queue; ulonglong abs_wait_timeout; + CONNECT* connect; bool logged_in; bool bound_to_poll_descriptor; bool waiting; @@ -809,7 +810,7 @@ static int create_worker(thread_group_t *thread_group) if (!err) { thread_group->last_thread_creation_time=microsecond_interval_timer(); - thread_created++; + statistic_increment(thread_created,&LOCK_status); add_thread_count(thread_group, 1); } else @@ -1203,18 +1204,19 @@ void wait_end(thread_group_t *thread_group) Allocate/initialize a new connection structure. */ -connection_t *alloc_connection(THD *thd) +connection_t *alloc_connection() { + connection_t* connection; DBUG_ENTER("alloc_connection"); + DBUG_EXECUTE_IF("simulate_failed_connection_1", DBUG_RETURN(0); ); - connection_t* connection = (connection_t *)my_malloc(sizeof(connection_t),0); - if (connection) + if ((connection = (connection_t *)my_malloc(sizeof(connection_t),0))) { - connection->thd = thd; connection->waiting= false; connection->logged_in= false; connection->bound_to_poll_descriptor= false; connection->abs_wait_timeout= ULONGLONG_MAX; + connection->thd= 0; } DBUG_RETURN(connection); } @@ -1225,38 +1227,34 @@ connection_t *alloc_connection(THD *thd) Add a new connection to thread pool.. */ -void tp_add_connection(THD *thd) +void tp_add_connection(CONNECT *connect) { + connection_t *connection; DBUG_ENTER("tp_add_connection"); - - threads.append(thd); - mysql_mutex_unlock(&LOCK_thread_count); - connection_t *connection= alloc_connection(thd); - if (connection) + + connection= alloc_connection(); + if (!connection) { - thd->event_scheduler.data= connection; - - /* Assign connection to a group. */ - thread_group_t *group= - &all_groups[thd->thread_id%group_count]; - - connection->thread_group=group; + connect->close_and_delete(); + DBUG_VOID_RETURN; + } + connection->connect= connect; + + /* Assign connection to a group. */ + thread_group_t *group= + &all_groups[connect->thread_id%group_count]; + + connection->thread_group=group; - mysql_mutex_lock(&group->mutex); - group->connection_count++; - mysql_mutex_unlock(&group->mutex); + mysql_mutex_lock(&group->mutex); + group->connection_count++; + mysql_mutex_unlock(&group->mutex); - /* - Add connection to the work queue.Actual logon - will be done by a worker thread. - */ - queue_put(group, connection); - } - else - { - /* Allocation failed */ - threadpool_cleanup_connection(thd); - } + /* + Add connection to the work queue.Actual logon + will be done by a worker thread. + */ + queue_put(group, connection); DBUG_VOID_RETURN; } @@ -1269,9 +1267,12 @@ static void connection_abort(connection_t *connection) { DBUG_ENTER("connection_abort"); thread_group_t *group= connection->thread_group; - - threadpool_remove_connection(connection->thd); - + + if (connection->thd) + { + threadpool_remove_connection(connection->thd); + } + mysql_mutex_lock(&group->mutex); group->connection_count--; mysql_mutex_unlock(&group->mutex); @@ -1440,7 +1441,8 @@ static void handle_event(connection_t *connection) if (!connection->logged_in) { - err= threadpool_add_connection(connection->thd); + connection->thd = threadpool_add_connection(connection->connect, connection); + err= (connection->thd == NULL); connection->logged_in= true; } else @@ -1548,7 +1550,6 @@ bool tp_init() DBUG_RETURN(0); } - void tp_end() { DBUG_ENTER("tp_end"); diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc index 8ae3252caa3..2ca815a6062 100644 --- a/sql/threadpool_win.cc +++ b/sql/threadpool_win.cc @@ -226,11 +226,12 @@ struct connection_t PTP_WAIT shm_read; /* Callback instance, used to inform treadpool about long callbacks */ PTP_CALLBACK_INSTANCE callback_instance; + CONNECT* connect; bool logged_in; }; -void init_connection(connection_t *connection) +void init_connection(connection_t *connection, CONNECT *connect) { connection->logged_in = false; connection->handle= 0; @@ -240,10 +241,11 @@ void init_connection(connection_t *connection) connection->logged_in = false; connection->timeout= ULONGLONG_MAX; connection->callback_instance= 0; + connection->thd= 0; memset(&connection->overlapped, 0, sizeof(OVERLAPPED)); InitializeThreadpoolEnvironment(&connection->callback_environ); SetThreadpoolCallbackPool(&connection->callback_environ, pool); - connection->thd = 0; + connection->connect= connect; } @@ -396,8 +398,8 @@ int start_io(connection_t *connection, PTP_CALLBACK_INSTANCE instance) int login(connection_t *connection, PTP_CALLBACK_INSTANCE instance) { - if (threadpool_add_connection(connection->thd) == 0 - && init_io(connection, connection->thd) == 0 + if ((connection->thd= threadpool_add_connection(connection->connect, connection)) + && init_io(connection, connection->thd) == 0 && start_io(connection, instance) == 0) { return 0; @@ -465,7 +467,7 @@ static void check_thread_init() if (FlsGetValue(fls) == NULL) { FlsSetValue(fls, (void *)1); - thread_created++; + statistic_increment(thread_created, &LOCK_status); InterlockedIncrement((volatile long *)&tp_stats.num_worker_threads); } } @@ -544,7 +546,6 @@ void tp_end(void) } } - /* Handle read completion/notification. */ @@ -656,24 +657,21 @@ static void CALLBACK shm_read_callback(PTP_CALLBACK_INSTANCE instance, /* Notify the thread pool about a new connection. - NOTE: LOCK_thread_count is locked on entry. This function must unlock it. */ -void tp_add_connection(THD *thd) -{ - threads.append(thd); - mysql_mutex_unlock(&LOCK_thread_count); - connection_t *con = (connection_t *)malloc(sizeof(connection_t)); - if(!con) +void tp_add_connection(CONNECT *connect) +{ + connection_t *con; + con= (connection_t *)malloc(sizeof(connection_t)); + DBUG_EXECUTE_IF("simulate_failed_connection_1", free(con);con= 0; ); + if (!con) { tp_log_warning("Allocation failed", "tp_add_connection"); - threadpool_cleanup_connection(thd); + connect->close_and_delete(); return; } - init_connection(con); - con->thd= thd; - thd->event_scheduler.data= con; + init_connection(con, connect); /* Try to login asynchronously, using threads in the pool */ PTP_WORK wrk = CreateThreadpoolWork(login_callback,con, &con->callback_environ); @@ -685,7 +683,7 @@ void tp_add_connection(THD *thd) else { /* Likely memory pressure */ - threadpool_cleanup_connection(thd); + connect->close_and_delete(); } } diff --git a/sql/tztime.cc b/sql/tztime.cc index bed5f416f13..ce0272d996d 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1800,8 +1800,6 @@ end: delete thd; if (org_thd) org_thd->store_globals(); /* purecov: inspected */ - else - my_pthread_setspecific_ptr(THR_MALLOC, 0); default_tz= default_tz_name ? global_system_variables.time_zone : my_tz_SYSTEM; diff --git a/sql/uniques.cc b/sql/uniques.cc index 63eb6e0eb90..f2fa0bf7b1a 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -37,7 +37,9 @@ #include "sql_sort.h" #include "queues.h" // QUEUE #include "my_tree.h" // element_count -#include "sql_class.h" // Unique +#include "uniques.h" // Unique +#include "sql_sort.h" +#include "myisamchk.h" // BUFFPEK int unique_write_to_file(uchar* key, element_count count, Unique *unique) { @@ -58,8 +60,8 @@ int unique_write_to_file_with_count(uchar* key, element_count count, Unique *uni int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique) { - memcpy(unique->record_pointers, key, unique->size); - unique->record_pointers+=unique->size; + memcpy(unique->sort.record_pointers, key, unique->size); + unique->sort.record_pointers+=unique->size; return 0; } @@ -67,8 +69,8 @@ int unique_intersect_write_to_ptrs(uchar* key, element_count count, Unique *uniq { if (count >= unique->min_dupl_count) { - memcpy(unique->record_pointers, key, unique->size); - unique->record_pointers+=unique->size; + memcpy(unique->sort.record_pointers, key, unique->size); + unique->sort.record_pointers+=unique->size; } else unique->filtered_out_elems++; @@ -80,16 +82,15 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, uint size_arg, ulonglong max_in_memory_size_arg, uint min_dupl_count_arg) :max_in_memory_size(max_in_memory_size_arg), - record_pointers(NULL), size(size_arg), elements(0) { + my_b_clear(&file); min_dupl_count= min_dupl_count_arg; full_size= size; if (min_dupl_count_arg) full_size+= sizeof(element_count); with_counters= MY_TEST(min_dupl_count_arg); - my_b_clear(&file); init_tree(&tree, (ulong) (max_in_memory_size / 16), 0, size, comp_func, NULL, comp_func_fixed_arg, MYF(MY_THREAD_SPECIFIC)); /* If the following fail's the next add will also fail */ @@ -408,8 +409,10 @@ Unique::reset() reset_dynamic(&file_ptrs); reinit_io_cache(&file, WRITE_CACHE, 0L, 0, 1); } + my_free(sort.record_pointers); elements= 0; tree.flag= 0; + sort.record_pointers= 0; } /* @@ -636,7 +639,7 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg) if (elements == 0) /* the whole tree is in memory */ return tree_walk(&tree, action, walk_action_arg, left_root_right); - table->sort.found_records=elements+tree.elements_in_tree; + sort.return_rows= elements+tree.elements_in_tree; /* flush current tree to the file to have some memory for merge buffer */ if (flush()) return 1; @@ -663,9 +666,11 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg) /* DESCRIPTION - Perform multi-pass sort merge of the elements accessed through table->sort, - using the buffer buff as the merge buffer. The last pass is not performed - if without_last_merge is TRUE. + + Perform multi-pass sort merge of the elements using the buffer buff as + the merge buffer. The last pass is not performed if without_last_merge is + TRUE. + SYNOPSIS Unique:merge() All params are 'IN': @@ -679,23 +684,19 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg) bool Unique::merge(TABLE *table, uchar *buff, bool without_last_merge) { - IO_CACHE *outfile= table->sort.io_cache; + IO_CACHE *outfile= &sort.io_cache; BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer; uint maxbuffer= file_ptrs.elements - 1; my_off_t save_pos; bool error= 1; + Sort_param sort_param; - /* Open cached file if it isn't open */ - if (!outfile) - outfile= table->sort.io_cache= (IO_CACHE*) my_malloc(sizeof(IO_CACHE), - MYF(MY_THREAD_SPECIFIC|MY_ZEROFILL)); - if (!outfile || - (! my_b_inited(outfile) && - open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, - MYF(MY_WME)))) + /* Open cached file for table records if it isn't open */ + if (! my_b_inited(outfile) && + open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, + MYF(MY_WME))) return 1; - Sort_param sort_param; bzero((char*) &sort_param,sizeof(sort_param)); sort_param.max_rows= elements; sort_param.sort_form= table; @@ -744,44 +745,49 @@ err: /* - Modify the TABLE element so that when one calls init_records() - the rows will be read in priority order. + Allocate memory that can be used with init_records() so that + rows will be read in priority order. */ bool Unique::get(TABLE *table) { bool rc= 1; uchar *sort_buffer= NULL; - table->sort.found_records= elements+tree.elements_in_tree; + sort.return_rows= elements+tree.elements_in_tree; + DBUG_ENTER("Unique::get"); if (my_b_tell(&file) == 0) { /* Whole tree is in memory; Don't use disk if you don't need to */ - if ((record_pointers=table->sort.record_pointers= (uchar*) + if ((sort.record_pointers= (uchar*) my_malloc(size * tree.elements_in_tree, MYF(MY_THREAD_SPECIFIC)))) { + uchar *save_record_pointers= sort.record_pointers; tree_walk_action action= min_dupl_count ? (tree_walk_action) unique_intersect_write_to_ptrs : (tree_walk_action) unique_write_to_ptrs; filtered_out_elems= 0; (void) tree_walk(&tree, action, this, left_root_right); - table->sort.found_records-= filtered_out_elems; - return 0; + /* Restore record_pointers that was changed in by 'action' above */ + sort.record_pointers= save_record_pointers; + sort.return_rows-= filtered_out_elems; + DBUG_RETURN(0); } } /* Not enough memory; Save the result to file && free memory used by tree */ if (flush()) - return 1; + DBUG_RETURN(1); size_t buff_sz= (max_in_memory_size / full_size + 1) * full_size; - if (!(sort_buffer= (uchar*) my_malloc(buff_sz, MYF(MY_THREAD_SPECIFIC|MY_WME)))) - return 1; + if (!(sort_buffer= (uchar*) my_malloc(buff_sz, + MYF(MY_THREAD_SPECIFIC|MY_WME)))) + DBUG_RETURN(1); if (merge(table, sort_buffer, FALSE)) - goto err; + goto err; rc= 0; err: my_free(sort_buffer); - return rc; + DBUG_RETURN(rc); } diff --git a/sql/uniques.h b/sql/uniques.h new file mode 100644 index 00000000000..0210e879788 --- /dev/null +++ b/sql/uniques.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2016 MariaDB corporation + + 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 */ + +#ifndef UNIQUE_INCLUDED +#define UNIQUE_INCLUDED + +#include "filesort.h" + +/* + Unique -- class for unique (removing of duplicates). + Puts all values to the TREE. If the tree becomes too big, + it's dumped to the file. User can request sorted values, or + just iterate through them. In the last case tree merging is performed in + memory simultaneously with iteration, so it should be ~2-3x faster. + */ + +class Unique :public Sql_alloc +{ + DYNAMIC_ARRAY file_ptrs; + ulong max_elements; + ulonglong max_in_memory_size; + IO_CACHE file; + TREE tree; + ulong filtered_out_elems; + uint size; + uint full_size; + uint min_dupl_count; /* always 0 for unions, > 0 for intersections */ + bool with_counters; + + bool merge(TABLE *table, uchar *buff, bool without_last_merge); + bool flush(); + +public: + ulong elements; + SORT_INFO sort; + Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg, + uint size_arg, ulonglong max_in_memory_size_arg, + uint min_dupl_count_arg= 0); + ~Unique(); + ulong elements_in_tree() { return tree.elements_in_tree; } + inline bool unique_add(void *ptr) + { + DBUG_ENTER("unique_add"); + DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements)); + if (!(tree.flag & TREE_ONLY_DUPS) && + tree.elements_in_tree >= max_elements && flush()) + DBUG_RETURN(1); + DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg)); + } + + bool is_in_memory() { return (my_b_tell(&file) == 0); } + void close_for_expansion() { tree.flag= TREE_ONLY_DUPS; } + + bool get(TABLE *table); + + /* Cost of searching for an element in the tree */ + inline static double get_search_cost(ulonglong tree_elems, uint compare_factor) + { + return log((double) tree_elems) / (compare_factor * M_LN2); + } + + static double get_use_cost(uint *buffer, size_t nkeys, uint key_size, + ulonglong max_in_memory_size, uint compare_factor, + bool intersect_fl, bool *in_memory); + inline static int get_cost_calc_buff_size(size_t nkeys, uint key_size, + ulonglong max_in_memory_size) + { + register ulonglong max_elems_in_tree= + max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size); + return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree)); + } + + void reset(); + bool walk(TABLE *table, tree_walk_action action, void *walk_action_arg); + + uint get_size() const { return size; } + ulonglong get_max_in_memory_size() const { return max_in_memory_size; } + + friend int unique_write_to_file(uchar* key, element_count count, Unique *unique); + friend int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique); + + friend int unique_write_to_file_with_count(uchar* key, element_count count, + Unique *unique); + friend int unique_intersect_write_to_ptrs(uchar* key, element_count count, + Unique *unique); +}; + +#endif /* UNIQUE_INCLUDED */ diff --git a/sql/unireg.cc b/sql/unireg.cc index 66959f400d9..f565fc97d86 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -874,7 +874,7 @@ static bool pack_fields(uchar *buff, List<Create_field> &create_fields, { *buff++= (uchar) (1 + MY_TEST(field->interval)); *buff++= (uchar) field->sql_type; - *buff++= (uchar) field->stored_in_db; + *buff++= (uchar) field->vcol_info->stored_in_db; if (field->interval) *buff++= (uchar) field->interval_id; memcpy(buff, field->vcol_info->expr_str.str, field->vcol_info->expr_str.length); @@ -921,9 +921,7 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values while ((field=it++)) { - /* - regfield don't have to be deleted as it's allocated with sql_alloc() - */ + /* regfield don't have to be deleted as it's allocated on THD::mem_root */ Field *regfield= make_field(&share, thd->mem_root, buff+field->offset + data_offset, field->length, diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index 477be1b55d1..cf1feb49f41 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -280,8 +280,8 @@ wsrep_cb_status_t wsrep_apply_cb(void* const ctx, TABLE *tmp; while ((tmp = thd->temporary_tables)) { - WSREP_DEBUG("Applier %lu, has temporary tables: %s.%s", - thd->thread_id, + WSREP_DEBUG("Applier %lld, has temporary tables: %s.%s", + (longlong) thd->thread_id, (tmp->s) ? tmp->s->db.str : "void", (tmp->s) ? tmp->s->table_name.str : "void"); close_temporary_table(thd, tmp, 1, 1); diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index 36917674128..7884df586a1 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -319,9 +319,9 @@ int wsrep_write_cache(wsrep_t* const wsrep, void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len) { char filename[PATH_MAX]= {0}; - int len= snprintf(filename, PATH_MAX, "%s/GRA_%ld_%lld.log", - wsrep_data_home_dir, thd->thread_id, - (long long)wsrep_thd_trx_seqno(thd)); + int len= snprintf(filename, PATH_MAX, "%s/GRA_%lld_%lld.log", + wsrep_data_home_dir, (longlong) thd->thread_id, + (longlong) wsrep_thd_trx_seqno(thd)); if (len >= PATH_MAX) { WSREP_ERROR("RBR dump path too long: %d, skipping dump.", len); @@ -374,9 +374,9 @@ int wsrep_binlog_savepoint_rollback(THD *thd, void *sv) void wsrep_dump_rbr_direct(THD* thd, IO_CACHE* cache) { char filename[PATH_MAX]= {0}; - int len= snprintf(filename, PATH_MAX, "%s/GRA_%ld_%lld.log", - wsrep_data_home_dir, thd->thread_id, - (long long)wsrep_thd_trx_seqno(thd)); + int len= snprintf(filename, PATH_MAX, "%s/GRA_%lld_%lld.log", + wsrep_data_home_dir, (longlong) thd->thread_id, + (longlong) wsrep_thd_trx_seqno(thd)); size_t bytes_in_cache = 0; // check path if (len >= PATH_MAX) @@ -448,8 +448,8 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void *rbr_buf, Log_event_writer writer(&cache); Format_description_log_event *ev= wsrep_get_apply_format(thd); - int len= my_snprintf(filename, PATH_MAX, "%s/GRA_%ld_%lld_v2.log", - wsrep_data_home_dir, thd->thread_id, + int len= my_snprintf(filename, PATH_MAX, "%s/GRA_%lld_%lld_v2.log", + wsrep_data_home_dir, (longlong) thd->thread_id, (long long) wsrep_thd_trx_seqno(thd)); if (len >= PATH_MAX) diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 3bce8ba7128..fa34a5bbc55 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -397,9 +397,9 @@ wsrep_run_wsrep_commit(THD *thd, bool all) &wtime); if (replay_round++ % 100000 == 0) - WSREP_DEBUG("commit waiting for replaying: replayers %d, thd: (%lu) " + WSREP_DEBUG("commit waiting for replaying: replayers %d, thd: %lld " "conflict: %d (round: %d)", - wsrep_replaying, thd->thread_id, + wsrep_replaying, (longlong) thd->thread_id, thd->wsrep_conflict_state, replay_round); mysql_mutex_unlock(&LOCK_wsrep_replaying); @@ -463,11 +463,11 @@ wsrep_run_wsrep_commit(THD *thd, bool all) if (WSREP_UNDEFINED_TRX_ID == thd->wsrep_ws_handle.trx_id) { - WSREP_WARN("SQL statement was ineffective, THD: %lu, buf: %zu\n" + WSREP_WARN("SQL statement was ineffective thd: %lld buf: %zu\n" "schema: %s \n" "QUERY: %s\n" " => Skipping replication", - thd->thread_id, data_len, + (longlong) thd->thread_id, data_len, (thd->db ? thd->db : "(null)"), thd->query()); rcode = WSREP_TRX_FAIL; } @@ -483,20 +483,22 @@ wsrep_run_wsrep_commit(THD *thd, bool all) &thd->wsrep_trx_meta); if (rcode == WSREP_TRX_MISSING) { - WSREP_WARN("Transaction missing in provider, thd: %ld, schema: %s, SQL: %s", - thd->thread_id, (thd->db ? thd->db : "(null)"), thd->query()); + WSREP_WARN("Transaction missing in provider, thd: %lld schema: %s SQL: %s", + (longlong) thd->thread_id, + (thd->db ? thd->db : "(null)"), thd->query()); rcode = WSREP_TRX_FAIL; } else if (rcode == WSREP_BF_ABORT) { - WSREP_DEBUG("thd %lu seqno %lld BF aborted by provider, will replay", - thd->thread_id, (long long)thd->wsrep_trx_meta.gtid.seqno); + WSREP_DEBUG("thd: %lld seqno: %lld BF aborted by provider, will replay", + (longlong) thd->thread_id, + (longlong) thd->wsrep_trx_meta.gtid.seqno); mysql_mutex_lock(&thd->LOCK_wsrep_thd); thd->wsrep_conflict_state = MUST_REPLAY; DBUG_ASSERT(wsrep_thd_trx_seqno(thd) > 0); mysql_mutex_unlock(&thd->LOCK_wsrep_thd); mysql_mutex_lock(&LOCK_wsrep_replaying); wsrep_replaying++; - WSREP_DEBUG("replaying increased: %d, thd: %lu", - wsrep_replaying, thd->thread_id); + WSREP_DEBUG("replaying increased: %d, thd: %lld", + wsrep_replaying, (longlong) thd->thread_id); mysql_mutex_unlock(&LOCK_wsrep_replaying); } } else { @@ -520,9 +522,9 @@ wsrep_run_wsrep_commit(THD *thd, bool all) if (thd->wsrep_conflict_state != NO_CONFLICT) { - WSREP_WARN("thd %lu seqno %lld: conflict state %d after post commit", - thd->thread_id, - (long long)thd->wsrep_trx_meta.gtid.seqno, + WSREP_WARN("thd: %llu seqno: %lld conflict state %d after post commit", + (longlong) thd->thread_id, + (longlong) thd->wsrep_trx_meta.gtid.seqno, thd->wsrep_conflict_state); } thd->wsrep_exec_mode= LOCAL_COMMIT; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 1d96176a70d..f84ebe4dbb9 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1566,8 +1566,8 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, if (thd->wsrep_conflict_state == MUST_ABORT) { - WSREP_INFO("thread: %lu, schema: %s, query: %s has been aborted due to multi-master conflict", - thd->thread_id, + WSREP_INFO("thread: %lld schema: %s query: %s has been aborted due to multi-master conflict", + (longlong) thd->thread_id, (thd->db ? thd->db : "(null)"), thd->query()); mysql_mutex_unlock(&thd->LOCK_wsrep_thd); @@ -1580,15 +1580,15 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, if (thd->global_read_lock.can_acquire_protection()) { - WSREP_DEBUG("Aborting TOI: Global Read-Lock (FTWRL) in place: %s %lu", - thd->query(), thd->thread_id); + WSREP_DEBUG("Aborting TOI: Global Read-Lock (FTWRL) in place: %s %lld", + thd->query(), (longlong) thd->thread_id); return -1; } if (wsrep_debug && thd->mdl_context.has_locks()) { - WSREP_DEBUG("thread holds MDL locks at TI begin: %s %lu", - thd->query(), thd->thread_id); + WSREP_DEBUG("thread holds MDL locks at TI begin: %s %lld", + thd->query(), (longlong) thd->thread_id); } /* @@ -1651,13 +1651,13 @@ void wsrep_to_isolation_end(THD *thd) WSREP_##severity( \ "%s\n" \ "schema: %.*s\n" \ - "request: (%lu \tseqno %lld \twsrep (%d, %d, %d) cmd %d %d \t%s)\n" \ - "granted: (%lu \tseqno %lld \twsrep (%d, %d, %d) cmd %d %d \t%s)", \ + "request: (%lld \tseqno %lld \twsrep (%d, %d, %d) cmd %d %d \t%s)\n" \ + "granted: (%lld \tseqno %lld \twsrep (%d, %d, %d) cmd %d %d \t%s)", \ msg, schema_len, schema, \ - req->thread_id, (long long)wsrep_thd_trx_seqno(req), \ + (longlong) req->thread_id, (long long)wsrep_thd_trx_seqno(req), \ req->wsrep_exec_mode, req->wsrep_query_state, req->wsrep_conflict_state, \ req->get_command(), req->lex->sql_command, req->query(), \ - gra->thread_id, (long long)wsrep_thd_trx_seqno(gra), \ + (longlong) gra->thread_id, (long long)wsrep_thd_trx_seqno(gra), \ gra->wsrep_exec_mode, gra->wsrep_query_state, gra->wsrep_conflict_state, \ gra->get_command(), gra->lex->sql_command, gra->query()); @@ -1757,8 +1757,9 @@ pthread_handler_t start_wsrep_THD(void *arg) goto error; } + thd->thread_id= next_thread_id(); + mysql_mutex_lock(&LOCK_thread_count); - thd->thread_id=thread_id++; if (wsrep_gtid_mode) { @@ -1859,14 +1860,15 @@ pthread_handler_t start_wsrep_THD(void *arg) // at server shutdown } - my_thread_end(); if (thread_handling > SCHEDULER_ONE_THREAD_PER_CONNECTION) { mysql_mutex_lock(&LOCK_thread_count); - delete thd; - thread_count--; + thd->unlink(); mysql_mutex_unlock(&LOCK_thread_count); + delete thd; + dec_thread_count(); } + my_thread_end(); return(NULL); error: @@ -1933,8 +1935,8 @@ static bool have_client_connections() I_List_iterator<THD> it(threads); while ((tmp=it++)) { - DBUG_PRINT("quit",("Informing thread %ld that it's time to die", - tmp->thread_id)); + DBUG_PRINT("quit",("Informing thread %lld that it's time to die", + (longlong) tmp->thread_id)); if (is_client_connection(tmp) && tmp->killed == KILL_CONNECTION) { (void)abort_replicated(tmp); @@ -2018,8 +2020,8 @@ void wsrep_close_client_connections(my_bool wait_to_end) I_List_iterator<THD> it(threads); while ((tmp=it++)) { - DBUG_PRINT("quit",("Informing thread %ld that it's time to die", - tmp->thread_id)); + DBUG_PRINT("quit",("Informing thread %lld that it's time to die", + (longlong) tmp->thread_id)); /* We skip slave threads & scheduler on this first loop through. */ if (!is_client_connection(tmp)) continue; @@ -2034,7 +2036,7 @@ void wsrep_close_client_connections(my_bool wait_to_end) if (abort_replicated(tmp)) continue; - WSREP_DEBUG("closing connection %ld", tmp->thread_id); + WSREP_DEBUG("closing connection %lld", (longlong) tmp->thread_id); wsrep_close_thread(tmp); } mysql_mutex_unlock(&LOCK_thread_count); @@ -2055,7 +2057,7 @@ void wsrep_close_client_connections(my_bool wait_to_end) !abort_replicated(tmp) && !is_replaying_connection(tmp)) { - WSREP_INFO("killing local connection: %ld",tmp->thread_id); + WSREP_INFO("killing local connection: %lld", (longlong) tmp->thread_id); close_connection(tmp,0); } #endif @@ -2080,7 +2082,7 @@ void wsrep_close_client_connections(my_bool wait_to_end) void wsrep_close_applier(THD *thd) { - WSREP_DEBUG("closing applier %ld", thd->thread_id); + WSREP_DEBUG("closing applier %lld", (longlong) thd->thread_id); wsrep_close_thread(thd); } @@ -2093,12 +2095,12 @@ void wsrep_close_threads(THD *thd) I_List_iterator<THD> it(threads); while ((tmp=it++)) { - DBUG_PRINT("quit",("Informing thread %ld that it's time to die", - tmp->thread_id)); + DBUG_PRINT("quit",("Informing thread %lld that it's time to die", + (longlong) tmp->thread_id)); /* We skip slave threads & scheduler on this first loop through. */ if (tmp->wsrep_applier && tmp != thd) { - WSREP_DEBUG("closing wsrep thread %ld", tmp->thread_id); + WSREP_DEBUG("closing wsrep thread %lld", (longlong) tmp->thread_id); wsrep_close_thread (tmp); } } diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 4f6cc51c3f8..6d04527cbcb 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -957,7 +957,7 @@ static int run_sql_command(THD *thd, const char *query) return -1; } - mysql_parse(thd, thd->query(), thd->query_length(), &ps); + mysql_parse(thd, thd->query(), thd->query_length(), &ps, FALSE); if (thd->is_error()) { int const err= thd->get_stmt_da()->sql_errno(); diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index fb48c1ad60e..3835c925745 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -50,8 +50,8 @@ int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff, /* must have (&thd->LOCK_wsrep_thd) */ void wsrep_client_rollback(THD *thd) { - WSREP_DEBUG("client rollback due to BF abort for (%ld), query: %s", - thd->thread_id, thd->query()); + WSREP_DEBUG("client rollback due to BF abort for (%lld), query: %s", + (longlong) thd->thread_id, thd->query()); WSREP_ATOMIC_ADD_LONG(&wsrep_bf_aborts_counter, 1); @@ -61,14 +61,16 @@ void wsrep_client_rollback(THD *thd) if (thd->locked_tables_mode && thd->lock) { - WSREP_DEBUG("unlocking tables for BF abort (%ld)", thd->thread_id); + WSREP_DEBUG("unlocking tables for BF abort (%lld)", + (longlong) thd->thread_id); thd->locked_tables_list.unlock_locked_tables(thd); thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); } if (thd->global_read_lock.is_acquired()) { - WSREP_DEBUG("unlocking GRL for BF abort (%ld)", thd->thread_id); + WSREP_DEBUG("unlocking GRL for BF abort (%lld)", + (longlong) thd->thread_id); thd->global_read_lock.unlock_global_read_lock(thd); } @@ -80,7 +82,8 @@ void wsrep_client_rollback(THD *thd) if (thd->get_binlog_table_maps()) { - WSREP_DEBUG("clearing binlog table map for BF abort (%ld)", thd->thread_id); + WSREP_DEBUG("clearing binlog table map for BF abort (%lld)", + (longlong) thd->thread_id); thd->clear_binlog_table_maps(); } mysql_mutex_lock(&thd->LOCK_wsrep_thd); @@ -202,8 +205,8 @@ void wsrep_replay_transaction(THD *thd) close_thread_tables(thd); if (thd->locked_tables_mode && thd->lock) { - WSREP_DEBUG("releasing table lock for replaying (%ld)", - thd->thread_id); + WSREP_DEBUG("releasing table lock for replaying (%lld)", + (longlong) thd->thread_id); thd->locked_tables_list.unlock_locked_tables(thd); thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); } @@ -242,8 +245,8 @@ void wsrep_replay_transaction(THD *thd) case WSREP_OK: thd->wsrep_conflict_state= NO_CONFLICT; wsrep->post_commit(wsrep, &thd->wsrep_ws_handle); - WSREP_DEBUG("trx_replay successful for: %ld %llu", - thd->thread_id, (long long)thd->real_id); + WSREP_DEBUG("trx_replay successful for: %lld %lld", + (longlong) thd->thread_id, (longlong) thd->real_id); if (thd->get_stmt_da()->is_sent()) { WSREP_WARN("replay ok, thd has reported status"); @@ -292,8 +295,8 @@ void wsrep_replay_transaction(THD *thd) mysql_mutex_lock(&LOCK_wsrep_replaying); wsrep_replaying--; - WSREP_DEBUG("replaying decreased: %d, thd: %lu", - wsrep_replaying, thd->thread_id); + WSREP_DEBUG("replaying decreased: %d, thd: %lld", + wsrep_replaying, (longlong) thd->thread_id); mysql_cond_broadcast(&COND_wsrep_replaying); mysql_mutex_unlock(&LOCK_wsrep_replaying); } @@ -360,10 +363,10 @@ static void wsrep_replication_process(THD *thd) TABLE *tmp; while ((tmp = thd->temporary_tables)) { - WSREP_WARN("Applier %lu, has temporary tables at exit: %s.%s", - thd->thread_id, - (tmp->s) ? tmp->s->db.str : "void", - (tmp->s) ? tmp->s->table_name.str : "void"); + WSREP_WARN("Applier %lld, has temporary tables at exit: %s.%s", + (longlong) thd->thread_id, + (tmp->s) ? tmp->s->db.str : "void", + (tmp->s) ? tmp->s->table_name.str : "void"); } wsrep_return_from_bf_mode(thd, &shadow); DBUG_VOID_RETURN; @@ -470,8 +473,9 @@ static void wsrep_rollback_process(THD *thd) mysql_mutex_lock(&aborting->LOCK_wsrep_thd); wsrep_client_rollback(aborting); - WSREP_DEBUG("WSREP rollbacker aborted thd: (%lu %llu)", - aborting->thread_id, (long long)aborting->real_id); + WSREP_DEBUG("WSREP rollbacker aborted thd: (%lld %lld)", + (longlong) aborting->thread_id, + (longlong) aborting->real_id); mysql_mutex_unlock(&aborting->LOCK_wsrep_thd); set_current_thd(thd); diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index ca07cc80a1a..c322c8eee54 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1645,7 +1645,7 @@ void ha_archive::update_create_info(HA_CREATE_INFO *create_info) } if (!(my_readlink(tmp_real_path, share->data_file_name, MYF(0)))) - create_info->data_file_name= sql_strdup(tmp_real_path); + create_info->data_file_name= thd_strdup(ha_thd(), tmp_real_path); DBUG_VOID_RETURN; } diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 3fa09044a71..d96d7455d8b 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1451,7 +1451,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) pcf->Flags |= U_NULLS; // Mark virtual columns as such - if (fp->vcol_info && !fp->stored_in_db) + if (!fp->stored_in_db()) pcf->Flags |= U_VIRTUAL; pcf->Key= 0; // Not used when called from MySQL @@ -1949,7 +1949,7 @@ int ha_connect::MakeRecord(char *buf) for (field= table->field; *field && !rc; field++) { fp= *field; - if (fp->vcol_info && !fp->stored_in_db) + if (!fp->stored_in_db()) continue; // This is a virtual column if (bitmap_is_set(map, fp->field_index) || alter) { @@ -2070,8 +2070,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *) for (Field **field=table->field ; *field ; field++) { fp= *field; - if ((fp->vcol_info && !fp->stored_in_db) || - fp->option_struct->special) + if (!fp->stored_in_db() || fp->option_struct->special) continue; // Is a virtual column possible here ??? if ((xmod == MODE_INSERT && tdbp->GetAmType() != TYPE_AM_MYSQL @@ -5997,7 +5996,7 @@ int ha_connect::create(const char *name, TABLE *table_arg, for (field= table_arg->field; *field; field++) { fp= *field; - if (fp->vcol_info && !fp->stored_in_db) + if (!fp->stored_in_db()) continue; // This is a virtual column if (fp->flags & AUTO_INCREMENT_FLAG) { diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 7ae962880d1..8c608e82388 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -83,6 +83,9 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG -DUNIV_SYNC_DEB #ENDIF() CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU) +IF(HAVE_SCHED_GETCPU) + ADD_DEFINITIONS(-DHAVE_SCHED_GETCPU) +ENDIF() IF(NOT MSVC) # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not @@ -240,11 +243,13 @@ IF(HAVE_IB_ATOMIC_PTHREAD_T_GCC) ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_GCC=1) ENDIF() -CHECK_C_SOURCE_COMPILES("struct t1{ int a; char *b; }; struct t1 c= { .a=1, .b=0 }; main() { }" HAVE_C99_INITIALIZERS) +CHECK_CXX_SOURCE_COMPILES("struct t1{ int a; char *b; }; struct t1 c= { .a=1, .b=0 }; main() { }" HAVE_C99_INITIALIZERS) +IF(HAVE_C99_INITIALIZERS) + ADD_DEFINITIONS(-DHAVE_C99_INITIALIZERS) +ENDIF() ENDIF(NOT MSVC) -CHECK_FUNCTION_EXISTS(asprintf HAVE_ASPRINTF) CHECK_FUNCTION_EXISTS(vasprintf HAVE_VASPRINTF) # Solaris atomics diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d9c2cef7d07..5edb6dc5190 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -786,16 +786,6 @@ innobase_map_isolation_level( /*=========================*/ enum_tx_isolation iso); /*!< in: MySQL isolation level code */ -/******************************************************************//** -Maps a MySQL trx isolation level code to the InnoDB isolation level code -@return InnoDB isolation level */ -static inline -ulint -innobase_map_isolation_level( -/*=========================*/ - enum_tx_isolation iso); /*!< in: MySQL isolation level code - */ - /*************************************************************//** Check for a valid value of innobase_compression_algorithm. @return 0 for valid innodb_compression_algorithm. */ @@ -7634,7 +7624,7 @@ ha_innobase::build_template( /* Push down an index condition or an end_range check. */ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { - while (!table->field[sql_idx]->stored_in_db) { + while (!table->field[sql_idx]->stored_in_db()) { sql_idx++; } @@ -7753,7 +7743,7 @@ ha_innobase::build_template( pushdown. */ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { - while (!table->field[sql_idx]->stored_in_db) { + while (!table->field[sql_idx]->stored_in_db()) { sql_idx++; } @@ -7793,7 +7783,7 @@ ha_innobase::build_template( for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { const Field* field; - while (!table->field[sql_idx]->stored_in_db) { + while (!table->field[sql_idx]->stored_in_db()) { sql_idx++; } @@ -8375,7 +8365,7 @@ calc_row_difference( for (sql_idx = 0; sql_idx < n_fields; sql_idx++) { field = table->field[sql_idx]; - if (!field->stored_in_db) + if (!field->stored_in_db()) continue; o_ptr = (const byte*) old_row + get_field_offset(table, field); @@ -8514,7 +8504,7 @@ calc_row_difference( } } } - if (field->stored_in_db) + if (field->stored_in_db()) innodb_idx++; } @@ -10731,7 +10721,7 @@ create_table_def( for (i = 0; i < n_cols; i++) { Field* field = form->field[i]; - if (!field->stored_in_db) + if (!field->stored_in_db()) continue; col_type = get_innobase_type_from_mysql_type(&unsigned_type, diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index c6e5f457f13..332c5f319fa 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -415,7 +415,7 @@ ha_innobase::check_if_supported_inplace_alter( const Field* field = table->field[i]; const dict_col_t* col = dict_table_get_nth_col(prebuilt->table, icol); ulint unsigned_flag; - if (!field->stored_in_db) + if (!field->stored_in_db()) continue; icol++; @@ -1263,7 +1263,7 @@ innobase_rec_to_mysql( ulint ilen; const uchar* ifield; - while (!((field= table->field[sql_idx])->stored_in_db)) + while (!((field= table->field[sql_idx])->stored_in_db())) sql_idx++; field->reset(); @@ -1316,7 +1316,7 @@ innobase_fields_to_mysql( Field* field; ulint ipos; - while (!((field= table->field[sql_idx])->stored_in_db)) + while (!((field= table->field[sql_idx])->stored_in_db())) sql_idx++; field->reset(); @@ -1365,7 +1365,7 @@ innobase_row_to_mysql( Field* field; const dfield_t* df = dtuple_get_nth_field(row, i); - while (!((field= table->field[sql_idx])->stored_in_db)) + while (!((field= table->field[sql_idx])->stored_in_db())) sql_idx++; field->reset(); @@ -1672,7 +1672,7 @@ innobase_fts_check_doc_id_col( for (i = 0; i < n_cols; i++, sql_idx++) { const Field* field; while (!((field= altered_table->field[sql_idx])-> - stored_in_db)) + stored_in_db())) sql_idx++; if (my_strcasecmp(system_charset_info, field->field_name, FTS_DOC_ID_COL_NAME)) { @@ -2541,7 +2541,7 @@ innobase_build_col_map( } while (const Create_field* new_field = cf_it++) { - if (!new_field->stored_in_db) + if (!new_field->stored_in_db()) { sql_idx++; continue; @@ -2550,7 +2550,7 @@ innobase_build_col_map( table->field[old_i]; old_i++) { const Field* field = table->field[old_i]; - if (!table->field[old_i]->stored_in_db) + if (!table->field[old_i]->stored_in_db()) continue; if (new_field->field == field) { col_map[old_innobase_i] = i; @@ -2928,7 +2928,7 @@ prepare_inplace_alter_table_dict( for (uint i = 0; i < altered_table->s->stored_fields; i++, sql_idx++) { const Field* field; while (!((field= altered_table->field[sql_idx])-> - stored_in_db)) + stored_in_db())) sql_idx++; ulint is_unsigned; ulint field_type @@ -4024,7 +4024,7 @@ func_exit: ha_alter_info->alter_info->create_list); while (const Create_field* new_field = cf_it++) { const Field* field; - if (!new_field->stored_in_db) { + if (!new_field->stored_in_db()) { i++; continue; } @@ -4033,7 +4033,7 @@ func_exit: DBUG_ASSERT(innodb_idx < altered_table->s->stored_fields); for (uint old_i = 0; table->field[old_i]; old_i++) { - if (!table->field[old_i]->stored_in_db) + if (!table->field[old_i]->stored_in_db()) continue; if (new_field->field == table->field[old_i]) { goto found_col; @@ -4733,7 +4733,7 @@ innobase_rename_columns_try( & Alter_inplace_info::ALTER_COLUMN_NAME); for (Field** fp = table->field; *fp; fp++, i++) { - if (!((*fp)->flags & FIELD_IS_RENAMED) || !((*fp)->stored_in_db)) { + if (!((*fp)->flags & FIELD_IS_RENAMED) || !((*fp)->stored_in_db())) { continue; } diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 5fdd2a920a5..844e8627939 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -255,7 +255,7 @@ static MYSQL_SYSVAR_ULONG(pagecache_file_hash_size, pagecache_file_hash_size, "value is probably 1/10 of number of possible open Aria files.", 0,0, 512, 128, 16384, 1); -static MYSQL_SYSVAR_SET(recover, maria_recover_options, PLUGIN_VAR_OPCMDARG, +static MYSQL_SYSVAR_SET(recover_options, maria_recover_options, PLUGIN_VAR_OPCMDARG, "Specifies how corrupted tables should be automatically repaired", NULL, NULL, HA_RECOVER_DEFAULT, &maria_recover_typelib); @@ -435,8 +435,8 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type, NullS) - name); /* TODO: switch from protocol to push_warning here. The main reason we didn't - it yet is parallel repair. Due to following trace: - ma_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr. + it yet is parallel repair, which threads have no THD object accessible via + current_thd. Also we likely need to lock mutex here (in both cases with protocol and push_warning). @@ -3494,7 +3494,7 @@ static int mark_recovery_start(const char* log_dir) DBUG_ENTER("mark_recovery_start"); if (!(maria_recover_options & HA_RECOVER_ANY)) ma_message_no_user(ME_JUST_WARNING, "Please consider using option" - " --aria-recover[=...] to automatically check and" + " --aria-recover-options[=...] to automatically check and" " repair tables when logs are removed by option" " --aria-force-start-after-recovery-failures=#"); if (recovery_failures >= force_start_after_recovery_failures) @@ -3701,7 +3701,7 @@ struct st_mysql_sys_var* system_variables[]= { MYSQL_SYSVAR(pagecache_buffer_size), MYSQL_SYSVAR(pagecache_division_limit), MYSQL_SYSVAR(pagecache_file_hash_size), - MYSQL_SYSVAR(recover), + MYSQL_SYSVAR(recover_options), MYSQL_SYSVAR(repair_threads), MYSQL_SYSVAR(sort_buffer_size), MYSQL_SYSVAR(stats_method), diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index bba99703119..ade91a159ca 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -1077,7 +1077,7 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache) { DBUG_PRINT("signal", ("thread %s %ld", last_thread->next->name, - last_thread->next->id)); + (ulong) last_thread->next->id)); pagecache_pthread_cond_signal(&last_thread->next->suspend); } } @@ -1341,7 +1341,8 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, */ if ((PAGECACHE_HASH_LINK *) thread->keycache_link == hash_link) { - DBUG_PRINT("signal", ("thread: %s %ld", thread->name, thread->id)); + DBUG_PRINT("signal", ("thread: %s %ld", thread->name, + (ulong) thread->id)); pagecache_pthread_cond_signal(&thread->suspend); wqueue_unlink_from_queue(&pagecache->waiting_for_block, thread); block->requests++; @@ -1579,7 +1580,7 @@ static inline void wait_for_readers(PAGECACHE *pagecache DBUG_ENTER("wait_for_readers"); DBUG_PRINT("wait", ("suspend thread: %s %ld block: %u", - thread->name, thread->id, + thread->name, (ulong) thread->id, PCBLOCK_NUMBER(pagecache, block))); block->condvar= &thread->suspend; pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); @@ -1604,7 +1605,7 @@ static void wait_for_flush(PAGECACHE *pagecache do { DBUG_PRINT("wait", - ("suspend thread %s %ld", thread->name, thread->id)); + ("suspend thread %s %ld", thread->name, (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -1671,7 +1672,8 @@ static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link) if (page->file.file == hash_link->file.file && page->pageno == hash_link->pageno) { - DBUG_PRINT("signal", ("thread %s %ld", thread->name, thread->id)); + DBUG_PRINT("signal", ("thread %s %ld", thread->name, + (ulong) thread->id)); pagecache_pthread_cond_signal(&thread->suspend); wqueue_unlink_from_queue(&pagecache->waiting_for_hash_link, thread); } @@ -1811,7 +1813,7 @@ restart: thread->keycache_link= (void *) &page; wqueue_link_into_queue(&pagecache->waiting_for_hash_link, thread); DBUG_PRINT("wait", - ("suspend thread %s %ld", thread->name, thread->id)); + ("suspend thread %s %ld", thread->name, (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); thread->keycache_link= NULL; @@ -1991,7 +1993,8 @@ restart: do { DBUG_PRINT("wait", - ("suspend thread %s %ld", thread->name, thread->id)); + ("suspend thread %s %ld", thread->name, + (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -2082,7 +2085,8 @@ restart: do { DBUG_PRINT("wait", - ("suspend thread %s %ld", thread->name, thread->id)); + ("suspend thread %s %ld", thread->name, + (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -2355,7 +2359,7 @@ static my_bool pagecache_wait_lock(PAGECACHE *pagecache, do { DBUG_PRINT("wait", - ("suspend thread %s %ld", thread->name, thread->id)); + ("suspend thread %s %ld", thread->name, (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -2755,7 +2759,8 @@ static void read_block(PAGECACHE *pagecache, do { DBUG_PRINT("wait", - ("suspend thread %s %ld", thread->name, thread->id)); + ("suspend thread %s %ld", thread->name, + (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -4549,7 +4554,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache, { DBUG_PRINT("wait", ("(1) suspend thread %s %ld", - thread->name, thread->id)); + thread->name, (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -4710,7 +4715,7 @@ restart: { DBUG_PRINT("wait", ("(2) suspend thread %s %ld", - thread->name, thread->id)); + thread->name, (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -4914,7 +4919,8 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache, do { DBUG_PRINT("wait", - ("suspend thread %s %ld", thread->name, thread->id)); + ("suspend thread %s %ld", thread->name, + (ulong) thread->id)); pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock); } @@ -5057,7 +5063,8 @@ static void pagecache_dump(PAGECACHE *pagecache) PAGECACHE_PAGE *page; uint i; - fprintf(pagecache_dump_file, "thread: %s %ld\n", thread->name, thread->id); + fprintf(pagecache_dump_file, "thread: %s %ld\n", thread->name, + (ulong) thread->id); i=0; thread=last=waiting_for_hash_link.last_thread; @@ -5069,7 +5076,7 @@ static void pagecache_dump(PAGECACHE *pagecache) page= (PAGECACHE_PAGE *) thread->keycache_link; fprintf(pagecache_dump_file, "thread: %s %ld, (file,pageno)=(%u,%lu)\n", - thread->name, thread->id, + thread->name, (ulong) thread->id, (uint) page->file.file,(ulong) page->pageno); if (++i == MAX_QUEUE_LEN) break; @@ -5086,7 +5093,7 @@ static void pagecache_dump(PAGECACHE *pagecache) hash_link= (PAGECACHE_HASH_LINK *) thread->keycache_link; fprintf(pagecache_dump_file, "thread: %s %u hash_link:%u (file,pageno)=(%u,%lu)\n", - thread->name, thread->id, + thread->name, (ulong) thread->id, (uint) PAGECACHE_HASH_LINK_NUMBER(pagecache, hash_link), (uint) hash_link->file.file,(ulong) hash_link->pageno); if (++i == MAX_QUEUE_LEN) @@ -5116,7 +5123,7 @@ static void pagecache_dump(PAGECACHE *pagecache) { thread=thread->next; fprintf(pagecache_dump_file, - "thread: %s %ld\n", thread->name, thread->id); + "thread: %s %ld\n", thread->name, (ulong) thread->id); if (++i == MAX_QUEUE_LEN) break; } diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp index a2ebbdeea95..144dbe0c530 100644 --- a/storage/mroonga/mrn_table.cpp +++ b/storage/mroonga/mrn_table.cpp @@ -1015,10 +1015,7 @@ TABLE_SHARE *mrn_get_table_share(TABLE_LIST *table_list, int *error) share = get_table_share(thd, table_list, key, key_length, 0, error, hash_value); #elif defined(MRN_HAVE_TDC_ACQUIRE_SHARE) - share = tdc_acquire_share(thd, table_list->db, table_list->table_name, key, - key_length, - table_list->mdl_request.key.tc_hash_value(), - GTS_TABLE, NULL); + share = tdc_acquire_share(thd, table_list, GTS_TABLE); #else share = get_table_share(thd, table_list, key, key_length, 0, error); #endif diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 72bc4c0c7fe..812166ce1cc 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -166,8 +166,8 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type, name); /* TODO: switch from protocol to push_warning here. The main reason we didn't - it yet is parallel repair. Due to following trace: - mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr. + it yet is parallel repair, which threads have no THD object accessible via + current_thd. Also we likely need to lock mutex here (in both cases with protocol and push_warning). @@ -637,7 +637,7 @@ void _mi_report_crashed(MI_INFO *file, const char *message, char buf[1024]; mysql_mutex_lock(&file->s->intern_lock); if ((cur_thd= (THD*) file->in_use.data)) - sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id, + sql_print_error("Got an error from thread_id=%lld, %s:%d", cur_thd->thread_id, sfile, sline); else sql_print_error("Got an error from unknown thread, %s:%d", sfile, sline); diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 05d5ef1d6ca..418e09547da 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -100,7 +100,7 @@ #include "../myisam/ha_myisam.h" #include "ha_myisammrg.h" #include "myrg_def.h" -#include "thr_malloc.h" // int_sql_alloc +#include "thr_malloc.h" // init_sql_alloc #include "sql_class.h" // THD #include "debug_sync.h" diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index dd61df5f861..dbe3241cfe8 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -1444,7 +1444,9 @@ static void register_statement_v1(const char *category, for (; count>0; count--, info++) { - DBUG_ASSERT(info->m_name != NULL); + if (info->m_name == NULL) + continue; + len= strlen(info->m_name); full_length= prefix_length + len; if (likely(full_length <= PFS_MAX_INFO_NAME_LENGTH)) diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc index c5c47064403..681a3fb144c 100644 --- a/storage/spider/spd_conn.cc +++ b/storage/spider/spd_conn.cc @@ -37,8 +37,6 @@ #include "spd_ping_table.h" #include "spd_malloc.h" -extern ulong *spd_db_att_thread_id; - extern handlerton *spider_hton_ptr; extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; pthread_mutex_t spider_conn_id_mutex; @@ -2269,9 +2267,7 @@ void *spider_bg_conn_action( my_thread_end(); DBUG_RETURN(NULL); } - pthread_mutex_lock(&LOCK_thread_count); - thd->thread_id = (*spd_db_att_thread_id)++; - pthread_mutex_unlock(&LOCK_thread_count); + thd->thread_id = next_thread_id(); #ifdef HAVE_PSI_INTERFACE mysql_thread_set_psi_id(thd->thread_id); #endif @@ -2782,9 +2778,7 @@ void *spider_bg_sts_action( #endif DBUG_RETURN(NULL); } - pthread_mutex_lock(&LOCK_thread_count); - thd->thread_id = (*spd_db_att_thread_id)++; - pthread_mutex_unlock(&LOCK_thread_count); + thd->thread_id = next_thread_id(); #ifdef HAVE_PSI_INTERFACE mysql_thread_set_psi_id(thd->thread_id); #endif @@ -3164,9 +3158,7 @@ void *spider_bg_crd_action( #endif DBUG_RETURN(NULL); } - pthread_mutex_lock(&LOCK_thread_count); - thd->thread_id = (*spd_db_att_thread_id)++; - pthread_mutex_unlock(&LOCK_thread_count); + thd->thread_id = next_thread_id(); #ifdef HAVE_PSI_INTERFACE mysql_thread_set_psi_id(thd->thread_id); #endif @@ -3653,9 +3645,7 @@ void *spider_bg_mon_action( my_thread_end(); DBUG_RETURN(NULL); } - pthread_mutex_lock(&LOCK_thread_count); - thd->thread_id = (*spd_db_att_thread_id)++; - pthread_mutex_unlock(&LOCK_thread_count); + thd->thread_id = next_thread_id(); #ifdef HAVE_PSI_INTERFACE mysql_thread_set_psi_id(thd->thread_id); #endif diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 9f46e55ca09..69a05dc94fb 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -737,7 +737,8 @@ int spider_db_errorno( "to %ld: %d %s\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - current_thd->thread_id, error_num, conn->db_conn->get_error()); + (ulong) current_thd->thread_id, error_num, + conn->db_conn->get_error()); } if (!conn->mta_conn_mutex_unlock_later) { @@ -757,7 +758,8 @@ int spider_db_errorno( "to %ld: %d %s\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - current_thd->thread_id, error_num, conn->db_conn->get_error()); + (ulong) current_thd->thread_id, error_num, + conn->db_conn->get_error()); } if (!conn->mta_conn_mutex_unlock_later) { diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 3f56d9a9d89..6215a5584d0 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -1717,7 +1717,7 @@ int spider_db_mysql::exec_query( l_time->tm_hour, l_time->tm_min, l_time->tm_sec, security_ctx->user ? security_ctx->user : "system user", security_ctx->host_or_ip, - thd->thread_id, + (ulong) thd->thread_id, tmp_query_str.c_ptr_safe()); } if (log_result_error_with_sql & 1) @@ -1731,7 +1731,7 @@ int spider_db_mysql::exec_query( "sql: %s\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - thd->thread_id, conn->tgt_host, db_conn->thread_id, + (ulong) thd->thread_id, conn->tgt_host, (ulong) db_conn->thread_id, tmp_query_str.c_ptr_safe()); } } @@ -1745,7 +1745,7 @@ int spider_db_mysql::exec_query( "affected_rows: %llu id: %llu status: %u warning_count: %u\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - conn->tgt_host, db_conn->thread_id, thd->thread_id, + conn->tgt_host, (ulong) db_conn->thread_id, (ulong) thd->thread_id, db_conn->affected_rows, db_conn->insert_id, db_conn->server_status, db_conn->warning_count); if (spider_param_log_result_errors() >= 3) @@ -1760,7 +1760,7 @@ int spider_db_mysql::exec_query( "affected_rows: %llu id: %llu status: %u warning_count: %u\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - conn->tgt_host, db_conn->thread_id, thd->thread_id, + conn->tgt_host, (ulong) db_conn->thread_id, (ulong) thd->thread_id, db_conn->affected_rows, db_conn->insert_id, db_conn->server_status, db_conn->warning_count); } @@ -1889,8 +1889,8 @@ void spider_db_mysql::print_warnings( "from [%s] %ld to %ld: %s %s %s\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - conn->tgt_host, db_conn->thread_id, - current_thd->thread_id, row[0], row[1], row[2]); + conn->tgt_host, (ulong) db_conn->thread_id, + (ulong) current_thd->thread_id, row[0], row[1], row[2]); row = mysql_fetch_row(res); } if (res) diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index fa712575610..d981dc6002b 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -41,7 +41,6 @@ #include "spd_direct_sql.h" #include "spd_malloc.h" -ulong *spd_db_att_thread_id; #ifdef SPIDER_XID_USES_xid_cache_iterate #else #ifdef XID_CACHE_IS_SPLITTED @@ -6327,8 +6326,6 @@ int spider_db_init( #ifdef _WIN32 HMODULE current_module = GetModuleHandle(NULL); - spd_db_att_thread_id = (ulong *) - GetProcAddress(current_module, "?thread_id@@3KA"); #ifdef SPIDER_XID_USES_xid_cache_iterate #else #ifdef XID_CACHE_IS_SPLITTED @@ -6362,7 +6359,6 @@ int spider_db_init( spd_abort_loop = (bool volatile *) GetProcAddress(current_module, "?abort_loop@@3_NC"); #else - spd_db_att_thread_id = &thread_id; #ifdef SPIDER_XID_USES_xid_cache_iterate #else #ifdef XID_CACHE_IS_SPLITTED @@ -8577,7 +8573,7 @@ int spider_discover_table_structure( DBUG_RETURN(ER_SPIDER_UNKNOWN_NUM); } #ifdef SPIDER_HAS_DISCOVER_TABLE_STRUCTURE_COMMENT - if (!(part_syntax = generate_partition_syntax(part_info, &part_syntax_len, + if (!(part_syntax = generate_partition_syntax(thd, part_info, &part_syntax_len, FALSE, TRUE, info, NULL, NULL))) #else if (!(part_syntax = generate_partition_syntax(part_info, &part_syntax_len, diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index d7127fa0084..b376265c1e7 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -2683,7 +2683,8 @@ int spider_initinal_xa_recover( FALSE, open_tables_backup, TRUE, &error_num)) ) goto error_open_table; - init_read_record(read_record, thd, table_xa, NULL, TRUE, FALSE, FALSE); + init_read_record(read_record, thd, table_xa, NULL, NULL, TRUE, FALSE, + FALSE); } SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); while ((!(read_record->read_record(read_record))) && cnt < (int) len) diff --git a/storage/tokudb/PerconaFT/CMakeLists.txt b/storage/tokudb/PerconaFT/CMakeLists.txt index 843b4c9d0e8..6e3aaee139b 100644 --- a/storage/tokudb/PerconaFT/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/CMakeLists.txt @@ -33,7 +33,7 @@ endif() include(TokuFeatureDetection) include(TokuSetupCompiler) -include(TokuSetupCTest) +#include(TokuSetupCTest) include(TokuThirdParty) set(TOKU_CMAKE_SCRIPT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake") diff --git a/storage/tokudb/PerconaFT/portability/toku_config.h.in b/storage/tokudb/PerconaFT/portability/toku_config.h.in index e1412cc9e14..9033f27fd25 100644 --- a/storage/tokudb/PerconaFT/portability/toku_config.h.in +++ b/storage/tokudb/PerconaFT/portability/toku_config.h.in @@ -78,6 +78,10 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #cmakedefine HAVE_O_DIRECT 1 #cmakedefine HAVE_F_NOCACHE 1 +#cmakedefine HAVE_MAP_ANONYMOUS 1 +#cmakedefine HAVE_MINCORE 1 +#cmakedefine HAVE_PR_SET_PTRACER 1 +#cmakedefine HAVE_PR_SET_PTRACER_ANY 1 #cmakedefine HAVE_MALLOC_SIZE 1 #cmakedefine HAVE_MALLOC_USABLE_SIZE 1 #cmakedefine HAVE_MEMALIGN 1 diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index 6ff879c9f1a..2e3542e6eb4 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -335,7 +335,7 @@ static inline bool do_ignore_flag_optimization(THD* thd, TABLE* table, bool opt_ static inline uint get_key_parts(const KEY *key) { #if (50609 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ - (100009 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199) + (100009 <= MYSQL_VERSION_ID) return key->user_defined_key_parts; #else return key->key_parts; @@ -1969,7 +1969,7 @@ int ha_tokudb::write_frm_data(DB* db, DB_TXN* txn, const char* frm_name) { size_t frm_len = 0; int error = 0; -#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199 +#if 100000 <= MYSQL_VERSION_ID error = table_share->read_frm_image((const uchar**)&frm_data,&frm_len); if (error) { goto cleanup; } #else @@ -2009,7 +2009,7 @@ int ha_tokudb::verify_frm_data(const char* frm_name, DB_TXN* txn) { HA_METADATA_KEY curr_key = hatoku_frm_data; // get the frm data from MySQL -#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199 +#if 100000 <= MYSQL_VERSION_ID error = table_share->read_frm_image((const uchar**)&mysql_frm_data,&mysql_frm_len); if (error) { goto cleanup; diff --git a/storage/tokudb/ha_tokudb_alter_56.cc b/storage/tokudb/ha_tokudb_alter_56.cc index a54bebc5420..9cf1affe0c5 100644 --- a/storage/tokudb/ha_tokudb_alter_56.cc +++ b/storage/tokudb/ha_tokudb_alter_56.cc @@ -156,7 +156,7 @@ static bool change_type_is_supported(TABLE *table, TABLE *altered_table, Alter_i static ulong fix_handler_flags(THD *thd, TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info) { ulong handler_flags = ha_alter_info->handler_flags; -#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199 +#if 100000 <= MYSQL_VERSION_ID // This is automatically supported, hide the flag from later checks handler_flags &= ~Alter_inplace_info::ALTER_PARTITIONED; #endif @@ -659,13 +659,13 @@ bool ha_tokudb::commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_i if (commit) { #if (50613 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ - (100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199) + (100000 <= MYSQL_VERSION_ID) if (ha_alter_info->group_commit_ctx) { ha_alter_info->group_commit_ctx = NULL; } #endif #if (50500 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50599) || \ - (100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199) + (100000 <= MYSQL_VERSION_ID) #if WITH_PARTITION_STORAGE_ENGINE if (TOKU_PARTITION_WRITE_FRM_DATA || altered_table->part_info == NULL) { #else diff --git a/storage/tokudb/hatoku_cmp.cc b/storage/tokudb/hatoku_cmp.cc index 001af657c1d..be0ea1e3ff3 100644 --- a/storage/tokudb/hatoku_cmp.cc +++ b/storage/tokudb/hatoku_cmp.cc @@ -54,7 +54,7 @@ static bool field_valid_for_tokudb_table(Field* field) { case MYSQL_TYPE_FLOAT: #if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ - (100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199) + (100000 <= MYSQL_VERSION_ID) case MYSQL_TYPE_DATETIME2: case MYSQL_TYPE_TIMESTAMP2: case MYSQL_TYPE_TIME2: @@ -203,7 +203,7 @@ static TOKU_TYPE mysql_to_toku_type (Field* field) { goto exit; #if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ - (100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199) + (100000 <= MYSQL_VERSION_ID) case MYSQL_TYPE_DATETIME2: case MYSQL_TYPE_TIMESTAMP2: case MYSQL_TYPE_TIME2: @@ -3167,7 +3167,7 @@ static bool fields_are_same_type(Field* a, Field* b) { case MYSQL_TYPE_TIMESTAMP: #if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ - (100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199) + (100000 <= MYSQL_VERSION_ID) case MYSQL_TYPE_DATETIME2: case MYSQL_TYPE_TIMESTAMP2: case MYSQL_TYPE_TIME2: diff --git a/storage/tokudb/hatoku_defines.h b/storage/tokudb/hatoku_defines.h index 3602e0b6b5a..83bf0f699c6 100644 --- a/storage/tokudb/hatoku_defines.h +++ b/storage/tokudb/hatoku_defines.h @@ -30,7 +30,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #pragma interface /* gcc class implementation */ #endif -#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199 +#if 100000 <= MYSQL_VERSION_ID #if !defined(TOKUDB_CHECK_JEMALLOC) #define TOKUDB_CHECK_JEMALLOC 1 diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 74e133ecffd..d97986f162b 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -103,7 +103,7 @@ static int tokudb_rollback_by_xid(handlerton* hton, XID* xid); static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *savepoint); static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint); static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoint); -#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199 +#if 100000 <= MYSQL_VERSION_ID static int tokudb_discover_table(handlerton *hton, THD* thd, TABLE_SHARE *ts); static int tokudb_discover_table_existence(handlerton *hton, const char *db, const char *name); #endif @@ -357,7 +357,7 @@ static int tokudb_init_func(void *p) { tokudb_hton->savepoint_rollback = tokudb_rollback_to_savepoint; tokudb_hton->savepoint_release = tokudb_release_savepoint; -#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199 +#if 100000 <= MYSQL_VERSION_ID tokudb_hton->discover_table = tokudb_discover_table; tokudb_hton->discover_table_existence = tokudb_discover_table_existence; #else @@ -1002,7 +1002,7 @@ static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoin TOKUDB_DBUG_RETURN(error); } -#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199 +#if 100000 <= MYSQL_VERSION_ID static int tokudb_discover_table(handlerton *hton, THD* thd, TABLE_SHARE *ts) { uchar *frmblob = 0; size_t frmlen; @@ -1047,7 +1047,7 @@ static int tokudb_discover3(handlerton *hton, THD* thd, const char *db, const ch DBT value = {}; bool do_commit = false; -#if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100199 +#if 100000 <= MYSQL_VERSION_ID tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); if (thd_sql_command(thd) == SQLCOM_CREATE_TABLE && trx && trx->sub_sp_level) { do_commit = false; diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt index 8d1bd543d0c..cdcdf0286e8 100644 --- a/storage/xtradb/CMakeLists.txt +++ b/storage/xtradb/CMakeLists.txt @@ -91,6 +91,9 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG -DUNIV_SYNC_DEB #ENDIF() CHECK_FUNCTION_EXISTS(sched_getcpu HAVE_SCHED_GETCPU) +IF(HAVE_SCHED_GETCPU) + ADD_DEFINITIONS(-DHAVE_SCHED_GETCPU) +ENDIF() IF(NOT MSVC) # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not @@ -249,11 +252,13 @@ IF(HAVE_IB_ATOMIC_PTHREAD_T_GCC) ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_GCC=1) ENDIF() -CHECK_C_SOURCE_COMPILES("struct t1{ int a; char *b; }; struct t1 c= { .a=1, .b=0 }; main() { }" HAVE_C99_INITIALIZERS) +CHECK_CXX_SOURCE_COMPILES("struct t1{ int a; char *b; }; struct t1 c= { .a=1, .b=0 }; main() { }" HAVE_C99_INITIALIZERS) +IF(HAVE_C99_INITIALIZERS) + ADD_DEFINITIONS(-DHAVE_C99_INITIALIZERS) +ENDIF() ENDIF(NOT MSVC) -CHECK_FUNCTION_EXISTS(asprintf HAVE_ASPRINTF) CHECK_FUNCTION_EXISTS(vasprintf HAVE_VASPRINTF) # Solaris atomics diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 065f1bd2ca0..b6d259c8bda 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -7960,7 +7960,7 @@ ha_innobase::build_template( /* Push down an index condition or an end_range check. */ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { - while (!table->field[sql_idx]->stored_in_db) { + while (!table->field[sql_idx]->stored_in_db()) { sql_idx++; } @@ -8079,7 +8079,7 @@ ha_innobase::build_template( pushdown. */ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { - while (!table->field[sql_idx]->stored_in_db) { + while (!table->field[sql_idx]->stored_in_db()) { sql_idx++; } @@ -8119,7 +8119,7 @@ ha_innobase::build_template( for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { const Field* field; - while (!table->field[sql_idx]->stored_in_db) { + while (!table->field[sql_idx]->stored_in_db()) { sql_idx++; } @@ -8730,7 +8730,7 @@ calc_row_difference( for (sql_idx = 0; sql_idx < n_fields; sql_idx++) { field = table->field[sql_idx]; - if (!field->stored_in_db) + if (!field->stored_in_db()) continue; o_ptr = (const byte*) old_row + get_field_offset(table, field); @@ -8868,7 +8868,7 @@ calc_row_difference( } } } - if (field->stored_in_db) + if (field->stored_in_db()) innodb_idx++; } @@ -11145,7 +11145,7 @@ create_table_def( for (i = 0; i < n_cols; i++) { Field* field = form->field[i]; - if (!field->stored_in_db) + if (!field->stored_in_db()) continue; col_type = get_innobase_type_from_mysql_type(&unsigned_type, diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index ea02463010c..c0d85451a9e 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -419,7 +419,7 @@ ha_innobase::check_if_supported_inplace_alter( const Field* field = table->field[i]; const dict_col_t* col = dict_table_get_nth_col(prebuilt->table, icol); ulint unsigned_flag; - if (!field->stored_in_db) + if (!field->stored_in_db()) continue; icol++; @@ -1266,7 +1266,7 @@ innobase_rec_to_mysql( ulint ilen; const uchar* ifield; - while (!((field= table->field[sql_idx])->stored_in_db)) + while (!((field= table->field[sql_idx])->stored_in_db())) sql_idx++; field->reset(); @@ -1319,7 +1319,7 @@ innobase_fields_to_mysql( Field* field; ulint ipos; - while (!((field= table->field[sql_idx])->stored_in_db)) + while (!((field= table->field[sql_idx])->stored_in_db())) sql_idx++; field->reset(); @@ -1368,7 +1368,7 @@ innobase_row_to_mysql( Field* field; const dfield_t* df = dtuple_get_nth_field(row, i); - while (!((field= table->field[sql_idx])->stored_in_db)) + while (!((field= table->field[sql_idx])->stored_in_db())) sql_idx++; field->reset(); @@ -1676,7 +1676,7 @@ innobase_fts_check_doc_id_col( for (i = 0; i < n_cols; i++, sql_idx++) { const Field* field; while (!((field= altered_table->field[sql_idx])-> - stored_in_db)) + stored_in_db())) sql_idx++; if (my_strcasecmp(system_charset_info, field->field_name, FTS_DOC_ID_COL_NAME)) { @@ -2545,7 +2545,7 @@ innobase_build_col_map( } while (const Create_field* new_field = cf_it++) { - if (!new_field->stored_in_db) + if (!new_field->stored_in_db()) { sql_idx++; continue; @@ -2554,7 +2554,7 @@ innobase_build_col_map( table->field[old_i]; old_i++) { const Field* field = table->field[old_i]; - if (!table->field[old_i]->stored_in_db) + if (!table->field[old_i]->stored_in_db()) continue; if (new_field->field == field) { col_map[old_innobase_i] = i; @@ -2929,7 +2929,7 @@ prepare_inplace_alter_table_dict( for (uint i = 0; i < altered_table->s->stored_fields; i++, sql_idx++) { const Field* field; while (!((field= altered_table->field[sql_idx])-> - stored_in_db)) + stored_in_db())) sql_idx++; ulint is_unsigned; ulint field_type @@ -4032,7 +4032,7 @@ func_exit: ha_alter_info->alter_info->create_list); while (const Create_field* new_field = cf_it++) { const Field* field; - if (!new_field->stored_in_db) { + if (!new_field->stored_in_db()) { i++; continue; } @@ -4041,7 +4041,7 @@ func_exit: DBUG_ASSERT(innodb_idx < altered_table->s->stored_fields); for (uint old_i = 0; table->field[old_i]; old_i++) { - if (!table->field[old_i]->stored_in_db) + if (!table->field[old_i]->stored_in_db()) continue; if (new_field->field == table->field[old_i]) { goto found_col; @@ -4740,7 +4740,7 @@ innobase_rename_columns_try( & Alter_inplace_info::ALTER_COLUMN_NAME); for (Field** fp = table->field; *fp; fp++, i++) { - if (!((*fp)->flags & FIELD_IS_RENAMED) || !((*fp)->stored_in_db)) { + if (!((*fp)->flags & FIELD_IS_RENAMED) || !((*fp)->stored_in_db())) { continue; } diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index d6a9695afbf..962931913a2 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -45,8 +45,6 @@ #define isbig5code(c,d) (isbig5head(c) && isbig5tail(d)) #define big5code(c,d) (((uchar)(c) <<8) | (uchar)(d)) -#define big5head(e) ((uchar)(e>>8)) -#define big5tail(e) ((uchar)(e&0xff)) #define MY_FUNCTION_NAME(x) my_ ## x ## _big5 #define IS_MB1_CHAR(x) ((uchar) (x) < 0x80) @@ -850,93 +848,6 @@ static uint16 big5strokexfrm(uint16 i) } -static size_t -my_strnxfrm_big5(CHARSET_INFO *cs, - uchar *dst, size_t dstlen, uint nweights, - const uchar *src, size_t srclen, uint flags) -{ - uchar *d0= dst; - uchar *de= dst + dstlen; - const uchar *se= src + srclen; - const uchar *sort_order= cs->sort_order; - - for (; dst < de && src < se && nweights; nweights--) - { - if (cs->cset->ismbchar(cs, (const char*) src, (const char*) se)) - { - /* - Note, it is safe not to check (src < se) - in the code below, because ismbchar() would - not return TRUE if src was too short - */ - uint16 e= big5strokexfrm((uint16) big5code(*src, *(src + 1))); - *dst++= big5head(e); - if (dst < de) - *dst++= big5tail(e); - src+= 2; - } - else - *dst++= sort_order ? sort_order[*src++] : *src++; - } - return my_strxfrm_pad_desc_and_reverse(cs, d0, dst, de, nweights, flags, 0); -} - -#if 0 -static int my_strcoll_big5(const uchar *s1, const uchar *s2) -{ - - while (*s1 && *s2) - { - if (*(s1+1) && *(s2+1) && isbig5code(*s1,*(s1+1)) && isbig5code(*s2, *(s2+1))) - { - if (*s1 != *s2 || *(s1+1) != *(s2+1)) - return ((int) big5code(*s1,*(s1+1)) - - (int) big5code(*s2,*(s2+1))); - s1 +=2; - s2 +=2; - } else if (sort_order_big5[(uchar) *s1++] != sort_order_big5[(uchar) *s2++]) - return ((int) sort_order_big5[(uchar) s1[-1]] - - (int) sort_order_big5[(uchar) s2[-1]]); - } - return 0; -} - -static int my_strxfrm_big5(uchar *dest, const uchar *src, int len) -{ - uint16 e; - uchar *d = dest; - - if (len < 1) return 0; - if (!*src) - { - *d = '\0'; - return 0; - } - while (*src && (len > 1)) - { - if (*(src+1) && isbig5code(*src, *(src+1))) - { - e = big5strokexfrm((uint16) big5code(*src, *(src+1))); - *d++ = big5head(e); - *d++ = big5tail(e); - src +=2; - len--; - } else - *d++ = sort_order_big5[(uchar) *src++]; - } - *d = '\0'; - return (int) (d-dest); -} -#endif - - -static uint ismbchar_big5(CHARSET_INFO *cs __attribute__((unused)), - const char* p, const char *e) -{ - return (isbig5head(*(p)) && (e)-(p)>1 && isbig5tail(*((p)+1))? 2: 0); -} - - static uint mbcharlen_big5(CHARSET_INFO *cs __attribute__((unused)), uint c) { return (isbig5head(c)? 2 : 1); @@ -6774,6 +6685,8 @@ my_mb_wc_big5(CHARSET_INFO *cs __attribute__((unused)), #define MY_FUNCTION_NAME(x) my_ ## x ## _big5_chinese_ci #define WEIGHT_MB1(x) (sort_order_big5[(uchar) (x)]) #define WEIGHT_MB2(x,y) (big5code(x, y)) +#define WEIGHT_MB2_FRM(x,y) (big5strokexfrm((uint16) WEIGHT_MB2(x, y))) +#define DEFINE_STRNXFRM #include "strcoll.ic" @@ -6788,7 +6701,7 @@ static MY_COLLATION_HANDLER my_collation_handler_big5_chinese_ci= NULL, /* init */ my_strnncoll_big5_chinese_ci, my_strnncollsp_big5_chinese_ci, - my_strnxfrm_big5, + my_strnxfrm_big5_chinese_ci, my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, @@ -6818,7 +6731,6 @@ static MY_COLLATION_HANDLER my_collation_handler_big5_bin= static MY_CHARSET_HANDLER my_charset_big5_handler= { NULL, /* init */ - ismbchar_big5, mbcharlen_big5, my_numchars_mb, my_charpos_mb, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 0be6ae95577..1027255af55 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -521,7 +521,6 @@ static MY_COLLATION_HANDLER my_collation_binary_handler = static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - NULL, /* ismbchar */ my_mbcharlen_8bit, /* mbcharlen */ my_numchars_8bit, my_charpos_8bit, diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 9bf206f1de7..2163662269d 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -191,12 +191,6 @@ static const uchar sort_order_cp932[]= #include "ctype-mb.ic" -static uint ismbchar_cp932(CHARSET_INFO *cs __attribute__((unused)), - const char* p, const char *e) -{ - return (iscp932head((uchar) *p) && (e-p)>1 && iscp932tail((uchar)p[1]) ? 2: 0); -} - static uint mbcharlen_cp932(CHARSET_INFO *cs __attribute__((unused)),uint c) { return (iscp932head((uchar) c) ? 2 : 1); @@ -34693,7 +34687,6 @@ static MY_COLLATION_HANDLER my_collation_handler_cp932_bin= static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - ismbchar_cp932, mbcharlen_cp932, my_numchars_mb, my_charpos_mb, diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 1f13ab66284..19ed586ea49 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -210,14 +210,6 @@ static const uchar sort_order_euc_kr[]= #include "ctype-mb.ic" -static uint ismbchar_euc_kr(CHARSET_INFO *cs __attribute__((unused)), - const char* p, const char *e) -{ - return ((*(uchar*)(p)<0x80)? 0:\ - iseuc_kr_head(*(p)) && (e)-(p)>1 && iseuc_kr_tail(*((p)+1))? 2:\ - 0); -} - static uint mbcharlen_euc_kr(CHARSET_INFO *cs __attribute__((unused)),uint c) { return (iseuc_kr_head(c) ? 2 : 1); @@ -9987,7 +9979,6 @@ static MY_COLLATION_HANDLER my_collation_handler_euckr_bin= static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - ismbchar_euc_kr, mbcharlen_euc_kr, my_numchars_mb, my_charpos_mb, diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c index 82c4bb5a4e8..52494b7dfb3 100644 --- a/strings/ctype-eucjpms.c +++ b/strings/ctype-eucjpms.c @@ -220,16 +220,6 @@ static const uchar sort_order_eucjpms[]= #include "strcoll.ic" -static uint ismbchar_eucjpms(CHARSET_INFO *cs __attribute__((unused)), - const char* p, const char *e) -{ - return ((*(uchar*)(p)<0x80)? 0:\ - iseucjpms(*(p)) && (e)-(p)>1 && iseucjpms(*((p)+1))? 2:\ - iseucjpms_ss2(*(p)) && (e)-(p)>1 && iskata(*((p)+1))? 2:\ - iseucjpms_ss3(*(p)) && (e)-(p)>2 && iseucjpms(*((p)+1)) && iseucjpms(*((p)+2))? 3:\ - 0); -} - static uint mbcharlen_eucjpms(CHARSET_INFO *cs __attribute__((unused)),uint c) { return (iseucjpms(c)? 2: iseucjpms_ss2(c)? 2: iseucjpms_ss3(c)? 3: 1); @@ -67520,7 +67510,6 @@ static MY_COLLATION_HANDLER my_collation_eucjpms_bin_handler = static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - ismbchar_eucjpms, mbcharlen_eucjpms, my_numchars_mb, my_charpos_mb, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index b0e275fe93d..a77237c1791 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -173,12 +173,6 @@ static const uchar sort_order_gb2312[]= #include "ctype-mb.ic" -static uint ismbchar_gb2312(CHARSET_INFO *cs __attribute__((unused)), - const char* p, const char *e) -{ - return (isgb2312head(*(p)) && (e)-(p)>1 && isgb2312tail(*((p)+1))? 2: 0); -} - static uint mbcharlen_gb2312(CHARSET_INFO *cs __attribute__((unused)),uint c) { return (isgb2312head(c)? 2 : 1); @@ -6391,7 +6385,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gb2312_bin= static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - ismbchar_gb2312, mbcharlen_gb2312, my_numchars_mb, my_charpos_mb, diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 37b003f1899..e4e015a59d2 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -3451,44 +3451,6 @@ static uint16 gbksortorder(uint16 i) } -static size_t -my_strnxfrm_gbk(CHARSET_INFO *cs, - uchar *dst, size_t dstlen, uint nweights, - const uchar *src, size_t srclen, uint flags) -{ - uchar *d0= dst; - uchar *de= dst + dstlen; - const uchar *se= src + srclen; - const uchar *sort_order= cs->sort_order; - - for (; dst < de && src < se && nweights; nweights--) - { - if (cs->cset->ismbchar(cs, (const char*) src, (const char*) se)) - { - /* - Note, it is safe not to check (src < se) - in the code below, because ismbchar() would - not return TRUE if src was too short - */ - uint16 e= gbksortorder((uint16) gbkcode(*src, *(src + 1))); - *dst++= gbkhead(e); - if (dst < de) - *dst++= gbktail(e); - src+= 2; - } - else - *dst++= sort_order ? sort_order[*src++] : *src++; - } - return my_strxfrm_pad_desc_and_reverse(cs, d0, dst, de, nweights, flags, 0); -} - - -static uint ismbchar_gbk(CHARSET_INFO *cs __attribute__((unused)), - const char* p, const char *e) -{ - return (isgbkhead(*(p)) && (e)-(p)>1 && isgbktail(*((p)+1))? 2: 0); -} - static uint mbcharlen_gbk(CHARSET_INFO *cs __attribute__((unused)),uint c) { return (isgbkhead(c)? 2 : 1); @@ -10658,6 +10620,7 @@ my_mb_wc_gbk(CHARSET_INFO *cs __attribute__((unused)), #define MY_FUNCTION_NAME(x) my_ ## x ## _gbk_chinese_ci #define WEIGHT_MB1(x) (sort_order_gbk[(uchar) (x)]) #define WEIGHT_MB2(x,y) (gbksortorder(gbkcode(x,y))) +#define DEFINE_STRNXFRM #include "strcoll.ic" @@ -10672,7 +10635,7 @@ static MY_COLLATION_HANDLER my_collation_handler_gbk_chinese_ci= NULL, /* init */ my_strnncoll_gbk_chinese_ci, my_strnncollsp_gbk_chinese_ci, - my_strnxfrm_gbk, + my_strnxfrm_gbk_chinese_ci, my_strnxfrmlen_simple, my_like_range_mb, my_wildcmp_mb, @@ -10703,7 +10666,6 @@ static MY_COLLATION_HANDLER my_collation_handler_gbk_bin= static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - ismbchar_gbk, mbcharlen_gbk, my_numchars_mb, my_charpos_mb, diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 26c66d60071..cf8f9bb7e28 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -396,7 +396,6 @@ int my_wc_mb_latin1(CHARSET_INFO *cs __attribute__((unused)), static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - NULL, my_mbcharlen_8bit, my_numchars_8bit, my_charpos_8bit, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index eef283d2925..9049596c7a4 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -668,7 +668,7 @@ my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), */ #define my_strnxfrm_mb_non_ascii_char(cs, dst, src, se) \ { \ - switch (cs->cset->ismbchar(cs, (const char*) src, (const char*) se)) { \ + switch (my_ismbchar(cs, (const char *) src, (const char *) se)) { \ case 4: \ *dst++= *src++; \ /* fall through */ \ @@ -740,8 +740,8 @@ my_strnxfrm_mb(CHARSET_INFO *cs, for (; src < se && nweights && dst < de; nweights--) { int chlen; - if (*src < 128 || - !(chlen= cs->cset->ismbchar(cs, (const char*) src, (const char*) se))) + if (*src < 128 || !(chlen= my_ismbchar(cs, (const char *) src, + (const char *) se))) { /* Single byte character */ *dst++= sort_order ? sort_order[*src++] : *src++; diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 288f5fdd49d..b205b1abc20 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1926,7 +1926,6 @@ my_strxfrm_pad_desc_and_reverse(CHARSET_INFO *cs, MY_CHARSET_HANDLER my_charset_8bit_handler= { my_cset_init_8bit, - NULL, /* ismbchar */ my_mbcharlen_8bit, /* mbcharlen */ my_numchars_8bit, my_charpos_8bit, diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 629e1cd8309..ebcea22d242 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -192,12 +192,6 @@ static const uchar sort_order_sjis[]= #include "ctype-mb.ic" -static uint ismbchar_sjis(CHARSET_INFO *cs __attribute__((unused)), - const char* p, const char *e) -{ - return (issjishead((uchar) *p) && (e-p)>1 && issjistail((uchar)p[1]) ? 2: 0); -} - static uint mbcharlen_sjis(CHARSET_INFO *cs __attribute__((unused)),uint c) { return (issjishead((uchar) c) ? 2 : 1); @@ -34072,7 +34066,6 @@ static MY_COLLATION_HANDLER my_collation_handler_sjis_bin= static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - ismbchar_sjis, mbcharlen_sjis, my_numchars_mb, my_charpos_mb, diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index a1ca320835d..6315b05ea96 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -860,7 +860,6 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - NULL, /* ismbchar */ my_mbcharlen_8bit, /* mbcharlen */ my_numchars_8bit, my_charpos_8bit, diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index cae85f38c12..74e474cc28c 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1413,15 +1413,6 @@ my_casedn_utf16(CHARSET_INFO *cs, char *src, size_t srclen, } -static uint -my_ismbchar_utf16(CHARSET_INFO *cs, const char *b, const char *e) -{ - my_wc_t wc; - int res= cs->cset->mb_wc(cs, &wc, (const uchar *) b, (const uchar *) e); - return (uint) (res > 0 ? res : 0); -} - - static int my_charlen_utf16(CHARSET_INFO *cs, const uchar *str, const uchar *end) { @@ -1456,7 +1447,7 @@ my_numchars_utf16(CHARSET_INFO *cs, size_t nchars= 0; for ( ; ; nchars++) { - size_t charlen= my_ismbchar_utf16(cs, b, e); + size_t charlen= my_ismbchar(cs, b, e); if (!charlen) break; b+= charlen; @@ -1576,7 +1567,6 @@ static MY_COLLATION_HANDLER my_collation_utf16_bin_handler = MY_CHARSET_HANDLER my_charset_utf16_handler= { NULL, /* init */ - my_ismbchar_utf16, /* ismbchar */ my_mbcharlen_utf16, /* mbcharlen */ my_numchars_utf16, my_charpos_utf16, @@ -1799,7 +1789,6 @@ static MY_COLLATION_HANDLER my_collation_utf16le_bin_handler = static MY_CHARSET_HANDLER my_charset_utf16le_handler= { NULL, /* init */ - my_ismbchar_utf16, my_mbcharlen_utf16, my_numchars_utf16, my_charpos_utf16, @@ -2075,15 +2064,6 @@ my_casedn_utf32(CHARSET_INFO *cs, char *src, size_t srclen, } -static uint -my_ismbchar_utf32(CHARSET_INFO *cs __attribute__((unused)), - const char *b, - const char *e) -{ - return b + 4 > e || !IS_UTF32_MBHEAD4(b[0], b[1]) ? 0 : 4; -} - - static int my_charlen_utf32(CHARSET_INFO *cs __attribute__((unused)), const uchar *b, const uchar *e) @@ -2545,7 +2525,6 @@ static MY_COLLATION_HANDLER my_collation_utf32_bin_handler = MY_CHARSET_HANDLER my_charset_utf32_handler= { NULL, /* init */ - my_ismbchar_utf32, my_mbcharlen_utf32, my_numchars_utf32, my_charpos_utf32, @@ -2883,14 +2862,6 @@ my_fill_ucs2(CHARSET_INFO *cs __attribute__((unused)), } -static uint my_ismbchar_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *b, - const char *e) -{ - return b + 2 > e ? 0 : 2; -} - - static uint my_mbcharlen_ucs2(CHARSET_INFO *cs __attribute__((unused)) , uint c __attribute__((unused))) { @@ -3032,7 +3003,6 @@ static MY_COLLATION_HANDLER my_collation_ucs2_bin_handler = MY_CHARSET_HANDLER my_charset_ucs2_handler= { NULL, /* init */ - my_ismbchar_ucs2, /* ismbchar */ my_mbcharlen_ucs2, /* mbcharlen */ my_numchars_ucs2, my_charpos_ucs2, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 308f5f0f7d1..67e68901573 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -219,16 +219,6 @@ static const uchar sort_order_ujis[]= #include "strcoll.ic" -static uint ismbchar_ujis(CHARSET_INFO *cs __attribute__((unused)), - const char* p, const char *e) -{ - return ((*(uchar*)(p)<0x80)? 0:\ - isujis(*(p)) && (e)-(p)>1 && isujis(*((p)+1))? 2:\ - isujis_ss2(*(p)) && (e)-(p)>1 && iskata(*((p)+1))? 2:\ - isujis_ss3(*(p)) && (e)-(p)>2 && isujis(*((p)+1)) && isujis(*((p)+2))? 3:\ - 0); -} - static uint mbcharlen_ujis(CHARSET_INFO *cs __attribute__((unused)),uint c) { return (isujis(c)? 2: isujis_ss2(c)? 2: isujis_ss3(c)? 3: 1); @@ -67264,7 +67254,6 @@ static MY_COLLATION_HANDLER my_collation_ujis_bin_handler = static MY_CHARSET_HANDLER my_charset_handler= { NULL, /* init */ - ismbchar_ujis, mbcharlen_ujis, my_numchars_mb, my_charpos_mb, diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index c0865157ad5..c0014b95d15 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -5426,12 +5426,6 @@ my_weight_mb3_utf8_general_mysql500_ci(uchar b0, uchar b1, uchar b2) #include "strcoll.ic" -static uint my_ismbchar_utf8(CHARSET_INFO *cs,const char *b, const char *e) -{ - int res= my_charlen_utf8(cs, (const uchar*) b, (const uchar*) e); - return (res>1) ? res : 0; -} - static uint my_mbcharlen_utf8(CHARSET_INFO *cs __attribute__((unused)), uint c) { @@ -5497,7 +5491,6 @@ static MY_COLLATION_HANDLER my_collation_utf8_bin_handler = MY_CHARSET_HANDLER my_charset_utf8_handler= { NULL, /* init */ - my_ismbchar_utf8, my_mbcharlen_utf8, my_numchars_mb, my_charpos_mb, @@ -7044,15 +7037,6 @@ my_charlen_filename(CHARSET_INFO *cs, const uchar *str, const uchar *end) } -static uint -my_ismbchar_filename(CHARSET_INFO *cs, const char *str, const char *end) -{ - my_wc_t wc; - int rc= my_mb_wc_filename(cs, &wc, (const uchar *) str, (const uchar *) end); - return rc > 1 ? rc : 0; -} - - #define MY_FUNCTION_NAME(x) my_ ## x ## _filename #define CHARLEN(cs,str,end) my_charlen_filename(cs,str,end) #define DEFINE_WELL_FORMED_CHAR_LENGTH_USING_CHARLEN @@ -7081,7 +7065,6 @@ static MY_COLLATION_HANDLER my_collation_filename_handler = static MY_CHARSET_HANDLER my_charset_filename_handler= { NULL, /* init */ - my_ismbchar_filename, my_mbcharlen_utf8, my_numchars_mb, my_charpos_mb, @@ -7793,14 +7776,6 @@ size_t my_well_formed_len_utf8mb4(CHARSET_INFO *cs, static uint -my_ismbchar_utf8mb4(CHARSET_INFO *cs, const char *b, const char *e) -{ - int res= my_charlen_utf8mb4(cs, (const uchar*) b, (const uchar*) e); - return (res > 1) ? res : 0; -} - - -static uint my_mbcharlen_utf8mb4(CHARSET_INFO *cs __attribute__((unused)), uint c) { if (c < 0x80) @@ -7852,7 +7827,6 @@ static MY_COLLATION_HANDLER my_collation_utf8mb4_bin_handler = MY_CHARSET_HANDLER my_charset_utf8mb4_handler= { NULL, /* init */ - my_ismbchar_utf8mb4, my_mbcharlen_utf8mb4, my_numchars_mb, my_charpos_mb, diff --git a/strings/decimal.c b/strings/decimal.c index 2353a8aefce..74d456c9c9f 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -283,7 +283,7 @@ static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result) from number for processing */ -int decimal_actual_fraction(decimal_t *from) +int decimal_actual_fraction(const decimal_t *from) { int frac= from->frac, i; dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1; diff --git a/strings/strcoll.ic b/strings/strcoll.ic index 4bced593a23..4ce362c1675 100644 --- a/strings/strcoll.ic +++ b/strings/strcoll.ic @@ -262,6 +262,45 @@ MY_FUNCTION_NAME(strnncollsp)(CHARSET_INFO *cs __attribute__((unused)), return 0; } + +#ifdef DEFINE_STRNXFRM +#ifndef WEIGHT_MB2_FRM +#define WEIGHT_MB2_FRM(x,y) WEIGHT_MB2(x,y) +#endif + +static size_t +MY_FUNCTION_NAME(strnxfrm)(CHARSET_INFO *cs, + uchar *dst, size_t dstlen, uint nweights, + const uchar *src, size_t srclen, uint flags) +{ + uchar *d0= dst; + uchar *de= dst + dstlen; + const uchar *se= src + srclen; + const uchar *sort_order= cs->sort_order; + + for (; dst < de && src < se && nweights; nweights--) + { + if (my_charlen(cs, (const char *) src, (const char *) se) > 1) + { + /* + Note, it is safe not to check (src < se) + in the code below, because my_charlen() would + not return 2 if src was too short + */ + uint16 e= WEIGHT_MB2_FRM(src[0], src[1]); + *dst++= (uchar) (e >> 8); + if (dst < de) + *dst++= (uchar) (e & 0xFF); + src+= 2; + } + else + *dst++= sort_order ? sort_order[*src++] : *src++; + } + return my_strxfrm_pad_desc_and_reverse(cs, d0, dst, de, nweights, flags, 0); +} +#endif /* DEFINE_STRNXFRM */ + + /* We usually include this file at least two times from the same source file, for the _ci and the _bin collations. Prepare for the second inclusion. @@ -273,3 +312,5 @@ MY_FUNCTION_NAME(strnncollsp)(CHARSET_INFO *cs __attribute__((unused)), #undef WEIGHT_MB3 #undef WEIGHT_MB4 #undef WEIGHT_PAD_SPACE +#undef WEIGHT_MB2_FRM +#undef DEFINE_STRNXFRM diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index bde146b2f21..7cc59f6aca5 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15385,7 +15385,7 @@ static void test_mysql_insert_id() myheader("test_mysql_insert_id"); - rc= mysql_query(mysql, "drop table if exists t1"); + rc= mysql_query(mysql, "drop table if exists t1,t2"); myquery(rc); /* table without auto_increment column */ rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))"); @@ -18748,8 +18748,11 @@ static void test_progress_reporting() myheader("test_progress_reporting"); - conn= client_connect(CLIENT_PROGRESS, MYSQL_PROTOCOL_TCP, 0); - DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS); + + conn= client_connect(CLIENT_PROGRESS_OBSOLETE, MYSQL_PROTOCOL_TCP, 0); + if (!(conn->server_capabilities & CLIENT_PROGRESS_OBSOLETE)) + return; + DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS_OBSOLETE); mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress); rc= mysql_query(conn, "set @save=@@global.progress_report_time"); |