From c06972bf2a9e9739c0eb926c6f750b8990fd4c17 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 May 2006 16:38:45 -0700 Subject: [PATCH 01/10] Bug #1039: tmpdir and datadir not available via @@ system variable syntax Bug #19606: ssl variables are not displayed in show variables Bug #19616: log_queries_not_using_indexes is not listed in show variables Make basedir, datadir, tmpdir, log_queries_not_using_indexes, ssl_ca, ssl_capath, ssl_cert, ssl_cipher, and ssl_key all available both from SHOW VARIABLES and as @@variables. As a side-effect of this change, log_queries_not_using_indexes can be changed at runtime (but only globally, not per-connection). include/sslopt-longopts.h: Put options in alphabetical order include/sslopt-vars.h: Allow define of SSL_VARS_NOT_STATIC to prevent variables from not being made static. mysql-test/r/variables.result: Add new results mysql-test/t/variables.test: Add new regression tests sql/mysql_priv.h: Add extern for opt_log_queries_not_using_indexes sql/mysqld.cc: Handle opt_log_queries_not_using_indexes as extern, and define SSL_VARS_NO_STATIC so they can be accessed outside of mysqld.cc sql/set_var.cc: Handle basedir, datadir, tmpdir, log_queries_not_using_indexes, and various ssl settings so that they are accessible as server variables and listed in SHOW VARIABLES. sql/set_var.h: Add new sys_var_constr_str_ptr class, for when we have a system variable that is only set via the command-line that is a pointer to a string. --- include/sslopt-longopts.h | 12 +++--- include/sslopt-vars.h | 17 ++++++--- mysql-test/r/variables.result | 28 ++++++++++++++ mysql-test/t/variables.test | 30 +++++++++++++++ sql/mysql_priv.h | 1 + sql/mysqld.cc | 3 +- sql/set_var.cc | 69 +++++++++++++++++++++++++++++++++-- sql/set_var.h | 29 +++++++++++++++ 8 files changed, 173 insertions(+), 16 deletions(-) diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h index dc3b0922327..99271571329 100644 --- a/include/sslopt-longopts.h +++ b/include/sslopt-longopts.h @@ -20,12 +20,6 @@ "Enable SSL for connection (automatically enabled with other flags). Disable with --skip-ssl.", (gptr*) &opt_use_ssl, (gptr*) &opt_use_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl).", - (gptr*) &opt_ssl_key, (gptr*) &opt_ssl_key, 0, GET_STR, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, - {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl).", - (gptr*) &opt_ssl_cert, (gptr*) &opt_ssl_cert, 0, GET_STR, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, {"ssl-ca", OPT_SSL_CA, "CA file in PEM format (check OpenSSL docs, implies --ssl).", (gptr*) &opt_ssl_ca, (gptr*) &opt_ssl_ca, 0, GET_STR, REQUIRED_ARG, @@ -34,8 +28,14 @@ "CA directory (check OpenSSL docs, implies --ssl).", (gptr*) &opt_ssl_capath, (gptr*) &opt_ssl_capath, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl).", + (gptr*) &opt_ssl_cert, (gptr*) &opt_ssl_cert, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use (implies --ssl).", (gptr*) &opt_ssl_cipher, (gptr*) &opt_ssl_cipher, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl).", + (gptr*) &opt_ssl_key, (gptr*) &opt_ssl_key, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, #endif /* HAVE_OPENSSL */ diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h index 164cf541381..3b9b10c82e7 100644 --- a/include/sslopt-vars.h +++ b/include/sslopt-vars.h @@ -15,10 +15,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_OPENSSL -static my_bool opt_use_ssl = 0; -static char *opt_ssl_key = 0; -static char *opt_ssl_cert = 0; -static char *opt_ssl_ca = 0; -static char *opt_ssl_capath = 0; -static char *opt_ssl_cipher = 0; +#ifdef SSL_VARS_NOT_STATIC +#define SSL_STATIC +#else +#define SSL_STATIC static +#endif +SSL_STATIC my_bool opt_use_ssl = 0; +SSL_STATIC char *opt_ssl_ca = 0; +SSL_STATIC char *opt_ssl_capath = 0; +SSL_STATIC char *opt_ssl_cert = 0; +SSL_STATIC char *opt_ssl_cipher = 0; +SSL_STATIC char *opt_ssl_key = 0; #endif diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 32cd8790874..70586a3e1e9 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -612,4 +612,32 @@ select @@version, @@version_comment, @@version_compile_machine, @@version_compile_os; @@version @@version_comment @@version_compile_machine @@version_compile_os # # # # +select @@basedir, @@datadir, @@tmpdir; +@@basedir @@datadir @@tmpdir +# # # +show variables like 'basedir'; +Variable_name Value +basedir # +show variables like 'datadir'; +Variable_name Value +datadir # +show variables like 'tmpdir'; +Variable_name Value +tmpdir # +select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key; +@@ssl_ca @@ssl_capath @@ssl_cert @@ssl_cipher @@ssl_key +# # # # # +show variables like 'ssl%'; +Variable_name Value +ssl_ca # +ssl_capath # +ssl_cert # +ssl_cipher # +ssl_key # +select @@log_queries_not_using_indexes; +@@log_queries_not_using_indexes +0 +show variables like 'log_queries_not_using_indexes'; +Variable_name Value +log_queries_not_using_indexes OFF End of 5.0 tests diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index d6bebe8b5cb..6a271a75e46 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -508,4 +508,34 @@ select @@system_time_zone; select @@version, @@version_comment, @@version_compile_machine, @@version_compile_os; +# +# Bug #1039: make tmpdir and datadir available as @@variables (also included +# basedir) +# +# Don't actually output, since it depends on the system +--replace_column 1 # 2 # 3 # +select @@basedir, @@datadir, @@tmpdir; +--replace_column 2 # +show variables like 'basedir'; +--replace_column 2 # +show variables like 'datadir'; +--replace_column 2 # +show variables like 'tmpdir'; + +# +# Bug #19606: make ssl settings available via SHOW VARIABLES and @@variables +# +# Don't actually output, since it depends on the system +--replace_column 1 # 2 # 3 # 4 # 5 # +select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key; +--replace_column 2 # +show variables like 'ssl%'; + +# +# Bug #19616: make log_queries_not_using_indexes available in SHOW VARIABLES +# and as @@log_queries_not_using_indexes +# +select @@log_queries_not_using_indexes; +show variables like 'log_queries_not_using_indexes'; + --echo End of 5.0 tests diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 779e2e277d5..399b861e8f4 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1185,6 +1185,7 @@ extern my_bool locked_in_memory; extern bool opt_using_transactions, mysqld_embedded; extern bool using_update_log, opt_large_files, server_id_supplied; extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log, opt_error_log; +extern my_bool opt_log_queries_not_using_indexes; extern bool opt_disable_networking, opt_skip_show_db; extern my_bool opt_character_set_client_handshake; extern bool volatile abort_loop, shutdown_in_progress, grant_option; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e84bcea8058..aa58617ee09 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -311,7 +311,6 @@ static bool volatile ready_to_exit; static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0; static my_bool opt_bdb, opt_isam, opt_ndbcluster; static my_bool opt_short_log_format= 0; -static my_bool opt_log_queries_not_using_indexes= 0; static uint kill_cached_threads, wake_thread; static ulong killed_threads, thread_created; static ulong max_used_connections; @@ -337,6 +336,7 @@ static my_bool opt_sync_bdb_logs; /* Global variables */ bool opt_log, opt_update_log, opt_bin_log, opt_slow_log; +my_bool opt_log_queries_not_using_indexes= 0; bool opt_error_log= IF_WIN(1,0); bool opt_disable_networking=0, opt_skip_show_db=0; my_bool opt_character_set_client_handshake= 1; @@ -603,6 +603,7 @@ my_bool opt_enable_shared_memory; HANDLE smem_event_connect_request= 0; #endif +#define SSL_VARS_NOT_STATIC #include "sslopt-vars.h" #ifdef HAVE_OPENSSL #include diff --git a/sql/set_var.cc b/sql/set_var.cc index 215d3cfc879..003dd4a8ab3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -122,6 +122,7 @@ static byte *get_error_count(THD *thd); static byte *get_warning_count(THD *thd); static byte *get_prepared_stmt_count(THD *thd); static byte *get_have_innodb(THD *thd); +static byte *get_tmpdir(THD *thd); /* Variable definition list @@ -138,6 +139,7 @@ sys_var_thd_ulong sys_auto_increment_offset("auto_increment_offset", sys_var_bool_ptr sys_automatic_sp_privileges("automatic_sp_privileges", &sp_automatic_privileges); +sys_var_const_str sys_basedir("basedir", mysql_home); sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size", &binlog_cache_size); sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size", @@ -161,6 +163,7 @@ sys_var_long_ptr sys_concurrent_insert("concurrent_insert", &myisam_concurrent_insert); sys_var_long_ptr sys_connect_timeout("connect_timeout", &connect_timeout); +sys_var_const_str sys_datadir("datadir", mysql_real_data_home); sys_var_enum sys_delay_key_write("delay_key_write", &delay_key_write_options, &delay_key_write_typelib, @@ -208,6 +211,9 @@ sys_trust_routine_creators("log_bin_trust_routine_creators", sys_var_bool_ptr sys_trust_function_creators("log_bin_trust_function_creators", &trust_function_creators); +sys_var_bool_ptr + sys_log_queries_not_using_indexes("log_queries_not_using_indexes", + &opt_log_queries_not_using_indexes); sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings); sys_var_thd_ulong sys_long_query_time("long_query_time", &SV::long_query_time); @@ -331,6 +337,7 @@ sys_var_thd_ulong sys_query_alloc_block_size("query_alloc_block_size", sys_var_thd_ulong sys_query_prealloc_size("query_prealloc_size", &SV::query_prealloc_size, 0, fix_thd_mem_root); +sys_var_readonly sys_tmpdir("tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir); sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size", &SV::trans_alloc_block_size, 0, fix_trans_mem_root); @@ -367,6 +374,21 @@ sys_var_thd_ulong sys_sort_buffer("sort_buffer_size", &SV::sortbuff_size); sys_var_thd_sql_mode sys_sql_mode("sql_mode", &SV::sql_mode); +#ifdef HAVE_OPENSSL +extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, + *opt_ssl_key; +sys_var_const_str_ptr sys_ssl_ca("ssl_ca", &opt_ssl_ca); +sys_var_const_str_ptr sys_ssl_capath("ssl_capath", &opt_ssl_capath); +sys_var_const_str_ptr sys_ssl_cert("ssl_cert", &opt_ssl_cert); +sys_var_const_str_ptr sys_ssl_cipher("ssl_cipher", &opt_ssl_cipher); +sys_var_const_str_ptr sys_ssl_key("ssl_key", &opt_ssl_key); +#else +sys_var_const_str sys_ssl_ca("ssl_ca", NULL); +sys_var_const_str sys_ssl_capath("ssl_capath", NULL); +sys_var_const_str sys_ssl_cert("ssl_cert", NULL); +sys_var_const_str sys_ssl_cipher("ssl_cipher", NULL); +sys_var_const_str sys_ssl_key("ssl_key", NULL); +#endif sys_var_thd_enum sys_updatable_views_with_limit("updatable_views_with_limit", &SV::updatable_views_with_limit, @@ -582,6 +604,7 @@ sys_var *sys_variables[]= &sys_auto_increment_offset, &sys_autocommit, &sys_automatic_sp_privileges, + &sys_basedir, &sys_big_tables, &sys_big_selects, &sys_binlog_cache_size, @@ -600,6 +623,7 @@ sys_var *sys_variables[]= &sys_completion_type, &sys_concurrent_insert, &sys_connect_timeout, + &sys_datadir, &sys_date_format, &sys_datetime_format, &sys_div_precincrement, @@ -631,6 +655,7 @@ sys_var *sys_variables[]= &sys_local_infile, &sys_log_binlog, &sys_log_off, + &sys_log_queries_not_using_indexes, &sys_log_update, &sys_log_warnings, &sys_long_query_time, @@ -710,6 +735,11 @@ sys_var *sys_variables[]= &sys_sql_mode, &sys_sql_warnings, &sys_sql_notes, + &sys_ssl_ca, + &sys_ssl_capath, + &sys_ssl_cert, + &sys_ssl_cipher, + &sys_ssl_key, &sys_storage_engine, #ifdef HAVE_REPLICATION &sys_sync_binlog_period, @@ -724,6 +754,7 @@ sys_var *sys_variables[]= &sys_timed_mutexes, &sys_timestamp, &sys_time_zone, + &sys_tmpdir, &sys_tmp_table_size, &sys_trans_alloc_block_size, &sys_trans_prealloc_size, @@ -775,7 +806,7 @@ struct show_var_st init_vars[]= { {"auto_increment_offset", (char*) &sys_auto_increment_offset, SHOW_SYS}, {sys_automatic_sp_privileges.name,(char*) &sys_automatic_sp_privileges, SHOW_SYS}, {"back_log", (char*) &back_log, SHOW_LONG}, - {"basedir", mysql_home, SHOW_CHAR}, + {sys_basedir.name, (char*) &sys_basedir, SHOW_SYS}, #ifdef HAVE_BERKELEY_DB {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG}, {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR}, @@ -801,7 +832,7 @@ struct show_var_st init_vars[]= { {sys_completion_type.name, (char*) &sys_completion_type, SHOW_SYS}, {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS}, {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, - {"datadir", mysql_real_data_home, SHOW_CHAR}, + {sys_datadir.name, (char*) &sys_datadir, SHOW_SYS}, {sys_date_format.name, (char*) &sys_date_format, SHOW_SYS}, {sys_datetime_format.name, (char*) &sys_datetime_format, SHOW_SYS}, {sys_default_week_format.name, (char*) &sys_default_week_format, SHOW_SYS}, @@ -899,6 +930,8 @@ struct show_var_st init_vars[]= { {"log_bin", (char*) &opt_bin_log, SHOW_BOOL}, {sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS}, {"log_error", (char*) log_error_file, SHOW_CHAR}, + {sys_log_queries_not_using_indexes.name, + (char*) &sys_log_queries_not_using_indexes, SHOW_SYS}, #ifdef HAVE_REPLICATION {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL}, #endif @@ -1017,6 +1050,11 @@ struct show_var_st init_vars[]= { {sys_sql_mode.name, (char*) &sys_sql_mode, SHOW_SYS}, {"sql_notes", (char*) &sys_sql_notes, SHOW_SYS}, {"sql_warnings", (char*) &sys_sql_warnings, SHOW_SYS}, + {sys_ssl_ca.name, (char*) &sys_ssl_ca, SHOW_SYS}, + {sys_ssl_capath.name, (char*) &sys_ssl_capath, SHOW_SYS}, + {sys_ssl_cert.name, (char*) &sys_ssl_cert, SHOW_SYS}, + {sys_ssl_cipher.name, (char*) &sys_ssl_cipher, SHOW_SYS}, + {sys_ssl_key.name, (char*) &sys_ssl_key, SHOW_SYS}, {sys_storage_engine.name, (char*) &sys_storage_engine, SHOW_SYS}, #ifdef HAVE_REPLICATION {sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period, SHOW_SYS}, @@ -1037,7 +1075,7 @@ struct show_var_st init_vars[]= { {"time_zone", (char*) &sys_time_zone, SHOW_SYS}, {sys_timed_mutexes.name, (char*) &sys_timed_mutexes, SHOW_SYS}, {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS}, - {"tmpdir", (char*) &opt_mysql_tmpdir, SHOW_CHAR_PTR}, + {sys_tmpdir.name, (char*) &sys_tmpdir, SHOW_SYS}, {sys_trans_alloc_block_size.name, (char*) &sys_trans_alloc_block_size, SHOW_SYS}, {sys_trans_prealloc_size.name, (char*) &sys_trans_prealloc_size, SHOW_SYS}, @@ -2863,6 +2901,31 @@ static byte *get_prepared_stmt_count(THD *thd) return (byte*) &thd->sys_var_tmp.ulong_value; } + +/* + Get the tmpdir that was specified or chosen by default + + SYNOPSIS + get_tmpdir() + thd thread handle + + DESCRIPTION + This is necessary because if the user does not specify a temporary + directory via the command line, one is chosen based on the environment + or system defaults. But we can't just always use mysql_tmpdir, because + that is actually a call to my_tmpdir() which cycles among possible + temporary directories. + + RETURN VALUES + ptr pointer to NUL-terminated string + */ +static byte *get_tmpdir(THD *thd) +{ + if (opt_mysql_tmpdir) + return (byte *)opt_mysql_tmpdir; + return (byte*)mysql_tmpdir; +} + /**************************************************************************** Main handling of variables: - Initialisation diff --git a/sql/set_var.h b/sql/set_var.h index 646a578ca36..8e5a94b1e1b 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -222,6 +222,35 @@ public: }; +class sys_var_const_str_ptr :public sys_var +{ +public: + char **value; // Pointer to const value + sys_var_const_str_ptr(const char *name_arg, char **value_arg) + :sys_var(name_arg),value(value_arg) + {} + bool check(THD *thd, set_var *var) + { + return 1; + } + bool update(THD *thd, set_var *var) + { + return 1; + } + SHOW_TYPE type() { return SHOW_CHAR; } + byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) + { + return (byte*) *value; + } + bool check_update_type(Item_result type) + { + return 1; + } + bool check_default(enum_var_type type) { return 1; } + bool is_readonly() const { return 1; } +}; + + class sys_var_enum :public sys_var { uint *value; From 5d023fa574310acf5025893035d6e74944207f35 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 15 May 2006 11:56:02 +0400 Subject: [PATCH 02/10] Fix possible race. Use LOCK_grant on access to grant_version. sql/sql_acl.cc: Use LOCK_grant on access to grant_version. --- sql/sql_acl.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d66a631dbcc..a4d46244ad4 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -6009,20 +6009,21 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, } /* table privileges */ + rw_rdlock(&LOCK_grant); if (grant->version != grant_version) { - rw_rdlock(&LOCK_grant); grant->grant_table= table_hash_search(sctx->host, sctx->ip, db, sctx->priv_user, table, 0); /* purecov: inspected */ grant->version= grant_version; /* purecov: inspected */ - rw_unlock(&LOCK_grant); } if (grant->grant_table != 0) { grant->privilege|= grant->grant_table->privs; } + rw_unlock(&LOCK_grant); + DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); DBUG_VOID_RETURN; } From 90ffe5392ac7d697238d4269cbf2f7cd0b269868 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 15 May 2006 18:18:37 +0400 Subject: [PATCH 03/10] Remove 'const' that prevents Microsoft VC realize that Item_trigger_field::set_required_privilege(const bool rw) is an overloading of Settable_routine_parameter::set_required_privilege(bool rw). --- sql/item.cc | 2 +- sql/item.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index fbdb0aa687b..7d0847dabaa 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5365,7 +5365,7 @@ bool Item_trigger_field::eq(const Item *item, bool binary_cmp) const } -void Item_trigger_field::set_required_privilege(const bool rw) +void Item_trigger_field::set_required_privilege(bool rw) { /* Require SELECT and UPDATE privilege if this field will be read and diff --git a/sql/item.h b/sql/item.h index 617690e1fd9..ee8ac829515 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2187,7 +2187,7 @@ public: void cleanup(); private: - void set_required_privilege(const bool rw); + void set_required_privilege(bool rw); bool set_value(THD *thd, sp_rcontext *ctx, Item *it); public: From ce7a7b20d1afa0fb1ba0e85430114193ba45cbdd Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 15 May 2006 19:53:29 +0200 Subject: [PATCH 04/10] ndb - bug#19537: arithmetic conversion Uint64 reg to Uint32 attr ndb/test/ndbapi/Makefile.am: enable testInterpreter ndb/test/ndbapi/testInterpreter.cpp: add test case Bug19537 the bug fix also fixed IncValue64 for whatever reason.. ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp: bug#19537: write_attr: perform arithmetic conversion Uint64 to Uint32 --- .../kernel/blocks/dbtup/DbtupExecQuery.cpp | 6 + ndb/test/ndbapi/Makefile.am | 3 + ndb/test/ndbapi/testInterpreter.cpp | 202 ++++++++++++++---- 3 files changed, 171 insertions(+), 40 deletions(-) diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 8e3ca6528c2..8171fa65771 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -1494,6 +1494,7 @@ int Dbtup::interpreterNextLab(Signal* signal, // word read. Thus we set the register to be a 32 bit register. /* ------------------------------------------------------------- */ TregMemBuffer[theRegister] = 0x50; + // arithmetic conversion if big-endian * (Int64*)(TregMemBuffer+theRegister+2) = TregMemBuffer[theRegister+1]; } else if (TnoDataRW == 3) { /* ------------------------------------------------------------- */ @@ -1557,6 +1558,11 @@ int Dbtup::interpreterNextLab(Signal* signal, Tlen = TattrNoOfWords + 1; if (Toptype == ZUPDATE) { if (TattrNoOfWords <= 2) { + if (TattrNoOfWords == 1) { + // arithmetic conversion if big-endian + TdataForUpdate[1] = *(Int64*)&TregMemBuffer[theRegister + 2]; + TdataForUpdate[2] = 0; + } if (TregType == 0) { /* --------------------------------------------------------- */ // Write a NULL value into the attribute diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am index 7b4a96f5890..29bbbb74422 100644 --- a/ndb/test/ndbapi/Makefile.am +++ b/ndb/test/ndbapi/Makefile.am @@ -24,6 +24,7 @@ testOIBasic \ testOperations \ testRestartGci \ testScan \ +testInterpreter \ testScanInterpreter \ testScanPerf \ testSystemRestart \ @@ -61,6 +62,7 @@ testOIBasic_SOURCES = testOIBasic.cpp testOperations_SOURCES = testOperations.cpp testRestartGci_SOURCES = testRestartGci.cpp testScan_SOURCES = testScan.cpp ScanFunctions.hpp +testInterpreter_SOURCES = testInterpreter.cpp testScanInterpreter_SOURCES = testScanInterpreter.cpp ScanFilter.hpp ScanInterpretTest.hpp testScanPerf_SOURCES = testScanPerf.cpp testSystemRestart_SOURCES = testSystemRestart.cpp @@ -152,3 +154,4 @@ testScan.dsp: Makefile \ @$(top_srcdir)/ndb/config/win-includes $@ $(INCLUDES) @$(top_srcdir)/ndb/config/win-sources $@ $(testScan_SOURCES) @$(top_srcdir)/ndb/config/win-libraries $@ LINK $(LDADD) + diff --git a/ndb/test/ndbapi/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter.cpp index 0baba33d2b2..5d930d3d555 100644 --- a/ndb/test/ndbapi/testInterpreter.cpp +++ b/ndb/test/ndbapi/testInterpreter.cpp @@ -79,46 +79,46 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); - NdbConnection* pTrans = pNdb->startTransaction(); - if (pTrans == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName()); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - int check = pOp->interpretedUpdateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - - // Primary keys - Uint32 pkVal = 1; - check = pOp->equal("KOL1", pkVal ); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - // Attributes - - // Update column - Uint32 valToIncWith = 1; - check = pOp->incValue("KOL2", valToIncWith); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } + NdbConnection* pTrans = pNdb->startTransaction(); + if (pTrans == NULL){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + int check = pOp->interpretedUpdateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + // Primary keys + Uint32 pkVal = 1; + check = pOp->equal("KOL1", pkVal ); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Attributes + + // Update column + Uint32 valToIncWith = 1; + check = pOp->incValue("KOL2", valToIncWith); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } NdbRecAttr* valueRec = pOp->getValue("KOL2"); if( valueRec == NULL ) { @@ -142,6 +142,122 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table * pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + if (strcmp(pTab->getName(), "T1") != 0) { + g_err << "runTestBug19537: skip, table != T1" << endl; + return NDBT_OK; + } + + + NdbConnection* pTrans = pNdb->startTransaction(); + if (pTrans == NULL){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (pOp->interpretedUpdateTuple() == -1) { + ERR(pOp->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + // Primary keys + const Uint32 pkVal = 1; + if (pOp->equal("KOL1", pkVal) == -1) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Load 64-bit constant into register 1 and + // write from register 1 to 32-bit column KOL2 + const Uint64 reg_val = 0x0102030405060708ULL; + + const Uint32* reg_ptr32 = (const Uint32*)®_val; + if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) { + g_err << "runTestBug19537: platform is LITTLE endian" << endl; + } else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) { + g_err << "runTestBug19537: platform is BIG endian" << endl; + } else { + g_err << "runTestBug19537: impossible platform" + << hex << " [0]=" << reg_ptr32[0] << " [1]=" <closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (pOp->load_const_u64(1, reg_val) == -1 || + pOp->write_attr("KOL2", 1) == -1) { + ERR(pOp->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (pTrans->execute(Commit) == -1) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Read value via a new transaction + + pTrans = pNdb->startTransaction(); + if (pTrans == NULL){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + pOp = pTrans->getNdbOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 kol2 = 0x09090909; + if (pOp->readTuple() == -1 || + pOp->equal("KOL1", pkVal) == -1 || + pOp->getValue("KOL2", (char*)&kol2) == 0) { + ERR(pOp->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (pTrans->execute(Commit) == -1) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Expected conversion as in C - truncate to lower (logical) word + + if (kol2 == 0x01020304) { + g_err << "runTestBug19537: the bug manifests itself !" << endl; + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (kol2 != 0x05060708) { + g_err << "runTestBug19537: impossible KOL2 " << hex << kol2 << endl; + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + pNdb->closeTransaction(pTrans); + return NDBT_OK; +} + NDBT_TESTSUITE(testInterpreter); TESTCASE("IncValue32", @@ -156,6 +272,12 @@ TESTCASE("IncValue64", INITIALIZER(runTestIncValue64); FINALIZER(runClearTable); } +TESTCASE("Bug19537", + "Test big-endian write_attr of 32 bit integer\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestBug19537); + FINALIZER(runClearTable); +} #if 0 TESTCASE("MaxTransactions", "Start transactions until no more can be created\n"){ From 32d954f3e624890aeac23a195ff289e0c55b392c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 16 May 2006 16:50:05 +0300 Subject: [PATCH 05/10] BUG#14157: utf8 encoding in binlog without set character_set_client: e.g DROP temporary fixing encoding example because of table names can not be in koi8r on some platforms. mysql-test/t/rpl_temporary.test: koi8r encoding to name tables is changed for latin1 for the former does not work on some platforms. The effect of the test remains: a test table is named to have multibyte utf8 representation, which is the essence of the bug. --- mysql-test/t/rpl_temporary.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test index 871ff096476..bc1b0e64565 100644 --- a/mysql-test/t/rpl_temporary.test +++ b/mysql-test/t/rpl_temporary.test @@ -164,7 +164,7 @@ drop table t1; # #14157: utf8 encoding in binlog without set character_set_client # ---exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=koi8r test -e 'create table t1 (a int); set names koi8r; create temporary table `ÑÝÉË` (a int); insert into `ÑÝÉË` values (1); insert into t1 select * from `ÑÝÉË`' +--exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=latin1 test -e 'create table t1 (a int); set names latin1; create temporary table `äöüÄÖÜ` (a int); insert into `äöüÄÖÜ` values (1); insert into t1 select * from `äöüÄÖÜ`' sync_slave_with_master; #connection slave; From f1efd0883d4201b7fb8a60ee40f0024cafd01fd3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 16 May 2006 22:19:44 -0700 Subject: [PATCH 06/10] Fixed bug #19573. The select statement that specified a view could be slightly changed when the view was saved in a frm file. In particular references to an alias name in the HAVING clause could be substituted for the expression named by this alias. This could result in an error message for a query of the form SELECT * FROM . Yet no such message appeared when executing the query specifying the view. mysql-test/r/having.result: Adjusted results after fixing bug #19573. mysql-test/r/view.result: Added a test case for bug #19573. mysql-test/t/view.test: Added a test case for bug #19573. --- mysql-test/r/having.result | 2 +- mysql-test/r/view.result | 25 +++++++++++++++++++++++++ mysql-test/t/view.test | 28 ++++++++++++++++++++++++++++ sql/item.cc | 11 ++++++++++- 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index a37f260ff31..68b13b5fc0a 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -12,7 +12,7 @@ explain extended select count(a) as b from t1 where a=0 having b >=0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: -Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (count(`test`.`t1`.`a`) >= 0) +Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (`b` >= 0) drop table t1; CREATE TABLE t1 ( raw_id int(10) NOT NULL default '0', diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 4baa56070b7..5f31a6b494a 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2660,3 +2660,28 @@ SELECT * FROM v1; id t COUNT(*) DROP VIEW v1; DROP TABLE t1; +CREATE TABLE t1( +fName varchar(25) NOT NULL, +lName varchar(25) NOT NULL, +DOB date NOT NULL, +uID int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY); +INSERT INTO t1(fName, lName, DOB) VALUES +('Hank', 'Hill', '1964-09-29'), +('Tom', 'Adams', '1908-02-14'), +('Homer', 'Simpson', '1968-03-05'); +CREATE VIEW v1 AS +SELECT (year(now())-year(DOB)) AS Age +FROM t1 HAVING Age < 75; +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache (year(now()) - year(`t1`.`DOB`)) AS `Age` from `t1` having (`Age` < 75) +SELECT (year(now())-year(DOB)) AS Age FROM t1 HAVING Age < 75; +Age +42 +38 +SELECT * FROM v1; +Age +42 +38 +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index ea22ada900a..ba892c593c6 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2528,3 +2528,31 @@ SELECT * FROM v1; DROP VIEW v1; DROP TABLE t1; + +# +# Bug #19573: VIEW with HAVING that refers an alias name +# + +CREATE TABLE t1( + fName varchar(25) NOT NULL, + lName varchar(25) NOT NULL, + DOB date NOT NULL, + uID int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY); + +INSERT INTO t1(fName, lName, DOB) VALUES + ('Hank', 'Hill', '1964-09-29'), + ('Tom', 'Adams', '1908-02-14'), + ('Homer', 'Simpson', '1968-03-05'); + +CREATE VIEW v1 AS + SELECT (year(now())-year(DOB)) AS Age + FROM t1 HAVING Age < 75; +SHOW CREATE VIEW v1; + +SELECT (year(now())-year(DOB)) AS Age FROM t1 HAVING Age < 75; +SELECT * FROM v1; + +DROP VIEW v1; +DROP TABLE t1; + + diff --git a/sql/item.cc b/sql/item.cc index 51a2f9a24f3..62052547ee9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4840,7 +4840,16 @@ void Item_ref::cleanup() void Item_ref::print(String *str) { if (ref) - (*ref)->print(str); + { + if ((*ref)->type() != Item::CACHE_ITEM && ref_type() != VIEW_REF && + name && alias_name_used) + { + THD *thd= current_thd; + append_identifier(thd, str, name, (uint) strlen(name)); + } + else + (*ref)->print(str); + } else Item_ident::print(str); } From 1c6beaee06a2c9aefc7d0cdefa149091504318a3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 May 2006 00:55:28 +0400 Subject: [PATCH 07/10] Fixed bug#19077: A nested materialized derived table is used before being populated. The convert_constant_item() function converts constant items to ints on prepare phase to optimize execution speed. In this case it tries to evaluate subselect which contains a derived table and is contained in a derived table. All derived tables are filled only after all derived tables are prepared. So evaluation of subselect with derived table at the prepare phase will return a wrong result. A new flag with_subselect is added to the Item class. It indicates that expression which this item represents is a subselect or contains a subselect. It is set to 0 by default. It is set to 1 in the Item_subselect constructor for subselects. For Item_func and Item_cond derived classes it is set after fixing any argument in Item_func::fix_fields() and Item_cond::fix_fields accordingly. The convert_constant_item() function now doesn't convert a constant item if the with_subselect flag set in it. mysql-test/t/view.test: Added test case for bug#19077: A nested materialized derived table is used before being populated. mysql-test/t/subselect.test: Added test case for bug#19077: A nested materialized derived table is used before being populated. mysql-test/r/view.result: Added test case for bug#19077: A nested materialized derived table is used before being populated. mysql-test/r/subselect.result: Added test case for bug#19077: A nested materialized derived table is used before being populated. sql/item_subselect.cc: Fixed bug#19077: A nested materialized derived table is used before being populated. The Item_subselect class constructor sets new with_subselect flag to 1. sql/item_func.cc: Fixed bug#19077: A nested materialized derived table is used before being populated. The Item_func::fix_fields() sets new with_subselect flag from with_subselect flags of its arguments. sql/item_cmpfunc.cc: Fixed bug#19077: A nested materialized derived table is used before being populated. The convert_constant_item() function now doesn't convert a constant item with the with_subselect flag set. The Item_cond::fix_fields() sets new with_subselect flag from with_subselect flags of its arguments. sql/item.cc: Fixed bug#19077: A nested materialized derived table is used before being populated. Set new with_subselect flag to default value - 0 in the Item constructor. sql/item.h: Fixed bug#19077: A nested materialized derived table is used before being populated. A new flag with_subselect is added to the Item class. It indicates that expression which this item represents is a subselect or contains a subselect. It is set to 0 by default. --- mysql-test/r/subselect.result | 6 ++++++ mysql-test/r/view.result | 9 +++++++++ mysql-test/t/subselect.test | 9 +++++++++ mysql-test/t/view.test | 11 +++++++++++ sql/item.cc | 1 + sql/item.h | 3 +++ sql/item_cmpfunc.cc | 29 ++++++++++++++++++++++++----- sql/item_func.cc | 1 + sql/item_subselect.cc | 1 + 9 files changed, 65 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 39cb95be9e1..056457a4786 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3177,3 +3177,9 @@ ERROR 42S22: Unknown column 'no_such_column' in 'where clause' SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1); ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery' DROP TABLE t1; +create table t1 (i int, j bigint); +insert into t1 values (1, 2), (2, 2), (3, 2); +select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3; +min(i) +1 +drop table t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 4baa56070b7..557b44a11eb 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2660,3 +2660,12 @@ SELECT * FROM v1; id t COUNT(*) DROP VIEW v1; DROP TABLE t1; +CREATE TABLE t1 (i INT, j BIGINT); +INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2); +CREATE VIEW v1 AS SELECT MIN(j) AS j FROM t1; +CREATE VIEW v2 AS SELECT MIN(i) FROM t1 WHERE j = ( SELECT * FROM v1 ); +SELECT * FROM v2; +MIN(i) +1 +DROP VIEW v2, v1; +DROP TABLE t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9f4d89a7e50..3f48b648f40 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2100,3 +2100,12 @@ CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1); SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1); DROP TABLE t1; + +# +# Bug#19077: A nested materialized derived table is used before being populated. +# +create table t1 (i int, j bigint); +insert into t1 values (1, 2), (2, 2), (3, 2); +select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3; +drop table t1; + diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index ea22ada900a..1271329a520 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2528,3 +2528,14 @@ SELECT * FROM v1; DROP VIEW v1; DROP TABLE t1; + +# +# Bug#19077: A nested materialized view is used before being populated. +# +CREATE TABLE t1 (i INT, j BIGINT); +INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2); +CREATE VIEW v1 AS SELECT MIN(j) AS j FROM t1; +CREATE VIEW v2 AS SELECT MIN(i) FROM t1 WHERE j = ( SELECT * FROM v1 ); +SELECT * FROM v2; +DROP VIEW v2, v1; +DROP TABLE t1; diff --git a/sql/item.cc b/sql/item.cc index 51a2f9a24f3..44aa583aa3f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -304,6 +304,7 @@ Item::Item(): marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; decimals= 0; max_length= 0; + with_subselect= 0; /* Put item in free list so that we can free all items at end */ THD *thd= current_thd; diff --git a/sql/item.h b/sql/item.h index 19a57a10720..28b1f54add7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -460,6 +460,9 @@ public: my_bool is_autogenerated_name; /* indicate was name of this Item autogenerated or set by user */ DTCollation collation; + my_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 Item(); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 54e281a1f14..ca5d79973e5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -204,10 +204,28 @@ longlong Item_func_nop_all::val_int() /* - Convert a constant expression or string to an integer. - This is done when comparing DATE's of different formats and - also when comparing bigint to strings (in which case the string - is converted once to a bigint). + Convert a constant item to an int and replace the original item + + SYNOPSIS + convert_constant_item() + thd thread handle + field item will be converted using the type of this field + item [in/out] reference to the item to convert + + DESCRIPTION + The function converts a constant expression or string to an integer. + On successful conversion the original item is substituted for the + result of the item evaluation. + This is done when comparing DATE/TIME of different formats and + also when comparing bigint to strings (in which case strings + are converted to bigints). + + NOTES + This function is called only at prepare stage. + As all derived tables are filled only after all derived tables + are prepared we do not evaluate items with subselects here because + they can contain derived tables and thus we may attempt to use a + table that has not been populated yet. RESULT VALUES 0 Can't convert item @@ -216,7 +234,7 @@ longlong Item_func_nop_all::val_int() static bool convert_constant_item(THD *thd, Field *field, Item **item) { - if ((*item)->const_item()) + if (!(*item)->with_subselect && (*item)->const_item()) { /* For comparison purposes allow invalid dates like 2000-01-32 */ ulong orig_sql_mode= field->table->in_use->variables.sql_mode; @@ -2578,6 +2596,7 @@ Item_cond::fix_fields(THD *thd, Item **ref) const_item_cache= FALSE; } with_sum_func= with_sum_func || item->with_sum_func; + with_subselect|= item->with_subselect; if (item->maybe_null) maybe_null=1; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 5ef9db6f52b..2c770bec1ad 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -184,6 +184,7 @@ Item_func::fix_fields(THD *thd, Item **ref) used_tables_cache|= item->used_tables(); not_null_tables_cache|= item->not_null_tables(); const_item_cache&= item->const_item(); + with_subselect|= item->with_subselect; } } fix_length_and_dec(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 4b304725927..87ef0fc080e 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -39,6 +39,7 @@ Item_subselect::Item_subselect(): engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1), engine_changed(0), changed(0) { + with_subselect= 1; reset(); /* item value is NULL if select_subselect not changed this value From 087be9ba2d230c21949d65140658b6ce198f4e9f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 17 May 2006 20:48:48 -0700 Subject: [PATCH 08/10] Fixed bug #19816. This bug was introduced when the patch resolving the performance problem 17164 was applied. As a result of that modification the not_null_tables attributes were calculated incorrectly for constant OR conditions. This triggered invalid conversion of outer joins into inner joins. mysql-test/r/join_outer.result: Added a test case for bug #19816. mysql-test/t/join_outer.test: Added a test case for bug #19816. --- mysql-test/r/join_outer.result | 39 ++++++++++++++++++++++++++++++++-- mysql-test/t/join_outer.test | 18 ++++++++++++++++ sql/item_cmpfunc.cc | 4 +++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 712a60828f7..eae023813b5 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1151,8 +1151,8 @@ EXPLAIN SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id WHERE t1.name LIKE 'A%' OR FALSE; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index -1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index +1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where DROP TABLE t1,t2; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2; @@ -1176,3 +1176,38 @@ a b 3 3 DROP VIEW v1,v2; DROP TABLE t1,t2; +CREATE TABLE t1 (a int); +CREATE TABLE t2 (b int); +INSERT INTO t1 VALUES (1), (2), (3), (4); +INSERT INTO t2 VALUES (2), (3); +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1); +a b +1 NULL +2 2 +3 3 +4 NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1 OR 1); +a b +1 NULL +2 2 +3 3 +4 NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (0 OR 1); +a b +1 NULL +2 2 +3 3 +4 NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 2=2); +a b +1 NULL +2 2 +3 3 +4 NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0); +a b +1 NULL +2 2 +3 3 +4 NULL +DROP TABLE t1,t2; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 7134137a430..dc4e240750c 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -805,3 +805,21 @@ SELECT v1.a, v2. b DROP VIEW v1,v2; DROP TABLE t1,t2; + +# +# Bug 19816: LEFT OUTER JOIN with constant ORed predicates in WHERE clause +# + +CREATE TABLE t1 (a int); +CREATE TABLE t2 (b int); +INSERT INTO t1 VALUES (1), (2), (3), (4); +INSERT INTO t2 VALUES (2), (3); + +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1); + +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1 OR 1); +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (0 OR 1); +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 2=2); +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0); + +DROP TABLE t1,t2; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 54e281a1f14..a9cf44f301f 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2570,7 +2570,9 @@ Item_cond::fix_fields(THD *thd, Item **ref) (item= *li.ref())->check_cols(1)) return TRUE; /* purecov: inspected */ used_tables_cache|= item->used_tables(); - if (!item->const_item()) + if (item->const_item()) + and_tables_cache= (table_map) 0; + else { tmp_table_map= item->not_null_tables(); not_null_tables_cache|= tmp_table_map; From 573d9e47ab9b97209d31b18fc8c21df4e18504e4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 May 2006 10:34:01 -0700 Subject: [PATCH 09/10] Bug #13975: "same string" + 0 has 2 different results The 'decimals' member of Item_func was being improperly initialized, which resulted in improper results when handling large numeric values. mysql-test/r/func_str.result: Add test results mysql-test/t/func_str.test: Add new regression test sql/item_strfunc.h: Remove unnecessary reset of decimals in Item_func_conv::fix_length_and_dec(). --- mysql-test/r/func_str.result | 6 ++++++ mysql-test/t/func_str.test | 6 ++++++ sql/item_strfunc.h | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 6f8269bdcbd..a17661d26d0 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1046,4 +1046,10 @@ cast(ltrim(' 20.06 ') as decimal(19,2)) select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2)); cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2)) 20.06 +select conv("18383815659218730760",10,10) + 0; +conv("18383815659218730760",10,10) + 0 +1.8383815659219e+19 +select "18383815659218730760" + 0; +"18383815659218730760" + 0 +1.8383815659219e+19 End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index dee06231deb..7f809dbc4a1 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -698,4 +698,10 @@ select cast(rtrim(' 20.06 ') as decimal(19,2)); select cast(ltrim(' 20.06 ') as decimal(19,2)); select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2)); +# +# Bug #13975: "same string" + 0 has 2 different results +# +select conv("18383815659218730760",10,10) + 0; +select "18383815659218730760" + 0; + --echo End of 5.0 tests diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 7d7b62df0dc..90d421a2c68 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -542,7 +542,7 @@ public: void fix_length_and_dec() { collation.set(default_charset()); - decimals=0; max_length=64; + max_length= 64; } }; From 5ceb394fe22182055cb16b99bec3c6fe6b1dc3d8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 May 2006 13:07:24 +0200 Subject: [PATCH 10/10] Bug#15869 Cannot shutdown the server - it restarts - A segfault occured when the function 'kill_server' called 'my_sigset' with signal number 0. 'my_sigset' is a macro which uses 'sigaction' to install the signal handler with an invalid signal number will on most platforms return EINVAL but yields a segfauilt on IRIX 6.5 - The server crash was detected by mysqld_safe and it was restarted although a shutdown was requested. - Semantics of kill_server(0) is not known, leaving it intact include/my_pthread.h: Check return value from sigaction with a DBUG_ASSERT Also DBUG_ASSERT if signal number 0 is passed sql/mysqld.cc: Don't call my_sigset if signo is 0 --- include/my_pthread.h | 6 ++++-- sql/mysqld.cc | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index b6b65d4389a..8d03de49574 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -329,12 +329,14 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ we want to make sure that no such flags are set. */ #if defined(HAVE_SIGACTION) && !defined(my_sigset) -#define my_sigset(A,B) do { struct sigaction s; sigset_t set; \ +#define my_sigset(A,B) do { struct sigaction s; sigset_t set; int rc; \ + DBUG_ASSERT((A) != 0); \ sigemptyset(&set); \ s.sa_handler = (B); \ s.sa_mask = set; \ s.sa_flags = 0; \ - sigaction((A), &s, (struct sigaction *) NULL); \ + rc= sigaction((A), &s, (struct sigaction *) NULL);\ + DBUG_ASSERT(rc == 0); \ } while (0) #elif defined(HAVE_SIGSET) && !defined(my_sigset) #define my_sigset(A,B) sigset((A),(B)) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 740e1a419c7..9c1089dbdb2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -884,7 +884,8 @@ static void __cdecl kill_server(int sig_ptr) RETURN_FROM_KILL_SERVER; kill_in_progress=TRUE; abort_loop=1; // This should be set - my_sigset(sig,SIG_IGN); + if (sig != 0) // 0 is not a valid signal number + my_sigset(sig,SIG_IGN); if (sig == MYSQL_KILL_SIGNAL || sig == 0) sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname); else