summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2021-04-18 15:29:13 +0300
committerMonty <monty@mariadb.org>2021-04-20 12:30:09 +0300
commit031f11717d9f351dfb12cd27c225c533e289261a (patch)
tree66da9cdbd1e8acb82da2e75e36a08b3461504716
parenteb4123eefc8e0ee4751d3cd3cc49ebf256aa9486 (diff)
downloadmariadb-git-031f11717d9f351dfb12cd27c225c533e289261a.tar.gz
Fix all warnings given by UBSAN
The easiest way to compile and test the server with UBSAN is to run: ./BUILD/compile-pentium64-ubsan and then run mysql-test-run. After this commit, one should be able to run this without any UBSAN warnings. There is still a few compiler warnings that should be fixed at some point, but these do not expose any real bugs. The 'special' cases where we disable, suppress or circumvent UBSAN are: - ref10 source (as here we intentionally do some shifts that UBSAN complains about. - x86 version of optimized int#korr() methods. UBSAN do not like unaligned memory access of integers. Fixed by using byte_order_generic.h when compiling with UBSAN - We use smaller thread stack with ASAN and UBSAN, which forced me to disable a few tests that prints the thread stack size. - Verifying class types does not work for shared libraries. I added suppression in mysql-test-run.pl for this case. - Added '#ifdef WITH_UBSAN' when using integer arithmetic where it is safe to have overflows (two cases, in item_func.cc). Things fixed: - Don't left shift signed values (byte_order_generic.h, mysqltest.c, item_sum.cc and many more) - Don't assign not non existing values to enum variables. - Ensure that bool and enum values are properly initialized in constructors. This was needed as UBSAN checks that these types has correct values when one copies an object. (gcalc_tools.h, ha_partition.cc, item_sum.cc, partition_element.h ...) - Ensure we do not called handler functions on unallocated objects or deleted objects. (events.cc, sql_acl.cc). - Fixed bugs in Item_sp::Item_sp() where we did not call constructor on Query_arena object. - Fixed several cast of objects to an incompatible class! (Item.cc, Item_buff.cc, item_timefunc.cc, opt_subselect.cc, sql_acl.cc, sql_select.cc ...) - Ensure we do not do integer arithmetic that causes over or underflows. This includes also ++ and -- of integers. (Item_func.cc, Item_strfunc.cc, item_timefunc.cc, sql_base.cc ...) - Added JSON_VALUE_UNITIALIZED to json_value_types and ensure that value_type is initialized to this instead of to -1, which is not a valid enum value for json_value_types. - Ensure we do not call memcpy() when second argument could be null. - Fixed that Item_func_str::make_empty_result() creates an empty string instead of a null string (safer as it ensures we do not do arithmetic on null strings). Other things: - Changed struct st_position to an OBJECT and added an initialization function to it to ensure that we do not copy or use uninitialized members. The change to a class was also motived that we used "struct st_position" and POSITION randomly trough the code which was confusing. - Notably big rewrite in sql_acl.cc to avoid using deleted objects. - Changed in sql_partition to use '^' instead of '-'. This is safe as the operator is either 0 or 0x8000000000000000ULL. - Added check for select_nr < INT_MAX in JOIN::build_explain() to avoid bug when get_select() could return NULL. - Reordered elements in POSITION for better alignment. - Changed sql_test.cc::print_plan() to use pointers instead of objects. - Fixed bug in find_set() where could could execute '1 << -1'. - Added variable have_sanitizer, used by mtr. (This variable was before only in 10.5 and up). It can now have one of two values: ASAN or UBSAN. - Moved ~Archive_share() from ha_archive.cc to ha_archive.h and marked it virtual. This was an effort to get UBSAN to work with loaded storage engines. I kept the change as the new place is better. - Added in CONNECT engine COLBLK::SetName(), to get around a wrong cast in tabutil.cpp. - Added HAVE_REPLICATION around usage of rgi_slave, to get embedded server to compile with UBSAN. (Patch from Marko). - Added #ifdef for powerpc64 to avoid a bug in old gcc versions related to integer arithmetic. Changes that should not be needed but had to be done to suppress warnings from UBSAN: - Added static_cast<<uint16_t>> around shift to get rid of a LOT of compiler warnings when using UBSAN. - Had to change some '/' of 2 base integers to shift to get rid of some compile time warnings. Reviewed by: - Json changes: Alexey Botchkov - Charset changes in ctype-uca.c: Alexander Barkov - InnoDB changes & Embedded server: Marko Mäkelä - sql_acl.cc changes: Vicențiu Ciorbaru - build_explain() changes: Sergey Petrunia
-rwxr-xr-xBUILD/SETUP.sh2
-rwxr-xr-xBUILD/compile-pentium64-ubsan29
-rw-r--r--client/mysqltest.cc2
-rw-r--r--cmake/configure.pl10
-rw-r--r--include/byte_order_generic.h8
-rw-r--r--include/byte_order_generic_x86.h1
-rw-r--r--include/json_lib.h1
-rw-r--r--include/my_byteorder.h4
-rw-r--r--include/my_compare.h11
-rw-r--r--include/myisampack.h10
-rw-r--r--mysql-test/include/not_asan.inc8
-rw-r--r--mysql-test/include/not_ubsan.inc8
-rw-r--r--mysql-test/main/mysqld--help.test2
-rwxr-xr-xmysql-test/mysql-test-run.pl9
-rw-r--r--mysql-test/suite/plugins/t/multiauth.test1
-rw-r--r--mysql-test/suite/sys_vars/inc/sysvars_server.inc2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result2
-rw-r--r--mysql-test/suite/sys_vars/t/thread_stack_basic.test2
-rw-r--r--mysys/ma_dyncol.c6
-rw-r--r--plugin/auth_ed25519/CMakeLists.txt4
-rw-r--r--sql/compat56.h4
-rw-r--r--sql/events.cc12
-rw-r--r--sql/field.h8
-rw-r--r--sql/gcalc_tools.h6
-rw-r--r--sql/ha_partition.cc1
-rw-r--r--sql/item.cc18
-rw-r--r--sql/item_buff.cc4
-rw-r--r--sql/item_cmpfunc.cc10
-rw-r--r--sql/item_func.cc74
-rw-r--r--sql/item_jsonfunc.cc5
-rw-r--r--sql/item_strfunc.cc16
-rw-r--r--sql/item_strfunc.h9
-rw-r--r--sql/item_sum.cc6
-rw-r--r--sql/item_timefunc.cc23
-rw-r--r--sql/opt_split.cc2
-rw-r--r--sql/opt_subselect.cc12
-rw-r--r--sql/partition_element.h3
-rw-r--r--sql/sql_acl.cc117
-rw-r--r--sql/sql_base.cc14
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h4
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_partition.cc2
-rw-r--r--sql/sql_select.cc47
-rw-r--r--sql/sql_select.h97
-rw-r--r--sql/sql_sequence.cc4
-rw-r--r--sql/sql_sequence.h4
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/sql_test.cc9
-rw-r--r--sql/strfunc.cc16
-rw-r--r--sql/sys_vars.cc18
-rw-r--r--sql/temporary_tables.cc16
-rw-r--r--storage/archive/ha_archive.cc15
-rw-r--r--storage/archive/ha_archive.h14
-rw-r--r--storage/connect/colblk.h2
-rw-r--r--storage/connect/connect.cc6
-rw-r--r--storage/connect/filamvct.cpp3
-rw-r--r--storage/connect/ha_connect.cc13
-rw-r--r--storage/connect/tabutil.cpp2
-rw-r--r--storage/innobase/include/page0page.ic2
-rw-r--r--storage/innobase/include/ut0ut.h2
-rw-r--r--storage/innobase/rem/rem0rec.cc10
-rw-r--r--storage/mroonga/lib/mrn_multiple_column_key_codec.cpp3
-rw-r--r--storage/mroonga/vendor/groonga/lib/alloc.c14
-rw-r--r--storage/mroonga/vendor/groonga/lib/db.c2
-rw-r--r--storage/mroonga/vendor/groonga/lib/pat.c4
-rw-r--r--storage/mroonga/vendor/groonga/lib/proc/proc_select.c3
-rw-r--r--storage/mroonga/vendor/groonga/lib/str.c5
-rw-r--r--storage/myisam/myisampack.c15
-rw-r--r--strings/ctype-simple.c5
-rw-r--r--strings/ctype-uca.c7
-rw-r--r--strings/json_lib.c1
73 files changed, 528 insertions, 291 deletions
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 44e74441de9..c3c7acecf96 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -141,7 +141,7 @@ elif [ "x$warning_mode" = "xmaintainer" ]; then
debug_extra_cflags="-g3"
else
# Both C and C++ warnings
- warnings="-Wall -Wextra -Wunused -Wwrite-strings -Wno-uninitialized -Wno-strict-aliasing -Wimplicit-fallthrough=2"
+ warnings="-Wall -Wextra -Wunused -Wwrite-strings -Wno-uninitialized -Wno-strict-aliasing -Wimplicit-fallthrough=2 -Wformat-security -Wvla"
# For more warnings, uncomment the following line
# warnings="$warnings -Wshadow"
diff --git a/BUILD/compile-pentium64-ubsan b/BUILD/compile-pentium64-ubsan
new file mode 100755
index 00000000000..bf56d84283f
--- /dev/null
+++ b/BUILD/compile-pentium64-ubsan
@@ -0,0 +1,29 @@
+#! /bin/sh
+# Copyright (c) 2018, MariaDB Corporation.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+
+# Compilation with UBSAN, The Undefined Behavior Sanitizer
+# We have to use -Wno-uninitialized and -Wno-unitialized we get a lot of false
+# positive warnings for this when compiling with -fsanitize=undefined.
+# We also have to compile without Spider as linking with Spider library does
+# not work. (errno: 11, undefined symbol: _ZTI12ha_partition)
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$pentium64_cflags $debug_cflags -fsanitize=undefined -DWITH_UBSAN -Wno-conversion -Wno-uninitialized"
+extra_configs="$pentium_configs $debug_configs -DWITH_UBSAN=ON -DMYSQL_MAINTAINER_MODE=NO --without-spider --without-tokudb"
+
+. "$path/FINISH.sh"
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 73a6f03d889..5dfcce53e83 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -10905,7 +10905,7 @@ int get_next_bit(REP_SET *set,uint lastpos)
start=set->bits+ ((lastpos+1) / WORD_BIT);
end=set->bits + set->size_of_bits;
- bits=start[0] & ~((1 << ((lastpos+1) % WORD_BIT)) -1);
+ bits=start[0] & ~((1U << ((lastpos+1) % WORD_BIT)) -1);
while (! bits && ++start < end)
bits=start[0];
diff --git a/cmake/configure.pl b/cmake/configure.pl
index c296c5ba4b8..4085110b6fa 100644
--- a/cmake/configure.pl
+++ b/cmake/configure.pl
@@ -93,6 +93,11 @@ foreach my $option (@ARGV)
{
$option = substr($option, 2);
}
+ elsif (substr ($option, 0, 2) eq "-D")
+ {
+ # Must be cmake config option
+ $option = substr($option, 1);
+ }
else
{
# This must be environment variable
@@ -119,6 +124,11 @@ foreach my $option (@ARGV)
$just_print=1;
next;
}
+ if ($option =~ /D.*=/)
+ {
+ $cmakeargs = $cmakeargs." -".$option;
+ next;
+ }
if($option =~ /with-plugins=/)
{
my @plugins= split(/,/, substr($option,13));
diff --git a/include/byte_order_generic.h b/include/byte_order_generic.h
index 8381941b9b9..d2b729a241d 100644
--- a/include/byte_order_generic.h
+++ b/include/byte_order_generic.h
@@ -28,10 +28,10 @@
(((uint32) (uchar) (A)[2]) << 16) |\
(((uint32) (uchar) (A)[1]) << 8) | \
((uint32) (uchar) (A)[0])))
-#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) |\
- (((int32) ((uchar) (A)[1]) << 8)) |\
- (((int32) ((uchar) (A)[2]) << 16)) |\
- (((int32) ((int16) (A)[3]) << 24)))
+#define sint4korr(A) (int32) (((uint32) ((uchar) (A)[0])) |\
+ (((uint32) ((uchar) (A)[1]) << 8)) |\
+ (((uint32) ((uchar) (A)[2]) << 16)) |\
+ (((uint32) ((uchar) (A)[3]) << 24)))
#define sint8korr(A) (longlong) uint8korr(A)
#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) |\
((uint16) ((uchar) (A)[1]) << 8))
diff --git a/include/byte_order_generic_x86.h b/include/byte_order_generic_x86.h
index 72e00be8c2c..c47564478c6 100644
--- a/include/byte_order_generic_x86.h
+++ b/include/byte_order_generic_x86.h
@@ -17,6 +17,7 @@
/*
Optimized function-like macros for the x86 architecture (_WIN32 included).
*/
+
#define sint2korr(A) (*((const int16 *) (A)))
#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
(((uint32) 255L << 24) | \
diff --git a/include/json_lib.h b/include/json_lib.h
index b6add6d13a3..bb649928eaa 100644
--- a/include/json_lib.h
+++ b/include/json_lib.h
@@ -172,6 +172,7 @@ enum json_states {
enum json_value_types
{
+ JSON_VALUE_UNINITALIZED=0,
JSON_VALUE_OBJECT=1,
JSON_VALUE_ARRAY=2,
JSON_VALUE_STRING=3,
diff --git a/include/my_byteorder.h b/include/my_byteorder.h
index c302781d9fc..abdf19a3632 100644
--- a/include/my_byteorder.h
+++ b/include/my_byteorder.h
@@ -31,10 +31,10 @@
format (low byte first). There are 'korr' (assume 'corrector') variants
for integer types, but 'get' (assume 'getter') for floating point types.
*/
-#if defined(__i386__) || defined(_WIN32)
+#if (defined(__i386__) || defined(_WIN32)) && !defined(WITH_UBSAN)
#define MY_BYTE_ORDER_ARCH_OPTIMIZED
#include "byte_order_generic_x86.h"
-#elif defined(__x86_64__)
+#elif defined(__x86_64__) && !defined(WITH_UBSAN)
#include "byte_order_generic_x86_64.h"
#else
#include "byte_order_generic.h"
diff --git a/include/my_compare.h b/include/my_compare.h
index 9ae6c9582fb..bd5dc418f8c 100644
--- a/include/my_compare.h
+++ b/include/my_compare.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2011, Oracle and/or its affiliates.
- Copyright (c) Monty Program Ab; 1991-2011
+ Copyright (c) 1991, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -95,15 +95,16 @@ static inline uchar get_rec_bits(const uchar *ptr, uchar ofs, uint len)
{
uint16 val= ptr[0];
if (ofs + len > 8)
- val|= (uint16)(ptr[1]) << 8;
- return (val >> ofs) & ((1 << len) - 1);
+ val|= (uint16)(((uint) ptr[1]) << 8);
+ return (uchar) ((val >> ofs) & ((1 << len) - 1));
}
static inline void set_rec_bits(uint16 bits, uchar *ptr, uchar ofs, uint len)
{
- ptr[0]= (ptr[0] & ~(((1 << len) - 1) << ofs)) | (bits << ofs);
+ ptr[0]= (uchar) ((ptr[0] & ~(((1 << len) - 1) << ofs)) | (bits << ofs));
if (ofs + len > 8)
- ptr[1]= (ptr[1] & ~((1 << (len - 8 + ofs)) - 1)) | (bits >> (8 - ofs));
+ ptr[1]= (uchar) ((ptr[1] & ~((1 << (len - 8 + ofs)) - 1)) |
+ bits >> (8 - ofs));
}
#define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \
diff --git a/include/myisampack.h b/include/myisampack.h
index 6bfe1958fbc..f3c5fe7114a 100644
--- a/include/myisampack.h
+++ b/include/myisampack.h
@@ -30,7 +30,7 @@
#define mi_uint1korr(A) ((uint8)(*A))
#define mi_sint2korr(A) ((int16) (((int16) (((const uchar*) (A))[1])) |\
- ((int16) ((int16) ((const char*) (A))[0]) << 8)))
+ ((int16) ((uint16) ((const uchar*) (A))[0]) << 8)))
#define mi_sint3korr(A) ((int32) (((((const uchar*) (A))[0]) & 128) ? \
(((uint32) 255L << 24) | \
(((uint32) ((const uchar*) (A))[0]) << 16) |\
@@ -39,10 +39,10 @@
(((uint32) ((const uchar*) (A))[0]) << 16) |\
(((uint32) ((const uchar*) (A))[1]) << 8) | \
((uint32) ((const uchar*) (A))[2])))
-#define mi_sint4korr(A) ((int32) (((int32) (((const uchar*) (A))[3])) |\
- ((int32) (((const uchar*) (A))[2]) << 8) |\
- ((int32) (((const uchar*) (A))[1]) << 16) |\
- ((int32) ((int16) ((const char*) (A))[0]) << 24)))
+#define mi_sint4korr(A) ((int32) (((uint32) (((const uchar*) (A))[3])) |\
+ ((uint32) (((const uchar*) (A))[2]) << 8) |\
+ ((uint32) (((const uchar*) (A))[1]) << 16) |\
+ ((uint32) (((const uchar*) (A))[0]) << 24)))
#define mi_sint8korr(A) ((longlong) mi_uint8korr(A))
#define mi_uint2korr(A) ((uint16) (((uint16) (((const uchar*) (A))[1])) |\
((uint16) (((const uchar*) (A))[0]) << 8)))
diff --git a/mysql-test/include/not_asan.inc b/mysql-test/include/not_asan.inc
new file mode 100644
index 00000000000..9fc86a8525a
--- /dev/null
+++ b/mysql-test/include/not_asan.inc
@@ -0,0 +1,8 @@
+# This file should only be used with test that finds bugs in ASan that can not
+# be overcome. In normal cases one should fix the bug server/test case or in
+# the worst case add a (temporary?) suppression in asan.supp or lsan.supp
+
+if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value="ASAN"`)
+{
+--skip Can't be run with ASan
+}
diff --git a/mysql-test/include/not_ubsan.inc b/mysql-test/include/not_ubsan.inc
new file mode 100644
index 00000000000..809f505507e
--- /dev/null
+++ b/mysql-test/include/not_ubsan.inc
@@ -0,0 +1,8 @@
+# This file should only be used with test that finds bugs in ASan that can not
+# be overcome. In normal cases one should fix the bug server/test case or in
+# the worst case add a (temporary?) suppression in asan.supp or lsan.supp
+
+if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value="UBSAN"`)
+{
+--skip Can't be run with UBSAN
+}
diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test
index 6efd088cbdd..6fff3f51006 100644
--- a/mysql-test/main/mysqld--help.test
+++ b/mysql-test/main/mysqld--help.test
@@ -2,6 +2,8 @@
# mysqld --help
#
--source include/not_embedded.inc
+--source include/not_asan.inc
+--source include/not_ubsan.inc
--source include/have_perfschema.inc
--source include/have_profiling.inc
--source include/platform.inc
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 98aed3b7933..e4ecc910556 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1731,7 +1731,6 @@ sub collect_mysqld_features {
}
-
sub collect_mysqld_features_from_running_server ()
{
my $mysql= mtr_exe_exists("$path_client_bindir/mysql");
@@ -4376,7 +4375,13 @@ sub extract_warning_lines ($$) {
qr/InnoDB: Table .*mysql.*innodb_table_stats.* not found./,
qr/InnoDB: User stopword table .* does not exist./,
qr/Dump thread [0-9]+ last sent to server [0-9]+ binlog file:pos .+/,
- qr/Detected table cache mutex contention at instance .* waits. Additional table cache instance cannot be activated: consider raising table_open_cache_instances. Number of active instances/
+ qr/Detected table cache mutex contention at instance .* waits. Additional table cache instance cannot be activated: consider raising table_open_cache_instances. Number of active instances/,
+
+ # for UBSAN
+ qr/decimal\.c.*: runtime error: signed integer overflow/,
+ # Disable test for UBSAN on dynamically loaded objects
+ qr/runtime error: member call.*object.*'Handler_share'/,
+ qr/sql_type\.cc.* runtime error: member call.*object.* 'Type_collection'/,
);
my $matched_lines= [];
diff --git a/mysql-test/suite/plugins/t/multiauth.test b/mysql-test/suite/plugins/t/multiauth.test
index cc6fc0c8644..4cf44fc7c65 100644
--- a/mysql-test/suite/plugins/t/multiauth.test
+++ b/mysql-test/suite/plugins/t/multiauth.test
@@ -1,3 +1,4 @@
+--source include/not_ubsan.inc
#
# MDEV-11340 Allow multiple alternative authentication methods for the same user
#
diff --git a/mysql-test/suite/sys_vars/inc/sysvars_server.inc b/mysql-test/suite/sys_vars/inc/sysvars_server.inc
index 36b41cbdc09..025f8a8922d 100644
--- a/mysql-test/suite/sys_vars/inc/sysvars_server.inc
+++ b/mysql-test/suite/sys_vars/inc/sysvars_server.inc
@@ -23,7 +23,7 @@ select VARIABLE_NAME,VARIABLE_SCOPE,VARIABLE_TYPE,VARIABLE_COMMENT,NUMERIC_MIN_V
variable_name not like 'wsrep%' and
variable_name not like 's3%' and
variable_name not in (
- 'log_tc_size'
+ 'log_tc_size','have_sanitizer'
)
order by variable_name;
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index 00927ebd4a5..7a8984a3736 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -9,7 +9,7 @@ where variable_name not like 'debug%' and
variable_name not like 'wsrep%' and
variable_name not like 's3%' and
variable_name not in (
-'log_tc_size'
+'log_tc_size','have_sanitizer'
)
order by variable_name;
VARIABLE_NAME ALTER_ALGORITHM
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 7bd3bedcc81..79512aa9032 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -9,7 +9,7 @@ where variable_name not like 'debug%' and
variable_name not like 'wsrep%' and
variable_name not like 's3%' and
variable_name not in (
-'log_tc_size'
+'log_tc_size','have_sanitizer'
)
order by variable_name;
VARIABLE_NAME ALTER_ALGORITHM
diff --git a/mysql-test/suite/sys_vars/t/thread_stack_basic.test b/mysql-test/suite/sys_vars/t/thread_stack_basic.test
index 41015033fe9..39f120e0de1 100644
--- a/mysql-test/suite/sys_vars/t/thread_stack_basic.test
+++ b/mysql-test/suite/sys_vars/t/thread_stack_basic.test
@@ -1,6 +1,8 @@
#
# only global
#
+--source include/not_asan.inc
+--source include/not_ubsan.inc
--replace_result 392192 299008
select @@global.thread_stack;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c
index 0085c375aa1..b438d910157 100644
--- a/mysys/ma_dyncol.c
+++ b/mysys/ma_dyncol.c
@@ -865,7 +865,7 @@ dynamic_column_uint_read(DYNAMIC_COLUMN_VALUE *store_it_here,
static size_t dynamic_column_sint_bytes(longlong val)
{
- return dynamic_column_uint_bytes((val << 1) ^
+ return dynamic_column_uint_bytes((((ulonglong) val) << 1) ^
(val < 0 ? 0xffffffffffffffffull : 0));
}
@@ -883,8 +883,8 @@ static enum enum_dyncol_func_result
dynamic_column_sint_store(DYNAMIC_COLUMN *str, longlong val)
{
return dynamic_column_uint_store(str,
- (val << 1) ^
- (val < 0 ? 0xffffffffffffffffULL : 0));
+ (((ulonglong) val) << 1) ^
+ (val < 0 ? 0xffffffffffffffffULL : 0));
}
diff --git a/plugin/auth_ed25519/CMakeLists.txt b/plugin/auth_ed25519/CMakeLists.txt
index 1a3d5cc4bce..1033dc053c8 100644
--- a/plugin/auth_ed25519/CMakeLists.txt
+++ b/plugin/auth_ed25519/CMakeLists.txt
@@ -19,6 +19,10 @@ IF(MSVC)
SET_SOURCE_FILES_PROPERTIES(${REF10_SOURCES} PROPERTY COMPILE_FLAGS "/wd4244 /wd4146")
ENDIF()
+IF(CMAKE_C_COMPILER_ID MATCHES "GNU" AND CMAKE_C_COMPILER_VERSION LESS 11 AND CMAKE_C_COMPILER_VERSION GREATER 6)
+ SET_SOURCE_FILES_PROPERTIES(${REF10_SOURCES} PROPERTY COMPILE_FLAGS -fno-sanitize=shift)
+ENDIF()
+
# server plugin *cannot* link with the library, it needs all sources to be
# compiled with MYSQL_DYNAMIC_PLUGIN
MYSQL_ADD_PLUGIN(auth_ed25519 server_ed25519.c ${REF10_SOURCES} MODULE_ONLY)
diff --git a/sql/compat56.h b/sql/compat56.h
index 347d6145048..65cd36dacfd 100644
--- a/sql/compat56.h
+++ b/sql/compat56.h
@@ -30,8 +30,8 @@
#define MY_PACKED_TIME_GET_INT_PART(x) ((x) >> 24)
#define MY_PACKED_TIME_GET_FRAC_PART(x) ((x) % (1LL << 24))
-#define MY_PACKED_TIME_MAKE(i, f) ((((longlong) (i)) << 24) + (f))
-#define MY_PACKED_TIME_MAKE_INT(i) ((((longlong) (i)) << 24))
+#define MY_PACKED_TIME_MAKE(i, f) ((((ulonglong) (i)) << 24) + (f))
+#define MY_PACKED_TIME_MAKE_INT(i) ((((ulonglong) (i)) << 24))
longlong TIME_to_longlong_datetime_packed(const MYSQL_TIME *);
longlong TIME_to_longlong_time_packed(const MYSQL_TIME *);
diff --git a/sql/events.cc b/sql/events.cc
index 195c0fa09e2..5e15b92dc49 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -658,8 +658,16 @@ Events::drop_schema_events(THD *thd, const char *db)
*/
if (event_queue)
event_queue->drop_schema_events(thd, &db_lex);
- db_repository->drop_schema_events(thd, &db_lex);
-
+ if (db_repository)
+ db_repository->drop_schema_events(thd, &db_lex);
+ else
+ {
+ if ((db_repository= new Event_db_repository))
+ {
+ db_repository->drop_schema_events(thd, &db_lex);
+ delete db_repository;
+ }
+ }
DBUG_VOID_RETURN;
}
diff --git a/sql/field.h b/sql/field.h
index 6cb19d1e238..421d6bddb2d 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -4534,7 +4534,13 @@ public:
void move_field_offset(my_ptrdiff_t ptr_diff)
{
Field::move_field_offset(ptr_diff);
- bit_ptr= ADD_TO_PTR(bit_ptr, ptr_diff, uchar*);
+
+ /*
+ clang does not like when things are added to a null pointer, even if
+ it is never referenced.
+ */
+ if (bit_ptr)
+ bit_ptr= ADD_TO_PTR(bit_ptr, ptr_diff, uchar*);
}
void hash(ulong *nr, ulong *nr2);
diff --git a/sql/gcalc_tools.h b/sql/gcalc_tools.h
index 77da791f0b9..e625b355d95 100644
--- a/sql/gcalc_tools.h
+++ b/sql/gcalc_tools.h
@@ -184,7 +184,11 @@ class Gcalc_result_receiver
double first_x, first_y, prev_x, prev_y;
double shape_area;
public:
- Gcalc_result_receiver() : collection_result(FALSE), n_shapes(0), n_holes(0)
+Gcalc_result_receiver() :
+ n_points(0),
+ common_shapetype(Gcalc_function::shape_point),
+ collection_result(FALSE), n_shapes(0), n_holes(0),
+ cur_shape(Gcalc_function::shape_point), shape_pos(0)
{}
int start_shape(Gcalc_function::shape_type shape);
int add_point(double x, double y);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 4c4a62e7fc4..24e08501bed 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -6461,6 +6461,7 @@ int ha_partition::multi_range_read_init(RANGE_SEQ_IF *seq,
DBUG_ENTER("ha_partition::multi_range_read_init");
DBUG_PRINT("enter", ("partition this: %p", this));
+ eq_range= 0;
m_seq_if= seq;
m_seq= seq->init(seq_init_param, n_ranges, mrr_mode);
if (unlikely((error= multi_range_key_create_key(seq, m_seq))))
diff --git a/sql/item.cc b/sql/item.cc
index 756f29a3ff8..6c52ade0d9f 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2599,9 +2599,7 @@ Item_sp::Item_sp(THD *thd, Name_resolution_context *context_arg,
dummy_table= (TABLE*) thd->calloc(sizeof(TABLE) + sizeof(TABLE_SHARE) +
sizeof(Query_arena));
dummy_table->s= (TABLE_SHARE*) (dummy_table + 1);
- /* TODO(cvicentiu) Move this sp_query_arena in the class as a direct member.
- Currently it can not be done due to header include dependencies. */
- sp_query_arena= (Query_arena *) (dummy_table->s + 1);
+ sp_query_arena= new(dummy_table->s + 1) Query_arena();
memset(&sp_mem_root, 0, sizeof(sp_mem_root));
}
@@ -2612,7 +2610,7 @@ Item_sp::Item_sp(THD *thd, Item_sp *item):
dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE) +
sizeof(Query_arena));
dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
- sp_query_arena= (Query_arena *) (dummy_table->s + 1);
+ sp_query_arena= new(dummy_table->s + 1) Query_arena();
memset(&sp_mem_root, 0, sizeof(sp_mem_root));
}
@@ -6208,12 +6206,14 @@ Item *Item_field::replace_equal_field(THD *thd, uchar *arg)
item_equal->compare_type_handler()->cmp_type());
return const_item2;
}
- Item_field *subst=
- (Item_field *)(item_equal->get_first(param->context_tab, this));
+ Item_ident *subst=
+ (Item_ident *) (item_equal->get_first(param->context_tab, this));
if (subst)
- subst= (Item_field *) (subst->real_item());
- if (subst && !field->eq(subst->field))
- return subst;
+ {
+ Item_field *subst2= (Item_field *) (subst->real_item());
+ if (subst2 && !field->eq(subst2->field))
+ return subst2;
+ }
}
return this;
}
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index 9c96fdb1a9a..05cef6871be 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -47,9 +47,9 @@ Cached_item *new_Cached_item(THD *thd, Item *item, bool pass_through_ref)
}
switch (item->result_type()) {
case STRING_RESULT:
- return new Cached_item_str(thd, (Item_field *) item);
+ return new Cached_item_str(thd, item);
case INT_RESULT:
- return new Cached_item_int((Item_field *) item);
+ return new Cached_item_int(item);
case REAL_RESULT:
return new Cached_item_real(item);
case DECIMAL_RESULT:
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 875aacec3bc..687aa7e192b 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -5657,13 +5657,17 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
if (!res2)
return FALSE; // Null argument
- const size_t len = res2->length();
- const char* first = res2->ptr();
- const char* last = first + len - 1;
+ const size_t len= res2->length();
+
/*
len must be > 2 ('%pattern%')
heuristic: only do TurboBM for pattern_len > 2
*/
+ if (len <= 2)
+ return FALSE;
+
+ const char* first= res2->ptr();
+ const char* last= first + len - 1;
if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
*first == wild_many &&
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 837156ce39a..d50fb22a154 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1095,17 +1095,20 @@ double Item_func_plus::real_op()
return check_float_overflow(value);
}
+#if defined(__powerpc64__) && GCC_VERSION >= 6003 && GCC_VERSION <= 10002
+#pragma GCC push_options
+#pragma GCC optimize ("no-expensive-optimizations")
+#endif
longlong Item_func_plus::int_op()
{
longlong val0= args[0]->val_int();
longlong val1= args[1]->val_int();
- longlong res= val0 + val1;
bool res_unsigned= FALSE;
+ longlong res;
if ((null_value= args[0]->null_value || args[1]->null_value))
return 0;
-
/*
First check whether the result can be represented as a
(bool unsigned_flag, longlong value) pair, then check if it is compatible
@@ -1146,16 +1149,29 @@ longlong Item_func_plus::int_op()
{
if (val0 >=0 && val1 >= 0)
res_unsigned= TRUE;
- else if (val0 < 0 && val1 < 0 && res >= 0)
+ else if (val0 < 0 && val1 < 0 && val0 < (LONGLONG_MIN - val1))
goto err;
}
}
+
+#ifndef WITH_UBSAN
+ res= val0 + val1;
+#else
+ if (res_unsigned)
+ res= (longlong) ((ulonglong) val0 + (ulonglong) val1);
+ else
+ res= val0+val1;
+#endif /* WITH_UBSAN */
+
return check_integer_overflow(res, res_unsigned);
err:
return raise_integer_overflow();
}
+#if defined(__powerpc64__) && GCC_VERSION >= 6003 && GCC_VERSION <= 10002
+#pragma GCC pop_options
+#endif
/**
Calculate plus of two decimals.
@@ -1248,12 +1264,17 @@ double Item_func_minus::real_op()
}
+#if defined(__powerpc64__) && GCC_VERSION >= 6003 && GCC_VERSION <= 10002
+#pragma GCC push_options
+#pragma GCC optimize ("no-expensive-optimizations")
+#endif
+
longlong Item_func_minus::int_op()
{
longlong val0= args[0]->val_int();
longlong val1= args[1]->val_int();
- longlong res= val0 - val1;
bool res_unsigned= FALSE;
+ longlong res;
if ((null_value= args[0]->null_value || args[1]->null_value))
return 0;
@@ -1268,12 +1289,8 @@ longlong Item_func_minus::int_op()
if (args[1]->unsigned_flag)
{
if ((ulonglong) val0 < (ulonglong) val1)
- {
- if (res >= 0)
- goto err;
- }
- else
- res_unsigned= TRUE;
+ goto err;
+ res_unsigned= TRUE;
}
else
{
@@ -1294,23 +1311,35 @@ longlong Item_func_minus::int_op()
{
if (args[1]->unsigned_flag)
{
- if ((ulonglong) (val0 - LONGLONG_MIN) < (ulonglong) val1)
+ if (((ulonglong) val0 - (ulonglong) LONGLONG_MIN) < (ulonglong) val1)
goto err;
}
else
{
if (val0 > 0 && val1 < 0)
res_unsigned= TRUE;
- else if (val0 < 0 && val1 > 0 && res >= 0)
+ else if (val0 < 0 && val1 > 0 && val0 < (LONGLONG_MIN + val1))
goto err;
}
}
+#ifndef WITH_UBSAN
+ res= val0 - val1;
+#else
+ if (res_unsigned)
+ res= (longlong) ((ulonglong) val0 - (ulonglong) val1);
+ else
+ res= val0 - val1;
+#endif /* WITH_UBSAN */
+
return check_integer_overflow(res, res_unsigned);
err:
return raise_integer_overflow();
}
+#if defined(__powerpc64__) && GCC_VERSION >= 6003 && GCC_VERSION <= 10002
+#pragma GCC pop_options
+#endif
/**
See Item_func_plus::decimal_op for comments.
@@ -2130,31 +2159,29 @@ double Item_func_cot::val_real()
longlong Item_func_shift_left::val_int()
{
DBUG_ASSERT(fixed == 1);
- uint shift;
- ulonglong res= ((ulonglong) args[0]->val_int() <<
- (shift=(uint) args[1]->val_int()));
+ uint shift= (uint) args[1]->val_int();
+ ulonglong value= args[0]->val_int();
if (args[0]->null_value || args[1]->null_value)
{
null_value=1;
return 0;
}
null_value=0;
- return (shift < sizeof(longlong)*8 ? (longlong) res : 0);
+ return (shift < sizeof(longlong)*8 ? (value << shift) : 0);
}
longlong Item_func_shift_right::val_int()
{
DBUG_ASSERT(fixed == 1);
- uint shift;
- ulonglong res= (ulonglong) args[0]->val_int() >>
- (shift=(uint) args[1]->val_int());
+ uint shift= (uint) args[1]->val_int();
+ ulonglong value= args[0]->val_int();
if (args[0]->null_value || args[1]->null_value)
{
null_value=1;
return 0;
}
null_value=0;
- return (shift < sizeof(longlong)*8 ? (longlong) res : 0);
+ return (shift < sizeof(longlong)*8 ? (value >> shift) : 0);
}
@@ -3054,10 +3081,11 @@ longlong Item_func_locate::val_int()
if (arg_count == 3)
{
- start0= start= args[2]->val_int() - 1;
+ start0= start= args[2]->val_int();
- if ((start < 0) || (start > a->length()))
+ if ((start <= 0) || (start > a->length()))
return 0;
+ start0--; start--;
/* start is now sufficiently valid to pass to charpos function */
start= a->charpos((int) start);
@@ -3222,7 +3250,7 @@ bool Item_func_find_in_set::fix_length_and_dec()
find->length(), 0);
enum_bit=0;
if (enum_value)
- enum_bit=1LL << (enum_value-1);
+ enum_bit= 1ULL << (enum_value-1);
}
}
}
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index 0d15c5e9ad0..4b4a94c814e 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -618,8 +618,6 @@ String *Item_func_json_unquote::read_json(json_engine_t *je)
json_scan_start(je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length());
- je->value_type= (enum json_value_types) -1; /* To report errors right. */
-
if (json_read_value(je))
goto error;
@@ -982,7 +980,8 @@ my_decimal *Item_func_json_extract::val_decimal(my_decimal *to)
case JSON_VALUE_ARRAY:
case JSON_VALUE_FALSE:
case JSON_VALUE_NULL:
- break;
+ case JSON_VALUE_UNINITALIZED:
+ break;
};
}
int2my_decimal(E_DEC_FATAL_ERROR, 0, false/*unsigned_flag*/, to);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index ea14e9d44f8..759b18c4657 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1514,17 +1514,18 @@ String *Item_func_insert::val_str(String *str)
null_value=0;
res=args[0]->val_str(str);
res2=args[3]->val_str(&tmp_value);
- start= args[1]->val_int() - 1;
+ start= args[1]->val_int();
length= args[2]->val_int();
if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
args[3]->null_value)
goto null; /* purecov: inspected */
- if ((start < 0) || (start > res->length()))
+ if ((start <= 0) || (start > res->length()))
return res; // Wrong param; skip insert
if ((length < 0) || (length > res->length()))
length= res->length();
+ start--;
/*
There is one exception not handled (intentionaly) by the character set
@@ -3795,13 +3796,12 @@ String *Item_func_unhex::val_str(String *str)
}
for (end=res->ptr()+res->length(); from < end ; from+=2, to++)
{
- int hex_char;
- *to= (hex_char= hexchar_to_int(from[0])) << 4;
- if ((null_value= (hex_char == -1)))
- return 0;
- *to|= hex_char= hexchar_to_int(from[1]);
- if ((null_value= (hex_char == -1)))
+ int hex_char1, hex_char2;
+ hex_char1= hexchar_to_int(from[0]);
+ hex_char2= hexchar_to_int(from[1]);
+ if ((null_value= (hex_char1 == -1 || hex_char2 == -1)))
return 0;
+ *to= (char) ((hex_char1 << 4) | hex_char2);
}
return str;
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index c13c49b8363..826a978805e 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -42,8 +42,13 @@ protected:
we don't want to free and potentially have to reallocate the buffer
for each call.
*/
- str_value.length(0);
- str_value.set_charset(collation.collation);
+ if (!str_value.is_alloced())
+ str_value.set("", 0, collation.collation); /* Avoid null ptrs */
+ else
+ {
+ str_value.length(0); /* Reuse allocated area */
+ str_value.set_charset(collation.collation);
+ }
return &str_value;
}
public:
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index c97220fd686..581c94bd191 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2635,9 +2635,9 @@ bool Item_sum_bit::add_as_window(ulonglong value)
void Item_sum_or::set_bits_from_counters()
{
ulonglong value= 0;
- for (int i= 0; i < NUM_BIT_COUNTERS; i++)
+ for (uint i= 0; i < NUM_BIT_COUNTERS; i++)
{
- value|= bit_counters[i] > 0 ? (1 << i) : 0;
+ value|= bit_counters[i] > 0 ? (1ULL << i) : 0ULL;
}
bits= value | reset_bits;
}
@@ -3738,7 +3738,7 @@ Item_func_group_concat(THD *thd, Name_resolution_context *context_arg,
arg_count_field(select_list->elements),
row_count(0),
distinct(distinct_arg),
- warning_for_row(FALSE),
+ warning_for_row(FALSE), always_null(FALSE),
force_copy_fields(0), row_limit(NULL),
offset_limit(NULL), limit_clause(limit_clause),
copy_offset_limit(0), copy_row_limit(0), original(0)
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index b476b5f1f27..7dbc81e8825 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -733,7 +733,10 @@ static bool make_date_time(const LEX_CSTRING &format, MYSQL_TIME *l_time,
For example, '1.1' -> '1.100000'
*/
-static bool get_interval_info(const char *str, size_t length,CHARSET_INFO *cs, size_t count, ulonglong *values,
+#define MAX_DIGITS_IN_TIME_SPEC 20
+
+static bool get_interval_info(const char *str, size_t length,CHARSET_INFO *cs,
+ size_t count, ulonglong *values,
bool transform_msec)
{
const char *end=str+length;
@@ -745,11 +748,21 @@ static bool get_interval_info(const char *str, size_t length,CHARSET_INFO *cs, s
for (i=0 ; i < count ; i++)
{
- longlong value;
+ ulonglong value;
const char *start= str;
- for (value= 0; str != end && my_isdigit(cs, *str); str++)
+ const char *local_end= end;
+
+ /*
+ We limit things to 19 digits to not get an overflow. This is ok as
+ this function is meant to read up to microseconds
+ */
+ if ((local_end-str) > MAX_DIGITS_IN_TIME_SPEC)
+ local_end= str+ MAX_DIGITS_IN_TIME_SPEC;
+
+ for (value= 0; str != local_end && my_isdigit(cs, *str) ; str++)
value= value*10 + *str - '0';
- if ((field_length= (size_t)(str - start)) >= 20)
+
+ if ((field_length= (size_t)(str - start)) >= MAX_DIGITS_IN_TIME_SPEC)
return true;
values[i]= value;
while (str != end && !my_isdigit(cs,*str))
@@ -2070,9 +2083,9 @@ bool Func_handler_date_add_interval_datetime_arg0_time::
bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
{
- Item_date_add_interval *other= (Item_date_add_interval*) item;
if (!Item_func::eq(item, binary_cmp))
return 0;
+ Item_date_add_interval *other= (Item_date_add_interval*) item;
return ((int_type == other->int_type) &&
(date_sub_interval == other->date_sub_interval));
}
diff --git a/sql/opt_split.cc b/sql/opt_split.cc
index c3a2d03a93b..395422de3c3 100644
--- a/sql/opt_split.cc
+++ b/sql/opt_split.cc
@@ -204,7 +204,7 @@ struct SplM_field_info
struct SplM_plan_info
{
/* The cached splitting execution plan P */
- struct st_position *best_positions;
+ POSITION *best_positions;
/* The cost of the above plan */
double cost;
/* Selectivity of splitting used in P */
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index f7349e7a1bf..7bd778e339f 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -2990,7 +2990,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
}
-void Sj_materialization_picker::set_from_prev(struct st_position *prev)
+void Sj_materialization_picker::set_from_prev(POSITION *prev)
{
if (prev->sjmat_picker.is_used)
set_empty();
@@ -3176,7 +3176,7 @@ bool Sj_materialization_picker::check_qep(JOIN *join,
}
-void LooseScan_picker::set_from_prev(struct st_position *prev)
+void LooseScan_picker::set_from_prev(POSITION *prev)
{
if (prev->loosescan_picker.is_used)
set_empty();
@@ -3197,7 +3197,7 @@ bool LooseScan_picker::check_qep(JOIN *join,
double *read_time,
table_map *handled_fanout,
sj_strategy_enum *strategy,
- struct st_position *loose_scan_pos)
+ POSITION *loose_scan_pos)
{
POSITION *first= join->positions + first_loosescan_table;
/*
@@ -3275,7 +3275,7 @@ bool LooseScan_picker::check_qep(JOIN *join,
return FALSE;
}
-void Firstmatch_picker::set_from_prev(struct st_position *prev)
+void Firstmatch_picker::set_from_prev(POSITION *prev)
{
if (prev->firstmatch_picker.is_used)
invalidate_firstmatch_prefix();
@@ -5789,8 +5789,8 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
((Item_func *) item)->functype() == Item_func::EQ_FUNC &&
check_simple_equality(thd,
Item::Context(Item::ANY_SUBST,
- ((Item_func_equal *)item)->compare_type_handler(),
- ((Item_func_equal *)item)->compare_collation()),
+ ((Item_func_eq *)item)->compare_type_handler(),
+ ((Item_func_eq *)item)->compare_collation()),
((Item_func *)item)->arguments()[0],
((Item_func *)item)->arguments()[1],
&new_cond_equal))
diff --git a/sql/partition_element.h b/sql/partition_element.h
index ff0d0d59fc4..e0a519065cc 100644
--- a/sql/partition_element.h
+++ b/sql/partition_element.h
@@ -144,6 +144,7 @@ public:
part_min_rows(part_elem->part_min_rows),
range_value(0), partition_name(NULL),
tablespace_name(part_elem->tablespace_name),
+ log_entry(NULL),
part_comment(part_elem->part_comment),
data_file_name(part_elem->data_file_name),
index_file_name(part_elem->index_file_name),
@@ -152,6 +153,8 @@ public:
part_state(part_elem->part_state),
nodegroup_id(part_elem->nodegroup_id),
has_null_value(FALSE),
+ signed_flag(part_elem->signed_flag),
+ max_value(part_elem->max_value),
id(part_elem->id),
empty(part_elem->empty),
type(CONVENTIONAL)
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index ddaa54588d7..96f1b87d5d7 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -5348,7 +5348,7 @@ routine_hash_search(const char *host, const char *ip, const char *db,
const char *user, const char *tname, const Sp_handler *sph,
bool exact)
{
- return (GRANT_TABLE*)
+ return (GRANT_NAME*)
name_hash_search(sph->get_priv_hash(),
host, ip, db, user, tname, exact, TRUE);
}
@@ -5362,6 +5362,10 @@ table_hash_search(const char *host, const char *ip, const char *db,
user, tname, exact, FALSE);
}
+static bool column_priv_insert(GRANT_TABLE *grant)
+{
+ return my_hash_insert(&column_priv_hash,(uchar*) grant);
+}
static GRANT_COLUMN *
column_hash_search(GRANT_TABLE *t, const char *cname, size_t length)
@@ -5591,6 +5595,15 @@ static inline void get_grantor(THD *thd, char *grantor)
strxmov(grantor, user, "@", host, NullS);
}
+
+/**
+ Revoke rights from a grant table entry.
+
+ @return 0 ok
+ @return 1 fatal error (error given)
+ @return -1 grant table was revoked
+*/
+
static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
TABLE *table, const LEX_USER &combo,
const char *db, const char *table_name,
@@ -5615,7 +5628,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
{
my_message(ER_PASSWORD_NO_MATCH, ER_THD(thd, ER_PASSWORD_NO_MATCH),
MYF(0)); /* purecov: deadcode */
- DBUG_RETURN(-1); /* purecov: deadcode */
+ DBUG_RETURN(1); /* purecov: deadcode */
}
}
@@ -5646,7 +5659,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
combo.user.str, combo.host.str,
table_name); /* purecov: deadcode */
- DBUG_RETURN(-1); /* purecov: deadcode */
+ DBUG_RETURN(1); /* purecov: deadcode */
}
old_row_exists = 0;
restore_record(table,record[1]); // Get saved record
@@ -5709,13 +5722,14 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
else
{
my_hash_delete(&column_priv_hash,(uchar*) grant_table);
+ DBUG_RETURN(-1); // Entry revoked
}
DBUG_RETURN(0);
/* This should never happen */
table_error:
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
- DBUG_RETURN(-1); /* purecov: deadcode */
+ DBUG_RETURN(1); /* purecov: deadcode */
}
@@ -6476,7 +6490,7 @@ static int update_role_table_columns(GRANT_TABLE *merged,
privs, cols);
merged->init_privs= merged->init_cols= 0;
update_role_columns(merged, first, last);
- my_hash_insert(&column_priv_hash,(uchar*) merged);
+ column_priv_insert(merged);
return 2;
}
else if ((privs | cols) == 0)
@@ -6796,7 +6810,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
bool revoke_grant)
{
ulong column_priv= 0;
- int result;
+ int result, res;
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str, *tmp_Str;
bool create_new_users=0;
@@ -6939,12 +6953,12 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
result= TRUE;
continue;
}
- grant_table = new GRANT_TABLE (Str->host.str, db_name,
- Str->user.str, table_name,
- rights,
- column_priv);
+ grant_table= new (&grant_memroot) GRANT_TABLE(Str->host.str, db_name,
+ Str->user.str, table_name,
+ rights,
+ column_priv);
if (!grant_table ||
- my_hash_insert(&column_priv_hash,(uchar*) grant_table))
+ column_priv_insert(grant_table))
{
result= TRUE; /* purecov: deadcode */
continue; /* purecov: deadcode */
@@ -6987,22 +7001,24 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
/* TODO(cvicentiu) refactor replace_table_table to use Tables_priv_table
instead of TABLE directly. */
- if (replace_table_table(thd, grant_table, tables.tables_priv_table().table(),
- *Str, db_name, table_name,
- rights, column_priv, revoke_grant))
- {
- /* Should only happen if table is crashed */
- result= TRUE; /* purecov: deadcode */
- }
- else if (tables.columns_priv_table().table_exists())
+ if (tables.columns_priv_table().table_exists())
{
/* TODO(cvicentiu) refactor replace_column_table to use Columns_priv_table
instead of TABLE directly. */
if (replace_column_table(grant_table, tables.columns_priv_table().table(),
*Str, columns, db_name, table_name, rights,
revoke_grant))
- {
result= TRUE;
+ }
+ if ((res= replace_table_table(thd, grant_table,
+ tables.tables_priv_table().table(),
+ *Str, db_name, table_name,
+ rights, column_priv, revoke_grant)))
+ {
+ if (res > 0)
+ {
+ /* Should only happen if table is crashed */
+ result= TRUE; /* purecov: deadcode */
}
}
if (Str->is_role())
@@ -7014,9 +7030,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
mysql_mutex_unlock(&acl_cache->lock);
if (!result) /* success */
- {
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
- }
mysql_rwlock_unlock(&LOCK_grant);
@@ -7704,7 +7718,7 @@ static bool grant_load(THD *thd,
if (! mem_check->ok())
delete mem_check;
- else if (my_hash_insert(&column_priv_hash,(uchar*) mem_check))
+ else if (column_priv_insert(mem_check))
{
delete mem_check;
goto end_unlock;
@@ -11100,7 +11114,7 @@ mysql_revoke_sp_privs(THD *thd, Grant_tables *tables, const Sp_handler *sph,
bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
{
uint counter, revoked;
- int result;
+ int result, res;
ACL_DB *acl_db;
DBUG_ENTER("mysql_revoke_all");
@@ -11193,36 +11207,35 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
if (!strcmp(lex_user->user.str,user) &&
!strcmp(lex_user->host.str, host))
{
- /* TODO(cvicentiu) refactor replace_db_table to use
- Db_table instead of TABLE directly. */
- if (replace_table_table(thd, grant_table,
- tables.tables_priv_table().table(),
- *lex_user, grant_table->db,
- grant_table->tname, ~(ulong)0, 0, 1))
- {
+ List<LEX_COLUMN> columns;
+ /* TODO(cvicentiu) refactor replace_db_table to use
+ Db_table instead of TABLE directly. */
+ if (replace_column_table(grant_table,
+ tables.columns_priv_table().table(),
+ *lex_user, columns, grant_table->db,
+ grant_table->tname, ~(ulong)0, 1))
result= -1;
- }
- else
+
+ /* TODO(cvicentiu) refactor replace_db_table to use
+ Db_table instead of TABLE directly. */
+ if ((res= replace_table_table(thd, grant_table,
+ tables.tables_priv_table().table(),
+ *lex_user, grant_table->db,
+ grant_table->tname, ~(ulong)0, 0, 1)))
{
- if (!grant_table->cols)
- {
- revoked= 1;
- continue;
- }
- List<LEX_COLUMN> columns;
- /* TODO(cvicentiu) refactor replace_db_table to use
- Db_table instead of TABLE directly. */
- if (!replace_column_table(grant_table,
- tables.columns_priv_table().table(),
- *lex_user, columns, grant_table->db,
- grant_table->tname, ~(ulong)0, 1))
- {
- revoked= 1;
- continue;
- }
- result= -1;
- }
- }
+ if (res > 0)
+ result= -1;
+ else
+ {
+ /*
+ Entry was deleted. We have to retry the loop as the
+ hash table has probably been reorganized.
+ */
+ revoked= 1;
+ continue;
+ }
+ }
+ }
counter++;
}
} while (revoked);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 242f03d536e..a1be9e76fc8 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -7898,11 +7898,15 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
DBUG_RETURN(1);
}
tablenr++;
- }
- if (tablenr > MAX_TABLES)
- {
- my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast<int>(MAX_TABLES));
- DBUG_RETURN(1);
+ /*
+ We test the max tables here as we setup_table_map() should not be called
+ with tablenr >= 64
+ */
+ if (tablenr > MAX_TABLES)
+ {
+ my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast<int>(MAX_TABLES));
+ DBUG_RETURN(1);
+ }
}
}
else
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 81718595fec..093a94f44f8 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -784,7 +784,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
net.reading_or_writing= 0;
client_capabilities= 0; // minimalistic client
system_thread= NON_SYSTEM_THREAD;
- cleanup_done= free_connection_done= abort_on_warning= 0;
+ cleanup_done= free_connection_done= abort_on_warning= got_warning= 0;
peer_port= 0; // For SHOW PROCESSLIST
transaction.m_pending_rows_event= 0;
transaction.on= 1;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 34a4edbb761..6701c366f0a 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -6048,11 +6048,13 @@ public:
- The sj-materialization temporary table
- Members needed to make index lookup or a full scan of the temptable.
*/
+class POSITION;
+
class SJ_MATERIALIZATION_INFO : public Sql_alloc
{
public:
/* Optimal join sub-order */
- struct st_position *positions;
+ POSITION *positions;
uint tables; /* Number of tables in the sj-nest */
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index ecde337ff6c..60b386f2cf4 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2433,6 +2433,7 @@ void st_select_lex::init_query()
is_service_select= 0;
parsing_place= NO_MATTER;
save_parsing_place= NO_MATTER;
+ context_analysis_place= NO_MATTER;
exclude_from_table_unique_test= no_wrap_view_item= FALSE;
nest_level= 0;
link_next= 0;
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 373326c75c6..43264e3e508 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1505,7 +1505,7 @@ static bool check_list_constants(THD *thd, partition_info *part_info)
List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
while ((list_value= list_val_it2++))
{
- calc_value= list_value->value - type_add;
+ calc_value= list_value->value ^ type_add;
part_info->list_array[list_index].list_value= calc_value;
part_info->list_array[list_index++].partition_id= i;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 1598746b667..44d15327ec1 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -350,7 +350,31 @@ bool dbug_user_var_equals_int(THD *thd, const char *name, int value)
}
return FALSE;
}
-#endif
+#endif /* DBUG_OFF */
+
+/*
+ Intialize POSITION structure.
+*/
+
+POSITION::POSITION()
+{
+ table= 0;
+ records_read= cond_selectivity= read_time= 0.0;
+ prefix_record_count= 0.0;
+ key= 0;
+ use_join_buffer= 0;
+ sj_strategy= SJ_OPT_NONE;
+ n_sj_tables= 0;
+ spl_plan= 0;
+ range_rowid_filter_info= 0;
+ ref_depend_map= dups_producing_tables= 0;
+ inner_tables_handled_with_other_sjs= 0;
+ dups_weedout_picker.set_empty();
+ firstmatch_picker.set_empty();
+ loosescan_picker.set_empty();
+ sjmat_picker.set_empty();
+}
+
static void trace_table_dependencies(THD *thd,
JOIN_TAB *join_tabs, uint table_count)
@@ -1587,10 +1611,11 @@ bool JOIN::build_explain()
curr_tab->tracker= thd->lex->explain->get_union(select_nr)->
get_tmptable_read_tracker();
}
- else
+ else if (select_nr < INT_MAX)
{
- curr_tab->tracker= thd->lex->explain->get_select(select_nr)->
- get_using_temporary_read_tracker();
+ Explain_select *tmp= thd->lex->explain->get_select(select_nr);
+ if (tmp)
+ curr_tab->tracker= tmp->get_using_temporary_read_tracker();
}
}
DBUG_RETURN(0);
@@ -4911,6 +4936,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
/* The following should be optimized to only clear critical things */
bzero((void*)stat, sizeof(JOIN_TAB)* table_count);
+
/* Initialize POSITION objects */
for (i=0 ; i <= table_count ; i++)
(void) new ((char*) (join->positions + i)) POSITION;
@@ -15996,7 +16022,7 @@ static void update_const_equal_items(THD *thd, COND *cond, JOIN_TAB *tab,
Item_func::COND_AND_FUNC));
}
else if (cond->type() == Item::FUNC_ITEM &&
- ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
+ ((Item_func*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
{
Item_equal *item_equal= (Item_equal *) cond;
bool contained_const= item_equal->get_const() != NULL;
@@ -16191,7 +16217,7 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
(((Item_func*) cond)->functype() == Item_func::EQ_FUNC ||
((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC))
{
- Item_func_eq *func=(Item_func_eq*) cond;
+ Item_bool_func2 *func= dynamic_cast<Item_bool_func2*>(cond);
Item **args= func->arguments();
bool left_const= args[0]->const_item() && !args[0]->is_expensive();
bool right_const= args[1]->const_item() && !args[1]->is_expensive();
@@ -17131,7 +17157,7 @@ void propagate_new_equalities(THD *thd, Item *cond,
}
}
else if (cond->type() == Item::FUNC_ITEM &&
- ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
+ ((Item_func*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
{
Item_equal *equal_item;
List_iterator<Item_equal> it(*new_equalities);
@@ -17376,7 +17402,7 @@ Item_cond::remove_eq_conds(THD *thd, Item::cond_result *cond_value,
}
else if (and_level &&
new_item->type() == Item::FUNC_ITEM &&
- ((Item_cond*) new_item)->functype() ==
+ ((Item_func*) new_item)->functype() ==
Item_func::MULT_EQUAL_FUNC)
{
li.remove();
@@ -25200,8 +25226,8 @@ copy_fields(TMP_TABLE_PARAM *param)
(*ptr->do_copy)(ptr);
List_iterator_fast<Item> it(param->copy_funcs);
- Item_copy_string *item;
- while ((item = (Item_copy_string*) it++))
+ Item_copy *item;
+ while ((item= (Item_copy*) it++))
item->copy();
}
@@ -29024,6 +29050,7 @@ select_handler *SELECT_LEX::find_select_handler(THD *thd)
}
+
/**
@} (end of group Query_Optimizer)
*/
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 1d928334bd8..d21d1bcc305 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -698,8 +698,6 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
bool end_of_records);
-struct st_position;
-
class Semi_join_strategy_picker
{
public:
@@ -710,7 +708,7 @@ public:
Update internal state after another table has been added to the join
prefix
*/
- virtual void set_from_prev(struct st_position *prev) = 0;
+ virtual void set_from_prev(POSITION *prev) = 0;
virtual bool check_qep(JOIN *join,
uint idx,
@@ -720,7 +718,7 @@ public:
double *read_time,
table_map *handled_fanout,
sj_strategy_enum *strategy,
- struct st_position *loose_scan_pos) = 0;
+ POSITION *loose_scan_pos) = 0;
virtual void mark_used() = 0;
@@ -751,7 +749,7 @@ public:
first_dupsweedout_table= MAX_TABLES;
is_used= FALSE;
}
- void set_from_prev(struct st_position *prev);
+ void set_from_prev(POSITION *prev);
bool check_qep(JOIN *join,
uint idx,
@@ -761,7 +759,7 @@ public:
double *read_time,
table_map *handled_fanout,
sj_strategy_enum *stratey,
- struct st_position *loose_scan_pos);
+ POSITION *loose_scan_pos);
void mark_used() { is_used= TRUE; }
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
@@ -797,7 +795,7 @@ public:
is_used= FALSE;
}
- void set_from_prev(struct st_position *prev);
+ void set_from_prev(POSITION *prev);
bool check_qep(JOIN *join,
uint idx,
table_map remaining_tables,
@@ -806,7 +804,7 @@ public:
double *read_time,
table_map *handled_fanout,
sj_strategy_enum *strategy,
- struct st_position *loose_scan_pos);
+ POSITION *loose_scan_pos);
void mark_used() { is_used= TRUE; }
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
@@ -815,6 +813,7 @@ public:
class LooseScan_picker : public Semi_join_strategy_picker
{
+public:
/* The first (i.e. driving) table we're doing loose scan for */
uint first_loosescan_table;
/*
@@ -833,14 +832,13 @@ class LooseScan_picker : public Semi_join_strategy_picker
uint loosescan_parts; /* Number of keyparts to be kept distinct */
bool is_used;
-public:
void set_empty()
{
first_loosescan_table= MAX_TABLES;
is_used= FALSE;
}
- void set_from_prev(struct st_position *prev);
+ void set_from_prev(POSITION *prev);
bool check_qep(JOIN *join,
uint idx,
table_map remaining_tables,
@@ -849,19 +847,19 @@ public:
double *read_time,
table_map *handled_fanout,
sj_strategy_enum *strategy,
- struct st_position *loose_scan_pos);
+ POSITION *loose_scan_pos);
void mark_used() { is_used= TRUE; }
friend class Loose_scan_opt;
friend void best_access_path(JOIN *join,
JOIN_TAB *s,
table_map remaining_tables,
- const struct st_position *join_positions,
+ const POSITION *join_positions,
uint idx,
bool disable_jbuf,
double record_count,
- struct st_position *pos,
- struct st_position *loose_scan_pos);
+ POSITION *pos,
+ POSITION *loose_scan_pos);
friend bool get_best_combination(JOIN *join);
friend int setup_semijoin_loosescan(JOIN *join);
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
@@ -888,7 +886,7 @@ public:
sjm_scan_last_inner= 0;
is_used= FALSE;
}
- void set_from_prev(struct st_position *prev);
+ void set_from_prev(POSITION *prev);
bool check_qep(JOIN *join,
uint idx,
table_map remaining_tables,
@@ -897,7 +895,7 @@ public:
double *read_time,
table_map *handled_fanout,
sj_strategy_enum *strategy,
- struct st_position *loose_scan_pos);
+ POSITION *loose_scan_pos);
void mark_used() { is_used= TRUE; }
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
@@ -912,8 +910,9 @@ class Rowid_filter;
Information about a position of table within a join order. Used in join
optimization.
*/
-typedef struct st_position
+class POSITION
{
+public:
/* The table that's put into join order */
JOIN_TAB *table;
@@ -925,7 +924,7 @@ typedef struct st_position
double records_read;
/* The selectivity of the pushed down conditions */
- double cond_selectivity;
+ double cond_selectivity;
/*
Cost accessing the table in course of the entire complete join execution,
@@ -934,8 +933,6 @@ typedef struct st_position
*/
double read_time;
- /* Cumulative cost and record count for the join prefix */
- Cost_estimate prefix_cost;
double prefix_record_count;
/*
@@ -944,29 +941,46 @@ typedef struct st_position
*/
KEYUSE *key;
+ /* Info on splitting plan used at this position */
+ SplM_plan_info *spl_plan;
+
+ /* Cost info for the range filter used at this position */
+ Range_rowid_filter_cost_info *range_rowid_filter_info;
+
/* If ref-based access is used: bitmap of tables this table depends on */
table_map ref_depend_map;
-
+
/*
- TRUE <=> join buffering will be used. At the moment this is based on
- *very* imprecise guesses made in best_access_path().
+ Bitmap of semi-join inner tables that are in the join prefix and for
+ which there's no provision for how to eliminate semi-join duplicates
+ they produce.
*/
- bool use_join_buffer;
-
+ table_map dups_producing_tables;
+
+ table_map inner_tables_handled_with_other_sjs;
+
+ Duplicate_weedout_picker dups_weedout_picker;
+ Firstmatch_picker firstmatch_picker;
+ LooseScan_picker loosescan_picker;
+ Sj_materialization_picker sjmat_picker;
+
+ /* Cumulative cost and record count for the join prefix */
+ Cost_estimate prefix_cost;
+
/*
Current optimization state: Semi-join strategy to be used for this
and preceding join tables.
-
+
Join optimizer sets this for the *last* join_tab in the
- duplicate-generating range. That is, in order to interpret this field,
+ duplicate-generating range. That is, in order to interpret this field,
one needs to traverse join->[best_]positions array from right to left.
When you see a join table with sj_strategy!= SJ_OPT_NONE, some other
- field (depending on the strategy) tells how many preceding positions
+ field (depending on the strategy) tells how many preceding positions
this applies to. The values of covered_preceding_positions->sj_strategy
must be ignored.
*/
enum sj_strategy_enum sj_strategy;
-
+
/*
Valid only after fix_semijoin_strategies_for_picked_join_order() call:
if sj_strategy!=SJ_OPT_NONE, this is the number of subsequent tables that
@@ -975,26 +989,12 @@ typedef struct st_position
uint n_sj_tables;
/*
- Bitmap of semi-join inner tables that are in the join prefix and for
- which there's no provision for how to eliminate semi-join duplicates
- they produce.
+ TRUE <=> join buffering will be used. At the moment this is based on
+ *very* imprecise guesses made in best_access_path().
*/
- table_map dups_producing_tables;
-
- table_map inner_tables_handled_with_other_sjs;
-
- Duplicate_weedout_picker dups_weedout_picker;
- Firstmatch_picker firstmatch_picker;
- LooseScan_picker loosescan_picker;
- Sj_materialization_picker sjmat_picker;
-
- /* Info on splitting plan used at this position */
- SplM_plan_info *spl_plan;
-
- /* Cost info for the range filter used at this position */
- Range_rowid_filter_cost_info *range_rowid_filter_info;
-
-} POSITION;
+ bool use_join_buffer;
+ POSITION();
+};
typedef Bounds_checked_array<Item_null_result*> Item_null_array;
@@ -1590,6 +1590,7 @@ public:
fields_list= fields_arg;
non_agg_fields.empty();
bzero((char*) &keyuse,sizeof(keyuse));
+ having_value= Item::COND_UNDEF;
tmp_table_param.init();
tmp_table_param.end_write_records= HA_POS_ERROR;
rollup.state= ROLLUP::STATE_NONE;
diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc
index b88933eac0c..83091cd67da 100644
--- a/sql/sql_sequence.cc
+++ b/sql/sql_sequence.cc
@@ -730,8 +730,8 @@ longlong SEQUENCE::next_value(TABLE *table, bool second_round, int *error)
if (real_increment > 0)
{
- if (reserved_until + add_to > max_value ||
- reserved_until > max_value - add_to)
+ if (reserved_until > max_value - add_to ||
+ reserved_until + add_to > max_value)
{
reserved_until= max_value + 1;
out_of_values= res_value >= reserved_until;
diff --git a/sql/sql_sequence.h b/sql/sql_sequence.h
index 2d609d8591b..29c589e67cd 100644
--- a/sql/sql_sequence.h
+++ b/sql/sql_sequence.h
@@ -111,8 +111,8 @@ public:
{
if (real_increment > 0)
{
- if (value + real_increment > max_value ||
- value > max_value - real_increment)
+ if (value > max_value - real_increment ||
+ value + real_increment > max_value)
value= max_value + 1;
else
value+= real_increment;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 8cb82c602d9..6f0c9761b6c 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -7096,8 +7096,7 @@ static bool store_trigger(THD *thd, Trigger *trigger,
(my_time_t)(trigger->create_time/100));
/* timestamp is with 6 digits */
timestamp.second_part= (trigger->create_time % 100) * 10000;
- ((Field_temporal_with_date*) table->field[16])->store_time_dec(&timestamp,
- 2);
+ table->field[16]->store_time_dec(&timestamp, 2);
}
sql_mode_string_representation(thd, trigger->sql_mode, &sql_mode_rep);
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 28e3cdc9d69..5ea132c83d4 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -294,7 +294,6 @@ print_plan(JOIN* join, uint idx, double record_count, double read_time,
double current_read_time, const char *info)
{
uint i;
- POSITION pos;
JOIN_TAB *join_table;
JOIN_TAB **plan_nodes;
TABLE* table;
@@ -321,8 +320,8 @@ print_plan(JOIN* join, uint idx, double record_count, double read_time,
fputs(" POSITIONS: ", DBUG_FILE);
for (i= 0; i < idx ; i++)
{
- pos = join->positions[i];
- table= pos.table->table;
+ POSITION *pos= join->positions + i;
+ table= pos->table->table;
if (table)
fputs(table->s->table_name.str, DBUG_FILE);
fputc(' ', DBUG_FILE);
@@ -338,8 +337,8 @@ print_plan(JOIN* join, uint idx, double record_count, double read_time,
fputs("BEST_POSITIONS: ", DBUG_FILE);
for (i= 0; i < idx ; i++)
{
- pos= join->best_positions[i];
- table= pos.table->table;
+ POSITION *pos= join->best_positions + i;
+ table= pos->table->table;
if (table)
fputs(table->s->table_name.str, DBUG_FILE);
fputc(' ', DBUG_FILE);
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index 99ff9c50588..58647c21e44 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -79,14 +79,17 @@ ulonglong find_set(TYPELIB *lib, const char *str, size_t length, CHARSET_INFO *c
var_len= (uint) (pos - start);
uint find= cs ? find_type2(lib, start, var_len, cs) :
find_type(lib, start, var_len, (bool) 0);
- if (unlikely(!find && *err_len == 0))
+ if (unlikely(!find))
{
- // report the first error with length > 0
- *err_pos= (char*) start;
- *err_len= var_len;
- *set_warning= 1;
+ if (*err_len == 0)
+ {
+ // report the first error with length > 0
+ *err_pos= (char*) start;
+ *err_len= var_len;
+ *set_warning= 1;
+ }
}
- else
+ else if (find <= sizeof(longlong) * 8)
found|= 1ULL << (find - 1);
if (pos >= end)
break;
@@ -400,4 +403,3 @@ const char *flagset_to_string(THD *thd, LEX_CSTRING *result, ulonglong set,
return result->str;
}
-
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index a39928309d8..c52a8f742a8 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -4834,6 +4834,24 @@ static Sys_var_have Sys_have_symlink(
"--skip-symbolic-links option.",
READ_ONLY GLOBAL_VAR(have_symlink), NO_CMD_LINE);
+#if defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN)
+
+#ifdef __SANITIZE_ADDRESS__
+#define SANITIZER_MODE "ASAN"
+#else
+#define SANITIZER_MODE "UBSAN"
+#endif /* __SANITIZE_ADDRESS__ */
+
+static char *have_sanitizer;
+static Sys_var_charptr Sys_have_santitizer(
+ "have_sanitizer",
+ "If the server is compiled with sanitize (compiler option), this "
+ "variable is set to the sanitizer mode used. Possible values are "
+ "ASAN (Address sanitizer) or UBSAN (The Undefined Behavior Sanitizer).",
+ READ_ONLY GLOBAL_VAR(have_sanitizer), NO_CMD_LINE,
+ IN_FS_CHARSET, DEFAULT(SANITIZER_MODE));
+#endif /* defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN) */
+
static bool fix_log_state(sys_var *self, THD *thd, enum_var_type type);
static Sys_var_mybool Sys_general_log(
diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc
index f2b27b7056b..5e4b5f7a713 100644
--- a/sql/temporary_tables.cc
+++ b/sql/temporary_tables.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2016, 2019, MariaDB Corporation.
+ Copyright (c) 2016, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -875,10 +875,12 @@ void THD::restore_tmp_table_share(TMP_TABLE_SHARE *share)
inline bool THD::has_temporary_tables()
{
DBUG_ENTER("THD::has_temporary_tables");
- bool result= (rgi_slave
- ? (rgi_slave->rli->save_temporary_tables &&
- !rgi_slave->rli->save_temporary_tables->is_empty())
- : (has_thd_temporary_tables()));
+ bool result=
+#ifdef HAVE_REPLICATION
+ rgi_slave ? (rgi_slave->rli->save_temporary_tables &&
+ !rgi_slave->rli->save_temporary_tables->is_empty()) :
+#endif
+ has_thd_temporary_tables();
DBUG_RETURN(result);
}
@@ -1508,12 +1510,14 @@ bool THD::lock_temporary_tables()
DBUG_RETURN(false);
}
+#ifdef HAVE_REPLICATION
if (rgi_slave)
{
mysql_mutex_lock(&rgi_slave->rli->data_lock);
temporary_tables= rgi_slave->rli->save_temporary_tables;
m_tmp_tables_locked= true;
}
+#endif
DBUG_RETURN(m_tmp_tables_locked);
}
@@ -1534,6 +1538,7 @@ void THD::unlock_temporary_tables()
DBUG_VOID_RETURN;
}
+#ifdef HAVE_REPLICATION
if (rgi_slave)
{
rgi_slave->rli->save_temporary_tables= temporary_tables;
@@ -1541,6 +1546,7 @@ void THD::unlock_temporary_tables()
mysql_mutex_unlock(&rgi_slave->rli->data_lock);
m_tmp_tables_locked= false;
}
+#endif
DBUG_VOID_RETURN;
}
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 689c61a0ff4..9526306a601 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -243,6 +243,20 @@ Archive_share::Archive_share()
}
+Archive_share::~Archive_share()
+{
+ DBUG_PRINT("ha_archive", ("~Archive_share: %p", this));
+ if (archive_write_open)
+ {
+ mysql_mutex_lock(&mutex);
+ (void) close_archive_writer(); // Will reset archive_write_open
+ mysql_mutex_unlock(&mutex);
+ }
+ thr_lock_delete(&lock);
+ mysql_mutex_destroy(&mutex);
+}
+
+
ha_archive::ha_archive(handlerton *hton, TABLE_SHARE *table_arg)
:handler(hton, table_arg), delayed_insert(0), bulk_insert(0)
{
@@ -676,7 +690,6 @@ int ha_archive::close(void)
if (azclose(&archive))
rc= 1;
}
-
DBUG_RETURN(rc);
}
diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h
index b9fcf10f96f..35291e469cd 100644
--- a/storage/archive/ha_archive.h
+++ b/storage/archive/ha_archive.h
@@ -46,19 +46,7 @@ public:
bool dirty; /* Flag for if a flush should occur */
bool crashed; /* Meta file is crashed */
Archive_share();
- ~Archive_share()
- {
- DBUG_PRINT("ha_archive", ("~Archive_share: %p",
- this));
- if (archive_write_open)
- {
- mysql_mutex_lock(&mutex);
- (void) close_archive_writer();
- mysql_mutex_unlock(&mutex);
- }
- thr_lock_delete(&lock);
- mysql_mutex_destroy(&mutex);
- }
+ virtual ~Archive_share();
int init_archive_writer();
void close_archive_writer();
int write_v1_metafile();
diff --git a/storage/connect/colblk.h b/storage/connect/colblk.h
index b22933d9ebb..51ab32cfae2 100644
--- a/storage/connect/colblk.h
+++ b/storage/connect/colblk.h
@@ -62,7 +62,7 @@ class DllExport COLBLK : public XOBJECT {
bool IsVirtual(void) {return Cdp->IsVirtual();}
bool IsNullable(void) {return Nullable;}
void SetNullable(bool b) {Nullable = b;}
-
+ void SetName(PSZ name_var) { Name= name_var; }
// Methods
virtual void Reset(void);
virtual bool Compare(PXOB xp);
diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc
index 484f75d6a04..ee62e0cd03e 100644
--- a/storage/connect/connect.cc
+++ b/storage/connect/connect.cc
@@ -294,9 +294,9 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
/* its column blocks in mode write (required by XML tables). */
/*******************************************************************/
if (mode == MODE_UPDATE) {
- PTDBASE utp;
+ PTDB utp;
- if (!(utp = (PTDBASE)tdbp->Duplicate(g))) {
+ if (!(utp = tdbp->Duplicate(g))) {
sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName());
throw 4;
} // endif tp
@@ -591,7 +591,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
if (!tdbp->IsRemote()) {
// Make all the eventual indexes
- PTDBDOS tbxp = (PTDBDOS)tdbp;
+ PTDBASE tbxp = (PTDBASE)tdbp;
tbxp->ResetKindex(g, NULL);
tbxp->SetKey_Col(NULL);
rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);
diff --git a/storage/connect/filamvct.cpp b/storage/connect/filamvct.cpp
index 56e6e3715fb..97f29dddc7e 100644
--- a/storage/connect/filamvct.cpp
+++ b/storage/connect/filamvct.cpp
@@ -4118,7 +4118,8 @@ bool BGVFAM::CleanUnusedSpace(PGLOBAL g)
} else {
int req;
- memset(To_Buf, 0, Buflen);
+ if (To_Buf)
+ memset(To_Buf, 0, Buflen);
for (n = Fpos - Tpos; n > 0; n -= req) {
/*****************************************************************/
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 7e3a2052564..0be262f6a63 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -286,7 +286,12 @@ static char *strz(PGLOBAL g, LEX_CSTRING &ls)
{
char *str= (char*)PlugSubAlloc(g, NULL, ls.length + 1);
- memcpy(str, ls.str, ls.length);
+ /*
+ ls.str can be NULL, for example when called with
+ create_info->connect_string
+ */
+ if (ls.str)
+ memcpy(str, ls.str, ls.length);
str[ls.length]= 0;
return str;
} // end of strz
@@ -2829,7 +2834,6 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
} else {
char buff[256];
String *res, tmp(buff, sizeof(buff), &my_charset_bin);
- Item_basic_constant *pval= (Item_basic_constant *)args[i];
PPARM pp= (PPARM)PlugSubAlloc(g, NULL, sizeof(PARM));
// IN and BETWEEN clauses should be col VOP list
@@ -2838,6 +2842,8 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
switch (args[i]->real_type()) {
case COND::CONST_ITEM:
+ {
+ Item *pval= (Item *)args[i];
switch (args[i]->cmp_type()) {
case STRING_RESULT:
res= pval->val_str(&tmp);
@@ -2864,6 +2870,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
DBUG_ASSERT(0);
return NULL;
}
+ }
break;
case COND::CACHE_ITEM: // Possible ???
case COND::NULL_ITEM: // TODO: handle this
@@ -3119,7 +3126,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
} else {
char buff[256];
String *res, tmp(buff, sizeof(buff), &my_charset_bin);
- Item_basic_constant *pval= (Item_basic_constant *)args[i];
+ Item *pval= (Item *)args[i];
Item::Type type= args[i]->real_type();
switch (type) {
diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp
index f5a105a530d..0a91f36afa7 100644
--- a/storage/connect/tabutil.cpp
+++ b/storage/connect/tabutil.cpp
@@ -708,7 +708,7 @@ bool PRXCOL::Init(PGLOBAL g, PTDB tp)
MODE mode = To_Tdb->GetMode();
// Needed for MYSQL subtables
- ((XCOLBLK*)Colp)->Name = Decode(g, Colp->GetName());
+ ((COLBLK*)Colp)->SetName(Decode(g, Colp->GetName()));
// May not have been done elsewhere
Colp->InitValue(g);
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index c0a3c86c737..b6584177fe4 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -1093,7 +1093,7 @@ page_get_instant(const page_t* page)
break;
}
#endif /* UNIV_DEBUG */
- return(i >> 3);
+ return static_cast<uint16_t>(i >> 3); /* i / 8 */
}
#endif /* !UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index 430b99d7667..807d99fb872 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -159,7 +159,7 @@ ut_time_ms(void);
store the given number of bits.
@param b in: bits
@return number of bytes (octets) needed to represent b */
-#define UT_BITS_IN_BYTES(b) (((b) + 7) / 8)
+#define UT_BITS_IN_BYTES(b) (((b) + 7) >> 3)
/** Determines if a number is zero or a power of two.
@param[in] n number
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index b5da791aa39..581637be073 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -1460,8 +1460,9 @@ rec_convert_dtuple_to_rec_old(
/* If the data is not SQL null, store it */
len = dfield_get_len(field);
- memcpy(rec + end_offset,
- dfield_get_data(field), len);
+ if (len)
+ memcpy(rec + end_offset,
+ dfield_get_data(field), len);
end_offset += len;
ored_offset = end_offset;
@@ -1488,8 +1489,9 @@ rec_convert_dtuple_to_rec_old(
/* If the data is not SQL null, store it */
len = dfield_get_len(field);
- memcpy(rec + end_offset,
- dfield_get_data(field), len);
+ if (len)
+ memcpy(rec + end_offset,
+ dfield_get_data(field), len);
end_offset += len;
ored_offset = end_offset;
diff --git a/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp b/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
index 5536eecb255..73639685d0e 100644
--- a/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
+++ b/storage/mroonga/lib/mrn_multiple_column_key_codec.cpp
@@ -675,7 +675,8 @@ namespace mrn {
&normalized, &normalized_length, NULL);
uint16 new_blob_data_length;
if (normalized_length <= UINT_MAX16) {
- memcpy(grn_key, normalized, normalized_length);
+ if (normalized_length)
+ memcpy(grn_key, normalized, normalized_length);
if (normalized_length < *mysql_key_size) {
memset(grn_key + normalized_length,
'\0', *mysql_key_size - normalized_length);
diff --git a/storage/mroonga/vendor/groonga/lib/alloc.c b/storage/mroonga/vendor/groonga/lib/alloc.c
index 2e28431595a..5e556b83712 100644
--- a/storage/mroonga/vendor/groonga/lib/alloc.c
+++ b/storage/mroonga/vendor/groonga/lib/alloc.c
@@ -310,13 +310,13 @@ grn_alloc_info_free(grn_ctx *ctx)
}
#endif /* USE_MEMORY_DEBUG */
-#define GRN_CTX_SEGMENT_SIZE (1<<22)
+#define GRN_CTX_SEGMENT_SIZE (1U <<22)
#define GRN_CTX_SEGMENT_MASK (GRN_CTX_SEGMENT_SIZE - 1)
-#define GRN_CTX_SEGMENT_WORD (1<<31)
-#define GRN_CTX_SEGMENT_VLEN (1<<30)
-#define GRN_CTX_SEGMENT_LIFO (1<<29)
-#define GRN_CTX_SEGMENT_DIRTY (1<<28)
+#define GRN_CTX_SEGMENT_WORD (1U <<31)
+#define GRN_CTX_SEGMENT_VLEN (1U <<30)
+#define GRN_CTX_SEGMENT_LIFO (1U <<29)
+#define GRN_CTX_SEGMENT_DIRTY (1U <<28)
void
grn_alloc_init_ctx_impl(grn_ctx *ctx)
@@ -400,8 +400,8 @@ grn_ctx_alloc(grn_ctx *ctx, size_t size, int flags,
header[0] = i;
header[1] = (int32_t) size;
} else {
- i = ctx->impl->currseg;
- mi = &ctx->impl->segs[i];
+ if ((i = ctx->impl->currseg) >= 0)
+ mi = &ctx->impl->segs[i];
if (i < 0 || size + mi->nref > GRN_CTX_SEGMENT_SIZE) {
for (i = 0, mi = ctx->impl->segs;; i++, mi++) {
if (i >= GRN_CTX_N_SEGMENTS) {
diff --git a/storage/mroonga/vendor/groonga/lib/db.c b/storage/mroonga/vendor/groonga/lib/db.c
index f3769f9aa4c..418335aaf00 100644
--- a/storage/mroonga/vendor/groonga/lib/db.c
+++ b/storage/mroonga/vendor/groonga/lib/db.c
@@ -12494,7 +12494,7 @@ grn_db_init_builtin_types(grn_ctx *ctx)
GRN_OBJ_KEY_VAR_SIZE, 1 << 16);
if (!obj || DB_OBJ(obj)->id != GRN_DB_TEXT) { return GRN_FILE_CORRUPT; }
obj = deftype(ctx, "LongText",
- GRN_OBJ_KEY_VAR_SIZE, 1 << 31);
+ GRN_OBJ_KEY_VAR_SIZE, 1U << 31);
if (!obj || DB_OBJ(obj)->id != GRN_DB_LONG_TEXT) { return GRN_FILE_CORRUPT; }
obj = deftype(ctx, "TokyoGeoPoint",
GRN_OBJ_KEY_GEO_POINT, sizeof(grn_geo_point));
diff --git a/storage/mroonga/vendor/groonga/lib/pat.c b/storage/mroonga/vendor/groonga/lib/pat.c
index 642173e2fdc..01f6108fbd0 100644
--- a/storage/mroonga/vendor/groonga/lib/pat.c
+++ b/storage/mroonga/vendor/groonga/lib/pat.c
@@ -899,7 +899,7 @@ chop(grn_ctx *ctx, grn_pat *pat, const char **key, const char *end, uint32_t *lk
case GRN_OBJ_KEY_FLOAT :\
if ((size) == sizeof(int64_t)) {\
int64_t v = *(int64_t *)(key);\
- v ^= ((v >> 63)|(1LL << 63));\
+ v ^= ((v >> 63)|(1ULL << 63));\
grn_hton((keybuf), &v, (size));\
}\
break;\
@@ -924,7 +924,7 @@ chop(grn_ctx *ctx, grn_pat *pat, const char **key, const char *end, uint32_t *lk
if ((size) == sizeof(int64_t)) {\
int64_t v;\
grn_hton(&v, (key), (size));\
- *((int64_t *)(keybuf)) = v ^ (((v^(1LL<<63))>> 63)|(1LL<<63)); \
+ *((int64_t *)(keybuf)) = v ^ ((((int64_t)(v^(1ULL<<63)))>> 63)|(1ULL<<63)); \
}\
break;\
}\
diff --git a/storage/mroonga/vendor/groonga/lib/proc/proc_select.c b/storage/mroonga/vendor/groonga/lib/proc/proc_select.c
index 605fd42239f..1f2a5005401 100644
--- a/storage/mroonga/vendor/groonga/lib/proc/proc_select.c
+++ b/storage/mroonga/vendor/groonga/lib/proc/proc_select.c
@@ -2989,7 +2989,8 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
char *cp = cache_key;
#define PUT_CACHE_KEY(string) \
- grn_memcpy(cp, (string).value, (string).length); \
+ if ((string).value) \
+ grn_memcpy(cp, (string).value, (string).length); \
cp += (string).length; \
*cp++ = '\0'
diff --git a/storage/mroonga/vendor/groonga/lib/str.c b/storage/mroonga/vendor/groonga/lib/str.c
index 6b2d17769ca..4f0a3a98699 100644
--- a/storage/mroonga/vendor/groonga/lib/str.c
+++ b/storage/mroonga/vendor/groonga/lib/str.c
@@ -46,7 +46,7 @@ grn_str_charlen_utf8(grn_ctx *ctx, const unsigned char *str, const unsigned char
if (*str & 0x80) {
int i;
int len;
- GRN_BIT_SCAN_REV(~(*str << 24), len);
+ GRN_BIT_SCAN_REV(~(((uint) *str) << 24), len);
len = 31 - len;
if ((unsigned int)(len - 2) >= 3) { /* (len == 1 || len >= 5) */
GRN_LOG(ctx, GRN_LOG_WARNING,
@@ -1963,7 +1963,8 @@ grn_bulk_write(grn_ctx *ctx, grn_obj *buf, const char *str, unsigned int len)
if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + len))) { return rc; }
}
curr = GRN_BULK_CURR(buf);
- grn_memcpy(curr, str, len);
+ if (str)
+ grn_memcpy(curr, str, len);
GRN_BULK_INCR_LEN(buf, len);
return rc;
}
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index ba6744ae815..8a0ca759871 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -1952,7 +1952,7 @@ static void make_traverse_code_tree(HUFF_TREE *huff_tree,
{
chr=element->a.leaf.element_nr;
huff_tree->code_len[chr]= (uchar) (8 * sizeof(ulonglong) - size);
- huff_tree->code[chr]= (code >> size);
+ huff_tree->code[chr]= (size == 8 * sizeof(ulonglong)) ? 0 : (code >> size);
if (huff_tree->height < 8 * sizeof(ulonglong) - size)
huff_tree->height= 8 * sizeof(ulonglong) - size;
}
@@ -2943,12 +2943,15 @@ static void flush_bits(void)
ulonglong bit_buffer;
bits= file_buffer.bits & ~7;
- bit_buffer= file_buffer.bitbucket >> bits;
- bits= BITS_SAVED - bits;
- while (bits > 0)
+ if (bits != BITS_SAVED)
{
- bits-= 8;
- *file_buffer.pos++= (uchar) (bit_buffer >> bits);
+ bit_buffer= file_buffer.bitbucket >> bits;
+ bits= BITS_SAVED - bits;
+ while (bits > 0)
+ {
+ bits-= 8;
+ *file_buffer.pos++= (uchar) (bit_buffer >> bits);
+ }
}
if (file_buffer.pos >= file_buffer.end)
(void) flush_buffer(~ (ulong) 0);
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index 1ce180e30e4..9c6cb34137d 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -1795,9 +1795,10 @@ ret_sign:
{
if (negative)
{
- if (ull > (ulonglong) LONGLONG_MIN)
+ if (ull >= (ulonglong) LONGLONG_MIN)
{
- *error= MY_ERRNO_ERANGE;
+ if (ull != (ulonglong) LONGLONG_MIN)
+ *error= MY_ERRNO_ERANGE;
return (ulonglong) LONGLONG_MIN;
}
*error= 0;
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 312b903ea64..a519287c0e4 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -31467,9 +31467,11 @@ static inline uint16 *
my_uca_contraction_weight(const MY_CONTRACTIONS *list, my_wc_t *wc, size_t len)
{
MY_CONTRACTION *c, *last;
+ DBUG_ASSERT(len <= MY_UCA_MAX_CONTRACTION);
+
for (c= list->item, last= c + list->nitems; c < last; c++)
{
- if ((len == MY_UCA_MAX_CONTRACTION || c->ch[len] == 0) &&
+ if ((len >= MY_UCA_MAX_CONTRACTION || c->ch[len] == 0) &&
!c->with_context &&
!my_wmemcmp(c->ch, wc, len))
return c->weight;
@@ -33212,7 +33214,8 @@ my_char_weight_put(MY_UCA_WEIGHT_LEVEL *dst,
for (chlen= len; chlen > 1; chlen--)
{
- if ((from= my_uca_contraction_weight(&dst->contractions, str, chlen)))
+ if (chlen <= MY_UCA_MAX_CONTRACTION &&
+ (from= my_uca_contraction_weight(&dst->contractions, str, chlen)))
{
str+= chlen;
len-= chlen;
diff --git a/strings/json_lib.c b/strings/json_lib.c
index 83d5fdaa016..7265afdf355 100644
--- a/strings/json_lib.c
+++ b/strings/json_lib.c
@@ -933,6 +933,7 @@ int json_read_value(json_engine_t *j)
{
int t_next, c_len, res;
+ j->value_type= JSON_VALUE_UNINITALIZED;
if (j->state == JST_KEY)
{
while (json_read_keyname_chr(j) == 0) {}