1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-12 20:49:12 +03:00

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
This commit is contained in:
Monty
2021-04-18 15:29:13 +03:00
parent eb4123eefc
commit 031f11717d
73 changed files with 533 additions and 296 deletions

View File

@@ -141,7 +141,7 @@ elif [ "x$warning_mode" = "xmaintainer" ]; then
debug_extra_cflags="-g3" debug_extra_cflags="-g3"
else else
# Both C and C++ warnings # 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 # For more warnings, uncomment the following line
# warnings="$warnings -Wshadow" # warnings="$warnings -Wshadow"

29
BUILD/compile-pentium64-ubsan Executable file
View File

@@ -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"

View File

@@ -10905,7 +10905,7 @@ int get_next_bit(REP_SET *set,uint lastpos)
start=set->bits+ ((lastpos+1) / WORD_BIT); start=set->bits+ ((lastpos+1) / WORD_BIT);
end=set->bits + set->size_of_bits; 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) while (! bits && ++start < end)
bits=start[0]; bits=start[0];

View File

@@ -93,6 +93,11 @@ foreach my $option (@ARGV)
{ {
$option = substr($option, 2); $option = substr($option, 2);
} }
elsif (substr ($option, 0, 2) eq "-D")
{
# Must be cmake config option
$option = substr($option, 1);
}
else else
{ {
# This must be environment variable # This must be environment variable
@@ -119,6 +124,11 @@ foreach my $option (@ARGV)
$just_print=1; $just_print=1;
next; next;
} }
if ($option =~ /D.*=/)
{
$cmakeargs = $cmakeargs." -".$option;
next;
}
if($option =~ /with-plugins=/) if($option =~ /with-plugins=/)
{ {
my @plugins= split(/,/, substr($option,13)); my @plugins= split(/,/, substr($option,13));

View File

@@ -28,10 +28,10 @@
(((uint32) (uchar) (A)[2]) << 16) |\ (((uint32) (uchar) (A)[2]) << 16) |\
(((uint32) (uchar) (A)[1]) << 8) | \ (((uint32) (uchar) (A)[1]) << 8) | \
((uint32) (uchar) (A)[0]))) ((uint32) (uchar) (A)[0])))
#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) |\ #define sint4korr(A) (int32) (((uint32) ((uchar) (A)[0])) |\
(((int32) ((uchar) (A)[1]) << 8)) |\ (((uint32) ((uchar) (A)[1]) << 8)) |\
(((int32) ((uchar) (A)[2]) << 16)) |\ (((uint32) ((uchar) (A)[2]) << 16)) |\
(((int32) ((int16) (A)[3]) << 24))) (((uint32) ((uchar) (A)[3]) << 24)))
#define sint8korr(A) (longlong) uint8korr(A) #define sint8korr(A) (longlong) uint8korr(A)
#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) |\ #define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) |\
((uint16) ((uchar) (A)[1]) << 8)) ((uint16) ((uchar) (A)[1]) << 8))

View File

@@ -17,6 +17,7 @@
/* /*
Optimized function-like macros for the x86 architecture (_WIN32 included). Optimized function-like macros for the x86 architecture (_WIN32 included).
*/ */
#define sint2korr(A) (*((const int16 *) (A))) #define sint2korr(A) (*((const int16 *) (A)))
#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \ #define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
(((uint32) 255L << 24) | \ (((uint32) 255L << 24) | \

View File

@@ -172,6 +172,7 @@ enum json_states {
enum json_value_types enum json_value_types
{ {
JSON_VALUE_UNINITALIZED=0,
JSON_VALUE_OBJECT=1, JSON_VALUE_OBJECT=1,
JSON_VALUE_ARRAY=2, JSON_VALUE_ARRAY=2,
JSON_VALUE_STRING=3, JSON_VALUE_STRING=3,

View File

@@ -31,10 +31,10 @@
format (low byte first). There are 'korr' (assume 'corrector') variants format (low byte first). There are 'korr' (assume 'corrector') variants
for integer types, but 'get' (assume 'getter') for floating point types. 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 #define MY_BYTE_ORDER_ARCH_OPTIMIZED
#include "byte_order_generic_x86.h" #include "byte_order_generic_x86.h"
#elif defined(__x86_64__) #elif defined(__x86_64__) && !defined(WITH_UBSAN)
#include "byte_order_generic_x86_64.h" #include "byte_order_generic_x86_64.h"
#else #else
#include "byte_order_generic.h" #include "byte_order_generic.h"

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2011, Oracle and/or its affiliates. /* 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 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 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]; uint16 val= ptr[0];
if (ofs + len > 8) if (ofs + len > 8)
val|= (uint16)(ptr[1]) << 8; val|= (uint16)(((uint) ptr[1]) << 8);
return (val >> ofs) & ((1 << len) - 1); return (uchar) ((val >> ofs) & ((1 << len) - 1));
} }
static inline void set_rec_bits(uint16 bits, uchar *ptr, uchar ofs, uint len) 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) 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) \ #define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \

View File

@@ -30,7 +30,7 @@
#define mi_uint1korr(A) ((uint8)(*A)) #define mi_uint1korr(A) ((uint8)(*A))
#define mi_sint2korr(A) ((int16) (((int16) (((const uchar*) (A))[1])) |\ #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) ? \ #define mi_sint3korr(A) ((int32) (((((const uchar*) (A))[0]) & 128) ? \
(((uint32) 255L << 24) | \ (((uint32) 255L << 24) | \
(((uint32) ((const uchar*) (A))[0]) << 16) |\ (((uint32) ((const uchar*) (A))[0]) << 16) |\
@@ -39,10 +39,10 @@
(((uint32) ((const uchar*) (A))[0]) << 16) |\ (((uint32) ((const uchar*) (A))[0]) << 16) |\
(((uint32) ((const uchar*) (A))[1]) << 8) | \ (((uint32) ((const uchar*) (A))[1]) << 8) | \
((uint32) ((const uchar*) (A))[2]))) ((uint32) ((const uchar*) (A))[2])))
#define mi_sint4korr(A) ((int32) (((int32) (((const uchar*) (A))[3])) |\ #define mi_sint4korr(A) ((int32) (((uint32) (((const uchar*) (A))[3])) |\
((int32) (((const uchar*) (A))[2]) << 8) |\ ((uint32) (((const uchar*) (A))[2]) << 8) |\
((int32) (((const uchar*) (A))[1]) << 16) |\ ((uint32) (((const uchar*) (A))[1]) << 16) |\
((int32) ((int16) ((const char*) (A))[0]) << 24))) ((uint32) (((const uchar*) (A))[0]) << 24)))
#define mi_sint8korr(A) ((longlong) mi_uint8korr(A)) #define mi_sint8korr(A) ((longlong) mi_uint8korr(A))
#define mi_uint2korr(A) ((uint16) (((uint16) (((const uchar*) (A))[1])) |\ #define mi_uint2korr(A) ((uint16) (((uint16) (((const uchar*) (A))[1])) |\
((uint16) (((const uchar*) (A))[0]) << 8))) ((uint16) (((const uchar*) (A))[0]) << 8)))

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -2,6 +2,8 @@
# mysqld --help # mysqld --help
# #
--source include/not_embedded.inc --source include/not_embedded.inc
--source include/not_asan.inc
--source include/not_ubsan.inc
--source include/have_perfschema.inc --source include/have_perfschema.inc
--source include/have_profiling.inc --source include/have_profiling.inc
--source include/platform.inc --source include/platform.inc

View File

@@ -1731,7 +1731,6 @@ sub collect_mysqld_features {
} }
sub collect_mysqld_features_from_running_server () sub collect_mysqld_features_from_running_server ()
{ {
my $mysql= mtr_exe_exists("$path_client_bindir/mysql"); 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: Table .*mysql.*innodb_table_stats.* not found./,
qr/InnoDB: User stopword table .* does not exist./, qr/InnoDB: User stopword table .* does not exist./,
qr/Dump thread [0-9]+ last sent to server [0-9]+ binlog file:pos .+/, 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= []; my $matched_lines= [];

View File

@@ -1,3 +1,4 @@
--source include/not_ubsan.inc
# #
# MDEV-11340 Allow multiple alternative authentication methods for the same user # MDEV-11340 Allow multiple alternative authentication methods for the same user
# #

View File

@@ -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 'wsrep%' and
variable_name not like 's3%' and variable_name not like 's3%' and
variable_name not in ( variable_name not in (
'log_tc_size' 'log_tc_size','have_sanitizer'
) )
order by variable_name; order by variable_name;

View File

@@ -9,7 +9,7 @@ where variable_name not like 'debug%' and
variable_name not like 'wsrep%' and variable_name not like 'wsrep%' and
variable_name not like 's3%' and variable_name not like 's3%' and
variable_name not in ( variable_name not in (
'log_tc_size' 'log_tc_size','have_sanitizer'
) )
order by variable_name; order by variable_name;
VARIABLE_NAME ALTER_ALGORITHM VARIABLE_NAME ALTER_ALGORITHM

View File

@@ -9,7 +9,7 @@ where variable_name not like 'debug%' and
variable_name not like 'wsrep%' and variable_name not like 'wsrep%' and
variable_name not like 's3%' and variable_name not like 's3%' and
variable_name not in ( variable_name not in (
'log_tc_size' 'log_tc_size','have_sanitizer'
) )
order by variable_name; order by variable_name;
VARIABLE_NAME ALTER_ALGORITHM VARIABLE_NAME ALTER_ALGORITHM

View File

@@ -1,6 +1,8 @@
# #
# only global # only global
# #
--source include/not_asan.inc
--source include/not_ubsan.inc
--replace_result 392192 299008 --replace_result 392192 299008
select @@global.thread_stack; select @@global.thread_stack;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR --error ER_INCORRECT_GLOBAL_LOCAL_VAR

View File

@@ -865,7 +865,7 @@ dynamic_column_uint_read(DYNAMIC_COLUMN_VALUE *store_it_here,
static size_t dynamic_column_sint_bytes(longlong val) 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)); (val < 0 ? 0xffffffffffffffffull : 0));
} }
@@ -883,7 +883,7 @@ static enum enum_dyncol_func_result
dynamic_column_sint_store(DYNAMIC_COLUMN *str, longlong val) dynamic_column_sint_store(DYNAMIC_COLUMN *str, longlong val)
{ {
return dynamic_column_uint_store(str, return dynamic_column_uint_store(str,
(val << 1) ^ (((ulonglong) val) << 1) ^
(val < 0 ? 0xffffffffffffffffULL : 0)); (val < 0 ? 0xffffffffffffffffULL : 0));
} }

View File

@@ -19,6 +19,10 @@ IF(MSVC)
SET_SOURCE_FILES_PROPERTIES(${REF10_SOURCES} PROPERTY COMPILE_FLAGS "/wd4244 /wd4146") SET_SOURCE_FILES_PROPERTIES(${REF10_SOURCES} PROPERTY COMPILE_FLAGS "/wd4244 /wd4146")
ENDIF() 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 # server plugin *cannot* link with the library, it needs all sources to be
# compiled with MYSQL_DYNAMIC_PLUGIN # compiled with MYSQL_DYNAMIC_PLUGIN
MYSQL_ADD_PLUGIN(auth_ed25519 server_ed25519.c ${REF10_SOURCES} MODULE_ONLY) MYSQL_ADD_PLUGIN(auth_ed25519 server_ed25519.c ${REF10_SOURCES} MODULE_ONLY)

View File

@@ -30,8 +30,8 @@
#define MY_PACKED_TIME_GET_INT_PART(x) ((x) >> 24) #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_GET_FRAC_PART(x) ((x) % (1LL << 24))
#define MY_PACKED_TIME_MAKE(i, f) ((((longlong) (i)) << 24) + (f)) #define MY_PACKED_TIME_MAKE(i, f) ((((ulonglong) (i)) << 24) + (f))
#define MY_PACKED_TIME_MAKE_INT(i) ((((longlong) (i)) << 24)) #define MY_PACKED_TIME_MAKE_INT(i) ((((ulonglong) (i)) << 24))
longlong TIME_to_longlong_datetime_packed(const MYSQL_TIME *); longlong TIME_to_longlong_datetime_packed(const MYSQL_TIME *);
longlong TIME_to_longlong_time_packed(const MYSQL_TIME *); longlong TIME_to_longlong_time_packed(const MYSQL_TIME *);

View File

@@ -658,8 +658,16 @@ Events::drop_schema_events(THD *thd, const char *db)
*/ */
if (event_queue) if (event_queue)
event_queue->drop_schema_events(thd, &db_lex); event_queue->drop_schema_events(thd, &db_lex);
if (db_repository)
db_repository->drop_schema_events(thd, &db_lex); 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; DBUG_VOID_RETURN;
} }

View File

@@ -4534,6 +4534,12 @@ public:
void move_field_offset(my_ptrdiff_t ptr_diff) void move_field_offset(my_ptrdiff_t ptr_diff)
{ {
Field::move_field_offset(ptr_diff); Field::move_field_offset(ptr_diff);
/*
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*); bit_ptr= ADD_TO_PTR(bit_ptr, ptr_diff, uchar*);
} }
void hash(ulong *nr, ulong *nr2); void hash(ulong *nr, ulong *nr2);

View File

@@ -184,7 +184,11 @@ class Gcalc_result_receiver
double first_x, first_y, prev_x, prev_y; double first_x, first_y, prev_x, prev_y;
double shape_area; double shape_area;
public: 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 start_shape(Gcalc_function::shape_type shape);
int add_point(double x, double y); int add_point(double x, double y);

View File

@@ -6461,6 +6461,7 @@ int ha_partition::multi_range_read_init(RANGE_SEQ_IF *seq,
DBUG_ENTER("ha_partition::multi_range_read_init"); DBUG_ENTER("ha_partition::multi_range_read_init");
DBUG_PRINT("enter", ("partition this: %p", this)); DBUG_PRINT("enter", ("partition this: %p", this));
eq_range= 0;
m_seq_if= seq; m_seq_if= seq;
m_seq= seq->init(seq_init_param, n_ranges, mrr_mode); m_seq= seq->init(seq_init_param, n_ranges, mrr_mode);
if (unlikely((error= multi_range_key_create_key(seq, m_seq)))) if (unlikely((error= multi_range_key_create_key(seq, m_seq))))

View File

@@ -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) + dummy_table= (TABLE*) thd->calloc(sizeof(TABLE) + sizeof(TABLE_SHARE) +
sizeof(Query_arena)); sizeof(Query_arena));
dummy_table->s= (TABLE_SHARE*) (dummy_table + 1); dummy_table->s= (TABLE_SHARE*) (dummy_table + 1);
/* TODO(cvicentiu) Move this sp_query_arena in the class as a direct member. sp_query_arena= new(dummy_table->s + 1) Query_arena();
Currently it can not be done due to header include dependencies. */
sp_query_arena= (Query_arena *) (dummy_table->s + 1);
memset(&sp_mem_root, 0, sizeof(sp_mem_root)); 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) + dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE) +
sizeof(Query_arena)); sizeof(Query_arena));
dummy_table->s= (TABLE_SHARE*) (dummy_table+1); 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)); 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()); item_equal->compare_type_handler()->cmp_type());
return const_item2; return const_item2;
} }
Item_field *subst= Item_ident *subst=
(Item_field *)(item_equal->get_first(param->context_tab, this)); (Item_ident *) (item_equal->get_first(param->context_tab, this));
if (subst) if (subst)
subst= (Item_field *) (subst->real_item()); {
if (subst && !field->eq(subst->field)) Item_field *subst2= (Item_field *) (subst->real_item());
return subst; if (subst2 && !field->eq(subst2->field))
return subst2;
}
} }
return this; return this;
} }

View File

@@ -47,9 +47,9 @@ Cached_item *new_Cached_item(THD *thd, Item *item, bool pass_through_ref)
} }
switch (item->result_type()) { switch (item->result_type()) {
case STRING_RESULT: case STRING_RESULT:
return new Cached_item_str(thd, (Item_field *) item); return new Cached_item_str(thd, item);
case INT_RESULT: case INT_RESULT:
return new Cached_item_int((Item_field *) item); return new Cached_item_int(item);
case REAL_RESULT: case REAL_RESULT:
return new Cached_item_real(item); return new Cached_item_real(item);
case DECIMAL_RESULT: case DECIMAL_RESULT:

View File

@@ -5658,12 +5658,16 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
return FALSE; // Null argument return FALSE; // Null argument
const size_t len= res2->length(); const size_t len= res2->length();
const char* first = res2->ptr();
const char* last = first + len - 1;
/* /*
len must be > 2 ('%pattern%') len must be > 2 ('%pattern%')
heuristic: only do TurboBM for pattern_len > 2 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 && if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
*first == wild_many && *first == wild_many &&

View File

@@ -1095,17 +1095,20 @@ double Item_func_plus::real_op()
return check_float_overflow(value); 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 Item_func_plus::int_op()
{ {
longlong val0= args[0]->val_int(); longlong val0= args[0]->val_int();
longlong val1= args[1]->val_int(); longlong val1= args[1]->val_int();
longlong res= val0 + val1;
bool res_unsigned= FALSE; bool res_unsigned= FALSE;
longlong res;
if ((null_value= args[0]->null_value || args[1]->null_value)) if ((null_value= args[0]->null_value || args[1]->null_value))
return 0; return 0;
/* /*
First check whether the result can be represented as a First check whether the result can be represented as a
(bool unsigned_flag, longlong value) pair, then check if it is compatible (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) if (val0 >=0 && val1 >= 0)
res_unsigned= TRUE; res_unsigned= TRUE;
else if (val0 < 0 && val1 < 0 && res >= 0) else if (val0 < 0 && val1 < 0 && val0 < (LONGLONG_MIN - val1))
goto err; 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); return check_integer_overflow(res, res_unsigned);
err: err:
return raise_integer_overflow(); return raise_integer_overflow();
} }
#if defined(__powerpc64__) && GCC_VERSION >= 6003 && GCC_VERSION <= 10002
#pragma GCC pop_options
#endif
/** /**
Calculate plus of two decimals. 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 Item_func_minus::int_op()
{ {
longlong val0= args[0]->val_int(); longlong val0= args[0]->val_int();
longlong val1= args[1]->val_int(); longlong val1= args[1]->val_int();
longlong res= val0 - val1;
bool res_unsigned= FALSE; bool res_unsigned= FALSE;
longlong res;
if ((null_value= args[0]->null_value || args[1]->null_value)) if ((null_value= args[0]->null_value || args[1]->null_value))
return 0; return 0;
@@ -1268,11 +1289,7 @@ longlong Item_func_minus::int_op()
if (args[1]->unsigned_flag) if (args[1]->unsigned_flag)
{ {
if ((ulonglong) val0 < (ulonglong) val1) if ((ulonglong) val0 < (ulonglong) val1)
{
if (res >= 0)
goto err; goto err;
}
else
res_unsigned= TRUE; res_unsigned= TRUE;
} }
else else
@@ -1294,23 +1311,35 @@ longlong Item_func_minus::int_op()
{ {
if (args[1]->unsigned_flag) if (args[1]->unsigned_flag)
{ {
if ((ulonglong) (val0 - LONGLONG_MIN) < (ulonglong) val1) if (((ulonglong) val0 - (ulonglong) LONGLONG_MIN) < (ulonglong) val1)
goto err; goto err;
} }
else else
{ {
if (val0 > 0 && val1 < 0) if (val0 > 0 && val1 < 0)
res_unsigned= TRUE; res_unsigned= TRUE;
else if (val0 < 0 && val1 > 0 && res >= 0) else if (val0 < 0 && val1 > 0 && val0 < (LONGLONG_MIN + val1))
goto err; 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); return check_integer_overflow(res, res_unsigned);
err: err:
return raise_integer_overflow(); 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. 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() longlong Item_func_shift_left::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
uint shift; uint shift= (uint) args[1]->val_int();
ulonglong res= ((ulonglong) args[0]->val_int() << ulonglong value= args[0]->val_int();
(shift=(uint) args[1]->val_int()));
if (args[0]->null_value || args[1]->null_value) if (args[0]->null_value || args[1]->null_value)
{ {
null_value=1; null_value=1;
return 0; return 0;
} }
null_value=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() longlong Item_func_shift_right::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
uint shift; uint shift= (uint) args[1]->val_int();
ulonglong res= (ulonglong) args[0]->val_int() >> ulonglong value= args[0]->val_int();
(shift=(uint) args[1]->val_int());
if (args[0]->null_value || args[1]->null_value) if (args[0]->null_value || args[1]->null_value)
{ {
null_value=1; null_value=1;
return 0; return 0;
} }
null_value=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) 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; return 0;
start0--; start--;
/* start is now sufficiently valid to pass to charpos function */ /* start is now sufficiently valid to pass to charpos function */
start= a->charpos((int) start); start= a->charpos((int) start);
@@ -3222,7 +3250,7 @@ bool Item_func_find_in_set::fix_length_and_dec()
find->length(), 0); find->length(), 0);
enum_bit=0; enum_bit=0;
if (enum_value) if (enum_value)
enum_bit=1LL << (enum_value-1); enum_bit= 1ULL << (enum_value-1);
} }
} }
} }

View File

@@ -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(), json_scan_start(je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length()); (const uchar *) js->ptr() + js->length());
je->value_type= (enum json_value_types) -1; /* To report errors right. */
if (json_read_value(je)) if (json_read_value(je))
goto error; goto error;
@@ -982,6 +980,7 @@ my_decimal *Item_func_json_extract::val_decimal(my_decimal *to)
case JSON_VALUE_ARRAY: case JSON_VALUE_ARRAY:
case JSON_VALUE_FALSE: case JSON_VALUE_FALSE:
case JSON_VALUE_NULL: case JSON_VALUE_NULL:
case JSON_VALUE_UNINITALIZED:
break; break;
}; };
} }

View File

@@ -1514,17 +1514,18 @@ String *Item_func_insert::val_str(String *str)
null_value=0; null_value=0;
res=args[0]->val_str(str); res=args[0]->val_str(str);
res2=args[3]->val_str(&tmp_value); res2=args[3]->val_str(&tmp_value);
start= args[1]->val_int() - 1; start= args[1]->val_int();
length= args[2]->val_int(); length= args[2]->val_int();
if (args[0]->null_value || args[1]->null_value || args[2]->null_value || if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
args[3]->null_value) args[3]->null_value)
goto null; /* purecov: inspected */ goto null; /* purecov: inspected */
if ((start < 0) || (start > res->length())) if ((start <= 0) || (start > res->length()))
return res; // Wrong param; skip insert return res; // Wrong param; skip insert
if ((length < 0) || (length > res->length())) if ((length < 0) || (length > res->length()))
length= res->length(); length= res->length();
start--;
/* /*
There is one exception not handled (intentionaly) by the character set 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++) for (end=res->ptr()+res->length(); from < end ; from+=2, to++)
{ {
int hex_char; int hex_char1, hex_char2;
*to= (hex_char= hexchar_to_int(from[0])) << 4; hex_char1= hexchar_to_int(from[0]);
if ((null_value= (hex_char == -1))) hex_char2= hexchar_to_int(from[1]);
return 0; if ((null_value= (hex_char1 == -1 || hex_char2 == -1)))
*to|= hex_char= hexchar_to_int(from[1]);
if ((null_value= (hex_char == -1)))
return 0; return 0;
*to= (char) ((hex_char1 << 4) | hex_char2);
} }
return str; return str;
} }

View File

@@ -42,8 +42,13 @@ protected:
we don't want to free and potentially have to reallocate the buffer we don't want to free and potentially have to reallocate the buffer
for each call. for each call.
*/ */
str_value.length(0); 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); str_value.set_charset(collation.collation);
}
return &str_value; return &str_value;
} }
public: public:

View File

@@ -2635,9 +2635,9 @@ bool Item_sum_bit::add_as_window(ulonglong value)
void Item_sum_or::set_bits_from_counters() void Item_sum_or::set_bits_from_counters()
{ {
ulonglong value= 0; 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; 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), arg_count_field(select_list->elements),
row_count(0), row_count(0),
distinct(distinct_arg), distinct(distinct_arg),
warning_for_row(FALSE), warning_for_row(FALSE), always_null(FALSE),
force_copy_fields(0), row_limit(NULL), force_copy_fields(0), row_limit(NULL),
offset_limit(NULL), limit_clause(limit_clause), offset_limit(NULL), limit_clause(limit_clause),
copy_offset_limit(0), copy_row_limit(0), original(0) copy_offset_limit(0), copy_row_limit(0), original(0)

View File

@@ -733,7 +733,10 @@ static bool make_date_time(const LEX_CSTRING &format, MYSQL_TIME *l_time,
For example, '1.1' -> '1.100000' 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) bool transform_msec)
{ {
const char *end=str+length; 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++) for (i=0 ; i < count ; i++)
{ {
longlong value; ulonglong value;
const char *start= str; 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'; 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; return true;
values[i]= value; values[i]= value;
while (str != end && !my_isdigit(cs,*str)) 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 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)) if (!Item_func::eq(item, binary_cmp))
return 0; return 0;
Item_date_add_interval *other= (Item_date_add_interval*) item;
return ((int_type == other->int_type) && return ((int_type == other->int_type) &&
(date_sub_interval == other->date_sub_interval)); (date_sub_interval == other->date_sub_interval));
} }

View File

@@ -204,7 +204,7 @@ struct SplM_field_info
struct SplM_plan_info struct SplM_plan_info
{ {
/* The cached splitting execution plan P */ /* The cached splitting execution plan P */
struct st_position *best_positions; POSITION *best_positions;
/* The cost of the above plan */ /* The cost of the above plan */
double cost; double cost;
/* Selectivity of splitting used in P */ /* Selectivity of splitting used in P */

View File

@@ -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) if (prev->sjmat_picker.is_used)
set_empty(); 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) if (prev->loosescan_picker.is_used)
set_empty(); set_empty();
@@ -3197,7 +3197,7 @@ bool LooseScan_picker::check_qep(JOIN *join,
double *read_time, double *read_time,
table_map *handled_fanout, table_map *handled_fanout,
sj_strategy_enum *strategy, sj_strategy_enum *strategy,
struct st_position *loose_scan_pos) POSITION *loose_scan_pos)
{ {
POSITION *first= join->positions + first_loosescan_table; POSITION *first= join->positions + first_loosescan_table;
/* /*
@@ -3275,7 +3275,7 @@ bool LooseScan_picker::check_qep(JOIN *join,
return FALSE; 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) if (prev->firstmatch_picker.is_used)
invalidate_firstmatch_prefix(); 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 && ((Item_func *) item)->functype() == Item_func::EQ_FUNC &&
check_simple_equality(thd, check_simple_equality(thd,
Item::Context(Item::ANY_SUBST, Item::Context(Item::ANY_SUBST,
((Item_func_equal *)item)->compare_type_handler(), ((Item_func_eq *)item)->compare_type_handler(),
((Item_func_equal *)item)->compare_collation()), ((Item_func_eq *)item)->compare_collation()),
((Item_func *)item)->arguments()[0], ((Item_func *)item)->arguments()[0],
((Item_func *)item)->arguments()[1], ((Item_func *)item)->arguments()[1],
&new_cond_equal)) &new_cond_equal))

View File

@@ -144,6 +144,7 @@ public:
part_min_rows(part_elem->part_min_rows), part_min_rows(part_elem->part_min_rows),
range_value(0), partition_name(NULL), range_value(0), partition_name(NULL),
tablespace_name(part_elem->tablespace_name), tablespace_name(part_elem->tablespace_name),
log_entry(NULL),
part_comment(part_elem->part_comment), part_comment(part_elem->part_comment),
data_file_name(part_elem->data_file_name), data_file_name(part_elem->data_file_name),
index_file_name(part_elem->index_file_name), index_file_name(part_elem->index_file_name),
@@ -152,6 +153,8 @@ public:
part_state(part_elem->part_state), part_state(part_elem->part_state),
nodegroup_id(part_elem->nodegroup_id), nodegroup_id(part_elem->nodegroup_id),
has_null_value(FALSE), has_null_value(FALSE),
signed_flag(part_elem->signed_flag),
max_value(part_elem->max_value),
id(part_elem->id), id(part_elem->id),
empty(part_elem->empty), empty(part_elem->empty),
type(CONVENTIONAL) type(CONVENTIONAL)

View File

@@ -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, const char *user, const char *tname, const Sp_handler *sph,
bool exact) bool exact)
{ {
return (GRANT_TABLE*) return (GRANT_NAME*)
name_hash_search(sph->get_priv_hash(), name_hash_search(sph->get_priv_hash(),
host, ip, db, user, tname, exact, TRUE); 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); user, tname, exact, FALSE);
} }
static bool column_priv_insert(GRANT_TABLE *grant)
{
return my_hash_insert(&column_priv_hash,(uchar*) grant);
}
static GRANT_COLUMN * static GRANT_COLUMN *
column_hash_search(GRANT_TABLE *t, const char *cname, size_t length) 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); 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, static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
TABLE *table, const LEX_USER &combo, TABLE *table, const LEX_USER &combo,
const char *db, const char *table_name, 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), my_message(ER_PASSWORD_NO_MATCH, ER_THD(thd, ER_PASSWORD_NO_MATCH),
MYF(0)); /* purecov: deadcode */ 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), my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
combo.user.str, combo.host.str, combo.user.str, combo.host.str,
table_name); /* purecov: deadcode */ table_name); /* purecov: deadcode */
DBUG_RETURN(-1); /* purecov: deadcode */ DBUG_RETURN(1); /* purecov: deadcode */
} }
old_row_exists = 0; old_row_exists = 0;
restore_record(table,record[1]); // Get saved record restore_record(table,record[1]); // Get saved record
@@ -5709,13 +5722,14 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
else else
{ {
my_hash_delete(&column_priv_hash,(uchar*) grant_table); my_hash_delete(&column_priv_hash,(uchar*) grant_table);
DBUG_RETURN(-1); // Entry revoked
} }
DBUG_RETURN(0); DBUG_RETURN(0);
/* This should never happen */ /* This should never happen */
table_error: table_error:
table->file->print_error(error,MYF(0)); /* purecov: deadcode */ 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); privs, cols);
merged->init_privs= merged->init_cols= 0; merged->init_privs= merged->init_cols= 0;
update_role_columns(merged, first, last); update_role_columns(merged, first, last);
my_hash_insert(&column_priv_hash,(uchar*) merged); column_priv_insert(merged);
return 2; return 2;
} }
else if ((privs | cols) == 0) else if ((privs | cols) == 0)
@@ -6796,7 +6810,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
bool revoke_grant) bool revoke_grant)
{ {
ulong column_priv= 0; ulong column_priv= 0;
int result; int result, res;
List_iterator <LEX_USER> str_list (user_list); List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str, *tmp_Str; LEX_USER *Str, *tmp_Str;
bool create_new_users=0; bool create_new_users=0;
@@ -6939,12 +6953,12 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
result= TRUE; result= TRUE;
continue; continue;
} }
grant_table = new GRANT_TABLE (Str->host.str, db_name, grant_table= new (&grant_memroot) GRANT_TABLE(Str->host.str, db_name,
Str->user.str, table_name, Str->user.str, table_name,
rights, rights,
column_priv); column_priv);
if (!grant_table || if (!grant_table ||
my_hash_insert(&column_priv_hash,(uchar*) grant_table)) column_priv_insert(grant_table))
{ {
result= TRUE; /* purecov: deadcode */ result= TRUE; /* purecov: deadcode */
continue; /* purecov: deadcode */ continue; /* purecov: deadcode */
@@ -6987,23 +7001,25 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
/* TODO(cvicentiu) refactor replace_table_table to use Tables_priv_table /* TODO(cvicentiu) refactor replace_table_table to use Tables_priv_table
instead of TABLE directly. */ instead of TABLE directly. */
if (replace_table_table(thd, grant_table, tables.tables_priv_table().table(), if (tables.columns_priv_table().table_exists())
*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())
{ {
/* TODO(cvicentiu) refactor replace_column_table to use Columns_priv_table /* TODO(cvicentiu) refactor replace_column_table to use Columns_priv_table
instead of TABLE directly. */ instead of TABLE directly. */
if (replace_column_table(grant_table, tables.columns_priv_table().table(), if (replace_column_table(grant_table, tables.columns_priv_table().table(),
*Str, columns, db_name, table_name, rights, *Str, columns, db_name, table_name, rights,
revoke_grant)) revoke_grant))
{
result= TRUE; 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()) if (Str->is_role())
propagate_role_grants(find_acl_role(Str->user.str), propagate_role_grants(find_acl_role(Str->user.str),
@@ -7014,9 +7030,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
mysql_mutex_unlock(&acl_cache->lock); mysql_mutex_unlock(&acl_cache->lock);
if (!result) /* success */ if (!result) /* success */
{
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
mysql_rwlock_unlock(&LOCK_grant); mysql_rwlock_unlock(&LOCK_grant);
@@ -7704,7 +7718,7 @@ static bool grant_load(THD *thd,
if (! mem_check->ok()) if (! mem_check->ok())
delete mem_check; delete mem_check;
else if (my_hash_insert(&column_priv_hash,(uchar*) mem_check)) else if (column_priv_insert(mem_check))
{ {
delete mem_check; delete mem_check;
goto end_unlock; 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) bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
{ {
uint counter, revoked; uint counter, revoked;
int result; int result, res;
ACL_DB *acl_db; ACL_DB *acl_db;
DBUG_ENTER("mysql_revoke_all"); DBUG_ENTER("mysql_revoke_all");
@@ -11193,34 +11207,33 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
if (!strcmp(lex_user->user.str,user) && if (!strcmp(lex_user->user.str,user) &&
!strcmp(lex_user->host.str, host)) !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))
{
result= -1;
}
else
{
if (!grant_table->cols)
{
revoked= 1;
continue;
}
List<LEX_COLUMN> columns; List<LEX_COLUMN> columns;
/* TODO(cvicentiu) refactor replace_db_table to use /* TODO(cvicentiu) refactor replace_db_table to use
Db_table instead of TABLE directly. */ Db_table instead of TABLE directly. */
if (!replace_column_table(grant_table, if (replace_column_table(grant_table,
tables.columns_priv_table().table(), tables.columns_priv_table().table(),
*lex_user, columns, grant_table->db, *lex_user, columns, grant_table->db,
grant_table->tname, ~(ulong)0, 1)) grant_table->tname, ~(ulong)0, 1))
result= -1;
/* 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 (res > 0)
result= -1;
else
{
/*
Entry was deleted. We have to retry the loop as the
hash table has probably been reorganized.
*/
revoked= 1; revoked= 1;
continue; continue;
} }
result= -1;
} }
} }
counter++; counter++;

View File

@@ -7898,13 +7898,17 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
tablenr++; tablenr++;
} /*
We test the max tables here as we setup_table_map() should not be called
with tablenr >= 64
*/
if (tablenr > MAX_TABLES) if (tablenr > MAX_TABLES)
{ {
my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast<int>(MAX_TABLES)); my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast<int>(MAX_TABLES));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
}
else else
{ {
List_iterator_fast <TABLE_LIST> ti(select_lex->leaf_tables_exec); List_iterator_fast <TABLE_LIST> ti(select_lex->leaf_tables_exec);

View File

@@ -784,7 +784,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
net.reading_or_writing= 0; net.reading_or_writing= 0;
client_capabilities= 0; // minimalistic client client_capabilities= 0; // minimalistic client
system_thread= NON_SYSTEM_THREAD; 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 peer_port= 0; // For SHOW PROCESSLIST
transaction.m_pending_rows_event= 0; transaction.m_pending_rows_event= 0;
transaction.on= 1; transaction.on= 1;

View File

@@ -6048,11 +6048,13 @@ public:
- The sj-materialization temporary table - The sj-materialization temporary table
- Members needed to make index lookup or a full scan of the temptable. - Members needed to make index lookup or a full scan of the temptable.
*/ */
class POSITION;
class SJ_MATERIALIZATION_INFO : public Sql_alloc class SJ_MATERIALIZATION_INFO : public Sql_alloc
{ {
public: public:
/* Optimal join sub-order */ /* Optimal join sub-order */
struct st_position *positions; POSITION *positions;
uint tables; /* Number of tables in the sj-nest */ uint tables; /* Number of tables in the sj-nest */

View File

@@ -2433,6 +2433,7 @@ void st_select_lex::init_query()
is_service_select= 0; is_service_select= 0;
parsing_place= NO_MATTER; parsing_place= NO_MATTER;
save_parsing_place= NO_MATTER; save_parsing_place= NO_MATTER;
context_analysis_place= NO_MATTER;
exclude_from_table_unique_test= no_wrap_view_item= FALSE; exclude_from_table_unique_test= no_wrap_view_item= FALSE;
nest_level= 0; nest_level= 0;
link_next= 0; link_next= 0;

View File

@@ -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); List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
while ((list_value= list_val_it2++)) 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].list_value= calc_value;
part_info->list_array[list_index++].partition_id= i; part_info->list_array[list_index++].partition_id= i;
} }

View File

@@ -350,7 +350,31 @@ bool dbug_user_var_equals_int(THD *thd, const char *name, int value)
} }
return FALSE; 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, static void trace_table_dependencies(THD *thd,
JOIN_TAB *join_tabs, uint table_count) 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)-> curr_tab->tracker= thd->lex->explain->get_union(select_nr)->
get_tmptable_read_tracker(); get_tmptable_read_tracker();
} }
else else if (select_nr < INT_MAX)
{ {
curr_tab->tracker= thd->lex->explain->get_select(select_nr)-> Explain_select *tmp= thd->lex->explain->get_select(select_nr);
get_using_temporary_read_tracker(); if (tmp)
curr_tab->tracker= tmp->get_using_temporary_read_tracker();
} }
} }
DBUG_RETURN(0); 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 */ /* The following should be optimized to only clear critical things */
bzero((void*)stat, sizeof(JOIN_TAB)* table_count); bzero((void*)stat, sizeof(JOIN_TAB)* table_count);
/* Initialize POSITION objects */ /* Initialize POSITION objects */
for (i=0 ; i <= table_count ; i++) for (i=0 ; i <= table_count ; i++)
(void) new ((char*) (join->positions + i)) POSITION; (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)); Item_func::COND_AND_FUNC));
} }
else if (cond->type() == Item::FUNC_ITEM && 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; Item_equal *item_equal= (Item_equal *) cond;
bool contained_const= item_equal->get_const() != NULL; 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::EQ_FUNC ||
((Item_func*) cond)->functype() == Item_func::EQUAL_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(); Item **args= func->arguments();
bool left_const= args[0]->const_item() && !args[0]->is_expensive(); bool left_const= args[0]->const_item() && !args[0]->is_expensive();
bool right_const= args[1]->const_item() && !args[1]->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 && 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; Item_equal *equal_item;
List_iterator<Item_equal> it(*new_equalities); 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 && else if (and_level &&
new_item->type() == Item::FUNC_ITEM && new_item->type() == Item::FUNC_ITEM &&
((Item_cond*) new_item)->functype() == ((Item_func*) new_item)->functype() ==
Item_func::MULT_EQUAL_FUNC) Item_func::MULT_EQUAL_FUNC)
{ {
li.remove(); li.remove();
@@ -25200,8 +25226,8 @@ copy_fields(TMP_TABLE_PARAM *param)
(*ptr->do_copy)(ptr); (*ptr->do_copy)(ptr);
List_iterator_fast<Item> it(param->copy_funcs); List_iterator_fast<Item> it(param->copy_funcs);
Item_copy_string *item; Item_copy *item;
while ((item = (Item_copy_string*) it++)) while ((item= (Item_copy*) it++))
item->copy(); item->copy();
} }
@@ -29024,6 +29050,7 @@ select_handler *SELECT_LEX::find_select_handler(THD *thd)
} }
/** /**
@} (end of group Query_Optimizer) @} (end of group Query_Optimizer)
*/ */

View File

@@ -698,8 +698,6 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
bool end_of_records); bool end_of_records);
struct st_position;
class Semi_join_strategy_picker class Semi_join_strategy_picker
{ {
public: public:
@@ -710,7 +708,7 @@ public:
Update internal state after another table has been added to the join Update internal state after another table has been added to the join
prefix 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, virtual bool check_qep(JOIN *join,
uint idx, uint idx,
@@ -720,7 +718,7 @@ public:
double *read_time, double *read_time,
table_map *handled_fanout, table_map *handled_fanout,
sj_strategy_enum *strategy, sj_strategy_enum *strategy,
struct st_position *loose_scan_pos) = 0; POSITION *loose_scan_pos) = 0;
virtual void mark_used() = 0; virtual void mark_used() = 0;
@@ -751,7 +749,7 @@ public:
first_dupsweedout_table= MAX_TABLES; first_dupsweedout_table= MAX_TABLES;
is_used= FALSE; is_used= FALSE;
} }
void set_from_prev(struct st_position *prev); void set_from_prev(POSITION *prev);
bool check_qep(JOIN *join, bool check_qep(JOIN *join,
uint idx, uint idx,
@@ -761,7 +759,7 @@ public:
double *read_time, double *read_time,
table_map *handled_fanout, table_map *handled_fanout,
sj_strategy_enum *stratey, sj_strategy_enum *stratey,
struct st_position *loose_scan_pos); POSITION *loose_scan_pos);
void mark_used() { is_used= TRUE; } void mark_used() { is_used= TRUE; }
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join); friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
@@ -797,7 +795,7 @@ public:
is_used= FALSE; is_used= FALSE;
} }
void set_from_prev(struct st_position *prev); void set_from_prev(POSITION *prev);
bool check_qep(JOIN *join, bool check_qep(JOIN *join,
uint idx, uint idx,
table_map remaining_tables, table_map remaining_tables,
@@ -806,7 +804,7 @@ public:
double *read_time, double *read_time,
table_map *handled_fanout, table_map *handled_fanout,
sj_strategy_enum *strategy, sj_strategy_enum *strategy,
struct st_position *loose_scan_pos); POSITION *loose_scan_pos);
void mark_used() { is_used= TRUE; } void mark_used() { is_used= TRUE; }
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join); friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
@@ -815,6 +813,7 @@ public:
class LooseScan_picker : public Semi_join_strategy_picker class LooseScan_picker : public Semi_join_strategy_picker
{ {
public:
/* The first (i.e. driving) table we're doing loose scan for */ /* The first (i.e. driving) table we're doing loose scan for */
uint first_loosescan_table; 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 */ uint loosescan_parts; /* Number of keyparts to be kept distinct */
bool is_used; bool is_used;
public:
void set_empty() void set_empty()
{ {
first_loosescan_table= MAX_TABLES; first_loosescan_table= MAX_TABLES;
is_used= FALSE; is_used= FALSE;
} }
void set_from_prev(struct st_position *prev); void set_from_prev(POSITION *prev);
bool check_qep(JOIN *join, bool check_qep(JOIN *join,
uint idx, uint idx,
table_map remaining_tables, table_map remaining_tables,
@@ -849,19 +847,19 @@ public:
double *read_time, double *read_time,
table_map *handled_fanout, table_map *handled_fanout,
sj_strategy_enum *strategy, sj_strategy_enum *strategy,
struct st_position *loose_scan_pos); POSITION *loose_scan_pos);
void mark_used() { is_used= TRUE; } void mark_used() { is_used= TRUE; }
friend class Loose_scan_opt; friend class Loose_scan_opt;
friend void best_access_path(JOIN *join, friend void best_access_path(JOIN *join,
JOIN_TAB *s, JOIN_TAB *s,
table_map remaining_tables, table_map remaining_tables,
const struct st_position *join_positions, const POSITION *join_positions,
uint idx, uint idx,
bool disable_jbuf, bool disable_jbuf,
double record_count, double record_count,
struct st_position *pos, POSITION *pos,
struct st_position *loose_scan_pos); POSITION *loose_scan_pos);
friend bool get_best_combination(JOIN *join); friend bool get_best_combination(JOIN *join);
friend int setup_semijoin_loosescan(JOIN *join); friend int setup_semijoin_loosescan(JOIN *join);
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join); friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
@@ -888,7 +886,7 @@ public:
sjm_scan_last_inner= 0; sjm_scan_last_inner= 0;
is_used= FALSE; is_used= FALSE;
} }
void set_from_prev(struct st_position *prev); void set_from_prev(POSITION *prev);
bool check_qep(JOIN *join, bool check_qep(JOIN *join,
uint idx, uint idx,
table_map remaining_tables, table_map remaining_tables,
@@ -897,7 +895,7 @@ public:
double *read_time, double *read_time,
table_map *handled_fanout, table_map *handled_fanout,
sj_strategy_enum *strategy, sj_strategy_enum *strategy,
struct st_position *loose_scan_pos); POSITION *loose_scan_pos);
void mark_used() { is_used= TRUE; } void mark_used() { is_used= TRUE; }
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join); 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 Information about a position of table within a join order. Used in join
optimization. optimization.
*/ */
typedef struct st_position class POSITION
{ {
public:
/* The table that's put into join order */ /* The table that's put into join order */
JOIN_TAB *table; JOIN_TAB *table;
@@ -934,8 +933,6 @@ typedef struct st_position
*/ */
double read_time; double read_time;
/* Cumulative cost and record count for the join prefix */
Cost_estimate prefix_cost;
double prefix_record_count; double prefix_record_count;
/* /*
@@ -944,14 +941,31 @@ typedef struct st_position
*/ */
KEYUSE *key; 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 */ /* If ref-based access is used: bitmap of tables this table depends on */
table_map ref_depend_map; table_map ref_depend_map;
/* /*
TRUE <=> join buffering will be used. At the moment this is based on Bitmap of semi-join inner tables that are in the join prefix and for
*very* imprecise guesses made in best_access_path(). 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 Current optimization state: Semi-join strategy to be used for this
@@ -975,26 +989,12 @@ typedef struct st_position
uint n_sj_tables; uint n_sj_tables;
/* /*
Bitmap of semi-join inner tables that are in the join prefix and for TRUE <=> join buffering will be used. At the moment this is based on
which there's no provision for how to eliminate semi-join duplicates *very* imprecise guesses made in best_access_path().
they produce.
*/ */
table_map dups_producing_tables; bool use_join_buffer;
POSITION();
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;
typedef Bounds_checked_array<Item_null_result*> Item_null_array; typedef Bounds_checked_array<Item_null_result*> Item_null_array;
@@ -1590,6 +1590,7 @@ public:
fields_list= fields_arg; fields_list= fields_arg;
non_agg_fields.empty(); non_agg_fields.empty();
bzero((char*) &keyuse,sizeof(keyuse)); bzero((char*) &keyuse,sizeof(keyuse));
having_value= Item::COND_UNDEF;
tmp_table_param.init(); tmp_table_param.init();
tmp_table_param.end_write_records= HA_POS_ERROR; tmp_table_param.end_write_records= HA_POS_ERROR;
rollup.state= ROLLUP::STATE_NONE; rollup.state= ROLLUP::STATE_NONE;

View File

@@ -730,8 +730,8 @@ longlong SEQUENCE::next_value(TABLE *table, bool second_round, int *error)
if (real_increment > 0) if (real_increment > 0)
{ {
if (reserved_until + add_to > max_value || if (reserved_until > max_value - add_to ||
reserved_until > max_value - add_to) reserved_until + add_to > max_value)
{ {
reserved_until= max_value + 1; reserved_until= max_value + 1;
out_of_values= res_value >= reserved_until; out_of_values= res_value >= reserved_until;

View File

@@ -111,8 +111,8 @@ public:
{ {
if (real_increment > 0) if (real_increment > 0)
{ {
if (value + real_increment > max_value || if (value > max_value - real_increment ||
value > max_value - real_increment) value + real_increment > max_value)
value= max_value + 1; value= max_value + 1;
else else
value+= real_increment; value+= real_increment;

View File

@@ -7096,8 +7096,7 @@ static bool store_trigger(THD *thd, Trigger *trigger,
(my_time_t)(trigger->create_time/100)); (my_time_t)(trigger->create_time/100));
/* timestamp is with 6 digits */ /* timestamp is with 6 digits */
timestamp.second_part= (trigger->create_time % 100) * 10000; timestamp.second_part= (trigger->create_time % 100) * 10000;
((Field_temporal_with_date*) table->field[16])->store_time_dec(&timestamp, table->field[16]->store_time_dec(&timestamp, 2);
2);
} }
sql_mode_string_representation(thd, trigger->sql_mode, &sql_mode_rep); sql_mode_string_representation(thd, trigger->sql_mode, &sql_mode_rep);

View File

@@ -294,7 +294,6 @@ print_plan(JOIN* join, uint idx, double record_count, double read_time,
double current_read_time, const char *info) double current_read_time, const char *info)
{ {
uint i; uint i;
POSITION pos;
JOIN_TAB *join_table; JOIN_TAB *join_table;
JOIN_TAB **plan_nodes; JOIN_TAB **plan_nodes;
TABLE* table; TABLE* table;
@@ -321,8 +320,8 @@ print_plan(JOIN* join, uint idx, double record_count, double read_time,
fputs(" POSITIONS: ", DBUG_FILE); fputs(" POSITIONS: ", DBUG_FILE);
for (i= 0; i < idx ; i++) for (i= 0; i < idx ; i++)
{ {
pos = join->positions[i]; POSITION *pos= join->positions + i;
table= pos.table->table; table= pos->table->table;
if (table) if (table)
fputs(table->s->table_name.str, DBUG_FILE); fputs(table->s->table_name.str, DBUG_FILE);
fputc(' ', 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); fputs("BEST_POSITIONS: ", DBUG_FILE);
for (i= 0; i < idx ; i++) for (i= 0; i < idx ; i++)
{ {
pos= join->best_positions[i]; POSITION *pos= join->best_positions + i;
table= pos.table->table; table= pos->table->table;
if (table) if (table)
fputs(table->s->table_name.str, DBUG_FILE); fputs(table->s->table_name.str, DBUG_FILE);
fputc(' ', DBUG_FILE); fputc(' ', DBUG_FILE);

View File

@@ -79,14 +79,17 @@ ulonglong find_set(TYPELIB *lib, const char *str, size_t length, CHARSET_INFO *c
var_len= (uint) (pos - start); var_len= (uint) (pos - start);
uint find= cs ? find_type2(lib, start, var_len, cs) : uint find= cs ? find_type2(lib, start, var_len, cs) :
find_type(lib, start, var_len, (bool) 0); find_type(lib, start, var_len, (bool) 0);
if (unlikely(!find && *err_len == 0)) if (unlikely(!find))
{
if (*err_len == 0)
{ {
// report the first error with length > 0 // report the first error with length > 0
*err_pos= (char*) start; *err_pos= (char*) start;
*err_len= var_len; *err_len= var_len;
*set_warning= 1; *set_warning= 1;
} }
else }
else if (find <= sizeof(longlong) * 8)
found|= 1ULL << (find - 1); found|= 1ULL << (find - 1);
if (pos >= end) if (pos >= end)
break; break;
@@ -400,4 +403,3 @@ const char *flagset_to_string(THD *thd, LEX_CSTRING *result, ulonglong set,
return result->str; return result->str;
} }

View File

@@ -4834,6 +4834,24 @@ static Sys_var_have Sys_have_symlink(
"--skip-symbolic-links option.", "--skip-symbolic-links option.",
READ_ONLY GLOBAL_VAR(have_symlink), NO_CMD_LINE); 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 bool fix_log_state(sys_var *self, THD *thd, enum_var_type type);
static Sys_var_mybool Sys_general_log( static Sys_var_mybool Sys_general_log(

View File

@@ -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 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 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() inline bool THD::has_temporary_tables()
{ {
DBUG_ENTER("THD::has_temporary_tables"); DBUG_ENTER("THD::has_temporary_tables");
bool result= (rgi_slave bool result=
? (rgi_slave->rli->save_temporary_tables && #ifdef HAVE_REPLICATION
!rgi_slave->rli->save_temporary_tables->is_empty()) rgi_slave ? (rgi_slave->rli->save_temporary_tables &&
: (has_thd_temporary_tables())); !rgi_slave->rli->save_temporary_tables->is_empty()) :
#endif
has_thd_temporary_tables();
DBUG_RETURN(result); DBUG_RETURN(result);
} }
@@ -1508,12 +1510,14 @@ bool THD::lock_temporary_tables()
DBUG_RETURN(false); DBUG_RETURN(false);
} }
#ifdef HAVE_REPLICATION
if (rgi_slave) if (rgi_slave)
{ {
mysql_mutex_lock(&rgi_slave->rli->data_lock); mysql_mutex_lock(&rgi_slave->rli->data_lock);
temporary_tables= rgi_slave->rli->save_temporary_tables; temporary_tables= rgi_slave->rli->save_temporary_tables;
m_tmp_tables_locked= true; m_tmp_tables_locked= true;
} }
#endif
DBUG_RETURN(m_tmp_tables_locked); DBUG_RETURN(m_tmp_tables_locked);
} }
@@ -1534,6 +1538,7 @@ void THD::unlock_temporary_tables()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#ifdef HAVE_REPLICATION
if (rgi_slave) if (rgi_slave)
{ {
rgi_slave->rli->save_temporary_tables= temporary_tables; 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); mysql_mutex_unlock(&rgi_slave->rli->data_lock);
m_tmp_tables_locked= false; m_tmp_tables_locked= false;
} }
#endif
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@@ -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) ha_archive::ha_archive(handlerton *hton, TABLE_SHARE *table_arg)
:handler(hton, table_arg), delayed_insert(0), bulk_insert(0) :handler(hton, table_arg), delayed_insert(0), bulk_insert(0)
{ {
@@ -676,7 +690,6 @@ int ha_archive::close(void)
if (azclose(&archive)) if (azclose(&archive))
rc= 1; rc= 1;
} }
DBUG_RETURN(rc); DBUG_RETURN(rc);
} }

View File

@@ -46,19 +46,7 @@ public:
bool dirty; /* Flag for if a flush should occur */ bool dirty; /* Flag for if a flush should occur */
bool crashed; /* Meta file is crashed */ bool crashed; /* Meta file is crashed */
Archive_share(); Archive_share();
~Archive_share() virtual ~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);
}
int init_archive_writer(); int init_archive_writer();
void close_archive_writer(); void close_archive_writer();
int write_v1_metafile(); int write_v1_metafile();

View File

@@ -62,7 +62,7 @@ class DllExport COLBLK : public XOBJECT {
bool IsVirtual(void) {return Cdp->IsVirtual();} bool IsVirtual(void) {return Cdp->IsVirtual();}
bool IsNullable(void) {return Nullable;} bool IsNullable(void) {return Nullable;}
void SetNullable(bool b) {Nullable = b;} void SetNullable(bool b) {Nullable = b;}
void SetName(PSZ name_var) { Name= name_var; }
// Methods // Methods
virtual void Reset(void); virtual void Reset(void);
virtual bool Compare(PXOB xp); virtual bool Compare(PXOB xp);

View File

@@ -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). */ /* its column blocks in mode write (required by XML tables). */
/*******************************************************************/ /*******************************************************************/
if (mode == MODE_UPDATE) { 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()); sprintf(g->Message, MSG(INV_UPDT_TABLE), tdbp->GetName());
throw 4; throw 4;
} // endif tp } // endif tp
@@ -591,7 +591,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort)
if (!tdbp->IsRemote()) { if (!tdbp->IsRemote()) {
// Make all the eventual indexes // Make all the eventual indexes
PTDBDOS tbxp = (PTDBDOS)tdbp; PTDBASE tbxp = (PTDBASE)tdbp;
tbxp->ResetKindex(g, NULL); tbxp->ResetKindex(g, NULL);
tbxp->SetKey_Col(NULL); tbxp->SetKey_Col(NULL);
rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1); rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1);

View File

@@ -4118,6 +4118,7 @@ bool BGVFAM::CleanUnusedSpace(PGLOBAL g)
} else { } else {
int req; int req;
if (To_Buf)
memset(To_Buf, 0, Buflen); memset(To_Buf, 0, Buflen);
for (n = Fpos - Tpos; n > 0; n -= req) { for (n = Fpos - Tpos; n > 0; n -= req) {

View File

@@ -286,6 +286,11 @@ static char *strz(PGLOBAL g, LEX_CSTRING &ls)
{ {
char *str= (char*)PlugSubAlloc(g, NULL, ls.length + 1); char *str= (char*)PlugSubAlloc(g, NULL, ls.length + 1);
/*
ls.str can be NULL, for example when called with
create_info->connect_string
*/
if (ls.str)
memcpy(str, ls.str, ls.length); memcpy(str, ls.str, ls.length);
str[ls.length]= 0; str[ls.length]= 0;
return str; return str;
@@ -2829,7 +2834,6 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
} else { } else {
char buff[256]; char buff[256];
String *res, tmp(buff, sizeof(buff), &my_charset_bin); 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)); PPARM pp= (PPARM)PlugSubAlloc(g, NULL, sizeof(PARM));
// IN and BETWEEN clauses should be col VOP list // 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()) { switch (args[i]->real_type()) {
case COND::CONST_ITEM: case COND::CONST_ITEM:
{
Item *pval= (Item *)args[i];
switch (args[i]->cmp_type()) { switch (args[i]->cmp_type()) {
case STRING_RESULT: case STRING_RESULT:
res= pval->val_str(&tmp); res= pval->val_str(&tmp);
@@ -2864,6 +2870,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
DBUG_ASSERT(0); DBUG_ASSERT(0);
return NULL; return NULL;
} }
}
break; break;
case COND::CACHE_ITEM: // Possible ??? case COND::CACHE_ITEM: // Possible ???
case COND::NULL_ITEM: // TODO: handle this case COND::NULL_ITEM: // TODO: handle this
@@ -3119,7 +3126,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
} else { } else {
char buff[256]; char buff[256];
String *res, tmp(buff, sizeof(buff), &my_charset_bin); 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(); Item::Type type= args[i]->real_type();
switch (type) { switch (type) {

View File

@@ -708,7 +708,7 @@ bool PRXCOL::Init(PGLOBAL g, PTDB tp)
MODE mode = To_Tdb->GetMode(); MODE mode = To_Tdb->GetMode();
// Needed for MYSQL subtables // Needed for MYSQL subtables
((XCOLBLK*)Colp)->Name = Decode(g, Colp->GetName()); ((COLBLK*)Colp)->SetName(Decode(g, Colp->GetName()));
// May not have been done elsewhere // May not have been done elsewhere
Colp->InitValue(g); Colp->InitValue(g);

View File

@@ -1093,7 +1093,7 @@ page_get_instant(const page_t* page)
break; break;
} }
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
return(i >> 3); return static_cast<uint16_t>(i >> 3); /* i / 8 */
} }
#endif /* !UNIV_INNOCHECKSUM */ #endif /* !UNIV_INNOCHECKSUM */

View File

@@ -159,7 +159,7 @@ ut_time_ms(void);
store the given number of bits. store the given number of bits.
@param b in: bits @param b in: bits
@return number of bytes (octets) needed to represent b */ @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. /** Determines if a number is zero or a power of two.
@param[in] n number @param[in] n number

View File

@@ -1460,6 +1460,7 @@ rec_convert_dtuple_to_rec_old(
/* If the data is not SQL null, store it */ /* If the data is not SQL null, store it */
len = dfield_get_len(field); len = dfield_get_len(field);
if (len)
memcpy(rec + end_offset, memcpy(rec + end_offset,
dfield_get_data(field), len); dfield_get_data(field), len);
@@ -1488,6 +1489,7 @@ rec_convert_dtuple_to_rec_old(
/* If the data is not SQL null, store it */ /* If the data is not SQL null, store it */
len = dfield_get_len(field); len = dfield_get_len(field);
if (len)
memcpy(rec + end_offset, memcpy(rec + end_offset,
dfield_get_data(field), len); dfield_get_data(field), len);

View File

@@ -675,6 +675,7 @@ namespace mrn {
&normalized, &normalized_length, NULL); &normalized, &normalized_length, NULL);
uint16 new_blob_data_length; uint16 new_blob_data_length;
if (normalized_length <= UINT_MAX16) { if (normalized_length <= UINT_MAX16) {
if (normalized_length)
memcpy(grn_key, normalized, normalized_length); memcpy(grn_key, normalized, normalized_length);
if (normalized_length < *mysql_key_size) { if (normalized_length < *mysql_key_size) {
memset(grn_key + normalized_length, memset(grn_key + normalized_length,

View File

@@ -310,13 +310,13 @@ grn_alloc_info_free(grn_ctx *ctx)
} }
#endif /* USE_MEMORY_DEBUG */ #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_MASK (GRN_CTX_SEGMENT_SIZE - 1)
#define GRN_CTX_SEGMENT_WORD (1<<31) #define GRN_CTX_SEGMENT_WORD (1U <<31)
#define GRN_CTX_SEGMENT_VLEN (1<<30) #define GRN_CTX_SEGMENT_VLEN (1U <<30)
#define GRN_CTX_SEGMENT_LIFO (1<<29) #define GRN_CTX_SEGMENT_LIFO (1U <<29)
#define GRN_CTX_SEGMENT_DIRTY (1<<28) #define GRN_CTX_SEGMENT_DIRTY (1U <<28)
void void
grn_alloc_init_ctx_impl(grn_ctx *ctx) grn_alloc_init_ctx_impl(grn_ctx *ctx)
@@ -400,7 +400,7 @@ grn_ctx_alloc(grn_ctx *ctx, size_t size, int flags,
header[0] = i; header[0] = i;
header[1] = (int32_t) size; header[1] = (int32_t) size;
} else { } else {
i = ctx->impl->currseg; if ((i = ctx->impl->currseg) >= 0)
mi = &ctx->impl->segs[i]; mi = &ctx->impl->segs[i];
if (i < 0 || size + mi->nref > GRN_CTX_SEGMENT_SIZE) { if (i < 0 || size + mi->nref > GRN_CTX_SEGMENT_SIZE) {
for (i = 0, mi = ctx->impl->segs;; i++, mi++) { for (i = 0, mi = ctx->impl->segs;; i++, mi++) {

View File

@@ -12494,7 +12494,7 @@ grn_db_init_builtin_types(grn_ctx *ctx)
GRN_OBJ_KEY_VAR_SIZE, 1 << 16); GRN_OBJ_KEY_VAR_SIZE, 1 << 16);
if (!obj || DB_OBJ(obj)->id != GRN_DB_TEXT) { return GRN_FILE_CORRUPT; } if (!obj || DB_OBJ(obj)->id != GRN_DB_TEXT) { return GRN_FILE_CORRUPT; }
obj = deftype(ctx, "LongText", 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; } if (!obj || DB_OBJ(obj)->id != GRN_DB_LONG_TEXT) { return GRN_FILE_CORRUPT; }
obj = deftype(ctx, "TokyoGeoPoint", obj = deftype(ctx, "TokyoGeoPoint",
GRN_OBJ_KEY_GEO_POINT, sizeof(grn_geo_point)); GRN_OBJ_KEY_GEO_POINT, sizeof(grn_geo_point));

View File

@@ -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 :\ case GRN_OBJ_KEY_FLOAT :\
if ((size) == sizeof(int64_t)) {\ if ((size) == sizeof(int64_t)) {\
int64_t v = *(int64_t *)(key);\ int64_t v = *(int64_t *)(key);\
v ^= ((v >> 63)|(1LL << 63));\ v ^= ((v >> 63)|(1ULL << 63));\
grn_hton((keybuf), &v, (size));\ grn_hton((keybuf), &v, (size));\
}\ }\
break;\ 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)) {\ if ((size) == sizeof(int64_t)) {\
int64_t v;\ int64_t v;\
grn_hton(&v, (key), (size));\ 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;\ break;\
}\ }\

View File

@@ -2989,6 +2989,7 @@ grn_select(grn_ctx *ctx, grn_select_data *data)
char *cp = cache_key; char *cp = cache_key;
#define PUT_CACHE_KEY(string) \ #define PUT_CACHE_KEY(string) \
if ((string).value) \
grn_memcpy(cp, (string).value, (string).length); \ grn_memcpy(cp, (string).value, (string).length); \
cp += (string).length; \ cp += (string).length; \
*cp++ = '\0' *cp++ = '\0'

View File

@@ -46,7 +46,7 @@ grn_str_charlen_utf8(grn_ctx *ctx, const unsigned char *str, const unsigned char
if (*str & 0x80) { if (*str & 0x80) {
int i; int i;
int len; int len;
GRN_BIT_SCAN_REV(~(*str << 24), len); GRN_BIT_SCAN_REV(~(((uint) *str) << 24), len);
len = 31 - len; len = 31 - len;
if ((unsigned int)(len - 2) >= 3) { /* (len == 1 || len >= 5) */ if ((unsigned int)(len - 2) >= 3) { /* (len == 1 || len >= 5) */
GRN_LOG(ctx, GRN_LOG_WARNING, GRN_LOG(ctx, GRN_LOG_WARNING,
@@ -1963,6 +1963,7 @@ 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; } if ((rc = grn_bulk_resize(ctx, buf, GRN_BULK_VSIZE(buf) + len))) { return rc; }
} }
curr = GRN_BULK_CURR(buf); curr = GRN_BULK_CURR(buf);
if (str)
grn_memcpy(curr, str, len); grn_memcpy(curr, str, len);
GRN_BULK_INCR_LEN(buf, len); GRN_BULK_INCR_LEN(buf, len);
return rc; return rc;

View File

@@ -1952,7 +1952,7 @@ static void make_traverse_code_tree(HUFF_TREE *huff_tree,
{ {
chr=element->a.leaf.element_nr; chr=element->a.leaf.element_nr;
huff_tree->code_len[chr]= (uchar) (8 * sizeof(ulonglong) - size); 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) if (huff_tree->height < 8 * sizeof(ulonglong) - size)
huff_tree->height= 8 * sizeof(ulonglong) - size; huff_tree->height= 8 * sizeof(ulonglong) - size;
} }
@@ -2943,6 +2943,8 @@ static void flush_bits(void)
ulonglong bit_buffer; ulonglong bit_buffer;
bits= file_buffer.bits & ~7; bits= file_buffer.bits & ~7;
if (bits != BITS_SAVED)
{
bit_buffer= file_buffer.bitbucket >> bits; bit_buffer= file_buffer.bitbucket >> bits;
bits= BITS_SAVED - bits; bits= BITS_SAVED - bits;
while (bits > 0) while (bits > 0)
@@ -2950,6 +2952,7 @@ static void flush_bits(void)
bits-= 8; bits-= 8;
*file_buffer.pos++= (uchar) (bit_buffer >> bits); *file_buffer.pos++= (uchar) (bit_buffer >> bits);
} }
}
if (file_buffer.pos >= file_buffer.end) if (file_buffer.pos >= file_buffer.end)
(void) flush_buffer(~ (ulong) 0); (void) flush_buffer(~ (ulong) 0);
file_buffer.bits= BITS_SAVED; file_buffer.bits= BITS_SAVED;

View File

@@ -1795,8 +1795,9 @@ ret_sign:
{ {
if (negative) if (negative)
{ {
if (ull > (ulonglong) LONGLONG_MIN) if (ull >= (ulonglong) LONGLONG_MIN)
{ {
if (ull != (ulonglong) LONGLONG_MIN)
*error= MY_ERRNO_ERANGE; *error= MY_ERRNO_ERANGE;
return (ulonglong) LONGLONG_MIN; return (ulonglong) LONGLONG_MIN;
} }

View File

@@ -31467,9 +31467,11 @@ static inline uint16 *
my_uca_contraction_weight(const MY_CONTRACTIONS *list, my_wc_t *wc, size_t len) my_uca_contraction_weight(const MY_CONTRACTIONS *list, my_wc_t *wc, size_t len)
{ {
MY_CONTRACTION *c, *last; MY_CONTRACTION *c, *last;
DBUG_ASSERT(len <= MY_UCA_MAX_CONTRACTION);
for (c= list->item, last= c + list->nitems; c < last; c++) 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 && !c->with_context &&
!my_wmemcmp(c->ch, wc, len)) !my_wmemcmp(c->ch, wc, len))
return c->weight; return c->weight;
@@ -33212,7 +33214,8 @@ my_char_weight_put(MY_UCA_WEIGHT_LEVEL *dst,
for (chlen= len; chlen > 1; chlen--) 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; str+= chlen;
len-= chlen; len-= chlen;

View File

@@ -933,6 +933,7 @@ int json_read_value(json_engine_t *j)
{ {
int t_next, c_len, res; int t_next, c_len, res;
j->value_type= JSON_VALUE_UNINITALIZED;
if (j->state == JST_KEY) if (j->state == JST_KEY)
{ {
while (json_read_keyname_chr(j) == 0) {} while (json_read_keyname_chr(j) == 0) {}