mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01: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:
parent
eb4123eefc
commit
031f11717d
73 changed files with 533 additions and 296 deletions
|
@ -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
29
BUILD/compile-pentium64-ubsan
Executable 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"
|
|
@ -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];
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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) | \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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)))
|
||||
|
|
8
mysql-test/include/not_asan.inc
Normal file
8
mysql-test/include/not_asan.inc
Normal 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
|
||||
}
|
8
mysql-test/include/not_ubsan.inc
Normal file
8
mysql-test/include/not_ubsan.inc
Normal 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
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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= [];
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
--source include/not_ubsan.inc
|
||||
#
|
||||
# MDEV-11340 Allow multiple alternative authentication methods for the same user
|
||||
#
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))))
|
||||
|
|
18
sql/item.cc
18
sql/item.cc
|
@ -2599,9 +2599,7 @@ Item_sp::Item_sp(THD *thd, Name_resolution_context *context_arg,
|
|||
dummy_table= (TABLE*) thd->calloc(sizeof(TABLE) + sizeof(TABLE_SHARE) +
|
||||
sizeof(Query_arena));
|
||||
dummy_table->s= (TABLE_SHARE*) (dummy_table + 1);
|
||||
/* TODO(cvicentiu) Move this sp_query_arena in the class as a direct member.
|
||||
Currently it can not be done due to header include dependencies. */
|
||||
sp_query_arena= (Query_arena *) (dummy_table->s + 1);
|
||||
sp_query_arena= new(dummy_table->s + 1) Query_arena();
|
||||
memset(&sp_mem_root, 0, sizeof(sp_mem_root));
|
||||
}
|
||||
|
||||
|
@ -2612,7 +2610,7 @@ Item_sp::Item_sp(THD *thd, Item_sp *item):
|
|||
dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE) +
|
||||
sizeof(Query_arena));
|
||||
dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
|
||||
sp_query_arena= (Query_arena *) (dummy_table->s + 1);
|
||||
sp_query_arena= new(dummy_table->s + 1) Query_arena();
|
||||
memset(&sp_mem_root, 0, sizeof(sp_mem_root));
|
||||
}
|
||||
|
||||
|
@ -6208,12 +6206,14 @@ Item *Item_field::replace_equal_field(THD *thd, uchar *arg)
|
|||
item_equal->compare_type_handler()->cmp_type());
|
||||
return const_item2;
|
||||
}
|
||||
Item_field *subst=
|
||||
(Item_field *)(item_equal->get_first(param->context_tab, this));
|
||||
Item_ident *subst=
|
||||
(Item_ident *) (item_equal->get_first(param->context_tab, this));
|
||||
if (subst)
|
||||
subst= (Item_field *) (subst->real_item());
|
||||
if (subst && !field->eq(subst->field))
|
||||
return subst;
|
||||
{
|
||||
Item_field *subst2= (Item_field *) (subst->real_item());
|
||||
if (subst2 && !field->eq(subst2->field))
|
||||
return subst2;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
117
sql/sql_acl.cc
117
sql/sql_acl.cc
|
@ -5348,7 +5348,7 @@ routine_hash_search(const char *host, const char *ip, const char *db,
|
|||
const char *user, const char *tname, const Sp_handler *sph,
|
||||
bool exact)
|
||||
{
|
||||
return (GRANT_TABLE*)
|
||||
return (GRANT_NAME*)
|
||||
name_hash_search(sph->get_priv_hash(),
|
||||
host, ip, db, user, tname, exact, TRUE);
|
||||
}
|
||||
|
@ -5362,6 +5362,10 @@ table_hash_search(const char *host, const char *ip, const char *db,
|
|||
user, tname, exact, FALSE);
|
||||
}
|
||||
|
||||
static bool column_priv_insert(GRANT_TABLE *grant)
|
||||
{
|
||||
return my_hash_insert(&column_priv_hash,(uchar*) grant);
|
||||
}
|
||||
|
||||
static GRANT_COLUMN *
|
||||
column_hash_search(GRANT_TABLE *t, const char *cname, size_t length)
|
||||
|
@ -5591,6 +5595,15 @@ static inline void get_grantor(THD *thd, char *grantor)
|
|||
strxmov(grantor, user, "@", host, NullS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Revoke rights from a grant table entry.
|
||||
|
||||
@return 0 ok
|
||||
@return 1 fatal error (error given)
|
||||
@return -1 grant table was revoked
|
||||
*/
|
||||
|
||||
static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
||||
TABLE *table, const LEX_USER &combo,
|
||||
const char *db, const char *table_name,
|
||||
|
@ -5615,7 +5628,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||
{
|
||||
my_message(ER_PASSWORD_NO_MATCH, ER_THD(thd, ER_PASSWORD_NO_MATCH),
|
||||
MYF(0)); /* purecov: deadcode */
|
||||
DBUG_RETURN(-1); /* purecov: deadcode */
|
||||
DBUG_RETURN(1); /* purecov: deadcode */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5646,7 +5659,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||
my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
|
||||
combo.user.str, combo.host.str,
|
||||
table_name); /* purecov: deadcode */
|
||||
DBUG_RETURN(-1); /* purecov: deadcode */
|
||||
DBUG_RETURN(1); /* purecov: deadcode */
|
||||
}
|
||||
old_row_exists = 0;
|
||||
restore_record(table,record[1]); // Get saved record
|
||||
|
@ -5709,13 +5722,14 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
|
|||
else
|
||||
{
|
||||
my_hash_delete(&column_priv_hash,(uchar*) grant_table);
|
||||
DBUG_RETURN(-1); // Entry revoked
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
||||
/* This should never happen */
|
||||
table_error:
|
||||
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
|
||||
DBUG_RETURN(-1); /* purecov: deadcode */
|
||||
DBUG_RETURN(1); /* purecov: deadcode */
|
||||
}
|
||||
|
||||
|
||||
|
@ -6476,7 +6490,7 @@ static int update_role_table_columns(GRANT_TABLE *merged,
|
|||
privs, cols);
|
||||
merged->init_privs= merged->init_cols= 0;
|
||||
update_role_columns(merged, first, last);
|
||||
my_hash_insert(&column_priv_hash,(uchar*) merged);
|
||||
column_priv_insert(merged);
|
||||
return 2;
|
||||
}
|
||||
else if ((privs | cols) == 0)
|
||||
|
@ -6796,7 +6810,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||
bool revoke_grant)
|
||||
{
|
||||
ulong column_priv= 0;
|
||||
int result;
|
||||
int result, res;
|
||||
List_iterator <LEX_USER> str_list (user_list);
|
||||
LEX_USER *Str, *tmp_Str;
|
||||
bool create_new_users=0;
|
||||
|
@ -6939,12 +6953,12 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||
result= TRUE;
|
||||
continue;
|
||||
}
|
||||
grant_table = new GRANT_TABLE (Str->host.str, db_name,
|
||||
Str->user.str, table_name,
|
||||
rights,
|
||||
column_priv);
|
||||
grant_table= new (&grant_memroot) GRANT_TABLE(Str->host.str, db_name,
|
||||
Str->user.str, table_name,
|
||||
rights,
|
||||
column_priv);
|
||||
if (!grant_table ||
|
||||
my_hash_insert(&column_priv_hash,(uchar*) grant_table))
|
||||
column_priv_insert(grant_table))
|
||||
{
|
||||
result= TRUE; /* purecov: deadcode */
|
||||
continue; /* purecov: deadcode */
|
||||
|
@ -6987,22 +7001,24 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||
|
||||
/* TODO(cvicentiu) refactor replace_table_table to use Tables_priv_table
|
||||
instead of TABLE directly. */
|
||||
if (replace_table_table(thd, grant_table, tables.tables_priv_table().table(),
|
||||
*Str, db_name, table_name,
|
||||
rights, column_priv, revoke_grant))
|
||||
{
|
||||
/* Should only happen if table is crashed */
|
||||
result= TRUE; /* purecov: deadcode */
|
||||
}
|
||||
else if (tables.columns_priv_table().table_exists())
|
||||
if (tables.columns_priv_table().table_exists())
|
||||
{
|
||||
/* TODO(cvicentiu) refactor replace_column_table to use Columns_priv_table
|
||||
instead of TABLE directly. */
|
||||
if (replace_column_table(grant_table, tables.columns_priv_table().table(),
|
||||
*Str, columns, db_name, table_name, rights,
|
||||
revoke_grant))
|
||||
{
|
||||
result= TRUE;
|
||||
}
|
||||
if ((res= replace_table_table(thd, grant_table,
|
||||
tables.tables_priv_table().table(),
|
||||
*Str, db_name, table_name,
|
||||
rights, column_priv, revoke_grant)))
|
||||
{
|
||||
if (res > 0)
|
||||
{
|
||||
/* Should only happen if table is crashed */
|
||||
result= TRUE; /* purecov: deadcode */
|
||||
}
|
||||
}
|
||||
if (Str->is_role())
|
||||
|
@ -7014,9 +7030,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||
mysql_mutex_unlock(&acl_cache->lock);
|
||||
|
||||
if (!result) /* success */
|
||||
{
|
||||
result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
|
||||
}
|
||||
|
||||
mysql_rwlock_unlock(&LOCK_grant);
|
||||
|
||||
|
@ -7704,7 +7718,7 @@ static bool grant_load(THD *thd,
|
|||
|
||||
if (! mem_check->ok())
|
||||
delete mem_check;
|
||||
else if (my_hash_insert(&column_priv_hash,(uchar*) mem_check))
|
||||
else if (column_priv_insert(mem_check))
|
||||
{
|
||||
delete mem_check;
|
||||
goto end_unlock;
|
||||
|
@ -11100,7 +11114,7 @@ mysql_revoke_sp_privs(THD *thd, Grant_tables *tables, const Sp_handler *sph,
|
|||
bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
||||
{
|
||||
uint counter, revoked;
|
||||
int result;
|
||||
int result, res;
|
||||
ACL_DB *acl_db;
|
||||
DBUG_ENTER("mysql_revoke_all");
|
||||
|
||||
|
@ -11193,36 +11207,35 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
|
|||
if (!strcmp(lex_user->user.str,user) &&
|
||||
!strcmp(lex_user->host.str, host))
|
||||
{
|
||||
/* TODO(cvicentiu) refactor replace_db_table to use
|
||||
Db_table instead of TABLE directly. */
|
||||
if (replace_table_table(thd, grant_table,
|
||||
tables.tables_priv_table().table(),
|
||||
*lex_user, grant_table->db,
|
||||
grant_table->tname, ~(ulong)0, 0, 1))
|
||||
{
|
||||
List<LEX_COLUMN> columns;
|
||||
/* TODO(cvicentiu) refactor replace_db_table to use
|
||||
Db_table instead of TABLE directly. */
|
||||
if (replace_column_table(grant_table,
|
||||
tables.columns_priv_table().table(),
|
||||
*lex_user, columns, grant_table->db,
|
||||
grant_table->tname, ~(ulong)0, 1))
|
||||
result= -1;
|
||||
}
|
||||
else
|
||||
|
||||
/* TODO(cvicentiu) refactor replace_db_table to use
|
||||
Db_table instead of TABLE directly. */
|
||||
if ((res= replace_table_table(thd, grant_table,
|
||||
tables.tables_priv_table().table(),
|
||||
*lex_user, grant_table->db,
|
||||
grant_table->tname, ~(ulong)0, 0, 1)))
|
||||
{
|
||||
if (!grant_table->cols)
|
||||
{
|
||||
revoked= 1;
|
||||
continue;
|
||||
}
|
||||
List<LEX_COLUMN> columns;
|
||||
/* TODO(cvicentiu) refactor replace_db_table to use
|
||||
Db_table instead of TABLE directly. */
|
||||
if (!replace_column_table(grant_table,
|
||||
tables.columns_priv_table().table(),
|
||||
*lex_user, columns, grant_table->db,
|
||||
grant_table->tname, ~(ulong)0, 1))
|
||||
{
|
||||
revoked= 1;
|
||||
continue;
|
||||
}
|
||||
result= -1;
|
||||
}
|
||||
}
|
||||
if (res > 0)
|
||||
result= -1;
|
||||
else
|
||||
{
|
||||
/*
|
||||
Entry was deleted. We have to retry the loop as the
|
||||
hash table has probably been reorganized.
|
||||
*/
|
||||
revoked= 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
} while (revoked);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
107
sql/sql_select.h
107
sql/sql_select.h
|
@ -698,8 +698,6 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||
bool end_of_records);
|
||||
|
||||
|
||||
struct st_position;
|
||||
|
||||
class Semi_join_strategy_picker
|
||||
{
|
||||
public:
|
||||
|
@ -710,7 +708,7 @@ public:
|
|||
Update internal state after another table has been added to the join
|
||||
prefix
|
||||
*/
|
||||
virtual void set_from_prev(struct st_position *prev) = 0;
|
||||
virtual void set_from_prev(POSITION *prev) = 0;
|
||||
|
||||
virtual bool check_qep(JOIN *join,
|
||||
uint idx,
|
||||
|
@ -720,7 +718,7 @@ public:
|
|||
double *read_time,
|
||||
table_map *handled_fanout,
|
||||
sj_strategy_enum *strategy,
|
||||
struct st_position *loose_scan_pos) = 0;
|
||||
POSITION *loose_scan_pos) = 0;
|
||||
|
||||
virtual void mark_used() = 0;
|
||||
|
||||
|
@ -751,7 +749,7 @@ public:
|
|||
first_dupsweedout_table= MAX_TABLES;
|
||||
is_used= FALSE;
|
||||
}
|
||||
void set_from_prev(struct st_position *prev);
|
||||
void set_from_prev(POSITION *prev);
|
||||
|
||||
bool check_qep(JOIN *join,
|
||||
uint idx,
|
||||
|
@ -761,7 +759,7 @@ public:
|
|||
double *read_time,
|
||||
table_map *handled_fanout,
|
||||
sj_strategy_enum *stratey,
|
||||
struct st_position *loose_scan_pos);
|
||||
POSITION *loose_scan_pos);
|
||||
|
||||
void mark_used() { is_used= TRUE; }
|
||||
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
|
||||
|
@ -797,7 +795,7 @@ public:
|
|||
is_used= FALSE;
|
||||
}
|
||||
|
||||
void set_from_prev(struct st_position *prev);
|
||||
void set_from_prev(POSITION *prev);
|
||||
bool check_qep(JOIN *join,
|
||||
uint idx,
|
||||
table_map remaining_tables,
|
||||
|
@ -806,7 +804,7 @@ public:
|
|||
double *read_time,
|
||||
table_map *handled_fanout,
|
||||
sj_strategy_enum *strategy,
|
||||
struct st_position *loose_scan_pos);
|
||||
POSITION *loose_scan_pos);
|
||||
|
||||
void mark_used() { is_used= TRUE; }
|
||||
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
|
||||
|
@ -815,6 +813,7 @@ public:
|
|||
|
||||
class LooseScan_picker : public Semi_join_strategy_picker
|
||||
{
|
||||
public:
|
||||
/* The first (i.e. driving) table we're doing loose scan for */
|
||||
uint first_loosescan_table;
|
||||
/*
|
||||
|
@ -833,14 +832,13 @@ class LooseScan_picker : public Semi_join_strategy_picker
|
|||
uint loosescan_parts; /* Number of keyparts to be kept distinct */
|
||||
|
||||
bool is_used;
|
||||
public:
|
||||
void set_empty()
|
||||
{
|
||||
first_loosescan_table= MAX_TABLES;
|
||||
is_used= FALSE;
|
||||
}
|
||||
|
||||
void set_from_prev(struct st_position *prev);
|
||||
void set_from_prev(POSITION *prev);
|
||||
bool check_qep(JOIN *join,
|
||||
uint idx,
|
||||
table_map remaining_tables,
|
||||
|
@ -849,19 +847,19 @@ public:
|
|||
double *read_time,
|
||||
table_map *handled_fanout,
|
||||
sj_strategy_enum *strategy,
|
||||
struct st_position *loose_scan_pos);
|
||||
POSITION *loose_scan_pos);
|
||||
void mark_used() { is_used= TRUE; }
|
||||
|
||||
friend class Loose_scan_opt;
|
||||
friend void best_access_path(JOIN *join,
|
||||
JOIN_TAB *s,
|
||||
table_map remaining_tables,
|
||||
const struct st_position *join_positions,
|
||||
const POSITION *join_positions,
|
||||
uint idx,
|
||||
bool disable_jbuf,
|
||||
double record_count,
|
||||
struct st_position *pos,
|
||||
struct st_position *loose_scan_pos);
|
||||
POSITION *pos,
|
||||
POSITION *loose_scan_pos);
|
||||
friend bool get_best_combination(JOIN *join);
|
||||
friend int setup_semijoin_loosescan(JOIN *join);
|
||||
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
|
||||
|
@ -888,7 +886,7 @@ public:
|
|||
sjm_scan_last_inner= 0;
|
||||
is_used= FALSE;
|
||||
}
|
||||
void set_from_prev(struct st_position *prev);
|
||||
void set_from_prev(POSITION *prev);
|
||||
bool check_qep(JOIN *join,
|
||||
uint idx,
|
||||
table_map remaining_tables,
|
||||
|
@ -897,7 +895,7 @@ public:
|
|||
double *read_time,
|
||||
table_map *handled_fanout,
|
||||
sj_strategy_enum *strategy,
|
||||
struct st_position *loose_scan_pos);
|
||||
POSITION *loose_scan_pos);
|
||||
void mark_used() { is_used= TRUE; }
|
||||
|
||||
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
|
||||
|
@ -912,8 +910,9 @@ class Rowid_filter;
|
|||
Information about a position of table within a join order. Used in join
|
||||
optimization.
|
||||
*/
|
||||
typedef struct st_position
|
||||
class POSITION
|
||||
{
|
||||
public:
|
||||
/* The table that's put into join order */
|
||||
JOIN_TAB *table;
|
||||
|
||||
|
@ -925,7 +924,7 @@ typedef struct st_position
|
|||
double records_read;
|
||||
|
||||
/* The selectivity of the pushed down conditions */
|
||||
double cond_selectivity;
|
||||
double cond_selectivity;
|
||||
|
||||
/*
|
||||
Cost accessing the table in course of the entire complete join execution,
|
||||
|
@ -934,8 +933,6 @@ typedef struct st_position
|
|||
*/
|
||||
double read_time;
|
||||
|
||||
/* Cumulative cost and record count for the join prefix */
|
||||
Cost_estimate prefix_cost;
|
||||
double prefix_record_count;
|
||||
|
||||
/*
|
||||
|
@ -944,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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(×tamp,
|
||||
2);
|
||||
table->field[16]->store_time_dec(×tamp, 2);
|
||||
}
|
||||
|
||||
sql_mode_string_representation(thd, trigger->sql_mode, &sql_mode_rep);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
/*****************************************************************/
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
14
storage/mroonga/vendor/groonga/lib/alloc.c
vendored
14
storage/mroonga/vendor/groonga/lib/alloc.c
vendored
|
@ -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) {
|
||||
|
|
2
storage/mroonga/vendor/groonga/lib/db.c
vendored
2
storage/mroonga/vendor/groonga/lib/db.c
vendored
|
@ -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));
|
||||
|
|
4
storage/mroonga/vendor/groonga/lib/pat.c
vendored
4
storage/mroonga/vendor/groonga/lib/pat.c
vendored
|
@ -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;\
|
||||
}\
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
5
storage/mroonga/vendor/groonga/lib/str.c
vendored
5
storage/mroonga/vendor/groonga/lib/str.c
vendored
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {}
|
||||
|
|
Loading…
Reference in a new issue