From 422c55a2404a7ec31d43962cdda0d782ef32dc45 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 20 Sep 2013 14:47:38 +0400 Subject: [PATCH 1/9] MDEV-5037: Server crash on a JOIN on a derived table with join_cache_level > 2 - The crash was caused because the optimizer called handler->multi_range_read_info() on a derived temporary table. That table has been created, but not opened yet. Because of that, handler::table was NULL, which caused crash. Fixed by changing DS-MRR methods to use handler::table_share instead. handler::table_share is set in handler ctor, so this should be safe. --- mysql-test/r/innodb_mrr_cpk.result | 23 +++++++++++++++++++++++ mysql-test/t/innodb_mrr_cpk.test | 27 +++++++++++++++++++++++++++ sql/handler.h | 3 ++- sql/multi_range_read.cc | 20 +++++++++++--------- sql/multi_range_read.h | 2 +- sql/opt_subselect.h | 2 +- 6 files changed, 65 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/innodb_mrr_cpk.result b/mysql-test/r/innodb_mrr_cpk.result index 15ef32447a8..bcee428bc57 100644 --- a/mysql-test/r/innodb_mrr_cpk.result +++ b/mysql-test/r/innodb_mrr_cpk.result @@ -171,3 +171,26 @@ a b c d e g 2 6 two 12 2 6 DROP TABLE t1, t2; set optimizer_switch=@tmp_mdev3817; +# +# MDEV-5037: Server crash on a JOIN on a derived table with join_cache_level > 2 +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +CREATE TABLE t1 ( +id char(8) CHARACTER SET utf8 NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +CREATE TABLE t2 ( +id char(8) CHARACTER SET utf8 DEFAULT NULL, +url text CHARACTER SET utf8 +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +insert into t1 select '03b2ca8c' from t0 A, t0 B limit 80; +insert into t2 select '03b2ca8c','' from t0 A, t0 B, t0 C; +set @tmp_mdev5037=@@join_cache_level; +set join_cache_level=3; +explain SELECT 1 FROM (SELECT url, id FROM t2 LIMIT 1 OFFSET 20) derived RIGHT JOIN t1 ON t1.id = derived.id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL # +1 PRIMARY hash_ALL key0 #hash#key0 25 test.t1.id # Using join buffer (flat, BNLH join) +2 DERIVED t2 ALL NULL NULL NULL NULL # +set join_cache_level= @tmp_mdev5037; +drop table t0,t1,t2; diff --git a/mysql-test/t/innodb_mrr_cpk.test b/mysql-test/t/innodb_mrr_cpk.test index a7b2d9c0ddd..bee8d5796ce 100644 --- a/mysql-test/t/innodb_mrr_cpk.test +++ b/mysql-test/t/innodb_mrr_cpk.test @@ -165,3 +165,30 @@ SELECT * FROM t1, t2 WHERE g = b AND ( a < 7 OR a > e ); DROP TABLE t1, t2; set optimizer_switch=@tmp_mdev3817; +--echo # +--echo # MDEV-5037: Server crash on a JOIN on a derived table with join_cache_level > 2 +--echo # +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +CREATE TABLE t1 ( + id char(8) CHARACTER SET utf8 NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE t2 ( + id char(8) CHARACTER SET utf8 DEFAULT NULL, + url text CHARACTER SET utf8 +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +insert into t1 select '03b2ca8c' from t0 A, t0 B limit 80; +insert into t2 select '03b2ca8c','' from t0 A, t0 B, t0 C; + +set @tmp_mdev5037=@@join_cache_level; +set join_cache_level=3; + +--replace_column 9 # +explain SELECT 1 FROM (SELECT url, id FROM t2 LIMIT 1 OFFSET 20) derived RIGHT JOIN t1 ON t1.id = derived.id; + +set join_cache_level= @tmp_mdev5037; + +drop table t0,t1,t2; diff --git a/sql/handler.h b/sql/handler.h index 5b83d8c9556..a23e3c2d17e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2715,6 +2715,7 @@ public: virtual bool check_if_supported_virtual_columns(void) { return FALSE;} TABLE* get_table() { return table; } + TABLE_SHARE* get_table_share() { return table_share; } protected: /* deprecated, don't use in new engines */ inline void ha_statistic_increment(ulong SSV::*offset) const { } @@ -2968,7 +2969,7 @@ public: #include "multi_range_read.h" -bool key_uses_partial_cols(TABLE *table, uint keyno); +bool key_uses_partial_cols(TABLE_SHARE *table, uint keyno); /* Some extern variables used with handlers */ diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 1f624f4bc63..d9aeff21400 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -1494,10 +1494,10 @@ ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq, @retval FALSE No */ -bool key_uses_partial_cols(TABLE *table, uint keyno) +bool key_uses_partial_cols(TABLE_SHARE *share, uint keyno) { - KEY_PART_INFO *kp= table->key_info[keyno].key_part; - KEY_PART_INFO *kp_end= kp + table->key_info[keyno].key_parts; + KEY_PART_INFO *kp= share->key_info[keyno].key_part; + KEY_PART_INFO *kp_end= kp + share->key_info[keyno].key_parts; for (; kp != kp_end; kp++) { if (!kp->field->part_of_key.is_set(keyno)) @@ -1518,10 +1518,11 @@ bool key_uses_partial_cols(TABLE *table, uint keyno) @retval FALSE Otherwise */ -bool DsMrr_impl::check_cpk_scan(THD *thd, uint keyno, uint mrr_flags) +bool DsMrr_impl::check_cpk_scan(THD *thd, TABLE_SHARE *share, uint keyno, + uint mrr_flags) { return test((mrr_flags & HA_MRR_SINGLE_POINT) && - keyno == table->s->primary_key && + keyno == share->primary_key && primary_file->primary_key_is_clustered() && optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS)); } @@ -1557,14 +1558,15 @@ bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, COST_VECT dsmrr_cost; bool res; THD *thd= current_thd; + TABLE_SHARE *share= primary_file->get_table_share(); - bool doing_cpk_scan= check_cpk_scan(thd, keyno, *flags); - bool using_cpk= test(keyno == table->s->primary_key && + bool doing_cpk_scan= check_cpk_scan(thd, share, keyno, *flags); + bool using_cpk= test(keyno == share->primary_key && primary_file->primary_key_is_clustered()); *flags &= ~HA_MRR_IMPLEMENTATION_FLAGS; if (!optimizer_flag(thd, OPTIMIZER_SWITCH_MRR) || *flags & HA_MRR_INDEX_ONLY || - (using_cpk && !doing_cpk_scan) || key_uses_partial_cols(table, keyno)) + (using_cpk && !doing_cpk_scan) || key_uses_partial_cols(share, keyno)) { /* Use the default implementation */ *flags |= HA_MRR_USE_DEFAULT_IMPL; @@ -1572,7 +1574,7 @@ bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, return TRUE; } - uint add_len= table->key_info[keyno].key_length + primary_file->ref_length; + uint add_len= share->key_info[keyno].key_length + primary_file->ref_length; *bufsz -= add_len; if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost)) return TRUE; diff --git a/sql/multi_range_read.h b/sql/multi_range_read.h index dcba92aab16..10715817308 100644 --- a/sql/multi_range_read.h +++ b/sql/multi_range_read.h @@ -627,7 +627,7 @@ private: COST_VECT *cost); bool get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, uint *buffer_size, COST_VECT *cost); - bool check_cpk_scan(THD *thd, uint keyno, uint mrr_flags); + bool check_cpk_scan(THD *thd, TABLE_SHARE *share, uint keyno, uint mrr_flags); bool setup_buffer_sharing(uint key_size_in_keybuf, key_part_map key_tuple_map); diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h index 1e8b4cc50a1..6d3457e2843 100644 --- a/sql/opt_subselect.h +++ b/sql/opt_subselect.h @@ -192,7 +192,7 @@ public: (PREV_BITS(key_part_map, max_loose_keypart+1) & // (3) (found_part | loose_scan_keyparts)) == // (3) PREV_BITS(key_part_map, max_loose_keypart+1) && // (3) - !key_uses_partial_cols(s->table, key)) + !key_uses_partial_cols(s->table->s, key)) { /* Ok, can use the strategy */ part1_conds_met= TRUE; From b0d98371b916a64b6c1c0213c1f0e63058b85e4a Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 20 Sep 2013 14:37:30 +0200 Subject: [PATCH 2/9] Update feedback plugin to recognize Windows 8.1 / Windows Server 2012 R2. --- plugin/feedback/utils.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugin/feedback/utils.cc b/plugin/feedback/utils.cc index a841ac244d1..f6fcb3d2082 100644 --- a/plugin/feedback/utils.cc +++ b/plugin/feedback/utils.cc @@ -44,12 +44,16 @@ static const char *get_os_version_name(OSVERSIONINFOEX *ver) DWORD major = ver->dwMajorVersion; DWORD minor = ver->dwMinorVersion; + if (major == 6 && minor == 3) + { + return (ver->wProductType == VER_NT_WORKSTATION)? + "Windows 8.1":"Windows Server 2012 R2"; + } if (major == 6 && minor == 2) { return (ver->wProductType == VER_NT_WORKSTATION)? "Windows 8":"Windows Server 2012"; } - if (major == 6 && minor == 1) { return (ver->wProductType == VER_NT_WORKSTATION)? From 28a8d40c22cb86a70a1306baed3426a02cfbd220 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Sep 2013 12:17:18 +0300 Subject: [PATCH 3/9] Tokudb made compilig. --- storage/tokudb/CMakeLists.txt | 2 +- storage/tokudb/ft-index/ft/CMakeLists.txt | 4 ++-- storage/tokudb/ft-index/src/CMakeLists.txt | 2 +- storage/tokudb/ft-index/src/tests/CMakeLists.txt | 2 +- storage/tokudb/ft-index/utils/CMakeLists.txt | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 716af3f9ba6..527d77996ff 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -46,7 +46,7 @@ SET(TOKUDB_PLUGIN_DYNAMIC "ha_tokudb") SET(TOKUDB_SOURCES ha_tokudb.cc) MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY COMPONENT "tokudb-engine" - LINK_LIBRARIES tokufractaltree_static tokuportability_static z stdc++) + LINK_LIBRARIES tokufractaltree_static tokuportability_static ${ZLIB_LIBRARY} stdc++) SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin") IF (INSTALL_SYSCONF2DIR) diff --git a/storage/tokudb/ft-index/ft/CMakeLists.txt b/storage/tokudb/ft-index/ft/CMakeLists.txt index d480a1464f3..748e501f922 100644 --- a/storage/tokudb/ft-index/ft/CMakeLists.txt +++ b/storage/tokudb/ft-index/ft/CMakeLists.txt @@ -87,14 +87,14 @@ add_dependencies(ft_static install_tdb_h generate_log_code build_lzma) ## link with lzma (which should be static) and link dependers with zlib target_link_libraries(ft LINK_PRIVATE util_static lzma ${LIBTOKUPORTABILITY}) -target_link_libraries(ft LINK_PUBLIC z) +target_link_libraries(ft LINK_PUBLIC ${ZLIB_LIBRARY} ) target_link_libraries(ft_static LINK_PRIVATE lzma) ## build the bins in this directory foreach(tool tokuftdump tdb_logprint tdb-recover ftverify) add_executable(${tool} ${tool}.cc) add_dependencies(${tool} install_tdb_h) - target_link_libraries(${tool} ft_static util_static z lzma ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}) + target_link_libraries(${tool} ft_static util_static ${ZLIB_LIBRARY} lzma ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}) add_space_separated_property(TARGET ${tool} COMPILE_FLAGS -fvisibility=hidden) endforeach(tool) diff --git a/storage/tokudb/ft-index/src/CMakeLists.txt b/storage/tokudb/ft-index/src/CMakeLists.txt index 0867a362645..394d120beaa 100644 --- a/storage/tokudb/ft-index/src/CMakeLists.txt +++ b/storage/tokudb/ft-index/src/CMakeLists.txt @@ -19,7 +19,7 @@ set(tokudb_srcs add_library(${LIBTOKUDB} SHARED ${tokudb_srcs}) add_dependencies(${LIBTOKUDB} install_tdb_h generate_log_code) target_link_libraries(${LIBTOKUDB} LINK_PRIVATE locktree_static ft_static util_static lzma ${LIBTOKUPORTABILITY}) -target_link_libraries(${LIBTOKUDB} LINK_PUBLIC z) +target_link_libraries(${LIBTOKUDB} LINK_PUBLIC ${ZLIB_LIBRARY} ) ## make the static library add_library(tokudb_static_conv STATIC ${tokudb_srcs}) diff --git a/storage/tokudb/ft-index/src/tests/CMakeLists.txt b/storage/tokudb/ft-index/src/tests/CMakeLists.txt index 394015defea..b0576a858aa 100644 --- a/storage/tokudb/ft-index/src/tests/CMakeLists.txt +++ b/storage/tokudb/ft-index/src/tests/CMakeLists.txt @@ -360,7 +360,7 @@ if(BUILD_TESTING OR BUILD_SRC_TESTS) ## #5138 only reproduces when using the static library. list(REMOVE_ITEM tdb_bins test-5138.tdb) add_executable(test-5138.tdb test-5138.cc) - target_link_libraries(test-5138.tdb ${LIBTOKUDB}_static z ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}) + target_link_libraries(test-5138.tdb ${LIBTOKUDB}_static ${ZLIB_LIBRARY} ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}) set_property(TARGET test-5138.tdb APPEND PROPERTY COMPILE_DEFINITIONS "USE_TDB;IS_TDB=1;TOKUDB=1") add_space_separated_property(TARGET test-5138.tdb COMPILE_FLAGS -fvisibility=hidden) diff --git a/storage/tokudb/ft-index/utils/CMakeLists.txt b/storage/tokudb/ft-index/utils/CMakeLists.txt index 5c73927dd80..b61de890677 100644 --- a/storage/tokudb/ft-index/utils/CMakeLists.txt +++ b/storage/tokudb/ft-index/utils/CMakeLists.txt @@ -5,7 +5,7 @@ foreach(util ${utils}) add_executable(${util} ${util}.cc) set_target_properties(${util} PROPERTIES COMPILE_DEFINITIONS "IS_TDB=1;USE_TDB=1;TDB_IS_STATIC=1") - target_link_libraries(${util} ${LIBTOKUDB}_static ft_static z lzma ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}) + target_link_libraries(${util} ${LIBTOKUDB}_static ft_static ${ZLIB_LIBRARY} lzma ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}) add_space_separated_property(TARGET ${util} COMPILE_FLAGS -fvisibility=hidden) From 45d3ada7c2f81227bb0b8b219b787f4d9746ca21 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 17 Sep 2013 18:51:14 +0400 Subject: [PATCH 4/9] MDEV-4684 - Enhancement request: --init-command support for mysqlslap Added --init-command argument to mysqlslap: SQL Command to execute when connecting to MySQL server. Will automatically be re-executed when reconnecting. --- client/mysqlslap.c | 10 +++++++++- man/mysqlslap.1 | 15 +++++++++++++++ mysql-test/r/mysqlslap.result | 4 ++++ mysql-test/t/mysqlslap.test | 7 +++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 8e70a2609c3..202fcf7950f 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -123,7 +123,8 @@ static char *host= NULL, *opt_password= NULL, *user= NULL, *default_engine= NULL, *pre_system= NULL, *post_system= NULL, - *opt_mysql_unix_port= NULL; + *opt_mysql_unix_port= NULL, + *opt_init_command= NULL; static char *opt_plugin_dir= 0, *opt_default_auth= 0; const char *delimiter= "\n"; @@ -629,6 +630,11 @@ static struct my_option my_long_options[] = GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", &host, &host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"init-command", OPT_INIT_COMMAND, + "SQL Command to execute when connecting to MySQL server. Will " + "automatically be re-executed when reconnecting.", + &opt_init_command, &opt_init_command, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"iterations", 'i', "Number of times to run the tests.", &iterations, &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, {"no-drop", OPT_SLAP_NO_DROP, "Do not drop the schema after the test.", @@ -2241,6 +2247,8 @@ slap_connect(MYSQL *mysql) for (x= 0; x < 10; x++) { set_mysql_connect_options(mysql); + if (opt_init_command) + mysql_options(mysql, MYSQL_INIT_COMMAND, opt_init_command); if (mysql_real_connect(mysql, host, user, opt_password, create_schema_string, opt_mysql_port, diff --git a/man/mysqlslap.1 b/man/mysqlslap.1 index 7446c30a839..e795be397a2 100644 --- a/man/mysqlslap.1 +++ b/man/mysqlslap.1 @@ -578,6 +578,21 @@ Connect to the MySQL server on the given host\&. .sp -1 .IP \(bu 2.3 .\} +.\" mysqlslap: init-command option +.\" init-command option: mysqlslap +\fB\-\-init\-command=str\fR +.sp +SQL Command to execute when connecting to MySQL server\&. Will automatically be re\-executed when reconnecting\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} .\" mysqlslap: iterations option .\" iterations option: mysqlslap \fB\-\-iterations=\fR\fB\fIN\fR\fR, diff --git a/mysql-test/r/mysqlslap.result b/mysql-test/r/mysqlslap.result index 069c9182de2..af78677647f 100644 --- a/mysql-test/r/mysqlslap.result +++ b/mysql-test/r/mysqlslap.result @@ -251,3 +251,7 @@ Benchmark Number of clients running queries: 1 Average number of queries per client: 0 +# +# MDEV-4684 - Enhancement request: --init-command support for mysqlslap +# +DROP TABLE t1; diff --git a/mysql-test/t/mysqlslap.test b/mysql-test/t/mysqlslap.test index 69eaae76409..c49c4ab3d7d 100644 --- a/mysql-test/t/mysqlslap.test +++ b/mysql-test/t/mysqlslap.test @@ -73,3 +73,10 @@ DROP DATABASE bug58090; --replace_regex /queries: [0-9]+.[0-9]+/queries: TIME/ --exec $MYSQL_SLAP + +--echo # +--echo # MDEV-4684 - Enhancement request: --init-command support for mysqlslap +--echo # + +--exec $MYSQL_SLAP --create-schema=test --init-command="CREATE TABLE t1(a INT)" --silent --concurrency=1 --iterations=1 +DROP TABLE t1; From 5f0c91998aaeb5b7e57bb0b304ce193edcaef1e1 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 23 Sep 2013 20:17:03 +0300 Subject: [PATCH 5/9] TokuDB fixes: - Better error message when using huge pages - Fixed link error - Test suite should run even on system with huge pages storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake: Fixed that linking works on systems that uses lib64 storage/tokudb/ft-index/portability/huge_page_detection.cc: Better error message storage/tokudb/mysql-test/rpl/suite.pm: Test suite should run even on system with huge pages storage/tokudb/mysql-test/tokudb/suite.pm: Test suite should run even on system with huge pages --- .../ft-index/cmake_modules/TokuThirdParty.cmake | 1 + .../ft-index/portability/huge_page_detection.cc | 2 +- storage/tokudb/mysql-test/rpl/suite.pm | 11 +++++++++++ storage/tokudb/mysql-test/tokudb/suite.pm | 3 +++ 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 storage/tokudb/mysql-test/rpl/suite.pm diff --git a/storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake b/storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake index 7436a4454c3..20bb010a545 100644 --- a/storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake +++ b/storage/tokudb/ft-index/cmake_modules/TokuThirdParty.cmake @@ -34,6 +34,7 @@ ExternalProject_Add(build_lzma CONFIGURE_COMMAND "/configure" ${xz_configure_opts} "--prefix=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/xz" + "--libdir=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/xz/lib" BUILD_COMMAND ${SUBMAKE_COMMAND} -C src/liblzma INSTALL_COMMAND diff --git a/storage/tokudb/ft-index/portability/huge_page_detection.cc b/storage/tokudb/ft-index/portability/huge_page_detection.cc index e4bfc8a1035..92891597fa0 100644 --- a/storage/tokudb/ft-index/portability/huge_page_detection.cc +++ b/storage/tokudb/ft-index/portability/huge_page_detection.cc @@ -109,7 +109,7 @@ static bool check_huge_pages_config_file(const char *fname) char *r = fgets(buf, sizeof(buf), f); assert(r != NULL); if (strstr(buf, "[always]")) { - fprintf(stderr, "Transparent huge pages are enabled, according to %s\n", fname); + fprintf(stderr,"TokuDB: Transparent huge pages are enabled, according to %s. TokuDB will be disabled. To use TokuDB disable huge pages in your kernel or, for testing, set the environment variable TOKU_HUGE_PAGES_OK to 1\n", fname); huge_pages_enabled = true; } else { huge_pages_enabled =false; diff --git a/storage/tokudb/mysql-test/rpl/suite.pm b/storage/tokudb/mysql-test/rpl/suite.pm new file mode 100644 index 00000000000..e001340cd14 --- /dev/null +++ b/storage/tokudb/mysql-test/rpl/suite.pm @@ -0,0 +1,11 @@ +package My::Suite::TokuDB; +use File::Basename; +@ISA = qw(My::Suite); + +# Ensure we can run the TokuDB tests even if hugepages are enabled +$ENV{TOKU_HUGE_PAGES_OK}=1; + +#return "Not run for embedded server" if $::opt_embedded_server; +return "No TokuDB engine" unless $ENV{HA_TOKUDB_SO} or $::mysqld_variables{tokudb}; +bless { }; + diff --git a/storage/tokudb/mysql-test/tokudb/suite.pm b/storage/tokudb/mysql-test/tokudb/suite.pm index c56ed6e4f4c..e001340cd14 100644 --- a/storage/tokudb/mysql-test/tokudb/suite.pm +++ b/storage/tokudb/mysql-test/tokudb/suite.pm @@ -2,6 +2,9 @@ package My::Suite::TokuDB; use File::Basename; @ISA = qw(My::Suite); +# Ensure we can run the TokuDB tests even if hugepages are enabled +$ENV{TOKU_HUGE_PAGES_OK}=1; + #return "Not run for embedded server" if $::opt_embedded_server; return "No TokuDB engine" unless $ENV{HA_TOKUDB_SO} or $::mysqld_variables{tokudb}; bless { }; From b722aae621cb2e4fc2f815292bce43cd5a73b342 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 23 Sep 2013 20:17:46 +0300 Subject: [PATCH 6/9] Allow unique prefix for command line options, like any GNU program. --- mysys/my_getopt.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 67e074e7e59..f4a0f58511b 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -869,12 +869,6 @@ static int findopt(char *optpat, uint length, } } } - if (is_prefix && count == 1) - my_getopt_error_reporter(WARNING_LEVEL, - "Using unique option prefix %.*s instead of %s " - "is deprecated and will be removed in a future " - "release. Please use the full name instead.", - length, optpat, *ffname); DBUG_RETURN(count); } From 11fc6b49d96931d08bb8d266270014c0633a0fa5 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 23 Sep 2013 23:33:18 +0200 Subject: [PATCH 7/9] MDEV-5053 - fix cyclic dependency when building with Ninja CMake generator --- cmake/jemalloc.cmake | 9 ++++++++- sql/CMakeLists.txt | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cmake/jemalloc.cmake b/cmake/jemalloc.cmake index 5cb9c493a20..fc7b2a73e72 100644 --- a/cmake/jemalloc.cmake +++ b/cmake/jemalloc.cmake @@ -15,13 +15,20 @@ MACRO (USE_BUNDLED_JEMALLOC) IF (CMAKE_BUILD_TYPE MATCHES "Debug" AND NOT APPLE) # see the comment in CMakeLists.txt LIST(APPEND JEMALLOC_CONFIGURE_OPTS --enable-debug) ENDIF() + + IF(CMAKE_GENERATOR MATCHES "Makefiles") + SET(MAKE_COMMAND ${CMAKE_MAKE_PROGRAM}) + ELSE() # Xcode/Ninja generators + SET(MAKE_COMMAND make) + ENDIF() + ExternalProject_Add(jemalloc PREFIX extra/jemalloc SOURCE_DIR ${SOURCE_DIR} BINARY_DIR ${BINARY_DIR} STAMP_DIR ${BINARY_DIR} CONFIGURE_COMMAND "${SOURCE_DIR}/configure" ${JEMALLOC_CONFIGURE_OPTS} - BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} "build_lib_static" + BUILD_COMMAND ${MAKE_COMMAND} "build_lib_static" INSTALL_COMMAND "" ) ADD_LIBRARY(libjemalloc STATIC IMPORTED) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 02265196e2d..6483ba01d2a 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -25,7 +25,6 @@ ${CMAKE_BINARY_DIR}/sql SET(GEN_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.h ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc -${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h ) @@ -85,6 +84,7 @@ SET (SQL_SOURCE gcalc_slicescan.cc gcalc_tools.cc threadpool_common.cc ../sql-common/mysql_async.c + ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) From 72dffd878e47e4fcfd224cadfea06caed0ac956b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 24 Sep 2013 19:52:51 +0200 Subject: [PATCH 8/9] MDEV-5062 : disable jemalloc by default everywhere, except Linux and OSX. Bundled jemalloc can only be on Linux and OSX without problems. On BSDs, build fails because make does not understand GNU extensions (also BSDs do not need jemalloc, it is already system malloc). On Solaris, build fails with compile error. --- BUILD/compile-solaris-amd64 | 2 +- cmake/jemalloc.cmake | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/BUILD/compile-solaris-amd64 b/BUILD/compile-solaris-amd64 index 58e5cba7d8c..2ae8ff333e8 100755 --- a/BUILD/compile-solaris-amd64 +++ b/BUILD/compile-solaris-amd64 @@ -3,6 +3,6 @@ export LDFLAGS='-m64 -lmtmalloc -R/usr/sfw/lib/64' export CFLAGS='-mtune=i386 -D__sun -m64 -mtune=athlon64' export CXXFLAGS='-mtune=i386 -D__sun -m64 -mtune=athlon64' -cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DWITH_EXTRA_CHARSETS=complex -DWITH_READLINE=ON -DWITH_SSL=bundled -DWITH_MAX=ON -DWITH_EMBEDDED_SERVER=ON -DWITH_JEMALLOC=NO +cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DWITH_EXTRA_CHARSETS=complex -DWITH_READLINE=ON -DWITH_SSL=bundled -DWITH_MAX=ON -DWITH_EMBEDDED_SERVER=ON gmake -j6 VERBOSE=1 diff --git a/cmake/jemalloc.cmake b/cmake/jemalloc.cmake index fc7b2a73e72..bc6bf60781d 100644 --- a/cmake/jemalloc.cmake +++ b/cmake/jemalloc.cmake @@ -36,13 +36,19 @@ MACRO (USE_BUNDLED_JEMALLOC) ADD_DEPENDENCIES(libjemalloc jemalloc) ENDMACRO() -SET(WITH_JEMALLOC "yes" CACHE STRING +IF(CMAKE_SYSTEM_NAME MATCHES "Linux" OR APPLE) + # Linux and OSX are the only systems where bundled jemalloc can be built without problems, + # as they both have GNU make and jemalloc actually compiles. + # Also, BSDs use jemalloc as malloc already + SET(WITH_JEMALLOC_DEFAULT "yes") +ELSE() + SET(WITH_JEMALLOC_DEFAULT "no") +ENDIF() + +SET(WITH_JEMALLOC ${WITH_JEMALLOC_DEFAULT} CACHE STRING "Which jemalloc to use (possible values are 'no', 'bundled', 'system', 'yes' (system if possible, otherwise bundled)") MACRO (CHECK_JEMALLOC) - IF(WIN32) - SET(WITH_JEMALLOC "no") - ENDIF() IF(WITH_JEMALLOC STREQUAL "system" OR WITH_JEMALLOC STREQUAL "yes") CHECK_LIBRARY_EXISTS(jemalloc malloc_stats_print "" HAVE_JEMALLOC) IF (HAVE_JEMALLOC) From ec7da1561e028aac40dee69433113978c982ce84 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Sep 2013 15:30:13 +0300 Subject: [PATCH 9/9] MDEV-5039: incorrect Item_func_regex::update_used_tables() Other fix of maybe_null problem and revert of revno: 3608 "MDEV-3873 & MDEV-3876 & MDEV-3912 : Wrong result (extra rows) with ALL subquery from a MERGE view." --- sql/item.cc | 10 +-------- sql/item.h | 4 ---- sql/item_cmpfunc.cc | 20 ++++++++---------- sql/item_cmpfunc.h | 28 +++----------------------- sql/item_func.cc | 25 ++++++++++------------- sql/item_func.h | 48 ++++++++++++++++++-------------------------- sql/item_geofunc.cc | 4 ++-- sql/item_geofunc.h | 30 +++++++++++++-------------- sql/item_strfunc.cc | 26 ++++++++++++------------ sql/item_strfunc.h | 28 ++++++++++++-------------- sql/item_timefunc.cc | 10 ++++----- sql/item_timefunc.h | 44 ++++++++++++++++++++-------------------- sql/item_xmlfunc.cc | 1 - sql/item_xmlfunc.h | 8 ++++++-- sql/sql_derived.cc | 13 ++++++++++++ sql/sql_select.cc | 5 +++-- sql/table.h | 1 + 17 files changed, 135 insertions(+), 170 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 5207d7d9ba3..9738a068d88 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9208,18 +9208,10 @@ table_map Item_ref::used_tables() const } -void Item_ref::update_used_tables() +void Item_ref::update_used_tables() { if (!get_depended_from()) (*ref)->update_used_tables(); - maybe_null|= (*ref)->maybe_null; -} - -void Item_direct_view_ref::update_used_tables() -{ - Item_ref::update_used_tables(); - if (view->table && view->table->maybe_null) - maybe_null= TRUE; } table_map Item_direct_view_ref::used_tables() const diff --git a/sql/item.h b/sql/item.h index 13f8e359dbd..fd19180f3be 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1877,8 +1877,6 @@ public: void update_used_tables() { update_table_bitmaps(); - if (field && field->table) - maybe_null|= field->maybe_null(); } Item *get_tmp_table_item(THD *thd); bool collect_item_field_processor(uchar * arg); @@ -2905,7 +2903,6 @@ public: void update_used_tables() { orig_item->update_used_tables(); - maybe_null|= orig_item->maybe_null; } bool const_item() const { return orig_item->const_item(); } table_map not_null_tables() const { return orig_item->not_null_tables(); } @@ -2998,7 +2995,6 @@ public: Item *replace_equal_field(uchar *arg); table_map used_tables() const; table_map not_null_tables() const; - void update_used_tables(); bool walk(Item_processor processor, bool walk_subquery, uchar *arg) { return (*ref)->walk(processor, walk_subquery, arg) || diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f0069757ee3..a6587fd4c3d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1352,7 +1352,7 @@ int Arg_comparator::compare_e_row() void Item_func_truth::fix_length_and_dec() { - set_persist_maybe_null(0); + maybe_null= 0; null_value= 0; decimals= 0; max_length= 1; @@ -1860,8 +1860,7 @@ longlong Item_func_eq::val_int() void Item_func_equal::fix_length_and_dec() { Item_bool_func2::fix_length_and_dec(); - set_persist_maybe_null(0); - null_value= 0; + maybe_null=null_value=0; } longlong Item_func_equal::val_int() @@ -2001,7 +2000,7 @@ void Item_func_interval::fix_length_and_dec() } } } - set_persist_maybe_null(0); + maybe_null= 0; max_length= 2; used_tables_cache|= row->used_tables(); not_null_tables_cache= row->not_null_tables(); @@ -2688,7 +2687,7 @@ void Item_func_nullif::fix_length_and_dec() { Item_bool_func2::fix_length_and_dec(); - set_persist_maybe_null(1); + maybe_null=1; if (args[0]) // Only false if EOM { max_length=args[0]->max_length; @@ -4482,8 +4481,6 @@ void Item_cond::update_used_tables() item->update_used_tables(); used_tables_cache|= item->used_tables(); const_item_cache&= item->const_item(); - if (!persistent_maybe_null && item->maybe_null) - maybe_null= 1; } } @@ -4662,9 +4659,10 @@ longlong Item_is_not_null_test::val_int() */ void Item_is_not_null_test::update_used_tables() { - args[0]->update_used_tables(); if (!args[0]->maybe_null) used_tables_cache= 0; /* is always true */ + else + args[0]->update_used_tables(); } @@ -4947,7 +4945,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref) int comp_res= regcomp(TRUE); if (comp_res == -1) { // Will always return NULL - set_persist_maybe_null(1); + maybe_null=1; fixed= 1; return FALSE; } @@ -4957,7 +4955,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref) maybe_null= args[0]->maybe_null; } else - set_persist_maybe_null(1); + maybe_null=1; fixed= 1; return FALSE; } @@ -5866,8 +5864,6 @@ void Item_equal::update_used_tables() item->update_used_tables(); used_tables_cache|= item->used_tables(); const_item_cache&= item->const_item(); - if (!persistent_maybe_null && item->maybe_null) - maybe_null= 1; } } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 37871c31e0b..99d89e16532 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -752,11 +752,6 @@ public: my_decimal *decimal_op(my_decimal *); bool date_op(MYSQL_TIME *ltime,uint fuzzydate); void fix_length_and_dec(); - void update_used_tables() - { - Item_func_coalesce::update_used_tables(); - maybe_null|= args[1]->maybe_null; - } const char *func_name() const { return "ifnull"; } Field *tmp_table_field(TABLE *table); uint decimal_precision() const; @@ -776,11 +771,6 @@ public: String *str_op(String *); bool fix_fields(THD *, Item **); void fix_length_and_dec(); - void update_used_tables() - { - Item_func::update_used_tables(); - maybe_null|= args[1]->maybe_null || args[2]->maybe_null; - } uint decimal_precision() const; const char *func_name() const { return "if"; } bool eval_not_null_tables(uchar *opt_arg); @@ -1244,12 +1234,6 @@ public: bool date_op(MYSQL_TIME *ltime, uint fuzzydate); bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); - void update_used_tables() - { - Item_func::update_used_tables(); - if (else_expr_num == -1 || args[else_expr_num]->maybe_null) - maybe_null= 1; - } uint decimal_precision() const; table_map not_null_tables() const { return 0; } const char *func_name() const { return "case"; } @@ -1369,14 +1353,13 @@ public: enum Functype functype() const { return ISNULL_FUNC; } void fix_length_and_dec() { - decimals=0; max_length=1; set_persist_maybe_null(0); + decimals=0; max_length=1; maybe_null=0; update_used_tables(); } const char *func_name() const { return "isnull"; } /* Optimize case of not_null_column IS NULL */ virtual void update_used_tables() { - args[0]->update_used_tables(); if (!args[0]->maybe_null) { used_tables_cache= 0; /* is always false */ @@ -1384,6 +1367,7 @@ public: } else { + args[0]->update_used_tables(); used_tables_cache= args[0]->used_tables(); const_item_cache= args[0]->const_item(); } @@ -1430,7 +1414,7 @@ public: enum Functype functype() const { return ISNOTNULL_FUNC; } void fix_length_and_dec() { - decimals=0; max_length=1; set_persist_maybe_null(0); + decimals=0; max_length=1; maybe_null=0; } const char *func_name() const { return "isnotnull"; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } @@ -1501,12 +1485,6 @@ public: void cleanup(); longlong val_int(); bool fix_fields(THD *thd, Item **ref); - void update_used_tables() - { - Item_bool_func::update_used_tables(); - if (regex_is_const) - maybe_null= 1; - } const char *func_name() const { return "regexp"; } virtual inline void print(String *str, enum_query_type query_type) diff --git a/sql/item_func.cc b/sql/item_func.cc index 98da660f8a7..c729893dae0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -86,7 +86,7 @@ void Item_func::set_arguments(List &list) } Item_func::Item_func(List &list) - :allowed_arg_cols(1), persistent_maybe_null(0) + :allowed_arg_cols(1) { set_arguments(list); } @@ -94,7 +94,6 @@ Item_func::Item_func(List &list) Item_func::Item_func(THD *thd, Item_func *item) :Item_result_field(thd, item), allowed_arg_cols(item->allowed_arg_cols), - persistent_maybe_null(0), arg_count(item->arg_count), used_tables_cache(item->used_tables_cache), not_null_tables_cache(item->not_null_tables_cache), @@ -424,8 +423,6 @@ void Item_func::update_used_tables() args[i]->update_used_tables(); used_tables_cache|=args[i]->used_tables(); const_item_cache&=args[i]->const_item(); - if (!persistent_maybe_null && args[i]->maybe_null) - maybe_null= 1; } } @@ -1657,7 +1654,7 @@ void Item_func_div::fix_length_and_dec() case IMPOSSIBLE_RESULT: DBUG_ASSERT(0); } - set_persist_maybe_null(1); // devision by zero + maybe_null= 1; // devision by zero DBUG_VOID_RETURN; } @@ -1692,7 +1689,7 @@ void Item_func_int_div::fix_length_and_dec() max_length=args[0]->max_length - (argtype == DECIMAL_RESULT || argtype == INT_RESULT ? args[0]->decimals : 0); - set_persist_maybe_null(1); + maybe_null=1; unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag; } @@ -1773,7 +1770,7 @@ void Item_func_mod::result_precision() void Item_func_mod::fix_length_and_dec() { Item_num_op::fix_length_and_dec(); - set_persist_maybe_null(1); + maybe_null= 1; unsigned_flag= args[0]->unsigned_flag; } @@ -2952,7 +2949,7 @@ longlong Item_func_field::val_int() void Item_func_field::fix_length_and_dec() { - set_persist_maybe_null(0); max_length=3; + maybe_null=0; max_length=3; cmp_type= args[0]->result_type(); for (uint i=1; i < arg_count ; i++) cmp_type= item_cmp_type(cmp_type, args[i]->result_type()); @@ -5018,7 +5015,7 @@ void Item_func_get_user_var::fix_length_and_dec() { THD *thd=current_thd; int error; - set_persist_maybe_null(1); + maybe_null=1; decimals=NOT_FIXED_DEC; max_length=MAX_BLOB_WIDTH; @@ -5224,7 +5221,7 @@ void Item_func_get_system_var::update_null_value() void Item_func_get_system_var::fix_length_and_dec() { char *cptr; - set_persist_maybe_null(1); + maybe_null= TRUE; max_length= 0; if (var->check_type(var_type)) @@ -5756,7 +5753,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) DBUG_ASSERT(fixed == 0); Item *UNINIT_VAR(item); // Safe as arg_count is > 1 - set_persist_maybe_null(1); + maybe_null=1; join_key=0; /* @@ -6090,7 +6087,7 @@ longlong Item_func_row_count::val_int() Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name) :Item_func(), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL) { - set_persist_maybe_null(1); + maybe_null= 1; m_name->init_qname(current_thd); dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE)); dummy_table->s= (TABLE_SHARE*) (dummy_table+1); @@ -6101,7 +6098,7 @@ Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name, List &list) :Item_func(list), context(context_arg), m_name(name), m_sp(NULL),sp_result_field(NULL) { - set_persist_maybe_null(1); + maybe_null= 1; m_name->init_qname(current_thd); dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE)); dummy_table->s= (TABLE_SHARE*) (dummy_table+1); @@ -6255,7 +6252,7 @@ void Item_func_sp::fix_length_and_dec() decimals= sp_result_field->decimals(); max_length= sp_result_field->field_length; collation.set(sp_result_field->charset()); - set_persist_maybe_null(1); + maybe_null= 1; unsigned_flag= test(sp_result_field->flags & UNSIGNED_FLAG); DBUG_VOID_RETURN; diff --git a/sql/item_func.h b/sql/item_func.h index 4eb0105376a..80b794f30d5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -38,8 +38,6 @@ protected: 0 means get this number from first argument */ uint allowed_arg_cols; - /* maybe_null can't be changed by parameters or used table state */ - bool persistent_maybe_null; public: uint arg_count; table_map used_tables_cache, not_null_tables_cache; @@ -65,13 +63,13 @@ public: enum Type type() const { return FUNC_ITEM; } virtual enum Functype functype() const { return UNKNOWN_FUNC; } Item_func(void): - allowed_arg_cols(1), persistent_maybe_null(0), arg_count(0) + allowed_arg_cols(1), arg_count(0) { with_sum_func= 0; with_field= 0; } Item_func(Item *a): - allowed_arg_cols(1), persistent_maybe_null(0), arg_count(1) + allowed_arg_cols(1), arg_count(1) { args= tmp_arg; args[0]= a; @@ -79,7 +77,7 @@ public: with_field= a->with_field; } Item_func(Item *a,Item *b): - allowed_arg_cols(1), persistent_maybe_null(0), arg_count(2) + allowed_arg_cols(1), arg_count(2) { args= tmp_arg; args[0]= a; args[1]= b; @@ -87,7 +85,7 @@ public: with_field= a->with_field || b->with_field; } Item_func(Item *a,Item *b,Item *c): - allowed_arg_cols(1), persistent_maybe_null(0) + allowed_arg_cols(1) { arg_count= 0; if ((args= (Item**) sql_alloc(sizeof(Item*)*3))) @@ -99,7 +97,7 @@ public: } } Item_func(Item *a,Item *b,Item *c,Item *d): - allowed_arg_cols(1), persistent_maybe_null(0) + allowed_arg_cols(1) { arg_count= 0; if ((args= (Item**) sql_alloc(sizeof(Item*)*4))) @@ -113,7 +111,7 @@ public: } } Item_func(Item *a,Item *b,Item *c,Item *d,Item* e): - allowed_arg_cols(1), persistent_maybe_null(0) + allowed_arg_cols(1) { arg_count= 5; if ((args= (Item**) sql_alloc(sizeof(Item*)*5))) @@ -305,11 +303,6 @@ public: info.bool_function= &Item::restore_to_before_no_rows_in_result; walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info); } - inline void set_persist_maybe_null(bool mb_null) - { - maybe_null= mb_null; - persistent_maybe_null= 1; - } }; @@ -582,7 +575,7 @@ public: } double val_real(); enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } - void fix_length_and_dec() { set_persist_maybe_null(1); } + void fix_length_and_dec() { maybe_null= 1; } const char *func_name() const { return "double_typecast"; } virtual void print(String *str, enum_query_type query_type); }; @@ -723,7 +716,7 @@ class Item_dec_func :public Item_real_func void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); - set_persist_maybe_null(1); + maybe_null=1; } }; @@ -1047,7 +1040,7 @@ public: Item_func_coercibility(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "coercibility"; } - void fix_length_and_dec() { max_length=10; set_persist_maybe_null(0); } + void fix_length_and_dec() { max_length=10; maybe_null= 0; } table_map not_null_tables() const { return 0; } }; @@ -1209,7 +1202,7 @@ public: {} longlong val_int(); const char *func_name() const { return "benchmark"; } - void fix_length_and_dec() { max_length=1; set_persist_maybe_null(0); } + void fix_length_and_dec() { max_length=1; maybe_null=0; } virtual void print(String *str, enum_query_type query_type); bool check_vcol_func_processor(uchar *int_arg) { @@ -1462,7 +1455,7 @@ public: double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } enum Item_result result_type () const { return STRING_RESULT; } - void fix_length_and_dec() { set_persist_maybe_null(1); max_length=0; } + void fix_length_and_dec() { maybe_null=1; max_length=0; } }; #endif /* HAVE_DLOPEN */ @@ -1483,7 +1476,7 @@ class Item_func_get_lock :public Item_int_func Item_func_get_lock(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "get_lock"; } - void fix_length_and_dec() { max_length=1; set_persist_maybe_null(1);} + void fix_length_and_dec() { max_length=1; maybe_null=1;} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1497,7 +1490,7 @@ public: Item_func_release_lock(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "release_lock"; } - void fix_length_and_dec() { max_length=1; set_persist_maybe_null(1);} + void fix_length_and_dec() { max_length=1; maybe_null=1;} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1514,7 +1507,7 @@ public: Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {} longlong val_int(); const char *func_name() const { return "master_pos_wait"; } - void fix_length_and_dec() { max_length=21; set_persist_maybe_null(1);} + void fix_length_and_dec() { max_length=21; maybe_null=1;} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1732,8 +1725,7 @@ public: Item_func_inet_aton(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "inet_aton"; } - void fix_length_and_dec() - { decimals= 0; max_length= 21; set_persist_maybe_null(1); unsigned_flag= 1; } + void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;} }; @@ -1801,8 +1793,7 @@ public: Item_func_is_free_lock(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "is_free_lock"; } - void fix_length_and_dec() - { decimals= 0; max_length= 1; set_persist_maybe_null(1); } + void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1816,8 +1807,7 @@ public: Item_func_is_used_lock(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "is_used_lock"; } - void fix_length_and_dec() - { decimals= 0; max_length= 10; set_persist_maybe_null(1);} + void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;} bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); @@ -1840,7 +1830,7 @@ public: Item_func_row_count() :Item_int_func() {} longlong val_int(); const char *func_name() const { return "row_count"; } - void fix_length_and_dec() { decimals= 0; set_persist_maybe_null(0); } + void fix_length_and_dec() { decimals= 0; maybe_null=0; } bool check_vcol_func_processor(uchar *int_arg) { @@ -1975,7 +1965,7 @@ public: Item_func_found_rows() :Item_int_func() {} longlong val_int(); const char *func_name() const { return "found_rows"; } - void fix_length_and_dec() { decimals= 0; set_persist_maybe_null(0); } + void fix_length_and_dec() { decimals= 0; maybe_null=0; } bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 1168813e275..211140c029b 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -52,7 +52,7 @@ void Item_geometry_func::fix_length_and_dec() collation.set(&my_charset_bin); decimals=0; max_length= (uint32) 4294967295U; - set_persist_maybe_null(1); + maybe_null= 1; } @@ -145,7 +145,7 @@ void Item_func_as_wkt::fix_length_and_dec() { collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); max_length=MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index eae6f425f4d..d2030ee7bb9 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -89,7 +89,7 @@ public: { // "GeometryCollection" is the longest max_length= 20; - set_persist_maybe_null(1); + maybe_null= 1; }; }; @@ -224,7 +224,7 @@ public: { Item_func::print(str, query_type); } - void fix_length_and_dec() { set_persist_maybe_null(1); } + void fix_length_and_dec() { maybe_null= 1; } bool is_null() { (void) val_int(); return null_value; } }; @@ -251,7 +251,7 @@ public: Item_func::print(str, query_type); } - void fix_length_and_dec() { set_persist_maybe_null(1); } + void fix_length_and_dec() { maybe_null= 1; } bool is_null() { (void) val_int(); return null_value; } }; @@ -342,7 +342,7 @@ public: longlong val_int(); optimize_type select_optimize() const { return OPTIMIZE_NONE; } const char *func_name() const { return "st_isempty"; } - void fix_length_and_dec() { set_persist_maybe_null(1); } + void fix_length_and_dec() { maybe_null= 1; } }; class Item_func_issimple: public Item_bool_func @@ -356,7 +356,7 @@ public: longlong val_int(); optimize_type select_optimize() const { return OPTIMIZE_NONE; } const char *func_name() const { return "st_issimple"; } - void fix_length_and_dec() { set_persist_maybe_null(1); } + void fix_length_and_dec() { maybe_null= 1; } }; class Item_func_isclosed: public Item_bool_func @@ -366,7 +366,7 @@ public: longlong val_int(); optimize_type select_optimize() const { return OPTIMIZE_NONE; } const char *func_name() const { return "st_isclosed"; } - void fix_length_and_dec() { set_persist_maybe_null(1); } + void fix_length_and_dec() { maybe_null= 1; } }; class Item_func_dimension: public Item_int_func @@ -376,7 +376,7 @@ public: Item_func_dimension(Item *a): Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "st_dimension"; } - void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); } + void fix_length_and_dec() { max_length= 10; maybe_null= 1; } }; class Item_func_x: public Item_real_func @@ -389,7 +389,7 @@ public: void fix_length_and_dec() { Item_real_func::fix_length_and_dec(); - set_persist_maybe_null(1); + maybe_null= 1; } }; @@ -404,7 +404,7 @@ public: void fix_length_and_dec() { Item_real_func::fix_length_and_dec(); - set_persist_maybe_null(1); + maybe_null= 1; } }; @@ -416,7 +416,7 @@ public: Item_func_numgeometries(Item *a): Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "st_numgeometries"; } - void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); } + void fix_length_and_dec() { max_length= 10; maybe_null= 1; } }; @@ -427,7 +427,7 @@ public: Item_func_numinteriorring(Item *a): Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "st_numinteriorrings"; } - void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); } + void fix_length_and_dec() { max_length= 10; maybe_null= 1; } }; @@ -438,7 +438,7 @@ public: Item_func_numpoints(Item *a): Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "st_numpoints"; } - void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); } + void fix_length_and_dec() { max_length= 10; maybe_null= 1; } }; @@ -452,7 +452,7 @@ public: void fix_length_and_dec() { Item_real_func::fix_length_and_dec(); - set_persist_maybe_null(1); + maybe_null= 1; } }; @@ -467,7 +467,7 @@ public: void fix_length_and_dec() { Item_real_func::fix_length_and_dec(); - set_persist_maybe_null(1); + maybe_null= 1; } }; @@ -479,7 +479,7 @@ public: Item_func_srid(Item *a): Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "srid"; } - void fix_length_and_dec() { max_length= 10; set_persist_maybe_null(1); } + void fix_length_and_dec() { max_length= 10; maybe_null= 1; } }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 50ca7d91a53..a21dd9cc02a 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -272,7 +272,7 @@ String *Item_func_aes_decrypt::val_str(String *str) void Item_func_aes_decrypt::fix_length_and_dec() { max_length=args[0]->max_length; - set_persist_maybe_null(1); + maybe_null= 1; } @@ -435,7 +435,7 @@ void Item_func_concat::fix_length_and_dec() if (max_result_length >= MAX_BLOB_WIDTH) { max_result_length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } max_length= (ulong) max_result_length; } @@ -795,7 +795,7 @@ void Item_func_concat_ws::fix_length_and_dec() if (max_result_length >= MAX_BLOB_WIDTH) { max_result_length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } max_length= (ulong) max_result_length; } @@ -997,7 +997,7 @@ void Item_func_replace::fix_length_and_dec() if (max_result_length >= MAX_BLOB_WIDTH) { max_result_length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } max_length= (ulong) max_result_length; @@ -1081,7 +1081,7 @@ void Item_func_insert::fix_length_and_dec() if (max_result_length >= MAX_BLOB_WIDTH) { max_result_length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } max_length= (ulong) max_result_length; } @@ -2186,7 +2186,7 @@ void Item_func_elt::fix_length_and_dec() set_if_bigger(max_length,args[i]->max_length); set_if_bigger(decimals,args[i]->decimals); } - set_persist_maybe_null(1); // NULL if wrong first arg + maybe_null=1; // NULL if wrong first arg } @@ -2366,14 +2366,14 @@ void Item_func_repeat::fix_length_and_dec() if (max_result_length >= MAX_BLOB_WIDTH) { max_result_length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } max_length= (ulong) max_result_length; } else { max_length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } } @@ -2458,14 +2458,14 @@ void Item_func_rpad::fix_length_and_dec() if (length >= MAX_BLOB_WIDTH) { length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } max_length= (ulong) length; } else { max_length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } } @@ -2577,14 +2577,14 @@ void Item_func_lpad::fix_length_and_dec() if (length >= MAX_BLOB_WIDTH) { length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } max_length= (ulong) length; } else { max_length= MAX_BLOB_WIDTH; - set_persist_maybe_null(1); + maybe_null= 1; } } @@ -3499,7 +3499,7 @@ bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref) void Item_func_dyncol_create::fix_length_and_dec() { - set_persist_maybe_null(1); + maybe_null= TRUE; collation.set(&my_charset_bin); decimals= 0; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 44eeb1ef876..bb2fc0d9a33 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -319,7 +319,7 @@ public: String *val_str(String *); void fix_length_and_dec() { - set_persist_maybe_null(1); + maybe_null=1; /* 9 = MAX ((8- (arg_len % 8)) + 1) */ max_length = args[0]->max_length + 9; } @@ -335,7 +335,7 @@ public: String *val_str(String *); void fix_length_and_dec() { - set_persist_maybe_null(1); + maybe_null=1; /* 9 = MAX ((8- (arg_len % 8)) + 1) */ max_length = args[0]->max_length - 9; } @@ -361,7 +361,7 @@ public: constructor_helper(); } String *val_str(String *); - void fix_length_and_dec() { set_persist_maybe_null(1); max_length = 13; } + void fix_length_and_dec() { maybe_null=1; max_length = 13; } const char *func_name() const { return "encrypt"; } bool check_vcol_func_processor(uchar *int_arg) { @@ -431,7 +431,7 @@ public: void fix_length_and_dec() { max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen; - set_persist_maybe_null(1); + maybe_null=1; } const char *func_name() const { return "database"; } const char *fully_qualified_func_name() const { return "database()"; } @@ -589,7 +589,7 @@ public: { collation.set(default_charset()); max_length=64; - set_persist_maybe_null(1); + maybe_null= 1; } }; @@ -616,7 +616,7 @@ public: Item_func_unhex(Item *a) :Item_str_func(a) { /* there can be bad hex strings */ - set_persist_maybe_null(1); + maybe_null= 1; } const char *func_name() const { return "unhex"; } String *val_str(String *); @@ -662,7 +662,7 @@ public: void fix_length_and_dec() { collation.set(&my_charset_bin, DERIVATION_COERCIBLE); - set_persist_maybe_null(1); + maybe_null=1; max_length=MAX_BLOB_WIDTH; } bool check_vcol_func_processor(uchar *int_arg) @@ -695,7 +695,7 @@ public: { decimals= 0; max_length= 3 * 8 + 7; - set_persist_maybe_null(1); + maybe_null= 1; } }; @@ -786,7 +786,7 @@ public: { collation.set(system_charset_info); max_length= 64 * collation.collation->mbmaxlen; // should be enough - set_persist_maybe_null(0); + maybe_null= 0; }; table_map not_null_tables() const { return 0; } }; @@ -801,7 +801,7 @@ public: { collation.set(system_charset_info); max_length= 64 * collation.collation->mbmaxlen; // should be enough - set_persist_maybe_null(0); + maybe_null= 0; }; table_map not_null_tables() const { return 0; } }; @@ -847,8 +847,7 @@ class Item_func_uncompress: public Item_str_func String buffer; public: Item_func_uncompress(Item *a): Item_str_func(a){} - void fix_length_and_dec() - { set_persist_maybe_null(1); max_length= MAX_BLOB_WIDTH; } + void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; } const char *func_name() const{return "uncompress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION }; @@ -920,7 +919,7 @@ public: max_length= MAX_DYNAMIC_COLUMN_LENGTH; } void fix_length_and_dec() - { set_persist_maybe_null(1); } + { maybe_null= 1; } /* Mark that collation can change between calls */ bool dynamic_result() { return 1; } @@ -939,8 +938,7 @@ class Item_func_dyncol_list: public Item_str_func { public: Item_func_dyncol_list(Item *str) :Item_str_func(str) {}; - void fix_length_and_dec() - { set_persist_maybe_null(1); max_length= MAX_BLOB_WIDTH; }; + void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; }; const char *func_name() const{ return "column_list"; } String *val_str(String *); }; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 37a9a42f392..6c304946abc 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -875,7 +875,7 @@ void Item_func_monthname::fix_length_and_dec() collation.set(cs, DERIVATION_COERCIBLE, repertoire); decimals=0; max_length= locale->max_month_name_length * collation.collation->mbmaxlen; - set_persist_maybe_null(1); + maybe_null=1; } @@ -1025,7 +1025,7 @@ void Item_func_dayname::fix_length_and_dec() collation.set(cs, DERIVATION_COERCIBLE, repertoire); decimals=0; max_length= locale->max_day_name_length * collation.collation->mbmaxlen; - set_persist_maybe_null(1); + maybe_null=1; } @@ -1407,7 +1407,7 @@ void Item_func_curdate::fix_length_and_dec() ltime.hour= ltime.minute= ltime.second= 0; ltime.time_type= MYSQL_TIMESTAMP_DATE; Item_datefunc::fix_length_and_dec(); - set_persist_maybe_null(0); + maybe_null= false; } /** @@ -1646,7 +1646,7 @@ void Item_func_date_format::fix_length_and_dec() collation.collation->mbmaxlen; set_if_smaller(max_length,MAX_BLOB_WIDTH); } - set_persist_maybe_null(1); // If wrong date + maybe_null=1; // If wrong date } @@ -2014,7 +2014,7 @@ void Item_extract::print(String *str, enum_query_type query_type) void Item_extract::fix_length_and_dec() { - set_persist_maybe_null(1); // If wrong date + maybe_null=1; // If wrong date switch (int_type) { case INTERVAL_YEAR: max_length=4; date_value=1; break; case INTERVAL_YEAR_MONTH: max_length=6; date_value=1; break; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 19a9ac12985..20365d4f25d 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -67,7 +67,7 @@ public: { decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } enum_monotonicity_info get_monotonicity_info() const; longlong val_int_endpoint(bool left_endp, bool *incl_endp); @@ -90,7 +90,7 @@ public: { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -123,7 +123,7 @@ public: collation.set(&my_charset_bin); decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -158,7 +158,7 @@ public: { decimals=0; max_length=3*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -179,7 +179,7 @@ public: { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -200,7 +200,7 @@ public: { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -221,7 +221,7 @@ public: { decimals=0; max_length=1*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -242,7 +242,7 @@ public: { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -263,7 +263,7 @@ public: { decimals=0; max_length=2*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } }; @@ -277,7 +277,7 @@ public: { decimals=0; max_length=6*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -300,7 +300,7 @@ public: { decimals=0; max_length=4*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -335,7 +335,7 @@ public: collation.set(&my_charset_bin); decimals=0; max_length=1*MY_CHARSET_BIN_MB_MAXLEN; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -372,7 +372,7 @@ public: decimals= args[0]->temporal_precision(arg0_expected_type()); set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); max_length=17 + (decimals ? decimals + 1 : 0); - set_persist_maybe_null(1); + maybe_null= true; } void find_num_type() { cached_result_type= decimals ? DECIMAL_RESULT : INT_RESULT; } @@ -424,7 +424,7 @@ public: const char *func_name() const { return "time_to_sec"; } void fix_num_length_and_dec() { - set_persist_maybe_null(1); + maybe_null= true; Item_func_seconds_hybrid::fix_num_length_and_dec(); } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} @@ -458,8 +458,8 @@ public: int save_in_field(Field *field, bool no_conversions) { return save_date_in_field(field); } void fix_length_and_dec() - { - set_persist_maybe_null(1); + { + maybe_null= true; max_length= mysql_temporal_int_part_length(field_type()); if (decimals) { @@ -475,7 +475,7 @@ public: We set maybe_null to 1 as default as any bad argument with date or time can get us to return NULL. */ - set_persist_maybe_null(1); + maybe_null= 1; } }; @@ -512,7 +512,7 @@ public: { store_now_in_TIME(<ime); Item_timefunc::fix_length_and_dec(); - set_persist_maybe_null(0); + maybe_null= false; } bool get_date(MYSQL_TIME *res, uint fuzzy_date); /* @@ -594,7 +594,7 @@ public: { store_now_in_TIME(<ime); Item_temporal_func::fix_length_and_dec(); - set_persist_maybe_null(0); + maybe_null= false; } bool get_date(MYSQL_TIME *res, uint fuzzy_date); virtual void store_now_in_TIME(MYSQL_TIME *now_time)=0; @@ -941,7 +941,7 @@ public: void fix_length_and_dec() { decimals=0; - set_persist_maybe_null(1); + maybe_null=1; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_vcol_func_processor(uchar *int_arg) { return FALSE;} @@ -963,7 +963,7 @@ public: void fix_length_and_dec() { decimals=0; - set_persist_maybe_null(1); + maybe_null=1; } virtual void print(String *str, enum_query_type query_type); }; @@ -985,7 +985,7 @@ public: const char *func_name() const { return "get_format"; } void fix_length_and_dec() { - set_persist_maybe_null(1); + maybe_null= 1; decimals=0; max_length=17*MY_CHARSET_BIN_MB_MAXLEN; } diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 4c12e6528ac..a873cc0b277 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2579,7 +2579,6 @@ void Item_xml_str_func::fix_length_and_dec() int rc; nodeset_func= 0; - set_persist_maybe_null(1); if (agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1)) return; diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index be56a83349f..ce33d161c79 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -30,10 +30,14 @@ protected: public: Item_xml_str_func(Item *a, Item *b): Item_str_func(a,b) - {} + { + maybe_null= TRUE; + } Item_xml_str_func(Item *a, Item *b, Item *c): Item_str_func(a,b,c) - {} + { + maybe_null= TRUE; + } void fix_length_and_dec(); String *parse_xml(String *raw_xml, String *parsed_xml_buf); bool check_vcol_func_processor(uchar *int_arg) diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index afc2dea359a..a8bfc8a11a7 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -622,6 +622,15 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) sl->context.outer_context= 0; // Prepare underlying views/DT first. sl->handle_derived(lex, DT_PREPARE); + + if (derived->outer_join) + { + /* Mark that table is part of OUTER JOIN and fields may be NULL */ + for (TABLE_LIST *cursor= (TABLE_LIST*) sl->table_list.first; + cursor; + cursor= cursor->next_local) + cursor->outer_join|= JOIN_TYPE_OUTER; + } } unit->derived= derived; @@ -716,6 +725,10 @@ exit: /* Add new temporary table to list of open derived tables */ table->next= thd->derived_tables; thd->derived_tables= table; + + /* If table is used by a left join, mark that any column may be null */ + if (derived->outer_join) + table->maybe_null= 1; } if (arena) thd->restore_active_arena(arena, &backup); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7f0362e6555..99157d9201b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8269,7 +8269,7 @@ make_outerjoin_info(JOIN *join) TABLE_LIST *tbl= table->pos_in_table_list; TABLE_LIST *embedding= tbl->embedding; - if (tbl->outer_join) + if (tbl->outer_join & (JOIN_TYPE_LEFT | JOIN_TYPE_RIGHT)) { /* Table tab is the only one inner table for outer join. @@ -12586,7 +12586,8 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top, table->embedding->nested_join->not_null_tables|= not_null_tables; } - if (!table->outer_join || (used_tables & not_null_tables)) + if (!(table->outer_join & (JOIN_TYPE_LEFT | JOIN_TYPE_RIGHT)) || + (used_tables & not_null_tables)) { /* For some of the inner tables there are conjunctive predicates diff --git a/sql/table.h b/sql/table.h index 49b9fe2a1b9..c3524ad3adf 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1202,6 +1202,7 @@ typedef struct st_schema_table #define JOIN_TYPE_LEFT 1 #define JOIN_TYPE_RIGHT 2 +#define JOIN_TYPE_OUTER 4 /* Marker that this is an outer join */ #define VIEW_SUID_INVOKER 0 #define VIEW_SUID_DEFINER 1