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

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);
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];

View file

@ -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));

View file

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

View file

@ -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) | \

View file

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

View file

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

View file

@ -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) \

View file

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

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
#
--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

View file

@ -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= [];

View file

@ -1,3 +1,4 @@
--source include/not_ubsan.inc
#
# 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 's3%' and
variable_name not in (
'log_tc_size'
'log_tc_size','have_sanitizer'
)
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 's3%' and
variable_name not in (
'log_tc_size'
'log_tc_size','have_sanitizer'
)
order by variable_name;
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 's3%' and
variable_name not in (
'log_tc_size'
'log_tc_size','have_sanitizer'
)
order by variable_name;
VARIABLE_NAME ALTER_ALGORITHM

View file

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

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)
{
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));
}

View file

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

View file

@ -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 *);

View file

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

View file

@ -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);

View file

@ -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);

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_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))))

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) +
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;
}

View file

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

View file

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

View file

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

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(),
(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);

View file

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

View file

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

View file

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

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'
*/
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));
}

View file

@ -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 */

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)
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))

View file

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

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,
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);

View file

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

View file

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

View file

@ -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 */

View file

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

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);
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;
}

View file

@ -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)
*/

View file

@ -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,35 +941,14 @@ 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().
*/
bool use_join_buffer;
/*
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,
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
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
are covered by the specified semi-join strategy
*/
uint n_sj_tables;
/*
Bitmap of semi-join inner tables that are in the join prefix and for
@ -982,19 +958,43 @@ typedef struct st_position
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;
/* Cumulative cost and record count for the join prefix */
Cost_estimate prefix_cost;
/* Cost info for the range filter used at this position */
Range_rowid_filter_cost_info *range_rowid_filter_info;
/*
Current optimization state: Semi-join strategy to be used for this
and preceding join tables.
} POSITION;
Join optimizer sets this for the *last* join_tab in the
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
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
are covered by the specified semi-join strategy
*/
uint n_sj_tables;
/*
TRUE <=> join buffering will be used. At the moment this is based on
*very* imprecise guesses made in best_access_path().
*/
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;

View file

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

View file

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

View file

@ -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);

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)
{
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);

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);
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;
}

View file

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

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

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)
: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);
}

View file

@ -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();

View file

@ -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);

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). */
/*******************************************************************/
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);

View file

@ -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) {
/*****************************************************************/

View file

@ -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) {

View file

@ -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);

View file

@ -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 */

View file

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

View file

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

View file

@ -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);

View file

@ -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) {

View file

@ -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));

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 :\
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;\
}\

View file

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

View file

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

View file

@ -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);

View file

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

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_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;

View file

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