diff options
174 files changed, 2118 insertions, 837 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 3521896c3b1..bc306c55880 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4559,8 +4559,11 @@ static char *get_arg(char *line, get_arg_mode mode) } for (start=ptr ; *ptr; ptr++) { - if ((*ptr == '\\' && ptr[1]) || // escaped character - (!short_cmd && qtype && *ptr == qtype && ptr[1] == qtype)) // quote + /* if short_cmd use historical rules (only backslash) otherwise SQL rules */ + if (short_cmd + ? (*ptr == '\\' && ptr[1]) // escaped character + : (*ptr == '\\' && ptr[1] && qtype != '`') || // escaped character + (qtype && *ptr == qtype && ptr[1] == qtype)) // quote { // Remove (or skip) the backslash (or a second quote) if (mode != CHECK) diff --git a/config.h.cmake b/config.h.cmake index ae0947d52b4..28285468624 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -148,6 +148,7 @@ #cmakedefine HAVE_CUSERID 1 #cmakedefine HAVE_CXX_NEW 1 #cmakedefine HAVE_DIRECTIO 1 +#cmakedefine HAVE_DLADDR 1 #cmakedefine HAVE_DLERROR 1 #cmakedefine HAVE_DLOPEN 1 #cmakedefine HAVE_DOPRNT 1 diff --git a/configure.cmake b/configure.cmake index 37a96109968..ed7cce9a10c 100644 --- a/configure.cmake +++ b/configure.cmake @@ -346,6 +346,7 @@ CHECK_FUNCTION_EXISTS (ftruncate HAVE_FTRUNCATE) CHECK_FUNCTION_EXISTS (getline HAVE_GETLINE) CHECK_FUNCTION_EXISTS (compress HAVE_COMPRESS) CHECK_FUNCTION_EXISTS (crypt HAVE_CRYPT) +CHECK_FUNCTION_EXISTS (dladdr HAVE_DLADDR) CHECK_FUNCTION_EXISTS (dlerror HAVE_DLERROR) CHECK_FUNCTION_EXISTS (dlopen HAVE_DLOPEN) CHECK_FUNCTION_EXISTS (fchmod HAVE_FCHMOD) diff --git a/debian/dist/Debian/control b/debian/dist/Debian/control index 9ff7705b007..ea6341292ef 100644 --- a/debian/dist/Debian/control +++ b/debian/dist/Debian/control @@ -12,8 +12,8 @@ Build-Depends: procps | hurd, debhelper, libncurses5-dev (>= 5.0-6), ${CMAKE_DEP}libaio-dev, libjemalloc-dev (>= 3.0.0) Standards-Version: 3.8.3 Homepage: http://mariadb.org/ -Vcs-Browser: http://bazaar.launchpad.net/~maria-captains/maria/5.5/files -Vcs-Bzr: bzr://lp:maria +Vcs-Git: https://github.com/MariaDB/server.git +Vcs-Browser: https://github.com/MariaDB/server/ Package: mariadb-galera-test-5.5 Section: database diff --git a/debian/dist/Ubuntu/control b/debian/dist/Ubuntu/control index 7d6e90abd82..9dfe258a517 100644 --- a/debian/dist/Ubuntu/control +++ b/debian/dist/Ubuntu/control @@ -12,8 +12,8 @@ Build-Depends: procps | hurd, debhelper, libncurses5-dev (>= 5.0-6), ${CMAKE_DEP}libaio-dev, libjemalloc-dev (>= 3.0.0) Standards-Version: 3.8.2 Homepage: http://mariadb.org/ -Vcs-Browser: http://bazaar.launchpad.net/~maria-captains/maria/5.5/files -Vcs-Bzr: bzr://lp:maria +Vcs-Git: https://github.com/MariaDB/server.git +Vcs-Browser: https://github.com/MariaDB/server/ Package: mariadb-galera-test-5.5 Section: database diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index aa2de39333c..bb8e3791552 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -787,6 +787,16 @@ int DoProcessReply(SSL& ssl) needHdr = true; else { buffer >> hdr; + /* + According to RFC 4346 (see "7.4.1.3. Server Hello"), the Server Hello + packet needs to specify the highest supported TLS version, but not + higher than what client requests. YaSSL highest supported version is + TLSv1.1 (=3.2) - if the client requests a higher version, downgrade it + here to 3.2. + See also Appendix E of RFC 5246 (TLS 1.2) + */ + if (hdr.version_.major_ == 3 && hdr.version_.minor_ > 2) + hdr.version_.minor_ = 2; ssl.verifyState(hdr); } diff --git a/include/heap.h b/include/heap.h index 2b7fd28699d..eecb7084e66 100644 --- a/include/heap.h +++ b/include/heap.h @@ -144,6 +144,7 @@ typedef struct st_heap_share uint key_version; /* Updated on key change */ uint file_version; /* Update on clear */ uint reclength; /* Length of one record */ + uint visible; /* Offset to the visible/deleted mark */ uint changed; uint keys,max_key_length; uint currently_disabled_keys; /* saved value from "keys" when disabled */ diff --git a/include/my_global.h b/include/my_global.h index 6e8fb33b137..476ef53515e 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1379,11 +1379,19 @@ static inline char *dlerror(void) #ifndef HAVE_DLERROR #define dlerror() "" #endif +#ifndef HAVE_DLADDR +#define dladdr(A, B) 0 +/* Dummy definition in case we're missing dladdr() */ +typedef struct { const char *dli_fname, dli_fbase; } Dl_info; +#endif #else #define dlerror() "No support for dynamic loading (static build?)" #define dlopen(A,B) 0 #define dlsym(A,B) 0 #define dlclose(A) 0 +#define dladdr(A, B) 0 +/* Dummy definition in case we're missing dladdr() */ +typedef struct { const char *dli_fname, dli_fbase; } Dl_info; #endif /* diff --git a/include/my_valgrind.h b/include/my_valgrind.h index a9dba1cb06c..8dde079b976 100644 --- a/include/my_valgrind.h +++ b/include/my_valgrind.h @@ -13,6 +13,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* clang -> gcc */ +#ifndef __has_feature +# define __has_feature(x) 0 +#endif +#if __has_feature(address_sanitizer) +# define __SANITIZE_ADDRESS__ 1 +#endif + #ifdef HAVE_valgrind #define IF_VALGRIND(A,B) A #else @@ -27,6 +35,8 @@ # define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len) #elif defined(__SANITIZE_ADDRESS__) # include <sanitizer/asan_interface.h> +/* How to do manual poisoning: +https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */ # define MEM_UNDEFINED(a,len) ASAN_UNPOISON_MEMORY_REGION(a,len) # define MEM_NOACCESS(a,len) ASAN_POISON_MEMORY_REGION(a,len) # define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0) @@ -39,10 +49,9 @@ #endif /* HAVE_VALGRIND */ #ifndef DBUG_OFF -#define TRASH_FILL(A,B,C) do { memset(A, C, B); MEM_UNDEFINED(A, B); } while (0) +#define TRASH_FILL(A,B,C) do { MEM_UNDEFINED(A,B); memset(A,C,B); } while(0) #else -#define TRASH_FILL(A,B,C) do { MEM_CHECK_ADDRESSABLE(A,B);MEM_UNDEFINED(A,B);} while (0) +#define TRASH_FILL(A,B,C) do { MEM_UNDEFINED(A,B); } while(0) #endif -#define TRASH_ALLOC(A,B) TRASH_FILL(A,B,0xA5) -#define TRASH_FREE(A,B) TRASH_FILL(A,B,0x8F) -#define TRASH(A,B) TRASH_FREE(A,B) +#define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0) +#define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0) diff --git a/include/mysql_com.h b/include/mysql_com.h index df9681e02a4..d76dc72e2b8 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab + Copyright (c) 2010, 2018, MariaDB 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 diff --git a/include/sql_common.h b/include/sql_common.h index a1c9faac82d..5bfe5ba8969 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -1,7 +1,7 @@ #ifndef SQL_COMMON_INCLUDED #define SQL_COMMON_INCLUDED /* Copyright (c) 2003, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2012, Monty Program Ab + Copyright (c) 2010, 2018, MariaDB 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 diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index e7917f8fb16..7059ceebdad 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -84,7 +84,7 @@ sub is_child { } -my @safe_process_cmd; +our @safe_process_cmd; my $safe_kill; my $bindir; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 150c7022274..9483eb070fb 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2,7 +2,7 @@ # -*- cperl -*- # Copyright (c) 2004, 2014, Oracle and/or its affiliates. -# Copyright (c) 2009, 2017, MariaDB Corporation +# Copyright (c) 2009, 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 @@ -1609,6 +1609,7 @@ sub command_line_setup { $opt_manual_debug || $opt_dbx || $opt_client_dbx || $opt_manual_dbx || $opt_debugger || $opt_client_debugger ) { + $ENV{ASAN_OPTIONS}= 'abort_on_error=1:'.($ENV{ASAN_OPTIONS} || ''); if ( using_extern() ) { mtr_error("Can't use --extern when using debugger"); @@ -5381,7 +5382,7 @@ sub mysqld_start ($$) { my $args; mtr_init_args(\$args); - if ( $opt_valgrind_mysqld ) + if ( $opt_valgrind_mysqld and not $opt_gdb and not $opt_manual_gdb ) { valgrind_arguments($args, \$exe); } @@ -5984,11 +5985,20 @@ sub gdb_arguments { unlink($gdb_init_file); # Put $args into a single string - my $str= join(" ", @$$args); $input = $input ? "< $input" : ""; - # write init file for mysqld or client - mtr_tofile($gdb_init_file, "set args $str $input\n"); + if ($type ne 'client' and $opt_valgrind_mysqld) { + my $v = $$exe; + my $vargs = []; + valgrind_arguments($vargs, \$v); + mtr_tofile($gdb_init_file, <<EOF); +shell @My::SafeProcess::safe_process_cmd --parent-pid=`pgrep -x gdb` -- $v --vgdb-error=0 @$vargs @$$args & +shell sleep 1 +target remote | /usr/lib64/valgrind/../../bin/vgdb +EOF + } else { + mtr_tofile($gdb_init_file, "set args @$$args $input\n"); + } if ( $opt_manual_gdb ) { diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 1bbd3af4af7..1c9e31d3a06 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -4397,5 +4397,36 @@ Field Type Null Key Default Extra c1 mediumtext YES NULL DROP TABLE t1; # +# MDEV-15624 Changing the default character set to utf8mb4 changes query evaluation in a very surprising way +# +SET NAMES utf8; +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT COUNT(DISTINCT c) FROM (SELECT id, REPLACE(uuid_short(), '0', CAST('o' AS CHAR CHARACTER SET ucs2)) AS c FROM t1) AS d1; +COUNT(DISTINCT c) +3 +SELECT DISTINCT REPLACE(uuid_short(), '0', CAST('o' AS CHAR CHARACTER SET ucs2)) AS c FROM t1; +c +xxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxx +SELECT COUNT(DISTINCT c) FROM (SELECT id, INSERT(uuid_short(), 1, 1, CAST('0' AS CHAR CHARACTER SET ucs2)) AS c FROM t1) AS d1; +COUNT(DISTINCT c) +3 +SELECT DISTINCT INSERT(uuid_short(), 1, 1, CAST('0' AS CHAR CHARACTER SET ucs2)) AS c FROM t1; +c +xxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxx +SELECT COUNT(DISTINCT c) FROM (SELECT id, CONCAT(uuid_short(), CAST('0' AS CHAR CHARACTER SET ucs2)) AS c FROM t1) AS d1; +COUNT(DISTINCT c) +3 +SELECT DISTINCT CONCAT(uuid_short(), CAST('0' AS CHAR CHARACTER SET ucs2)) AS c FROM t1; +c +xxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxx +DROP TABLE t1; +# # End of 5.5 tests # diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result index 17a1a2f787e..2c0bdfb2307 100644 --- a/mysql-test/r/ctype_utf8mb4.result +++ b/mysql-test/r/ctype_utf8mb4.result @@ -2656,6 +2656,29 @@ SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 65536) AS data ) AS sub; len 196608 # +# MDEV-15624 Changing the default character set to utf8mb4 changes query evaluation in a very surprising way +# +SET NAMES utf8mb4; +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT COUNT(DISTINCT c) FROM (SELECT id, REPLACE(UUID(), "-", "") AS c FROM t1) AS d1; +COUNT(DISTINCT c) +3 +SELECT DISTINCT INSERT(uuid(), 9, 1, "X") AS c FROM t1; +c +xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +SELECT COUNT(DISTINCT c) FROM (SELECT id, INSERT(UUID(), 9, 1, "X") AS c FROM t1) AS d1; +COUNT(DISTINCT c) +3 +SELECT DISTINCT INSERT(UUID(), 9, 1, "X") AS c FROM t1; +c +xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +DROP TABLE t1; +# # End of 5.5 tests # # diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 33af7c61613..54c78dc9f6f 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -1011,4 +1011,45 @@ id id data 2 2 yes 1 NULL NULL drop table t1; +# +# MDEV-14241: Server crash in key_copy / get_matching_chain_by_join_key +# or valgrind warnings +# +CREATE TABLE t1 (a VARCHAR(10)) ENGINE=MyISAM; +CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES ('foo'),('bar'); +CREATE TABLE t2 (b integer auto_increment primary key) ENGINE=MyISAM; +INSERT INTO t2 VALUES (NULL),(NULL); +CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM; +CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3; +INSERT INTO t3 VALUES ('abc',NULL),('def',4); +SET join_cache_level= 8; +explain +SELECT * FROM v1, t2, v3 WHERE a = c AND b = d; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 +1 PRIMARY <derived3> hash_ALL NULL #hash#$hj 3075 func 2 Using where; Using join buffer (flat, BNLH join) +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 v3.d 1 Using index +3 DERIVED t3 ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM v1, t2, v3 WHERE a = c AND b = d; +a b c d +DROP VIEW v1, v3; +DROP TABLE t1, t2, t3; +# +# MDEV-14786: Server crashes in Item_cond::transform on 2nd +# execution of SP querying from a view +# +create table t1 (i int, row_start timestamp(6) not null default now(), +row_end timestamp(6) not null default '2030-01-01 0:0:0'); +create view v1 as select i from t1 where i < 5 and (row_end = +TIMESTAMP'2030-01-01 0:0:0' or row_end is null); +create procedure pr(x int) select i from v1; +call pr(1); +i +call pr(2); +i +drop procedure pr; +drop view v1; +drop table t1; # end of 5.5 diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 1c106acf333..66e3cfd4ff4 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -572,6 +572,17 @@ N AVG 0 NULL drop table t1; # +# MDEV-15630 uuid() function evaluates at wrong time in query +# +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT COUNT(1), UUID() as uid FROM t1 GROUP BY uid; +COUNT(1) uid +1 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +1 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +1 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +DROP TABLE t1; +# # End of 5.5 tests # SELECT NAME_CONST('a', -(1 OR 2)) OR 1; diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index cc64393f975..386f7119bc8 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5813,4 +5813,62 @@ id select_type table type possible_keys key key_len ref rows Extra set join_buffer_size=default; set join_cache_level = default; DROP TABLE t1,t2; +# +# MDEV-14960: BNLH used for materialized semi-join +# +CREATE TABLE t1 (i1 int); +CREATE TABLE t2 (e1 int); +CREATE TABLE t4 (e1 int); +CREATE TABLE t5 (e1 int); +INSERT INTO t1 VALUES +(1),(2),(3),(4),(5),(6),(7),(8); +INSERT INTO t1 SELECT i1+8 FROM t1; +INSERT INTO t1 SELECT i1+16 FROM t1; +INSERT INTO t1 SELECT i1+32 FROM t1; +INSERT INTO t1 SELECT i1+64 FROM t1; +INSERT INTO t2 SELECT * FROM t1; +INSERT INTO t4 SELECT * FROM t1; +INSERT INTO t5 SELECT * FROM t1; +set @save_optimizer_switch= @@optimizer_switch; +SET join_cache_level = 6; +SET join_buffer_size=4096; +SET join_buffer_space_limit=4096; +SET optimizer_switch = 'join_cache_hashed=on,optimize_join_buffer_size=on'; +EXPLAIN SELECT * FROM t1 +WHERE +i1 < 10 AND +i1 IN +(SELECT i1 FROM +(SELECT (t4.e1) i1 FROM t4 +LEFT JOIN t5 ON t4.e1 = t5.e1 +LEFT JOIN (SELECT e1 FROM t2 ) AS d ON t4.e1 = d.e1) a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 128 Using where +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 +2 MATERIALIZED t4 ALL NULL NULL NULL NULL 128 +2 MATERIALIZED t5 hash_ALL NULL #hash#$hj 5 test.t4.e1 128 Using where; Using join buffer (flat, BNLH join) +2 MATERIALIZED t2 hash_ALL NULL #hash#$hj 5 test.t4.e1 128 Using where; Using join buffer (incremental, BNLH join) +SELECT * FROM t1 +WHERE +i1 < 10 AND +i1 IN +(SELECT i1 FROM +(SELECT (t4.e1) i1 FROM t4 +LEFT JOIN t5 ON t4.e1 = t5.e1 +LEFT JOIN (SELECT e1 FROM t2 ) AS d ON t4.e1 = d.e1) a); +i1 +1 +2 +3 +4 +5 +6 +7 +8 +9 +SET join_cache_level = default; +SET join_buffer_size = default; +SET join_buffer_space_limit= default; +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t4,t5,t2; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 74580e67499..67b22ca86b2 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -2346,11 +2346,27 @@ CREATE TABLE t1 (b1 BIT NOT NULL); INSERT INTO t1 VALUES (0),(1); CREATE TABLE t2 (b2 BIT NOT NULL); INSERT INTO t2 VALUES (0),(1); -SET SESSION JOIN_CACHE_LEVEL = 3; +set @save_join_cache_level= @@join_cache_level; +SET @@join_cache_level = 3; SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2; t1.b1+'0' t2.b2 + '0' 0 0 1 1 DROP TABLE t1, t2; +set @join_cache_level= @save_join_cache_level; +# +# MDEV-14779: using left join causes incorrect results with materialization and derived tables +# +create table t1(id int); +insert into t1 values (1),(2); +create table t2(sid int, id int); +insert into t2 values (1,1),(2,2); +select * from t1 t +left join (select * from t2 where sid in (select max(sid) from t2 where 0=1 group by id)) r +on t.id=r.id ; +id sid id +1 NULL NULL +2 NULL NULL +drop table t1, t2; # end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index d46a4ee6c7a..c019da6197b 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -2357,12 +2357,28 @@ CREATE TABLE t1 (b1 BIT NOT NULL); INSERT INTO t1 VALUES (0),(1); CREATE TABLE t2 (b2 BIT NOT NULL); INSERT INTO t2 VALUES (0),(1); -SET SESSION JOIN_CACHE_LEVEL = 3; +set @save_join_cache_level= @@join_cache_level; +SET @@join_cache_level = 3; SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2; t1.b1+'0' t2.b2 + '0' 0 0 1 1 DROP TABLE t1, t2; +set @join_cache_level= @save_join_cache_level; +# +# MDEV-14779: using left join causes incorrect results with materialization and derived tables +# +create table t1(id int); +insert into t1 values (1),(2); +create table t2(sid int, id int); +insert into t2 values (1,1),(2,2); +select * from t1 t +left join (select * from t2 where sid in (select max(sid) from t2 where 0=1 group by id)) r +on t.id=r.id ; +id sid id +1 NULL NULL +2 NULL NULL +drop table t1, t2; # end of 5.5 tests SET optimizer_switch=@save_optimizer_switch; set join_cache_level=default; diff --git a/mysql-test/r/mdev_14586.result b/mysql-test/r/mdev_14586.result new file mode 100644 index 00000000000..f6c2095d3cd --- /dev/null +++ b/mysql-test/r/mdev_14586.result @@ -0,0 +1,44 @@ +create table t1(a bit(1), b int auto_increment ,id int, index(a,b)); +insert into t1 values(1,null,1); +insert into t1 values(1,null,2); +insert into t1 values(0,null,3); +insert into t1 values(0,null,4); +select a+0, b as auto_increment , id from t1 order by id; +a+0 auto_increment id +1 1 1 +1 2 2 +0 1 3 +0 2 4 +drop table t1; +create table t1(a int auto_increment, b bit(5) ,id int, index (b,a)); +insert into t1 values(null,b'1',1); +insert into t1 values(null,b'1',2); +insert into t1 values(null,b'11',3); +insert into t1 values(null,b'11',4); +select a as auto_increment, b+0, id from t1 order by id; +auto_increment b+0 id +1 1 1 +2 1 2 +1 3 3 +2 3 4 +drop table t1; +create table t1(a bit(1), b int auto_increment , c bit(1) , d bit(1), id int,index(a,c,b,d)); +insert into t1 values(1,null,1,1,1); +insert into t1 values(1,null,1,1,2); +insert into t1 values(0,null,1,1,3); +insert into t1 values(1,null,0,1,4); +select a+0, b as auto_increment, c+0, d+0, id from t1 order by id; +a+0 auto_increment c+0 d+0 id +1 1 1 1 1 +1 2 1 1 2 +0 1 1 1 3 +1 1 0 1 4 +drop table t1; +CREATE TABLE t1 (b BIT(1), pk INTEGER AUTO_INCREMENT PRIMARY KEY); +ALTER TABLE t1 ADD INDEX(b,pk); +INSERT INTO t1 VALUES (1,b'1'); +ALTER TABLE t1 DROP PRIMARY KEY; +select b+0, pk as auto_increment from t1; +b+0 auto_increment +1 1 +DROP TABLE t1; diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 91131870752..5b25b4d01a7 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -1,8 +1,10 @@ The following options may be given as the first argument: --print-defaults Print the program argument list and exit. --no-defaults Don't read default options from any option file. +The following specify which files/extra groups are read (specified before remaining options): --defaults-file=# Only read default options from the given file #. --defaults-extra-file=# Read this file after the global files are read. +--defaults-group-suffix=# Additionally read default groups with # appended as a suffix. --allow-suspicious-udfs Allows use of UDFs consisting of only one symbol xxx() diff --git a/mysql-test/r/mysqldump-nl.result b/mysql-test/r/mysqldump-nl.result index 6de439bdf3c..bca199dc46a 100644 --- a/mysql-test/r/mysqldump-nl.result +++ b/mysql-test/r/mysqldump-nl.result @@ -124,3 +124,46 @@ v1 1v drop database `mysqltest1 1tsetlqsym`; +create database `test```; +create database `test\`` +\! ls +#`; +show databases like 'test%'; +Database (test%) +test +test\` +\! ls +# +test` + +-- +-- Current Database: `test``` +-- + +/*!40000 DROP DATABASE IF EXISTS `test```*/; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test``` /*!40100 DEFAULT CHARACTER SET latin1 */; + +USE `test```; + +-- +-- Current Database: `test\`` +-- \! ls +-- #` +-- + +/*!40000 DROP DATABASE IF EXISTS `test\`` +\! ls +#`*/; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test\`` +\! ls +#` /*!40100 DEFAULT CHARACTER SET latin1 */; + +USE `test\`` +\! ls +#`; +drop database `test```; +drop database `test\`` +\! ls +#`; diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 9a14c0e324b..70dc7a4c1cf 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -672,3 +672,10 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp PREPARE stmt FROM 'CREATE TRIGGER tr AFTER DELETE ON t1 FOR EACH ROW SET @a = 1\\'; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\' at line 1 DROP TABLE t1; +# +# MDEV-15620 Crash when using "SET @@NEW.a=expr" inside a trigger +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @@NEW.a=0; +ERROR HY000: Unknown system variable 'NEW' +DROP TABLE t1; diff --git a/mysql-test/r/ps_qc_innodb.result b/mysql-test/r/ps_qc_innodb.result new file mode 100644 index 00000000000..775055e858f --- /dev/null +++ b/mysql-test/r/ps_qc_innodb.result @@ -0,0 +1,23 @@ +# +# MDEV-15492: Subquery crash similar to MDEV-10050 +# +SET @qcs.save= @@global.query_cache_size, @qct.save= @@global.query_cache_type; +SET GLOBAL query_cache_size= 512*1024*1024, query_cache_type= ON; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (b INT) ENGINE=InnoDB; +CREATE VIEW v AS select a from t1 join t2; +PREPARE stmt1 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)"; +PREPARE stmt2 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)"; +EXECUTE stmt2; +a +EXECUTE stmt1; +a +INSERT INTO t2 VALUES (0); +EXECUTE stmt1; +a +START TRANSACTION; +EXECUTE stmt1; +a +DROP VIEW v; +DROP TABLE t1, t2; +SET GLOBAL query_cache_size= @qcs.save, query_cache_type= @qct.save; diff --git a/mysql-test/r/read_only_innodb.result b/mysql-test/r/read_only_innodb.result index 1e041395d3c..2af72d30851 100644 --- a/mysql-test/r/read_only_innodb.result +++ b/mysql-test/r/read_only_innodb.result @@ -221,6 +221,14 @@ a a 5 10 DROP TABLE temp1, temp2; +# MDEV-14185 CREATE TEMPORARY TABLE AS SELECT causes error 1290 with read_only and InnoDB. + +CREATE TEMPORARY TABLE temp1 ENGINE=INNODB AS SELECT a FROM t1; +SELECT * FROM temp1; +a +1 +DROP TABLE temp1; + # Disconnect and cleanup SET GLOBAL READ_ONLY = OFF; diff --git a/mysql-test/r/sp-destruct.result b/mysql-test/r/sp-destruct.result index 2dac0270ce1..b8f9a516d1e 100644 --- a/mysql-test/r/sp-destruct.result +++ b/mysql-test/r/sp-destruct.result @@ -174,3 +174,9 @@ create database mysqltest1; create procedure mysqltest1.foo() select "foo"; update mysql.proc set name='' where db='mysqltest1'; drop database mysqltest1; +create procedure p1() set @foo = 10; +alter table mysql.proc drop primary key; +drop procedure p1; +ERROR HY000: Cannot load from mysql.proc. The table is probably corrupted +alter table mysql.proc add primary key (db,name,type); +drop procedure p1; diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index d3c63ff9a2f..6accc23d18a 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -1056,7 +1056,7 @@ EXPLAIN SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); f1 f2 SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off'; @@ -1147,7 +1147,7 @@ EXPLAIN SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); f1 f2 set @@optimizer_switch=@save_optimizer_switch; @@ -2498,5 +2498,36 @@ FROM t2 WHERE b <= 'quux' GROUP BY field; field COUNT(DISTINCT c) 0 1 drop table t1,t2; +# +# MDEV-15555: select from DUAL where false yielding wrong result when in a IN +# +explain +SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1); +2 IN (SELECT 2 from DUAL WHERE 1 != 1) +0 SET optimizer_switch= @@global.optimizer_switch; set @@tmp_table_size= @@global.tmp_table_size; +# +# mfrv-14515: Wrong results for tableless query with subquery in WHERE +# and implicit aggregation +# +create table t1 (i1 int, i2 int); +insert into t1 values (1314, 1084),(1330, 1084),(1401, 1084),(580, 1084); +create table t2 (cd int); +insert into t2 values +(1330), (1330), (1330), (1330), (1330), (1330), (1330), (1330), +(1330), (1330), (1330), (1330), (1330), (1330), (1330), (1330); +select max(10) from dual +where exists (select 1 from t2 join t1 on t1.i1 = t2.cd and t1.i2 = 345); +max(10) +NULL +insert into t2 select * from t2; +select max(10) from dual +where exists (select 1 from t2 join t1 on t1.i1 = t2.cd and t1.i2 = 345); +max(10) +NULL +DROP TABLE t1,t2; diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index d4dc519227b..00448ac4f91 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -2642,3 +2642,18 @@ a b sq 4 4 1 4 2 1 drop table t1, t2; +# +# MDEV-15235: Assertion `length > 0' failed in create_ref_for_key +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f CHAR(1)); +INSERT INTO t2 VALUES ('a'),('b'); +explain +SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); +f +DROP TABLE t1, t2; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index fe2339db471..83d889b7b73 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1995,4 +1995,41 @@ avg(f) sub 31.5000 0 1.5000 1 drop table t1,t2,t3; +# +# MDEV-14715 Assertion `!table || (!table->read_set || +# bitmap_is_set(table->read_set, field_index))' +# failed in Field_num::val_decimal +# +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1, NULL),(3, 4); +(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + sum(a)) +UNION +(SELECT 2, 2); +ERROR HY000: Invalid use of group function +(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1) +UNION +(SELECT 2, 2); +a f +1 1 +3 3 +2 2 +SELECT a, b FROM t1 +UNION +(SELECT a, VAR_POP(a) AS f FROM v1 GROUP BY a ORDER BY b/a ); +a b +1 NULL +3 4 +1 0 +3 0 +DROP TABLE t1; +(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1) +UNION +(SELECT 2, 2); +ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +DROP VIEW v1; +(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1) +UNION +(SELECT 2, 2); +ERROR 42S02: Table 'test.v1' doesn't exist End of 5.5 tests diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 8bc33a8860b..7fc3c48c3a0 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5236,114 +5236,6 @@ execute stmt1; deallocate prepare stmt1; drop view v1,v2; drop table t1,t2; -# -# MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized -# with MERGE view) -# -CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE OR REPLACE view v1 AS -SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -; -SELECT 1 -FROM (( SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t1) -LEFT OUTER JOIN (( SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t2) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t3) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t4) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t5) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t6) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t7) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 -FROM t1 a_alias_1 -LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 -LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 -LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 -LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 -LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t8) ON 1=1 -; -1 -SELECT 1 -FROM (v1 t1) -LEFT OUTER JOIN (v1 t2) ON 1=1 -LEFT OUTER JOIN (v1 t3) ON 1=1 -LEFT OUTER JOIN (v1 t4) ON 1=1 -LEFT OUTER JOIN (v1 t5) ON 1=1 -LEFT OUTER JOIN (v1 t6) ON 1=1 -LEFT OUTER JOIN (v1 t7) ON 1=1 -LEFT OUTER JOIN (v1 t8) ON 1=1 -; -1 -drop view v1; -drop table t1,t2,t3,t4,t5,t6; # ----------------------------------------------------------------- # -- End of 5.3 tests. # ----------------------------------------------------------------- @@ -5643,6 +5535,203 @@ View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select group_concat(`t1`.`str` separator '\\') AS `GROUP_CONCAT(str SEPARATOR '\\')` from `t1` latin1 latin1_swedish_ci drop view v1; drop table t1; +CREATE TABLE IF NOT EXISTS t0 (f0 INT); +CREATE TABLE IF NOT EXISTS t1 (f1 INT); +CREATE TABLE IF NOT EXISTS t2 (f2 INT); +CREATE TABLE IF NOT EXISTS t3 (f3 INT); +CREATE TABLE IF NOT EXISTS t4 (f4 INT); +CREATE TABLE IF NOT EXISTS t5 (f5 INT); +CREATE TABLE IF NOT EXISTS t6 (f6 INT); +CREATE TABLE IF NOT EXISTS t7 (f7 INT); +CREATE TABLE IF NOT EXISTS t8 (f8 INT); +CREATE TABLE IF NOT EXISTS t9 (f9 INT); +CREATE TABLE IF NOT EXISTS t10 (f10 INT); +CREATE TABLE IF NOT EXISTS t11 (f11 INT); +CREATE TABLE IF NOT EXISTS t12 (f12 INT); +CREATE TABLE IF NOT EXISTS t13 (f13 INT); +CREATE TABLE IF NOT EXISTS t14 (f14 INT); +CREATE TABLE IF NOT EXISTS t15 (f15 INT); +CREATE TABLE IF NOT EXISTS t16 (f16 INT); +CREATE TABLE IF NOT EXISTS t17 (f17 INT); +CREATE TABLE IF NOT EXISTS t18 (f18 INT); +CREATE TABLE IF NOT EXISTS t19 (f19 INT); +CREATE TABLE IF NOT EXISTS t20 (f20 INT); +CREATE TABLE IF NOT EXISTS t21 (f21 INT); +CREATE TABLE IF NOT EXISTS t22 (f22 INT); +CREATE TABLE IF NOT EXISTS t23 (f23 INT); +CREATE TABLE IF NOT EXISTS t24 (f24 INT); +CREATE TABLE IF NOT EXISTS t25 (f25 INT); +CREATE TABLE IF NOT EXISTS t26 (f26 INT); +CREATE TABLE IF NOT EXISTS t27 (f27 INT); +CREATE TABLE IF NOT EXISTS t28 (f28 INT); +CREATE TABLE IF NOT EXISTS t29 (f29 INT); +CREATE TABLE IF NOT EXISTS t30 (f30 INT); +CREATE TABLE IF NOT EXISTS t31 (f31 INT); +CREATE TABLE IF NOT EXISTS t32 (f32 INT); +CREATE TABLE IF NOT EXISTS t33 (f33 INT); +CREATE TABLE IF NOT EXISTS t34 (f34 INT); +CREATE TABLE IF NOT EXISTS t35 (f35 INT); +CREATE TABLE IF NOT EXISTS t36 (f36 INT); +CREATE TABLE IF NOT EXISTS t37 (f37 INT); +CREATE TABLE IF NOT EXISTS t38 (f38 INT); +CREATE TABLE IF NOT EXISTS t39 (f39 INT); +CREATE TABLE IF NOT EXISTS t40 (f40 INT); +CREATE TABLE IF NOT EXISTS t41 (f41 INT); +CREATE TABLE IF NOT EXISTS t42 (f42 INT); +CREATE TABLE IF NOT EXISTS t43 (f43 INT); +CREATE TABLE IF NOT EXISTS t44 (f44 INT); +CREATE TABLE IF NOT EXISTS t45 (f45 INT); +CREATE TABLE IF NOT EXISTS t46 (f46 INT); +CREATE TABLE IF NOT EXISTS t47 (f47 INT); +CREATE TABLE IF NOT EXISTS t48 (f48 INT); +CREATE TABLE IF NOT EXISTS t49 (f49 INT); +CREATE TABLE IF NOT EXISTS t50 (f50 INT); +CREATE TABLE IF NOT EXISTS t51 (f51 INT); +CREATE TABLE IF NOT EXISTS t52 (f52 INT); +CREATE TABLE IF NOT EXISTS t53 (f53 INT); +CREATE TABLE IF NOT EXISTS t54 (f54 INT); +CREATE TABLE IF NOT EXISTS t55 (f55 INT); +CREATE TABLE IF NOT EXISTS t56 (f56 INT); +CREATE TABLE IF NOT EXISTS t57 (f57 INT); +CREATE TABLE IF NOT EXISTS t58 (f58 INT); +CREATE TABLE IF NOT EXISTS t59 (f59 INT); +CREATE TABLE IF NOT EXISTS t60 (f60 INT); +CREATE OR REPLACE VIEW v60 AS SELECT * FROM t60; +EXPLAIN +SELECT t0.* +FROM t0 +JOIN t1 +ON t1.f1 = t0.f0 +LEFT JOIN t2 +ON t0.f0 = t2.f2 +LEFT JOIN t3 +ON t0.f0 = t3.f3 +LEFT JOIN t4 +ON t0.f0 = t4.f4 +LEFT JOIN t5 +ON t4.f4 = t5.f5 +LEFT JOIN t6 +ON t0.f0 = t6.f6 +LEFT JOIN t7 +ON t0.f0 = t7.f7 +LEFT JOIN t8 +ON t0.f0 = t8.f8 +LEFT JOIN t9 +ON t0.f0 = t9.f9 +LEFT JOIN t10 +ON t0.f0 = t10.f10 +LEFT JOIN t11 +ON t0.f0 = t11.f11 +LEFT JOIN t12 +ON t0.f0 = t12.f12 +LEFT JOIN t13 +ON t0.f0 = t13.f13 +LEFT JOIN t14 +ON t0.f0 = t14.f14 +LEFT JOIN t15 +ON t0.f0 = t15.f15 +LEFT JOIN t16 +ON t0.f0 = t16.f16 +LEFT JOIN t17 +ON t0.f0 = t17.f17 +LEFT JOIN t18 +ON t0.f0 = t18.f18 +LEFT JOIN t19 +ON t18.f18 = t19.f19 +LEFT JOIN t20 +ON t20.f20 = t19.f19 +LEFT JOIN t21 +ON t20.f20 = t21.f21 +LEFT JOIN t22 +ON t19.f19 = t22.f22 +LEFT JOIN t23 +ON t23.f23 = t0.f0 +LEFT JOIN t24 +ON t24.f24 = t23.f23 +LEFT JOIN t25 +ON t0.f0 = t25.f25 +LEFT JOIN t26 +ON t26.f26 = t0.f0 +LEFT JOIN t27 +ON t27.f27 = t0.f0 +LEFT JOIN t28 +ON t0.f0 = t28.f28 +LEFT JOIN t29 +ON t0.f0 = t29.f29 +LEFT JOIN t30 +ON t30.f30 = t0.f0 +LEFT JOIN t31 +ON t0.f0 = t31.f31 +LEFT JOIN t32 +ON t32.f32 = t31.f31 +LEFT JOIN t33 +ON t33.f33 = t0.f0 +LEFT JOIN t34 +ON t33.f33 = t34.f34 +LEFT JOIN t35 +ON t33.f33 = t35.f35 +LEFT JOIN t36 +ON t36.f36 = t0.f0 +LEFT JOIN t37 +ON t32.f32 = t37.f37 +LEFT JOIN t38 +ON t31.f31 = t38.f38 +LEFT JOIN t39 +ON t39.f39 = t0.f0 +LEFT JOIN t40 +ON t40.f40 = t39.f39 +LEFT JOIN t41 +ON t41.f41 = t0.f0 +LEFT JOIN t42 +ON t42.f42 = t41.f41 +LEFT JOIN t43 +ON t43.f43 = t41.f41 +LEFT JOIN t44 +ON t44.f44 = t0.f0 +LEFT JOIN t45 +ON t45.f45 = t0.f0 +LEFT JOIN t46 +ON t46.f46 = t0.f0 +LEFT JOIN t47 +ON t47.f47 = t0.f0 +LEFT JOIN t48 +ON t48.f48 = t0.f0 +LEFT JOIN t49 +ON t0.f0 = t49.f49 +LEFT JOIN t50 +ON t0.f0 = t50.f50 +LEFT JOIN t51 +ON t0.f0 = t51.f51 +LEFT JOIN t52 +ON t52.f52 = t0.f0 +LEFT JOIN t53 +ON t53.f53 = t0.f0 +LEFT JOIN t54 +ON t54.f54 = t0.f0 +LEFT JOIN t55 +ON t55.f55 = t0.f0 +LEFT JOIN t56 +ON t56.f56 = t0.f0 +LEFT JOIN t57 +ON t57.f57 = t0.f0 +LEFT JOIN t58 +ON t58.f58 = t57.f57 +LEFT JOIN t59 +ON t36.f36 = t59.f59 +LEFT JOIN v60 +ON t36.f36 = v60.f60 +; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table +drop table t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, +t10, t11, t12, t13, t14, t15, t16, t17, t18, +t19, t20, t21, t22, t23, t24, t25, t26, t27, +t28, t29, t30, t31, t32, t33, t34, t35, t36, +t37, t38, t39, t40, t41, t42, t43, t44, t45, +t46, t47, t48, t49, t50, t51, t52, t53, t54, +t55, t56, t57, t58, t59,t60; +drop view v60; # ----------------------------------------------------------------- # -- End of 5.5 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/suite/innodb/r/innodb-replace-debug.result b/mysql-test/suite/innodb/r/innodb-replace-debug.result index 84bc9dc9769..989fb055cbc 100644 --- a/mysql-test/suite/innodb/r/innodb-replace-debug.result +++ b/mysql-test/suite/innodb/r/innodb-replace-debug.result @@ -4,10 +4,11 @@ create table t1 (f1 int primary key, f2 int, f3 int, unique key k1(f2), key k2(f3)) engine=innodb; insert into t1 values (14, 24, 34); -set @@debug_dbug = '+d,row_ins_sec_index_entry_timeout'; +set @old_dbug= @@session.debug_dbug; +set debug_dbug = '+d,row_ins_sec_index_entry_timeout'; replace into t1 values (14, 25, 34); select * from t1; f1 f2 f3 14 25 34 drop table t1; -set @@debug_dbug = '-d,row_ins_sec_index_entry_timeout'; +set debug_dbug = @old_dbug; diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index a7db250d8c7..c427038e8a1 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -1,3 +1,5 @@ +create temporary table t (a char(1) character set filename) engine=innodb; +drop temporary table t; set optimizer_switch = 'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; drop table if exists t1,t2,t3,t4; drop database if exists mysqltest; diff --git a/mysql-test/suite/innodb/r/innodb_bug27216817.result b/mysql-test/suite/innodb/r/innodb_bug27216817.result new file mode 100644 index 00000000000..f930171ff23 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug27216817.result @@ -0,0 +1,24 @@ +create table t1 (a int not null, b int not null) engine=innodb; +insert t1 values (1,2),(3,4); +lock table t1 write, t1 tr read; +flush status; +alter table t1 add primary key (b); +show status like 'Handler_read_rnd_next'; +Variable_name Value +Handler_read_rnd_next 3 +unlock tables; +alter table t1 drop primary key; +lock table t1 write; +flush status; +alter table t1 add primary key (b); +show status like 'Handler_read_rnd_next'; +Variable_name Value +Handler_read_rnd_next 0 +unlock tables; +alter table t1 drop primary key; +flush status; +alter table t1 add primary key (b); +show status like 'Handler_read_rnd_next'; +Variable_name Value +Handler_read_rnd_next 0 +drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result index bc4334bd219..8acbcf74cf6 100644 --- a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result +++ b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result @@ -1,27 +1,63 @@ +set names utf8; +SET UNIQUE_CHECKS=0; +CREATE TABLE corrupt_bit_test_ā( +a INT AUTO_INCREMENT PRIMARY KEY, +b CHAR(100), +c INT, +z INT, +INDEX idx(b)) +ENGINE=InnoDB; +INSERT INTO corrupt_bit_test_ā VALUES(0,'x',1, 1); +CREATE UNIQUE INDEX idxā ON corrupt_bit_test_ā(c, b); +CREATE UNIQUE INDEX idxē ON corrupt_bit_test_ā(z, b); +SELECT * FROM corrupt_bit_test_ā; a b c z 1 x 1 1 +INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_ā; +select count(*) from corrupt_bit_test_ā; count(*) 2 +SET @save_dbug = @@SESSION.debug_dbug; +SET debug_dbug = '+d,dict_set_index_corrupted'; +check table corrupt_bit_test_ā; Table Op Msg_type Msg_text test.corrupt_bit_test_ā check Warning InnoDB: Index "idx" is marked as corrupted test.corrupt_bit_test_ā check Warning InnoDB: Index "idxā" is marked as corrupted test.corrupt_bit_test_ā check Warning InnoDB: Index "idxē" is marked as corrupted test.corrupt_bit_test_ā check error Corrupt +SET debug_dbug = @save_dbug; +CREATE INDEX idx3 ON corrupt_bit_test_ā(b, c); ERROR HY000: Index corrupt_bit_test_ā is corrupted +CREATE INDEX idx4 ON corrupt_bit_test_ā(b, z); ERROR HY000: Index corrupt_bit_test_ā is corrupted +select c from corrupt_bit_test_ā; ERROR HY000: Index corrupt_bit_test_ā is corrupted +select z from corrupt_bit_test_ā; ERROR HY000: Index corrupt_bit_test_ā is corrupted +show warnings; Level Code Message Warning 179 InnoDB: Index "idxē" for table "test"."corrupt_bit_test_ā" is marked as corrupted Warning 179 Got error 179 when reading table `test`.`corrupt_bit_test_ā` Error 1712 Index corrupt_bit_test_ā is corrupted +insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001); +select * from corrupt_bit_test_ā use index(primary) where a = 10001; a b c z 10001 a 20001 20001 +begin; +insert into corrupt_bit_test_ā values (10002, "a", 20002, 20002); +delete from corrupt_bit_test_ā where a = 10001; +insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001); +rollback; +drop index idxā on corrupt_bit_test_ā; +check table corrupt_bit_test_ā; Table Op Msg_type Msg_text test.corrupt_bit_test_ā check Warning InnoDB: Index "idx" is marked as corrupted test.corrupt_bit_test_ā check Warning InnoDB: Index "idxē" is marked as corrupted test.corrupt_bit_test_ā check error Corrupt +set names utf8; +select z from corrupt_bit_test_ā; ERROR HY000: Index corrupt_bit_test_ā is corrupted +show create table corrupt_bit_test_ā; Table Create Table corrupt_bit_test_ā CREATE TABLE `corrupt_bit_test_ā` ( `a` int(11) NOT NULL AUTO_INCREMENT, @@ -32,8 +68,12 @@ corrupt_bit_test_ā CREATE TABLE `corrupt_bit_test_ā` ( UNIQUE KEY `idxē` (`z`,`b`), KEY `idx` (`b`) ) ENGINE=InnoDB AUTO_INCREMENT=10003 DEFAULT CHARSET=latin1 +drop index idxē on corrupt_bit_test_ā; +CREATE INDEX idx3 ON corrupt_bit_test_ā(b, c); ERROR HY000: Index corrupt_bit_test_ā is corrupted +CREATE INDEX idx4 ON corrupt_bit_test_ā(b, z); ERROR HY000: Index corrupt_bit_test_ā is corrupted +show create table corrupt_bit_test_ā; Table Create Table corrupt_bit_test_ā CREATE TABLE `corrupt_bit_test_ā` ( `a` int(11) NOT NULL AUTO_INCREMENT, @@ -43,7 +83,12 @@ corrupt_bit_test_ā CREATE TABLE `corrupt_bit_test_ā` ( PRIMARY KEY (`a`), KEY `idx` (`b`) ) ENGINE=InnoDB AUTO_INCREMENT=10003 DEFAULT CHARSET=latin1 +drop index idx on corrupt_bit_test_ā; +CREATE INDEX idx3 ON corrupt_bit_test_ā(b, c); +CREATE INDEX idx4 ON corrupt_bit_test_ā(b, z); +select z from corrupt_bit_test_ā limit 10; z 20001 1 2 +drop table corrupt_bit_test_ā; diff --git a/mysql-test/suite/innodb/t/innodb-replace-debug.test b/mysql-test/suite/innodb/t/innodb-replace-debug.test index 5cec9e1febf..7e710ae154c 100644 --- a/mysql-test/suite/innodb/t/innodb-replace-debug.test +++ b/mysql-test/suite/innodb/t/innodb-replace-debug.test @@ -8,8 +8,9 @@ create table t1 (f1 int primary key, f2 int, f3 int, unique key k1(f2), key k2(f3)) engine=innodb; insert into t1 values (14, 24, 34); -set @@debug_dbug = '+d,row_ins_sec_index_entry_timeout'; +set @old_dbug= @@session.debug_dbug; +set debug_dbug = '+d,row_ins_sec_index_entry_timeout'; replace into t1 values (14, 25, 34); select * from t1; drop table t1; -set @@debug_dbug = '-d,row_ins_sec_index_entry_timeout'; +set debug_dbug = @old_dbug; diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index c36dc1c5f95..b91fbe13718 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -1,23 +1,11 @@ -####################################################################### -# # -# Please, DO NOT TOUCH this file as well as the innodb.result file. # -# These files are to be modified ONLY BY INNOBASE guys. # -# # -# Use innodb_mysql.[test|result] files instead. # -# # -# If nevertheless you need to make some changes here, please, forward # -# your commit message # -# To: innodb_dev_ww@oracle.com # -# Cc: dev-innodb@mysql.com # -# (otherwise your changes may be erased). # -# # -####################################################################### - -- source include/have_innodb.inc let $MYSQLD_DATADIR= `select @@datadir`; let collation=utf8_unicode_ci; --source include/have_collation.inc +create temporary table t (a char(1) character set filename) engine=innodb; +drop temporary table t; + set optimizer_switch = 'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; # Save the original values of some variables in order to be able to @@ -2546,18 +2534,3 @@ show status like "handler_read_key"; select f1 from t1; show status like "handler_read_key"; drop table t1; - -####################################################################### -# # -# Please, DO NOT TOUCH this file as well as the innodb.result file. # -# These files are to be modified ONLY BY INNOBASE guys. # -# # -# Use innodb_mysql.[test|result] files instead. # -# # -# If nevertheless you need to make some changes here, please, forward # -# your commit message # -# To: innodb_dev_ww@oracle.com # -# Cc: dev-innodb@mysql.com # -# (otherwise your changes may be erased). # -# # -####################################################################### diff --git a/mysql-test/suite/innodb/t/innodb_bug27216817.test b/mysql-test/suite/innodb/t/innodb_bug27216817.test new file mode 100644 index 00000000000..a93932b4a04 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug27216817.test @@ -0,0 +1,28 @@ +# +# BUG#27216817: INNODB: FAILING ASSERTION: +# PREBUILT->TABLE->N_MYSQL_HANDLES_OPENED == 1 +# + +source include/have_innodb.inc; +create table t1 (a int not null, b int not null) engine=innodb; +insert t1 values (1,2),(3,4); + +lock table t1 write, t1 tr read; +flush status; +alter table t1 add primary key (b); +show status like 'Handler_read_rnd_next'; +unlock tables; +alter table t1 drop primary key; + +lock table t1 write; +flush status; +alter table t1 add primary key (b); +show status like 'Handler_read_rnd_next'; +unlock tables; +alter table t1 drop primary key; + +flush status; +alter table t1 add primary key (b); +show status like 'Handler_read_rnd_next'; + +drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test index f67e2e7e047..34fe0a7812a 100644 --- a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test +++ b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test @@ -8,6 +8,7 @@ -- disable_query_log call mtr.add_suppression("Flagged corruption of idx.*in CHECK TABLE"); +-- enable_query_log set names utf8; @@ -36,9 +37,10 @@ INSERT INTO corrupt_bit_test_ā SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_ā; select count(*) from corrupt_bit_test_ā; # This will flag all secondary indexes corrupted -SET SESSION debug_dbug="+d,dict_set_index_corrupted"; +SET @save_dbug = @@SESSION.debug_dbug; +SET debug_dbug = '+d,dict_set_index_corrupted'; check table corrupt_bit_test_ā; -SET SESSION debug_dbug="-d,dict_set_index_corrupted"; +SET debug_dbug = @save_dbug; # Cannot create new indexes while corrupted indexes exist --error ER_INDEX_CORRUPT diff --git a/mysql-test/suite/maria/dynamic.result b/mysql-test/suite/maria/dynamic.result new file mode 100644 index 00000000000..1e87010e9ca --- /dev/null +++ b/mysql-test/suite/maria/dynamic.result @@ -0,0 +1,4 @@ +create table t1 (a blob, b varchar(20000)) engine=aria row_format=dynamic; +insert t1 (b) values (repeat('a', 20000)); +update t1 set b='b'; +drop table t1; diff --git a/mysql-test/suite/maria/dynamic.test b/mysql-test/suite/maria/dynamic.test new file mode 100644 index 00000000000..f8a1e98cd41 --- /dev/null +++ b/mysql-test/suite/maria/dynamic.test @@ -0,0 +1,7 @@ +# +# MDEV-13748 Assertion `status_var.local_memory_used == 0 || !debug_assert_on_not_freed_memory' failed in virtual THD::~THD after query with INTERSECT +# +create table t1 (a blob, b varchar(20000)) engine=aria row_format=dynamic; +insert t1 (b) values (repeat('a', 20000)); +update t1 set b='b'; +drop table t1; diff --git a/mysql-test/suite/parts/r/partition_alter_maria.result b/mysql-test/suite/parts/r/partition_alter_maria.result index 460d20b9255..d79bc0a41fe 100644 --- a/mysql-test/suite/parts/r/partition_alter_maria.result +++ b/mysql-test/suite/parts/r/partition_alter_maria.result @@ -16,6 +16,15 @@ select * from t1; pk dt 1 2017-09-28 15:12:00 drop table t1; +create table t1 (a int) engine=Aria transactional=1 partition by hash(a) partitions 2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=Aria DEFAULT CHARSET=latin1 TRANSACTIONAL=1 +/*!50100 PARTITION BY HASH (a) +PARTITIONS 2 */ +drop table t1; # # MDEV-13788 Server crash when issuing bad SQL partition syntax # diff --git a/mysql-test/suite/parts/t/partition_alter_maria.test b/mysql-test/suite/parts/t/partition_alter_maria.test index e21f0dfab82..e0b9256391d 100644 --- a/mysql-test/suite/parts/t/partition_alter_maria.test +++ b/mysql-test/suite/parts/t/partition_alter_maria.test @@ -17,5 +17,12 @@ alter table t1 drop partition p20181231; select * from t1; drop table t1; +# +# MDEV-13982 Server crashes in in ha_partition::engine_name +# +create table t1 (a int) engine=Aria transactional=1 partition by hash(a) partitions 2; +show create table t1; +drop table t1; + --let $engine=Aria --source inc/part_alter_values.inc diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index 9be0d5556f0..6c5eaffd9a2 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -42,8 +42,10 @@ select 1, 3; insert into t2 values (1), (2); select * from t2; +--disable_ps_protocol --error ER_NO_SUCH_TABLE select * from t_doesnt_exist; +--enable_ps_protocol --error 1064 syntax_error_query; drop table renamed_t1, t2; diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index b3d0be4432f..6f846eae771 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -886,5 +886,27 @@ DROP TABLE t1; --echo # +--echo # MDEV-15624 Changing the default character set to utf8mb4 changes query evaluation in a very surprising way +--echo # + +SET NAMES utf8; +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (1),(2),(3); + +SELECT COUNT(DISTINCT c) FROM (SELECT id, REPLACE(uuid_short(), '0', CAST('o' AS CHAR CHARACTER SET ucs2)) AS c FROM t1) AS d1; +--replace_column 1 xxxxxxxxxxxxxxxxx +SELECT DISTINCT REPLACE(uuid_short(), '0', CAST('o' AS CHAR CHARACTER SET ucs2)) AS c FROM t1; + +SELECT COUNT(DISTINCT c) FROM (SELECT id, INSERT(uuid_short(), 1, 1, CAST('0' AS CHAR CHARACTER SET ucs2)) AS c FROM t1) AS d1; +--replace_column 1 xxxxxxxxxxxxxxxxx +SELECT DISTINCT INSERT(uuid_short(), 1, 1, CAST('0' AS CHAR CHARACTER SET ucs2)) AS c FROM t1; + +SELECT COUNT(DISTINCT c) FROM (SELECT id, CONCAT(uuid_short(), CAST('0' AS CHAR CHARACTER SET ucs2)) AS c FROM t1) AS d1; +--replace_column 1 xxxxxxxxxxxxxxxxx +SELECT DISTINCT CONCAT(uuid_short(), CAST('0' AS CHAR CHARACTER SET ucs2)) AS c FROM t1; +DROP TABLE t1; + + +--echo # --echo # End of 5.5 tests --echo # diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test index c240f261af4..551a570c0fc 100644 --- a/mysql-test/t/ctype_utf8mb4.test +++ b/mysql-test/t/ctype_utf8mb4.test @@ -1859,6 +1859,25 @@ SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 65535) AS data ) AS sub; SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 65536) AS data ) AS sub; --echo # +--echo # MDEV-15624 Changing the default character set to utf8mb4 changes query evaluation in a very surprising way +--echo # + +SET NAMES utf8mb4; +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (1),(2),(3); + +SELECT COUNT(DISTINCT c) FROM (SELECT id, REPLACE(UUID(), "-", "") AS c FROM t1) AS d1; +--replace_column 1 xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +SELECT DISTINCT INSERT(uuid(), 9, 1, "X") AS c FROM t1; + +SELECT COUNT(DISTINCT c) FROM (SELECT id, INSERT(UUID(), 9, 1, "X") AS c FROM t1) AS d1; +--replace_column 1 xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +SELECT DISTINCT INSERT(UUID(), 9, 1, "X") AS c FROM t1; + +DROP TABLE t1; + + +--echo # --echo # End of 5.5 tests --echo # diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index f8ba87ac1f5..c5b792c8d4d 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -864,5 +864,43 @@ select distinct t1.id, tt.id, tt.data drop table t1; +--echo # +--echo # MDEV-14241: Server crash in key_copy / get_matching_chain_by_join_key +--echo # or valgrind warnings +--echo # + +CREATE TABLE t1 (a VARCHAR(10)) ENGINE=MyISAM; +CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES ('foo'),('bar'); + +CREATE TABLE t2 (b integer auto_increment primary key) ENGINE=MyISAM; +INSERT INTO t2 VALUES (NULL),(NULL); + +CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM; +CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3; +INSERT INTO t3 VALUES ('abc',NULL),('def',4); + +SET join_cache_level= 8; +explain +SELECT * FROM v1, t2, v3 WHERE a = c AND b = d; +SELECT * FROM v1, t2, v3 WHERE a = c AND b = d; + +DROP VIEW v1, v3; +DROP TABLE t1, t2, t3; + +--echo # +--echo # MDEV-14786: Server crashes in Item_cond::transform on 2nd +--echo # execution of SP querying from a view +--echo # +create table t1 (i int, row_start timestamp(6) not null default now(), + row_end timestamp(6) not null default '2030-01-01 0:0:0'); +create view v1 as select i from t1 where i < 5 and (row_end = +TIMESTAMP'2030-01-01 0:0:0' or row_end is null); +create procedure pr(x int) select i from v1; +call pr(1); +call pr(2); +drop procedure pr; +drop view v1; +drop table t1; --echo # end of 5.5 diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index d7eda5ee4e6..c21630c0c7b 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -596,6 +596,18 @@ AND 57813X540X1723 = 'Test'; drop table t1; + +--echo # +--echo # MDEV-15630 uuid() function evaluates at wrong time in query +--echo # + +CREATE TABLE t1 (id INT); +INSERT INTO t1 VALUES (1),(2),(3); +--replace_column 2 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +SELECT COUNT(1), UUID() as uid FROM t1 GROUP BY uid; +DROP TABLE t1; + + --echo # --echo # End of 5.5 tests --echo # diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 77e8fce0d27..58a7b885356 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3791,5 +3791,50 @@ set join_cache_level = default; DROP TABLE t1,t2; +--echo # +--echo # MDEV-14960: BNLH used for materialized semi-join +--echo # + +CREATE TABLE t1 (i1 int); +CREATE TABLE t2 (e1 int); +CREATE TABLE t4 (e1 int); +CREATE TABLE t5 (e1 int); + +INSERT INTO t1 VALUES + (1),(2),(3),(4),(5),(6),(7),(8); +INSERT INTO t1 SELECT i1+8 FROM t1; +INSERT INTO t1 SELECT i1+16 FROM t1; +INSERT INTO t1 SELECT i1+32 FROM t1; +INSERT INTO t1 SELECT i1+64 FROM t1; +INSERT INTO t2 SELECT * FROM t1; +INSERT INTO t4 SELECT * FROM t1; +INSERT INTO t5 SELECT * FROM t1; + +set @save_optimizer_switch= @@optimizer_switch; +SET join_cache_level = 6; +SET join_buffer_size=4096; +SET join_buffer_space_limit=4096; +SET optimizer_switch = 'join_cache_hashed=on,optimize_join_buffer_size=on'; + +let $q= +SELECT * FROM t1 +WHERE + i1 < 10 AND + i1 IN + (SELECT i1 FROM + (SELECT (t4.e1) i1 FROM t4 + LEFT JOIN t5 ON t4.e1 = t5.e1 + LEFT JOIN (SELECT e1 FROM t2 ) AS d ON t4.e1 = d.e1) a); + +eval EXPLAIN $q; +eval $q; + +SET join_cache_level = default; +SET join_buffer_size = default; +SET join_buffer_space_limit= default; +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE t1,t4,t5,t2; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 896cc137e07..2769aea9969 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1891,9 +1891,25 @@ INSERT INTO t1 VALUES (0),(1); CREATE TABLE t2 (b2 BIT NOT NULL); INSERT INTO t2 VALUES (0),(1); -SET SESSION JOIN_CACHE_LEVEL = 3; +set @save_join_cache_level= @@join_cache_level; +SET @@join_cache_level = 3; SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2; DROP TABLE t1, t2; +set @join_cache_level= @save_join_cache_level; + +--echo # +--echo # MDEV-14779: using left join causes incorrect results with materialization and derived tables +--echo # + +create table t1(id int); +insert into t1 values (1),(2); +create table t2(sid int, id int); +insert into t2 values (1,1),(2,2); + +select * from t1 t + left join (select * from t2 where sid in (select max(sid) from t2 where 0=1 group by id)) r + on t.id=r.id ; +drop table t1, t2; --echo # end of 5.5 tests diff --git a/mysql-test/t/mdev_14586.test b/mysql-test/t/mdev_14586.test new file mode 100644 index 00000000000..8b3d3780151 --- /dev/null +++ b/mysql-test/t/mdev_14586.test @@ -0,0 +1,27 @@ +create table t1(a bit(1), b int auto_increment ,id int, index(a,b)); +insert into t1 values(1,null,1); +insert into t1 values(1,null,2); +insert into t1 values(0,null,3); +insert into t1 values(0,null,4); +select a+0, b as auto_increment , id from t1 order by id; +drop table t1; +create table t1(a int auto_increment, b bit(5) ,id int, index (b,a)); +insert into t1 values(null,b'1',1); +insert into t1 values(null,b'1',2); +insert into t1 values(null,b'11',3); +insert into t1 values(null,b'11',4); +select a as auto_increment, b+0, id from t1 order by id; +drop table t1; +create table t1(a bit(1), b int auto_increment , c bit(1) , d bit(1), id int,index(a,c,b,d)); +insert into t1 values(1,null,1,1,1); +insert into t1 values(1,null,1,1,2); +insert into t1 values(0,null,1,1,3); +insert into t1 values(1,null,0,1,4); +select a+0, b as auto_increment, c+0, d+0, id from t1 order by id; +drop table t1; +CREATE TABLE t1 (b BIT(1), pk INTEGER AUTO_INCREMENT PRIMARY KEY); +ALTER TABLE t1 ADD INDEX(b,pk); +INSERT INTO t1 VALUES (1,b'1'); +ALTER TABLE t1 DROP PRIMARY KEY; +select b+0, pk as auto_increment from t1; +DROP TABLE t1; diff --git a/mysql-test/t/mysqldump-nl.test b/mysql-test/t/mysqldump-nl.test index 311996e77c3..4513fb2c637 100644 --- a/mysql-test/t/mysqldump-nl.test +++ b/mysql-test/t/mysqldump-nl.test @@ -36,3 +36,23 @@ show tables from `mysqltest1 drop database `mysqltest1 1tsetlqsym`; + +create database `test```; +create database `test\`` +\! ls +#`; + +show databases like 'test%'; + +exec $MYSQL_DUMP --compact --comment --add-drop-database --databases 'test`' 'test\` +\! ls +#'; + +exec $MYSQL_DUMP --compact --comment --add-drop-database --databases 'test`' 'test\` +\! ls +#' | $MYSQL; + +drop database `test```; +drop database `test\`` +\! ls +#`; diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 1e3458eafdf..06ec3164ad1 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -780,3 +780,12 @@ CREATE TRIGGER tr AFTER DELETE ON t1 FOR EACH ROW SET @a = 1\; --error ER_PARSE_ERROR PREPARE stmt FROM 'CREATE TRIGGER tr AFTER DELETE ON t1 FOR EACH ROW SET @a = 1\\'; DROP TABLE t1; + +--echo # +--echo # MDEV-15620 Crash when using "SET @@NEW.a=expr" inside a trigger +--echo # + +CREATE TABLE t1 (a INT); +--error ER_UNKNOWN_SYSTEM_VARIABLE +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @@NEW.a=0; +DROP TABLE t1; diff --git a/mysql-test/t/ps_qc_innodb.test b/mysql-test/t/ps_qc_innodb.test new file mode 100644 index 00000000000..e09a2bf4070 --- /dev/null +++ b/mysql-test/t/ps_qc_innodb.test @@ -0,0 +1,35 @@ +--source include/have_query_cache.inc +--source include/have_innodb.inc + +--echo # +--echo # MDEV-15492: Subquery crash similar to MDEV-10050 +--echo # + +SET @qcs.save= @@global.query_cache_size, @qct.save= @@global.query_cache_type; +SET GLOBAL query_cache_size= 512*1024*1024, query_cache_type= ON; + +--connect (con1,localhost,root,,test) +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (b INT) ENGINE=InnoDB; +CREATE VIEW v AS select a from t1 join t2; + +PREPARE stmt1 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)"; + +--connect (con2,localhost,root,,test) +PREPARE stmt2 FROM "SELECT * FROM t1 WHERE a in (SELECT a FROM v)"; +EXECUTE stmt2; + +--connection con1 +EXECUTE stmt1; +INSERT INTO t2 VALUES (0); +EXECUTE stmt1; +START TRANSACTION; +EXECUTE stmt1; + +# Cleanup +--disconnect con1 +--disconnect con2 +--connection default +DROP VIEW v; +DROP TABLE t1, t2; +SET GLOBAL query_cache_size= @qcs.save, query_cache_type= @qct.save; diff --git a/mysql-test/t/read_only_innodb.test b/mysql-test/t/read_only_innodb.test index de237fecbb6..f89cf745973 100644 --- a/mysql-test/t/read_only_innodb.test +++ b/mysql-test/t/read_only_innodb.test @@ -244,6 +244,15 @@ SELECT * FROM temp1, temp2; DROP TABLE temp1, temp2; --echo +--echo # MDEV-14185 CREATE TEMPORARY TABLE AS SELECT causes error 1290 with read_only and InnoDB. +--echo + +CREATE TEMPORARY TABLE temp1 ENGINE=INNODB AS SELECT a FROM t1; +SELECT * FROM temp1; +DROP TABLE temp1; + + +--echo --echo # Disconnect and cleanup --echo disconnect con1; diff --git a/mysql-test/t/sp-destruct.test b/mysql-test/t/sp-destruct.test index 3a2e9259938..e5314f89fd5 100644 --- a/mysql-test/t/sp-destruct.test +++ b/mysql-test/t/sp-destruct.test @@ -289,3 +289,13 @@ create database mysqltest1; create procedure mysqltest1.foo() select "foo"; update mysql.proc set name='' where db='mysqltest1'; drop database mysqltest1; + +# +# BUG#26881798: SERVER EXITS WHEN PRIMARY KEY IN MYSQL.PROC IS DROPPED +# +create procedure p1() set @foo = 10; +alter table mysql.proc drop primary key; +--error ER_CANNOT_LOAD_FROM_TABLE +drop procedure p1; +alter table mysql.proc add primary key (db,name,type); +drop procedure p1; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index f051c8eaaf2..2b53b55b735 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -2035,5 +2035,36 @@ SELECT ( SELECT COUNT(*) FROM t1 WHERE a = c ) AS field, COUNT(DISTINCT c) FROM t2 WHERE b <= 'quux' GROUP BY field; drop table t1,t2; +--echo # +--echo # MDEV-15555: select from DUAL where false yielding wrong result when in a IN +--echo # + +explain +SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1); +SELECT 2 IN (SELECT 2 from DUAL WHERE 1 != 1); + SET optimizer_switch= @@global.optimizer_switch; set @@tmp_table_size= @@global.tmp_table_size; + +--echo # +--echo # mfrv-14515: Wrong results for tableless query with subquery in WHERE +--echo # and implicit aggregation +--echo # + +create table t1 (i1 int, i2 int); +insert into t1 values (1314, 1084),(1330, 1084),(1401, 1084),(580, 1084); + +create table t2 (cd int); +insert into t2 values + (1330), (1330), (1330), (1330), (1330), (1330), (1330), (1330), + (1330), (1330), (1330), (1330), (1330), (1330), (1330), (1330); + +select max(10) from dual + where exists (select 1 from t2 join t1 on t1.i1 = t2.cd and t1.i2 = 345); + +insert into t2 select * from t2; + +select max(10) from dual + where exists (select 1 from t2 join t1 on t1.i1 = t2.cd and t1.i2 = 345); + +DROP TABLE t1,t2; diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test index 09c6b3e1747..5211f35b48b 100644 --- a/mysql-test/t/subselect_mat.test +++ b/mysql-test/t/subselect_mat.test @@ -254,3 +254,16 @@ SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq FROM t1; drop table t1, t2; + +--echo # +--echo # MDEV-15235: Assertion `length > 0' failed in create_ref_for_key +--echo # + +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (f CHAR(1)); +INSERT INTO t2 VALUES ('a'),('b'); +explain +SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); +SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 ); +DROP TABLE t1, t2; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 4a3c19b49ab..55d09a7d5ac 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1384,4 +1384,41 @@ select e,f, (e , f) in (select e,b from t1 union select c,d from t2) as sub from select avg(f), (e , f) in (select e,b from t1 union select c,d from t2) as sub from t3 group by sub; drop table t1,t2,t3; +--echo # +--echo # MDEV-14715 Assertion `!table || (!table->read_set || +--echo # bitmap_is_set(table->read_set, field_index))' +--echo # failed in Field_num::val_decimal +--echo # + +CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM; +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1, NULL),(3, 4); + +--error ER_INVALID_GROUP_FUNC_USE +(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + sum(a)) +UNION +(SELECT 2, 2); + +(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1) +UNION +(SELECT 2, 2); + +SELECT a, b FROM t1 +UNION +(SELECT a, VAR_POP(a) AS f FROM v1 GROUP BY a ORDER BY b/a ); + +DROP TABLE t1; + +--error ER_VIEW_INVALID +(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1) +UNION +(SELECT 2, 2); + +DROP VIEW v1; + +--error ER_NO_SUCH_TABLE +(SELECT a, sum(a) AS f FROM v1 group by a ORDER BY b + 1) +UNION +(SELECT 2, 2); + --echo End of 5.5 tests diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 0fc7cb6adf7..835f12957d4 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5169,118 +5169,6 @@ deallocate prepare stmt1; drop view v1,v2; drop table t1,t2; ---echo # ---echo # MDEV-6251: SIGSEGV in query optimizer (in set_check_materialized ---echo # with MERGE view) ---echo # - -CREATE TABLE t1 (a1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t2 (b1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t3 (c1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t4 (d1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t5 (e1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); -CREATE TABLE t6 (f1 INT(11) NOT NULL DEFAULT NULL AUTO_INCREMENT PRIMARY KEY); - -CREATE OR REPLACE view v1 AS - SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -; - -SELECT 1 -FROM (( SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t1) -LEFT OUTER JOIN (( SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t2) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t3) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t4) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t5) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t6) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t7) ON 1=1 -LEFT OUTER JOIN (( SELECT 1 - FROM t1 a_alias_1 - LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1 - LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1 - LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1 - LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1 - LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1 -) t8) ON 1=1 -; - -SELECT 1 -FROM (v1 t1) -LEFT OUTER JOIN (v1 t2) ON 1=1 -LEFT OUTER JOIN (v1 t3) ON 1=1 -LEFT OUTER JOIN (v1 t4) ON 1=1 -LEFT OUTER JOIN (v1 t5) ON 1=1 -LEFT OUTER JOIN (v1 t6) ON 1=1 -LEFT OUTER JOIN (v1 t7) ON 1=1 -LEFT OUTER JOIN (v1 t8) ON 1=1 -; - -drop view v1; -drop table t1,t2,t3,t4,t5,t6; - --echo # ----------------------------------------------------------------- --echo # -- End of 5.3 tests. --echo # ----------------------------------------------------------------- @@ -5590,6 +5478,202 @@ SHOW CREATE VIEW v1; drop view v1; drop table t1; +CREATE TABLE IF NOT EXISTS t0 (f0 INT); +CREATE TABLE IF NOT EXISTS t1 (f1 INT); +CREATE TABLE IF NOT EXISTS t2 (f2 INT); +CREATE TABLE IF NOT EXISTS t3 (f3 INT); +CREATE TABLE IF NOT EXISTS t4 (f4 INT); +CREATE TABLE IF NOT EXISTS t5 (f5 INT); +CREATE TABLE IF NOT EXISTS t6 (f6 INT); +CREATE TABLE IF NOT EXISTS t7 (f7 INT); +CREATE TABLE IF NOT EXISTS t8 (f8 INT); +CREATE TABLE IF NOT EXISTS t9 (f9 INT); +CREATE TABLE IF NOT EXISTS t10 (f10 INT); +CREATE TABLE IF NOT EXISTS t11 (f11 INT); +CREATE TABLE IF NOT EXISTS t12 (f12 INT); +CREATE TABLE IF NOT EXISTS t13 (f13 INT); +CREATE TABLE IF NOT EXISTS t14 (f14 INT); +CREATE TABLE IF NOT EXISTS t15 (f15 INT); +CREATE TABLE IF NOT EXISTS t16 (f16 INT); +CREATE TABLE IF NOT EXISTS t17 (f17 INT); +CREATE TABLE IF NOT EXISTS t18 (f18 INT); +CREATE TABLE IF NOT EXISTS t19 (f19 INT); +CREATE TABLE IF NOT EXISTS t20 (f20 INT); +CREATE TABLE IF NOT EXISTS t21 (f21 INT); +CREATE TABLE IF NOT EXISTS t22 (f22 INT); +CREATE TABLE IF NOT EXISTS t23 (f23 INT); +CREATE TABLE IF NOT EXISTS t24 (f24 INT); +CREATE TABLE IF NOT EXISTS t25 (f25 INT); +CREATE TABLE IF NOT EXISTS t26 (f26 INT); +CREATE TABLE IF NOT EXISTS t27 (f27 INT); +CREATE TABLE IF NOT EXISTS t28 (f28 INT); +CREATE TABLE IF NOT EXISTS t29 (f29 INT); +CREATE TABLE IF NOT EXISTS t30 (f30 INT); +CREATE TABLE IF NOT EXISTS t31 (f31 INT); +CREATE TABLE IF NOT EXISTS t32 (f32 INT); +CREATE TABLE IF NOT EXISTS t33 (f33 INT); +CREATE TABLE IF NOT EXISTS t34 (f34 INT); +CREATE TABLE IF NOT EXISTS t35 (f35 INT); +CREATE TABLE IF NOT EXISTS t36 (f36 INT); +CREATE TABLE IF NOT EXISTS t37 (f37 INT); +CREATE TABLE IF NOT EXISTS t38 (f38 INT); +CREATE TABLE IF NOT EXISTS t39 (f39 INT); +CREATE TABLE IF NOT EXISTS t40 (f40 INT); +CREATE TABLE IF NOT EXISTS t41 (f41 INT); +CREATE TABLE IF NOT EXISTS t42 (f42 INT); +CREATE TABLE IF NOT EXISTS t43 (f43 INT); +CREATE TABLE IF NOT EXISTS t44 (f44 INT); +CREATE TABLE IF NOT EXISTS t45 (f45 INT); +CREATE TABLE IF NOT EXISTS t46 (f46 INT); +CREATE TABLE IF NOT EXISTS t47 (f47 INT); +CREATE TABLE IF NOT EXISTS t48 (f48 INT); +CREATE TABLE IF NOT EXISTS t49 (f49 INT); +CREATE TABLE IF NOT EXISTS t50 (f50 INT); +CREATE TABLE IF NOT EXISTS t51 (f51 INT); +CREATE TABLE IF NOT EXISTS t52 (f52 INT); +CREATE TABLE IF NOT EXISTS t53 (f53 INT); +CREATE TABLE IF NOT EXISTS t54 (f54 INT); +CREATE TABLE IF NOT EXISTS t55 (f55 INT); +CREATE TABLE IF NOT EXISTS t56 (f56 INT); +CREATE TABLE IF NOT EXISTS t57 (f57 INT); +CREATE TABLE IF NOT EXISTS t58 (f58 INT); +CREATE TABLE IF NOT EXISTS t59 (f59 INT); +CREATE TABLE IF NOT EXISTS t60 (f60 INT); +CREATE OR REPLACE VIEW v60 AS SELECT * FROM t60; + +EXPLAIN + SELECT t0.* +FROM t0 +JOIN t1 + ON t1.f1 = t0.f0 +LEFT JOIN t2 + ON t0.f0 = t2.f2 +LEFT JOIN t3 + ON t0.f0 = t3.f3 +LEFT JOIN t4 + ON t0.f0 = t4.f4 +LEFT JOIN t5 + ON t4.f4 = t5.f5 +LEFT JOIN t6 + ON t0.f0 = t6.f6 +LEFT JOIN t7 + ON t0.f0 = t7.f7 +LEFT JOIN t8 + ON t0.f0 = t8.f8 +LEFT JOIN t9 + ON t0.f0 = t9.f9 +LEFT JOIN t10 + ON t0.f0 = t10.f10 +LEFT JOIN t11 + ON t0.f0 = t11.f11 +LEFT JOIN t12 + ON t0.f0 = t12.f12 +LEFT JOIN t13 + ON t0.f0 = t13.f13 +LEFT JOIN t14 + ON t0.f0 = t14.f14 +LEFT JOIN t15 + ON t0.f0 = t15.f15 +LEFT JOIN t16 + ON t0.f0 = t16.f16 +LEFT JOIN t17 + ON t0.f0 = t17.f17 +LEFT JOIN t18 + ON t0.f0 = t18.f18 +LEFT JOIN t19 + ON t18.f18 = t19.f19 +LEFT JOIN t20 + ON t20.f20 = t19.f19 +LEFT JOIN t21 + ON t20.f20 = t21.f21 +LEFT JOIN t22 + ON t19.f19 = t22.f22 +LEFT JOIN t23 + ON t23.f23 = t0.f0 +LEFT JOIN t24 + ON t24.f24 = t23.f23 +LEFT JOIN t25 + ON t0.f0 = t25.f25 +LEFT JOIN t26 + ON t26.f26 = t0.f0 +LEFT JOIN t27 + ON t27.f27 = t0.f0 +LEFT JOIN t28 + ON t0.f0 = t28.f28 +LEFT JOIN t29 + ON t0.f0 = t29.f29 +LEFT JOIN t30 + ON t30.f30 = t0.f0 +LEFT JOIN t31 + ON t0.f0 = t31.f31 +LEFT JOIN t32 + ON t32.f32 = t31.f31 +LEFT JOIN t33 + ON t33.f33 = t0.f0 +LEFT JOIN t34 + ON t33.f33 = t34.f34 +LEFT JOIN t35 + ON t33.f33 = t35.f35 +LEFT JOIN t36 + ON t36.f36 = t0.f0 +LEFT JOIN t37 + ON t32.f32 = t37.f37 +LEFT JOIN t38 + ON t31.f31 = t38.f38 +LEFT JOIN t39 + ON t39.f39 = t0.f0 +LEFT JOIN t40 + ON t40.f40 = t39.f39 +LEFT JOIN t41 + ON t41.f41 = t0.f0 +LEFT JOIN t42 + ON t42.f42 = t41.f41 +LEFT JOIN t43 + ON t43.f43 = t41.f41 +LEFT JOIN t44 + ON t44.f44 = t0.f0 +LEFT JOIN t45 + ON t45.f45 = t0.f0 +LEFT JOIN t46 + ON t46.f46 = t0.f0 +LEFT JOIN t47 + ON t47.f47 = t0.f0 +LEFT JOIN t48 + ON t48.f48 = t0.f0 +LEFT JOIN t49 + ON t0.f0 = t49.f49 +LEFT JOIN t50 + ON t0.f0 = t50.f50 +LEFT JOIN t51 + ON t0.f0 = t51.f51 +LEFT JOIN t52 + ON t52.f52 = t0.f0 +LEFT JOIN t53 + ON t53.f53 = t0.f0 +LEFT JOIN t54 + ON t54.f54 = t0.f0 +LEFT JOIN t55 + ON t55.f55 = t0.f0 +LEFT JOIN t56 + ON t56.f56 = t0.f0 +LEFT JOIN t57 + ON t57.f57 = t0.f0 +LEFT JOIN t58 + ON t58.f58 = t57.f57 +LEFT JOIN t59 + ON t36.f36 = t59.f59 +LEFT JOIN v60 + ON t36.f36 = v60.f60 +; +drop table t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, +t10, t11, t12, t13, t14, t15, t16, t17, t18, +t19, t20, t21, t22, t23, t24, t25, t26, t27, +t28, t29, t30, t31, t32, t33, t34, t35, t36, +t37, t38, t39, t40, t41, t42, t43, t44, t45, +t46, t47, t48, t49, t50, t51, t52, t53, t54, +t55, t56, t57, t58, t59,t60; +drop view v60; + --echo # ----------------------------------------------------------------- --echo # -- End of 5.5 tests. --echo # ----------------------------------------------------------------- diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index cb86850c2de..15f3fbad9bf 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -67,7 +67,7 @@ ENDIF() ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES}) TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY} - ${LIBNSL} ${LIBM} ${LIBRT} ${LIBSOCKET} ${LIBEXECINFO}) + ${LIBNSL} ${LIBM} ${LIBRT} ${LIBSOCKET} ${LIBEXECINFO} ${LIBDL}) DTRACE_INSTRUMENT(mysys) IF(HAVE_BFD_H) diff --git a/mysys/default.c b/mysys/default.c index d42d4f44a13..89e0e89722d 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -1114,10 +1114,12 @@ void print_defaults(const char *conf_file, const char **groups) } } puts("\nThe following options may be given as the first argument:\n\ ---print-defaults Print the program argument list and exit.\n\ ---no-defaults Don't read default options from any option file.\n\ ---defaults-file=# Only read default options from the given file #.\n\ ---defaults-extra-file=# Read this file after the global files are read."); +--print-defaults Print the program argument list and exit.\n\ +--no-defaults Don't read default options from any option file.\n\ +The following specify which files/extra groups are read (specified before remaining options):\n\ +--defaults-file=# Only read default options from the given file #.\n\ +--defaults-extra-file=# Read this file after the global files are read.\n\ +--defaults-group-suffix=# Additionally read default groups with # appended as a suffix."); } diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index 797c20e819e..8d74aaf8cc2 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB +/* Copyright (c) 2006, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB 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 @@ -86,7 +86,8 @@ retry: do { /* PTR() isn't necessary below, head is a dummy node */ cursor->curr= (LF_SLIST *)(*cursor->prev); _lf_pin(pins, 1, cursor->curr); - } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF); + } while (my_atomic_loadptr((void**)cursor->prev) != cursor->curr && + LF_BACKOFF); for (;;) { if (unlikely(!cursor->curr)) @@ -100,7 +101,7 @@ retry: cur_hashnr= cursor->curr->hashnr; cur_key= cursor->curr->key; cur_keylen= cursor->curr->keylen; - if (*cursor->prev != (intptr)cursor->curr) + if (my_atomic_loadptr((void**)cursor->prev) != cursor->curr) { (void)LF_BACKOFF; goto retry; diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 31a09e214d2..bd71e2ae527 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -258,7 +258,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize, else { /* Clear mutex so that safe_mutex will notice that it's not initialized */ - bzero((char*) &info->append_buffer_lock, sizeof(info)); + bzero((char*) &info->append_buffer_lock, sizeof(info->append_buffer_lock)); } #endif diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 90e6f43f390..02f71fd72bd 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -132,15 +132,79 @@ err: #include <m_string.h> #include <ctype.h> + +#include <sys/wait.h> + static int in[2], out[2]; -static int initialized= 0; +static pid_t pid; +static char addr2line_binary[1024]; static char output[1024]; + +int start_addr2line_fork(const char *binary_path) +{ + + if (pid > 0) + { + /* Don't leak FDs */ + close(in[1]); + close(out[0]); + /* Don't create zombie processes. */ + waitpid(pid, NULL, 0); + } + + if (pipe(in) < 0) + return 1; + if (pipe(out) < 0) + return 1; + + pid = fork(); + if (pid == -1) + return 1; + + if (!pid) /* child */ + { + dup2(in[0], 0); + dup2(out[1], 1); + close(in[0]); + close(in[1]); + close(out[0]); + close(out[1]); + execlp("addr2line", "addr2line", "-C", "-f", "-e", binary_path, NULL); + exit(1); + } + + close(in[0]); + close(out[1]); + + return 0; +} + int my_addr_resolve(void *ptr, my_addr_loc *loc) { char input[32], *s; size_t len; - len= my_snprintf(input, sizeof(input), "%p\n", ptr); + Dl_info info; + void *offset; + + if (!dladdr(ptr, &info)) + return 1; + + if (strcmp(addr2line_binary, info.dli_fname)) + { + /* We use dli_fname in case the path is longer than the length of our static + string. We don't want to allocate anything dynamicaly here as we are in + a "crashed" state. */ + if (start_addr2line_fork(info.dli_fname)) + { + addr2line_binary[0] = '\0'; + return 1; + } + /* Save result for future comparisons. */ + strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary)); + } + offset = info.dli_fbase; + len= my_snprintf(input, sizeof(input), "%08x\n", (ulonglong)(ptr - offset)); if (write(in[1], input, len) <= 0) return 1; if (read(out[0], output, sizeof(output)) <= 0) @@ -168,35 +232,6 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) const char *my_addr_resolve_init() { - if (!initialized) - { - pid_t pid; - - if (pipe(in) < 0) - return "pipe(in)"; - if (pipe(out) < 0) - return "pipe(out)"; - - pid = fork(); - if (pid == -1) - return "fork"; - - if (!pid) /* child */ - { - dup2(in[0], 0); - dup2(out[1], 1); - close(in[0]); - close(in[1]); - close(out[0]); - close(out[1]); - execlp("addr2line", "addr2line", "-C", "-f", "-e", my_progname, NULL); - exit(1); - } - - close(in[0]); - close(out[1]); - initialized= 1; - } return 0; } #endif diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 9e44707b1a2..4ff353fc366 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -22,6 +22,8 @@ #undef EXTRA_DEBUG #define EXTRA_DEBUG +#define TRASH_MEM(X) TRASH_FREE(((char*)(X) + ((X)->size-(X)->left)), (X)->left) + /* Initialize memory root @@ -60,12 +62,13 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, if (pre_alloc_size) { if ((mem_root->free= mem_root->pre_alloc= - (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)), + (USED_MEM*) my_malloc(pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM)), MYF(0)))) { mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM)); mem_root->free->left= pre_alloc_size; mem_root->free->next= 0; + TRASH_MEM(mem_root->free); } } #endif @@ -133,6 +136,7 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, mem->left= pre_alloc_size; mem->next= *prev; *prev= mem_root->pre_alloc= mem; + TRASH_MEM(mem); } else { @@ -228,6 +232,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) next->size= get_size; next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM)); *prev=next; + TRASH_MEM(next); } point= (uchar*) ((char*) next+ (next->size-next->left)); @@ -296,8 +301,6 @@ void *multi_alloc_root(MEM_ROOT *root, ...) DBUG_RETURN((void*) start); } -#define TRASH_MEM(X) TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left) - /* Mark all data in blocks free for reusage */ static inline void mark_blocks_free(MEM_ROOT* root) diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index aefd3564185..55ee1db657e 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -423,8 +423,6 @@ void my_thread_end(void) if (--THR_thread_count == 0) mysql_cond_signal(&THR_COND_threads); mysql_mutex_unlock(&THR_LOCK_threads); - - TRASH(tmp, sizeof(*tmp)); free(tmp); } } diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 7d644e835da..2c5f8d7082d 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -448,7 +448,7 @@ else echo echo "You can also try to start the mysqld daemon with:" echo - echo " shell> $mysqld --skip-grant --general-log &" + echo " shell> $mysqld --skip-grant-tables --general-log &" echo echo "and use the command line tool $bindir/mysql" echo "to connect to the mysql database and look at the grant tables:" @@ -459,8 +459,8 @@ else echo "Try 'mysqld --help' if you have problems with paths. Using" echo "--general-log gives you a log in $ldata that may be helpful." link_to_help - echo "MariaDB is hosted on launchpad; You can find the latest source and" - echo "email lists at http://launchpad.net/maria" + echo "You can find the latest source at https://downloads.mariadb.org and" + echo "the maria-discuss email list at https://launchpad.net/~maria-discuss" echo echo "Please check all of the above before submitting a bug report" echo "at http://mariadb.org/jira" diff --git a/sql-common/client.c b/sql-common/client.c index 7d92f71d69f..bb7bdb1ff7d 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1708,7 +1708,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) } else { - if (len > (ulong) (end_pos - pos)) + if (pos + len > end_pos) { set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate); return -1; @@ -2532,10 +2532,10 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, if (mysql->client_flag & CLIENT_MULTI_STATEMENTS) mysql->client_flag|= CLIENT_MULTI_RESULTS; -#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) +#ifdef HAVE_OPENSSL if (mysql->options.use_ssl) mysql->client_flag|= CLIENT_SSL; -#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY*/ +#endif /* HAVE_OPENSSL */ if (mpvio->db) mysql->client_flag|= CLIENT_CONNECT_WITH_DB; diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 673250ffd22..481a49bf5b0 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -1,5 +1,6 @@ /* - Copyright (c) 2006, 2011, Oracle and/or its affiliates. + Copyright (c) 2006, 2017, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB 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 @@ -176,6 +177,8 @@ protected: error_log_print(ERROR_LEVEL, fmt, args); va_end(args); } +public: + Event_db_intact() { has_keys= TRUE; } }; /** In case of an error, a message is printed to the error log. */ diff --git a/sql/field.h b/sql/field.h index f8fc7427618..d484b31d682 100644 --- a/sql/field.h +++ b/sql/field.h @@ -208,7 +208,7 @@ class Field public: static void *operator new(size_t size) throw () { return sql_alloc(size); } - static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); } + static void operator delete(void *ptr_arg, size_t size) { TRASH_FREE(ptr_arg, size); } uchar *ptr; // Position to field in record /** diff --git a/sql/handler.cc b/sql/handler.cc index 5cff15821c7..7da373e6802 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3841,7 +3841,8 @@ int handler::ha_create_handler_files(const char *name, const char *old_name, int action_flag, HA_CREATE_INFO *info) { - mark_trx_read_write(); + if (!opt_readonly || !info || !(info->options & HA_LEX_CREATE_TMP_TABLE)) + mark_trx_read_write(); return create_handler_files(name, old_name, action_flag, info); } diff --git a/sql/item.cc b/sql/item.cc index 576dce78299..08a00615c0c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -10010,7 +10010,7 @@ const char *dbug_print_item(Item *item) if (!item) return "(Item*)NULL"; item->print(&str ,QT_ORDINARY); - if (str.c_ptr() == buf) + if (str.c_ptr_safe() == buf) return buf; else return "Couldn't fit into buffer"; diff --git a/sql/item.h b/sql/item.h index e01cf5384b9..830f8bf14a4 100644 --- a/sql/item.h +++ b/sql/item.h @@ -50,6 +50,12 @@ bool trace_unsupported_by_check_vcol_func_processor(const char *where) return trace_unsupported_func(where, "check_vcol_func_processor"); } +#ifdef DBUG_OFF +static inline const char *dbug_print_item(Item *item) { return NULL; } +#else +extern const char *dbug_print_item(Item *item); +#endif + class Protocol; struct TABLE_LIST; void item_init(void); /* Init item functions */ @@ -580,7 +586,7 @@ public: { return sql_alloc(size); } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return alloc_root(mem_root, size); } - static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } + static void operator delete(void *ptr,size_t size) { TRASH_FREE(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) {} enum Type {FIELD_ITEM= 0, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM, diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 62e76922c0e..39f497e3828 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1420,6 +1420,7 @@ bool Item_in_optimizer::is_top_level_item() void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, Item **ref) { + DBUG_ASSERT(fixed); /* This will re-calculate attributes of our Item_in_subselect: */ Item_bool_func::fix_after_pullout(new_parent, ref); @@ -1443,6 +1444,33 @@ bool Item_in_optimizer::eval_not_null_tables(uchar *opt_arg) } +void Item_in_optimizer::print(String *str, enum_query_type query_type) +{ + restore_first_argument(); + Item_func::print(str, query_type); +} + + +/** + "Restore" first argument before fix_fields() call (after it is harmless). + + @Note: Main pointer to left part of IN/ALL/ANY subselect is subselect's + lest_expr (see Item_in_optimizer::fix_left) so changes made during + fix_fields will be rolled back there which can make + Item_in_optimizer::args[0] unusable on second execution before fix_left() + call. This call fix the pointer. +*/ + +void Item_in_optimizer::restore_first_argument() +{ + if (args[1]->type() == Item::SUBSELECT_ITEM && + ((Item_subselect *)args[1])->is_in_predicate()) + { + args[0]= ((Item_in_subselect *)args[1])->left_expr; + } +} + + bool Item_in_optimizer::fix_left(THD *thd, Item **ref) { DBUG_ENTER("Item_in_optimizer::fix_left"); @@ -1588,6 +1616,8 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg) { THD *thd= (THD*) thd_arg; DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer"); + DBUG_ASSERT(fixed); + if (args[1]->type() != Item::SUBSELECT_ITEM) DBUG_RETURN(this); // MAX/MIN transformed => do nothing @@ -1611,6 +1641,7 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg) void Item_in_optimizer::get_cache_parameters(List<Item> ¶meters) { + DBUG_ASSERT(fixed); /* Add left expression to the list of the parameters of the subquery */ if (args[0]->cols() == 1) parameters.add_unique(args[0], &cmp_items); @@ -1842,6 +1873,7 @@ Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument { Item *new_item; + DBUG_ASSERT(fixed); DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare()); DBUG_ASSERT(arg_count == 2); @@ -1893,6 +1925,7 @@ Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument bool Item_in_optimizer::is_expensive_processor(uchar *arg) { + DBUG_ASSERT(fixed); return args[0]->is_expensive_processor(arg) || args[1]->is_expensive_processor(arg); } @@ -1900,6 +1933,7 @@ bool Item_in_optimizer::is_expensive_processor(uchar *arg) bool Item_in_optimizer::is_expensive() { + DBUG_ASSERT(fixed); return args[0]->is_expensive() || args[1]->is_expensive(); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 7b7ca9223fd..3c8cc71370d 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -255,6 +255,7 @@ public: bool is_null(); longlong val_int(); void cleanup(); + enum Functype functype() const { return IN_OPTIMIZER_FUNC; } const char *func_name() const { return "<in_optimizer>"; } Item_cache **get_cache() { return &cache; } void keep_top_level_cache(); @@ -268,6 +269,12 @@ public: bool is_top_level_item(); bool eval_not_null_tables(uchar *opt_arg); void fix_after_pullout(st_select_lex *new_parent, Item **ref); + virtual void print(String *str, enum_query_type query_type); + void restore_first_argument(); + Item* get_wrapped_in_subselect_item() + { + return args[1]; + } }; class Comp_creator diff --git a/sql/item_func.cc b/sql/item_func.cc index 0b1ad97de44..6833e30af23 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -595,6 +595,7 @@ my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value) } +#ifdef HAVE_DLOPEN void Item_udf_func::fix_num_length_and_dec() { uint fl_length= 0; @@ -611,6 +612,7 @@ void Item_udf_func::fix_num_length_and_dec() max_length= float_length(NOT_FIXED_DEC); } } +#endif /** diff --git a/sql/item_func.h b/sql/item_func.h index 2157c6b6b6d..57818228b98 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -66,7 +66,7 @@ public: NOW_FUNC, TRIG_COND_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC, - NEG_FUNC, GSYSVAR_FUNC }; + NEG_FUNC, GSYSVAR_FUNC, IN_OPTIMIZER_FUNC }; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } @@ -2133,6 +2133,8 @@ public: Item_func_uuid_short() :Item_int_func() {} const char *func_name() const { return "uuid_short"; } longlong val_int(); + bool const_item() const { return false; } + table_map used_tables() const { return RAND_TABLE_BIT; } void fix_length_and_dec() { max_length= 21; unsigned_flag=1; } bool check_vcol_func_processor(uchar *int_arg) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 00ae60a7fb1..c1138c2a930 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -997,6 +997,8 @@ public: DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); fix_char_length(MY_UUID_STRING_LENGTH); } + bool const_item() const { return false; } + table_map used_tables() const { return RAND_TABLE_BIT; } const char *func_name() const{ return "uuid"; } String *val_str(String *); bool check_vcol_func_processor(uchar *int_arg) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 46d41fd61e3..57dcbd4f540 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1746,7 +1746,7 @@ Item_in_subselect::single_value_transformer(JOIN *join) Item* join_having= join->having ? join->having : join->tmp_having; if (!(join_having || select_lex->with_sum_func || select_lex->group_list.elements) && - select_lex->table_list.elements == 0 && + select_lex->table_list.elements == 0 && !join->conds && !select_lex->master_unit()->is_union()) { Item *where_item= (Item*) select_lex->item_list.head(); diff --git a/sql/key.cc b/sql/key.cc index 110b13000ed..700bf6a05a6 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -62,7 +62,8 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field, i < (int) key_count ; i++, key_info++) { - if (key_info->key_part[0].offset == fieldpos) + if (key_info->key_part[0].offset == fieldpos && + key_info->key_part[0].field->type() != MYSQL_TYPE_BIT) { /* Found key. Calc keylength */ *key_length= *keypart= 0; return i; /* Use this key */ @@ -81,7 +82,8 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field, j < key_info->key_parts ; j++, key_part++) { - if (key_part->offset == fieldpos) + if (key_part->offset == fieldpos && + key_part->field->type() != MYSQL_TYPE_BIT) { *keypart= j; return i; /* Use this key */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 9ec76051b06..12489d6d7eb 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + Copyright (c) 2000, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB 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 @@ -3343,6 +3343,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, db= (char *)start; query= (char *)(start + db_len + 1); q_len= data_len - db_len -1; + + if (data_len && (data_len < db_len || + data_len < q_len || + data_len != (db_len + q_len + 1))) + { + q_len= 0; + query= NULL; + DBUG_VOID_RETURN; + } + + unsigned int max_length; + max_length= (event_len - ((const char*)(end + db_len + 1) - + (buf - common_header_len))); + if (q_len != max_length) + { + q_len= 0; + query= NULL; + DBUG_VOID_RETURN; + } /** Append the db length at the end of the buffer. This will be used by Query_cache::send_result_to_client() in case the query cache is On. @@ -3623,6 +3642,20 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, you. */ thd->catalog= catalog_len ? (char *) catalog : (char *)""; + + int len_error; + size_t valid_len= system_charset_info->cset->well_formed_len(system_charset_info, + db, db + db_len, db_len, &len_error); + + if (valid_len != db_len) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid database name in Query event."); + thd->is_slave_error= true; + goto end; + } + new_db.length= db_len; new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length); thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */ @@ -3799,7 +3832,23 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, } else thd->variables.collation_database= thd->db_charset; - + + { + const CHARSET_INFO *cs= thd->charset(); + /* + We cannot ask for parsing a statement using a character set + without state_maps (parser internal data). + */ + if (!cs->state_map) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "character_set cannot be parsed"); + thd->is_slave_error= true; + goto end; + } + } + thd->table_map_for_update= (table_map)table_map_for_update; thd->set_invoker(&user, &host); /* @@ -4281,7 +4330,13 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli) */ break; default: - /* this case is impossible */ + /* + This case is not expected. It can be either an event corruption or an + unsupported binary log version. + */ + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Binlog version not supported"); DBUG_RETURN(1); } DBUG_RETURN(error); @@ -5207,6 +5262,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, fields = (char*)field_lens + num_fields; table_name = fields + field_block_len; + if (strlen(table_name) > NAME_LEN) + goto err; + db = table_name + table_name_len + 1; DBUG_EXECUTE_IF ("simulate_invalid_address", db_len = data_len;); @@ -6417,6 +6475,13 @@ User_var_log_event(const char* buf, uint event_len, buf+= description_event->common_header_len + description_event->post_header_len[USER_VAR_EVENT-1]; name_len= uint4korr(buf); + /* Avoid reading out of buffer */ + if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len) + { + error= true; + goto err; + } + name= (char *) buf + UV_NAME_LEN_SIZE; /* @@ -6476,6 +6541,11 @@ User_var_log_event(const char* buf, uint event_len, we keep the flags set to UNDEF_F. */ uint bytes_read= ((val + val_len) - start); + if (bytes_read > event_len) + { + error= true; + goto err; + } if ((data_written - bytes_read) > 0) { flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + @@ -6690,7 +6760,12 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) } if (!(charset= get_charset(charset_number, MYF(MY_WME)))) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid character set for User var event"); DBUG_RETURN(1); + } LEX_STRING user_var_name; user_var_name.str= name; user_var_name.length= name_len; @@ -6711,12 +6786,26 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) { switch (type) { case REAL_RESULT: + if (val_len != 8) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } float8get(real_val, val); it= new Item_float(real_val, 0); val= (char*) &real_val; // Pointer to value in native format val_len= 8; break; case INT_RESULT: + if (val_len != 8) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } int_val= (longlong) uint8korr(val); it= new Item_int(int_val); val= (char*) &int_val; // Pointer to value in native format @@ -6724,6 +6813,13 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) break; case DECIMAL_RESULT: { + if (val_len < 3) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]); it= dec; val= (char *)dec->val_decimal(NULL); @@ -8177,6 +8273,15 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); m_width = net_field_length(&ptr_after_width); DBUG_PRINT("debug", ("m_width=%lu", m_width)); + /* Avoid reading out of buffer */ + if (static_cast<unsigned int>((ptr_after_width + + (m_width + 7) / 8) - + (uchar*)buf) > event_len) + { + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } + /* if bitmap_init fails, catched in is_valid() */ if (likely(!bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, @@ -8225,7 +8330,12 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, const uchar* const ptr_rows_data= (const uchar*) ptr_after_width; - size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf); + size_t const read_size= ptr_rows_data - (const unsigned char *) buf; + if (read_size > event_len) + { + DBUG_VOID_RETURN; + } + size_t const data_size= event_len - read_size; DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu", m_table_id, m_flags, m_width, (ulong) data_size)); diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 51fcf902f77..3d54ffdf7eb 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2007, 2016, Oracle and/or its affiliates. +/* Copyright (c) 2007, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB 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 @@ -1357,6 +1358,15 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len, DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); m_width = net_field_length(&ptr_after_width); DBUG_PRINT("debug", ("m_width=%lu", m_width)); + /* Avoid reading out of buffer */ + if (static_cast<unsigned int>(m_width + + (ptr_after_width - + (const uchar *)buf)) > event_len) + { + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } + /* if bitmap_init fails, catched in is_valid() */ if (likely(!bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3edbeafe224..4acfe57c684 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2015, SkySQL Ab. + Copyright (c) 2008, 2018, MariaDB 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 @@ -3627,7 +3627,7 @@ static int init_common_variables() /* TODO: remove this when my_time_t is 64 bit compatible */ if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time)) { - sql_print_error("This MySQL server doesn't support dates later then 2038"); + sql_print_error("This MySQL server doesn't support dates later than 2038"); return 1; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 25a9e729a8b..04ab8415dfe 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2651,7 +2651,7 @@ public: /* Table read plans are allocated on MEM_ROOT and are never deleted */ static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } - static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } + static void operator delete(void *ptr,size_t size) { TRASH_FREE(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Never called */ } virtual ~TABLE_READ_PLAN() {} /* Remove gcc warning */ diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 028bf44bf79..1bda84bacd7 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -873,8 +873,10 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs) Make sure that create_tmp_table will not fail due to too long keys. See MDEV-7122. This check is performed inside create_tmp_table also and we must do it so that we know the table has keys created. + Make sure that the length of the key for the temp_table is atleast + greater than 0. */ - if (total_key_length > tmp_table_max_key_length() || + if (!total_key_length || total_key_length > tmp_table_max_key_length() || elements > tmp_table_max_key_parts()) DBUG_RETURN(FALSE); @@ -1004,6 +1006,10 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list) void find_and_block_conversion_to_sj(Item *to_find, List_iterator_fast<Item_in_subselect> &li) { + if (to_find->type() == Item::FUNC_ITEM && + ((Item_func*)to_find)->functype() == Item_func::IN_OPTIMIZER_FUNC) + to_find= ((Item_in_optimizer*)to_find)->get_wrapped_in_subselect_item(); + if (to_find->type() != Item::SUBSELECT_ITEM || ((Item_subselect *) to_find)->substype() != Item_subselect::IN_SUBS) return; @@ -5897,5 +5903,6 @@ bool JOIN::choose_tableless_subquery_plan() tmp_having= having; } } + exec_const_cond= conds; return FALSE; } diff --git a/sql/sp.cc b/sql/sp.cc index 932e801a01d..b176c0f3686 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2002, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB + Copyright (c) 2002, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB 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 @@ -354,7 +354,7 @@ private: bool m_print_once; public: - Proc_table_intact() : m_print_once(TRUE) {} + Proc_table_intact() : m_print_once(TRUE) { has_keys= TRUE; } protected: void report_error(uint code, const char *fmt, ...); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 11351f28a07..c3740f8ab29 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + Copyright (c) 2009, 2018, MariaDB 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 diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 7207ff6d55c..4e4e8c8cab4 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2010, 2015, Oracle and/or its affiliates. - Copyright (c) 2011, 2016, MariaDB + Copyright (c) 2011, 2018, MariaDB 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 diff --git a/sql/sql_base.h b/sql/sql_base.h index 0cde933afb8..646e391a58b 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -1,4 +1,6 @@ /* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, 2018, MariaDB + 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 diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 2a03b13aa75..fe5641f8e97 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2497,6 +2497,7 @@ void Query_cache::init() */ if (global_system_variables.query_cache_type == 0) { + m_cache_status= DISABLE_REQUEST; free_cache(); m_cache_status= DISABLED; } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7aae3ed91ed..ce875ba87ef 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2486,6 +2486,9 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value, MEM_ROOT *runtime_memroot) { Item_change_record *change; + DBUG_ENTER("THD::check_and_register_item_tree_change"); + DBUG_PRINT("enter", ("Register: %p (%p) <- %p (%p)", + *place, place, *new_value, new_value)); I_List_iterator<Item_change_record> it(change_list); while ((change= it++)) { @@ -2495,19 +2498,20 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value, if (change) nocheck_register_item_tree_change(place, change->old_value, runtime_memroot); + DBUG_VOID_RETURN; } void THD::rollback_item_tree_changes() { + DBUG_ENTER("THD::rollback_item_tree_changes"); I_List_iterator<Item_change_record> it(change_list); Item_change_record *change; - DBUG_ENTER("rollback_item_tree_changes"); while ((change= it++)) { - DBUG_PRINT("info", ("revert %p -> %p", - change->old_value, (*change->place))); + DBUG_PRINT("info", ("Rollback: %p (%p) <- %p", + *change->place, change->place, change->old_value)); *change->place= change->old_value; } /* We can forget about changes memory: it's allocated in runtime memroot */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 2bb2b12aebe..cd1ac4fefd7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2786,10 +2786,14 @@ public: void change_item_tree(Item **place, Item *new_value) { + DBUG_ENTER("THD::change_item_tree"); + DBUG_PRINT("enter", ("Register: %p (%p) <- %p", + *place, place, new_value)); /* TODO: check for OOM condition here */ if (!stmt_arena->is_conventional()) nocheck_register_item_tree_change(place, *place, mem_root); *place= new_value; + DBUG_VOID_RETURN; } /** Make change in item tree after checking whether it needs registering diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 230a8b2c802..f7ffd86fe83 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -187,7 +187,7 @@ void Server_side_cursor::operator delete(void *ptr, size_t size) MEM_ROOT own_root= *cursor->mem_root; DBUG_ENTER("Server_side_cursor::operator delete"); - TRASH(ptr, size); + TRASH_FREE(ptr, size); /* If this cursor has never been opened mem_root is empty. Otherwise mem_root points to the memory the cursor object was allocated in. diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 2a6d82c161a..2e947ecba16 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -366,7 +366,11 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) derived->get_unit())); if (derived->merged) + { + + DBUG_PRINT("info", ("Irreversibly merged: exit")); DBUG_RETURN(FALSE); + } if (dt_select->uncacheable & UNCACHEABLE_RAND) { @@ -667,6 +671,17 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) unit->derived= derived; + /* + Above cascade call of prepare is important for PS protocol, but after it + is called we can check if we really need prepare for this derived + */ + if (derived->merged) + { + DBUG_PRINT("info", ("Irreversibly merged: exit")); + DBUG_RETURN(FALSE); + } + + derived->fill_me= FALSE; if (!(derived->derived_result= new select_union)) @@ -795,6 +810,11 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", (derived->alias ? derived->alias : "<NULL>"), derived->get_unit())); + if (derived->merged) + { + DBUG_PRINT("info", ("Irreversibly merged: exit")); + DBUG_RETURN(FALSE); + } if (unit->optimized) DBUG_RETURN(FALSE); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index cf34c567626..57129cfedc7 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -548,7 +548,7 @@ public: } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return (void*) alloc_root(mem_root, (uint) size); } - static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } + static void operator delete(void *ptr,size_t size) { TRASH_FREE(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) {} // Ensures that at least all members used during cleanup() are initialized. @@ -2949,7 +2949,7 @@ struct st_lex_local: public LEX return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr,size_t size) - { TRASH(ptr, size); } + { TRASH_FREE(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Never called */ } }; diff --git a/sql/sql_lifo_buffer.h b/sql/sql_lifo_buffer.h index feec4aeb4c2..f551cc48c23 100644 --- a/sql/sql_lifo_buffer.h +++ b/sql/sql_lifo_buffer.h @@ -84,7 +84,7 @@ public: start= start_arg; end= end_arg; if (end != start) - TRASH(start, end - start); + TRASH_ALLOC(start, end - start); reset(); } @@ -224,7 +224,7 @@ public: { DBUG_ASSERT(unused_end >= unused_start); DBUG_ASSERT(end == unused_start); - TRASH(unused_start, unused_end - unused_start); + TRASH_ALLOC(unused_start, unused_end - unused_start); end= unused_end; } /* Return pointer to start of the memory area that is occupied by the data */ diff --git a/sql/sql_list.h b/sql/sql_list.h index 7538f69766d..08667bed02a 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -41,12 +41,12 @@ public: { return alloc_root(mem_root, size); } static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return alloc_root(mem_root, size); } - static void operator delete(void *ptr, size_t size) { TRASH(ptr, size); } + static void operator delete(void *ptr, size_t size) { TRASH_FREE(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* never called */ } static void operator delete[](void *ptr, MEM_ROOT *mem_root) { /* never called */ } - static void operator delete[](void *ptr, size_t size) { TRASH(ptr, size); } + static void operator delete[](void *ptr, size_t size) { TRASH_FREE(ptr, size); } #ifdef HAVE_valgrind bool dummy; inline Sql_alloc() :dummy(0) {} diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 01dcc7cc2ac..b25a3c2bcf3 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2005, 2017, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, SkySQL Ab. + Copyright (c) 2009, 2018, MariaDB 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 @@ -283,7 +283,7 @@ bool partition_default_handling(TABLE *table, partition_info *part_info, } } part_info->set_up_defaults_for_partitioning(table->file, - (ulonglong)0, (uint)0); + NULL, (uint)0); DBUG_RETURN(FALSE); } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 7e5c7c9c852..81b59a5be90 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2005, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2014, SkySQL Ab. + Copyright (c) 2005, 2018, Oracle and/or its affiliates. + Copyright (c) 2010, 2018, MariaDB 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 @@ -267,7 +267,7 @@ public: static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, size); } static void operator delete(void *ptr_arg,size_t size) - { TRASH(ptr_arg, size); } + { TRASH_FREE(ptr_arg, size); } sys_var_pluginvar(sys_var_chain *chain, const char *name_arg, struct st_mysql_sys_var *plugin_var_arg, @@ -477,6 +477,11 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl) sizeof(struct st_plugin_dl)); DBUG_RETURN(tmp); } +#else +static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *) +{ + return 0; +} #endif /* HAVE_DLOPEN */ @@ -2247,6 +2252,16 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT))) DBUG_RETURN(TRUE); + if (!table->key_info) + { + my_printf_error(ER_UNKNOWN_ERROR, + "The table %s.%s has no primary key. " + "Please check the table definition and " + "create the primary key accordingly.", MYF(0), + table->s->db.str, table->s->table_name.str); + DBUG_RETURN(TRUE); + } + /* Pre-acquire audit plugins for events that may potentially occur during [UN]INSTALL PLUGIN. diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 78079a11bec..8de3a8ddb50 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3230,9 +3230,9 @@ void Prepared_statement::cleanup_stmt() DBUG_ENTER("Prepared_statement::cleanup_stmt"); DBUG_PRINT("enter",("stmt: 0x%lx", (long) this)); + thd->rollback_item_tree_changes(); cleanup_items(free_list); thd->cleanup_after_query(); - thd->rollback_item_tree_changes(); DBUG_VOID_RETURN; } @@ -3837,6 +3837,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) Statement stmt_backup; Query_arena *old_stmt_arena; bool error= TRUE; + bool qc_executed= FALSE; char saved_cur_db_name_buf[SAFE_NAME_LEN+1]; LEX_STRING saved_cur_db_name= @@ -3955,6 +3956,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) thd->lex->sql_command= SQLCOM_SELECT; status_var_increment(thd->status_var.com_stat[SQLCOM_SELECT]); thd->update_stats(); + qc_executed= TRUE; } } @@ -3978,7 +3980,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) thd->set_statement(&stmt_backup); thd->stmt_arena= old_stmt_arena; - if (state == Query_arena::STMT_PREPARED) + if (state == Query_arena::STMT_PREPARED && !qc_executed) state= Query_arena::STMT_EXECUTED; if (error == 0 && this->lex->sql_command == SQLCOM_CALL) diff --git a/sql/sql_priv.h b/sql/sql_priv.h index b5589cb4b22..3195c5bb4a4 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2010, 2014, Monty Program Ab. +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. + Copyright (c) 2010, 2018, Monty Program Ab. 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 @@ -193,6 +193,11 @@ template <class T> T available_buffer(const char* buf_start, const char* buf_current, T buf_len) { + /* Sanity check */ + if (buf_current < buf_start || + buf_len < static_cast<T>(buf_current - buf_start)) + return static_cast<T>(0); + return buf_len - (buf_current - buf_start); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9f89a261540..90bb536c0e2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -279,6 +279,10 @@ enum enum_exec_or_opt {WALK_OPTIMIZATION_TABS , WALK_EXECUTION_TABS}; JOIN_TAB *first_breadth_first_tab(JOIN *join, enum enum_exec_or_opt tabs_kind); JOIN_TAB *next_breadth_first_tab(JOIN *join, enum enum_exec_or_opt tabs_kind, JOIN_TAB *tab); +static bool +find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, + ORDER *order, List<Item> &fields, List<Item> &all_fields, + bool is_group_field, bool add_to_all_fields); /** This handles SELECT with and without UNION. @@ -634,6 +638,9 @@ JOIN::prepare(Item ***rref_pointer_array, join_list= &select_lex->top_join_list; union_part= unit_arg->is_union(); + // simple check that we got usable conds + dbug_print_item(conds); + if (select_lex->handle_derived(thd->lex, DT_PREPARE)) DBUG_RETURN(1); @@ -696,12 +703,11 @@ JOIN::prepare(Item ***rref_pointer_array, } table_count= select_lex->leaf_tables.elements; - + TABLE_LIST *tbl; List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables); while ((tbl= li++)) { - //table_count++; /* Count the number of tables in the join. */ /* If the query uses implicit grouping where the select list contains both aggregate functions and non-aggregate fields, any non-aggregated field @@ -736,9 +742,15 @@ JOIN::prepare(Item ***rref_pointer_array, /* Resolve the ORDER BY that was skipped, then remove it. */ if (skip_order_by && select_lex != select_lex->master_unit()->global_parameters) { - if (setup_order(thd, (*rref_pointer_array), tables_list, fields_list, - all_fields, select_lex->order_list.first)) - DBUG_RETURN(-1); + thd->where= "order clause"; + for (ORDER *order= select_lex->order_list.first; order; order= order->next) + { + /* Don't add the order items to all fields. Just resolve them to ensure + the query is valid, we'll drop them immediately after. */ + if (find_order_in_list(thd, *rref_pointer_array, tables_list, order, + fields_list, all_fields, false, false)) + DBUG_RETURN(-1); + } select_lex->order_list.empty(); } @@ -2085,8 +2097,11 @@ bool JOIN::shrink_join_buffers(JOIN_TAB *jt, ulonglong curr_space, ulonglong needed_space) { + JOIN_TAB *tab; JOIN_CACHE *cache; - for (JOIN_TAB *tab= join_tab+const_tables; tab < jt; tab++) + for (tab= first_linear_tab(this, WITHOUT_BUSH_ROOTS, WITHOUT_CONST_TABLES); + tab != jt; + tab= next_linear_tab(this, tab, WITHOUT_BUSH_ROOTS)) { cache= tab->cache; if (cache) @@ -9510,7 +9525,7 @@ void JOIN::drop_unused_derived_keys() table->use_index(tab->ref.key); if (table->s->keys) { - if (tab->ref.key >= 0) + if (tab->ref.key >= 0 && tab->ref.key < MAX_KEY) tab->ref.key= 0; else table->s->keys= 0; @@ -11527,7 +11542,7 @@ public: } static void operator delete(void *ptr __attribute__((unused)), size_t size __attribute__((unused))) - { TRASH(ptr, size); } + { TRASH_FREE(ptr, size); } Item *and_level; Item_func *cmp_func; @@ -20623,7 +20638,10 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref) SELECT list) @param[in,out] all_fields All select, group and order by fields @param[in] is_group_field True if order is a GROUP field, false if - ORDER by field + ORDER by field + @param[in] add_to_all_fields If the item is to be added to all_fields and + ref_pointer_array, this flag can be set to + false to stop the automatic insertion. @retval FALSE if OK @@ -20634,7 +20652,7 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref) static bool find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, ORDER *order, List<Item> &fields, List<Item> &all_fields, - bool is_group_field) + bool is_group_field, bool add_to_all_fields) { Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */ Item::Type order_item_type; @@ -20753,6 +20771,9 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, thd->is_error())) return TRUE; /* Wrong field. */ + if (!add_to_all_fields) + return FALSE; + uint el= all_fields.elements; DBUG_ASSERT(all_fields.elements <= thd->lex->current_select->ref_pointer_array_size); @@ -20782,13 +20803,13 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, */ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, - List<Item> &fields, List<Item> &all_fields, ORDER *order) + List<Item> &fields, List<Item> &all_fields, ORDER *order) { thd->where="order clause"; for (; order; order=order->next) { if (find_order_in_list(thd, ref_pointer_array, tables, order, fields, - all_fields, FALSE)) + all_fields, FALSE, true)) return 1; } return 0; @@ -20840,7 +20861,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, for (ord= order; ord; ord= ord->next) { if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields, - all_fields, TRUE)) + all_fields, TRUE, true)) return 1; (*ord->item)->marker= UNDEF_POS; /* Mark found */ if ((*ord->item)->with_sum_func) diff --git a/sql/sql_select.h b/sql/sql_select.h index 1bc1e4c2b7a..e208377e275 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1757,7 +1757,7 @@ int get_quick_record(SQL_SELECT *select); SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length, SORT_FIELD *sortorder); int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, - List<Item> &fields, List <Item> &all_fields, ORDER *order); + List<Item> &fields, List <Item> &all_fields, ORDER *order); int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, List<Item> &fields, List<Item> &all_fields, ORDER *order, bool *hidden_group_fields); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2218c949d49..aa6c13bcd07 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2128,7 +2128,7 @@ public: } static void operator delete(void *ptr __attribute__((unused)), size_t size __attribute__((unused))) - { TRASH(ptr, size); } + { TRASH_FREE(ptr, size); } ulong thread_id; time_t start_time; diff --git a/sql/sql_string.h b/sql/sql_string.h index 1fce3ae6c6f..3175a6616bf 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -102,7 +102,7 @@ public: { (void) ptr_arg; (void) size; - TRASH(ptr_arg, size); + TRASH_FREE(ptr_arg, size); } static void operator delete(void *, MEM_ROOT *) { /* never called */ } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6ea0a7efbf3..95ba647378c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2016, MariaDB + Copyright (c) 2010, 2018, MariaDB 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 @@ -4397,7 +4397,7 @@ bool mysql_create_table_no_lock(THD *thd, /* Give warnings for not supported table options */ #if defined(WITH_ARIA_STORAGE_ENGINE) extern handlerton *maria_hton; - if (file->ht != maria_hton) + if (file->partition_ht() != maria_hton) #endif if (create_info->transactional) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 70ed6f0e600..25f8ae8064b 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2004, 2012, Oracle and/or its affiliates. + Copyright (c) 2010, 2018, MariaDB 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 diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 388232b2a21..890dfc9b012 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. + Copyright (c) 2012, 2018, MariaDB 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 diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 2d816e0309d..bbb4133417e 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -935,22 +935,6 @@ bool st_select_lex_unit::cleanup() void st_select_lex_unit::reinit_exec_mechanism() { prepared= optimized= executed= 0; -#ifndef DBUG_OFF - if (is_union()) - { - List_iterator_fast<Item> it(item_list); - Item *field; - while ((field= it++)) - { - /* - we can't cleanup here, because it broke link to temporary table field, - but have to drop fixed flag to allow next fix_field of this field - during re-executing - */ - field->fixed= 0; - } - } -#endif } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index a2f65961c0f..bf864a2db67 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -628,6 +628,8 @@ int mysql_update(THD *thd, if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) error=1; /* purecov: inspected */ select->file=tempfile; // Read row ptrs from this file + // select->file was copied, update self-references. + setup_io_cache(&select->file); if (error >= 0) goto err; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8dd38e286b2..53bb3df99bb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -13573,6 +13573,11 @@ option_value: | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default { struct sys_var_with_base tmp= $4; + if (tmp.var == trg_new_row_fake_var) + { + my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), "NEW"); + MYSQL_YYABORT; + } /* Lookup if necessary: must be a system variable. */ if (tmp.var == NULL) { diff --git a/sql/table.cc b/sql/table.cc index 5db14599adc..2381343bc66 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2015, MariaDB +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. + Copyright (c) 2008, 2018, MariaDB 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 @@ -1272,9 +1272,10 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, extra_rec_buf_length= uint2korr(head+59); rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length); share->rec_buff_length= rec_buff_length; - if (!(record= (uchar *) alloc_root(&share->mem_root, - rec_buff_length))) + if (!(record= (uchar *) alloc_root(&share->mem_root, rec_buff_length))) goto err; /* purecov: inspected */ + MEM_NOACCESS(record, rec_buff_length); + MEM_UNDEFINED(record, share->reclength); share->default_values= record; if (mysql_file_pread(file, record, (size_t) share->reclength, record_offset, MYF(MY_NABP))) @@ -2433,6 +2434,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, if (!(record= (uchar*) alloc_root(&outparam->mem_root, share->rec_buff_length * records))) goto err; /* purecov: inspected */ + MEM_NOACCESS(record, share->rec_buff_length * records); if (records == 0) { @@ -2447,6 +2449,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, else outparam->record[1]= outparam->record[0]; // Safety } + MEM_UNDEFINED(outparam->record[0], share->reclength); + MEM_UNDEFINED(outparam->record[1], share->reclength); if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root, (uint) ((share->fields+1)* @@ -3629,7 +3633,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) /* Whether the table definition has already been validated. */ if (table->s->table_field_def_cache == table_def) - DBUG_RETURN(FALSE); + goto end; if (table->s->fields != table_def->count) { @@ -3752,6 +3756,16 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) if (! error) table->s->table_field_def_cache= table_def; +end: + + if (has_keys && !error && !table->key_info) + { + report_error(0, "Incorrect definition of table %s.%s: " + "indexes are missing", + table->s->db.str, table->alias.c_ptr()); + error= TRUE; + } + DBUG_RETURN(error); } @@ -4000,7 +4014,7 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) DBUG_ASSERT(key_read == 0); /* mark the record[0] uninitialized */ - TRASH(record[0], s->reclength); + TRASH_ALLOC(record[0], s->reclength); /* Initialize the null marker bits, to ensure that if we are doing a read diff --git a/sql/table.h b/sql/table.h index 98f8c7ad73f..1d4a1d9a2d2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1,7 +1,7 @@ #ifndef TABLE_INCLUDED #define TABLE_INCLUDED -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2014, SkySQL Ab. +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB 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 @@ -496,10 +496,11 @@ typedef struct st_ha_data_partition class Table_check_intact { protected: + bool has_keys; virtual void report_error(uint code, const char *fmt, ...)= 0; public: - Table_check_intact() {} + Table_check_intact() : has_keys(FALSE) {} virtual ~Table_check_intact() {} /** Checks whether a table is intact. */ @@ -2125,6 +2126,7 @@ struct TABLE_LIST DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", (alias ? alias : "<NULL>"), get_unit())); + derived= get_unit(); derived_type= ((derived_type & (derived ? DTYPE_MASK : DTYPE_VIEW)) | DTYPE_TABLE | DTYPE_MATERIALIZE); set_check_materialized(); diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index 1c64892418e..9529cb126e7 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -169,7 +169,7 @@ public: static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return alloc_root(mem_root, size); } static void operator delete(void *ptr, size_t size) - { TRASH(ptr, size); } + { TRASH_FREE(ptr, size); } virtual int query(const char *buffer, uint length)=0; virtual FEDERATEDX_IO_RESULT *store_result()=0; diff --git a/storage/heap/_check.c b/storage/heap/_check.c index b64c9ab1831..f2fd8ab94be 100644 --- a/storage/heap/_check.c +++ b/storage/heap/_check.c @@ -79,7 +79,7 @@ int heap_check_heap(HP_INFO *info, my_bool print_status) } hp_find_record(info,pos); - if (!info->current_ptr[share->reclength]) + if (!info->current_ptr[share->visible]) deleted++; else records++; diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 345ebb8419f..ec76d08bf97 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -100,7 +100,6 @@ const char **ha_heap::bas_ext() const int ha_heap::open(const char *name, int mode, uint test_if_locked) { - set_if_bigger(table->s->reclength, sizeof (uchar*)); internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE); if (internal_table || (!(file= heap_open(name, mode)) && my_errno == ENOENT)) { @@ -728,7 +727,7 @@ heap_prepare_hp_create_info(TABLE *table_arg, bool internal_table, } } } - mem_per_row+= MY_ALIGN(share->reclength + 1, sizeof(char*)); + mem_per_row+= MY_ALIGN(max(share->reclength, sizeof(char*)) + 1, sizeof(char*)); if (table_arg->found_next_number_field) { keydef[share->next_number_index].flag|= HA_AUTO_KEY; diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c index 0b5dc841ada..1daca0beeb5 100644 --- a/storage/heap/hp_create.c +++ b/storage/heap/hp_create.c @@ -33,6 +33,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, uint keys= create_info->keys; ulong min_records= create_info->min_records; ulong max_records= create_info->max_records; + uint visible_offset; DBUG_ENTER("heap_create"); if (!create_info->internal_table) @@ -58,9 +59,9 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, /* We have to store sometimes uchar* del_link in records, - so the record length should be at least sizeof(uchar*) + so the visible_offset must be least at sizeof(uchar*) */ - set_if_bigger(reclength, sizeof (uchar*)); + visible_offset= max(reclength, sizeof (char*)); for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++) { @@ -152,7 +153,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, share->keydef= (HP_KEYDEF*) (share + 1); share->key_stat_version= 1; keyseg= (HA_KEYSEG*) (share->keydef + keys); - init_block(&share->block, reclength + 1, min_records, max_records); + init_block(&share->block, visible_offset + 1, min_records, max_records); /* Fix keys */ memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys)); for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++) @@ -192,6 +193,7 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info, share->max_table_size= create_info->max_table_size; share->data_length= share->index_length= 0; share->reclength= reclength; + share->visible= visible_offset; share->blength= 1; share->keys= keys; share->max_key_length= max_length; diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c index 1cbfe7408d4..eb9749601aa 100644 --- a/storage/heap/hp_delete.c +++ b/storage/heap/hp_delete.c @@ -45,7 +45,7 @@ int heap_delete(HP_INFO *info, const uchar *record) info->update=HA_STATE_DELETED; *((uchar**) pos)=share->del_link; share->del_link=pos; - pos[share->reclength]=0; /* Record deleted */ + pos[share->visible]=0; /* Record deleted */ share->deleted++; share->key_version++; #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG) diff --git a/storage/heap/hp_rrnd.c b/storage/heap/hp_rrnd.c index 8e0d51a78ca..d105c5c2e13 100644 --- a/storage/heap/hp_rrnd.c +++ b/storage/heap/hp_rrnd.c @@ -37,7 +37,7 @@ int heap_rrnd(register HP_INFO *info, uchar *record, uchar *pos) info->update= 0; DBUG_RETURN(my_errno= HA_ERR_END_OF_FILE); } - if (!info->current_ptr[share->reclength]) + if (!info->current_ptr[share->visible]) { info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND; DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED); @@ -91,7 +91,7 @@ int heap_rrnd_old(register HP_INFO *info, uchar *record, ulong pos) hp_find_record(info, pos); end: - if (!info->current_ptr[share->reclength]) + if (!info->current_ptr[share->visible]) { info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND; DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED); diff --git a/storage/heap/hp_rsame.c b/storage/heap/hp_rsame.c index 40c5a18f974..19767fd752b 100644 --- a/storage/heap/hp_rsame.c +++ b/storage/heap/hp_rsame.c @@ -32,7 +32,7 @@ int heap_rsame(register HP_INFO *info, uchar *record, int inx) DBUG_ENTER("heap_rsame"); test_active(info); - if (info->current_ptr[share->reclength]) + if (info->current_ptr[share->visible]) { if (inx < -1 || inx >= (int) share->keys) { diff --git a/storage/heap/hp_scan.c b/storage/heap/hp_scan.c index 39a6f2082a3..65726c37e1f 100644 --- a/storage/heap/hp_scan.c +++ b/storage/heap/hp_scan.c @@ -62,7 +62,7 @@ int heap_scan(register HP_INFO *info, uchar *record) } hp_find_record(info, pos); } - if (!info->current_ptr[share->reclength]) + if (!info->current_ptr[share->visible]) { DBUG_PRINT("warning",("Found deleted record")); info->update= HA_STATE_PREV_FOUND | HA_STATE_NEXT_FOUND; diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c index e45c78b75f1..4a9c1ba59c0 100644 --- a/storage/heap/hp_write.c +++ b/storage/heap/hp_write.c @@ -54,7 +54,7 @@ int heap_write(HP_INFO *info, const uchar *record) } memcpy(pos,record,(size_t) share->reclength); - pos[share->reclength]=1; /* Mark record as not deleted */ + pos[share->visible]= 1; /* Mark record as not deleted */ if (++share->records == share->blength) share->blength+= share->blength; info->s->key_version++; @@ -92,7 +92,7 @@ err: share->deleted++; *((uchar**) pos)=share->del_link; share->del_link=pos; - pos[share->reclength]=0; /* Record deleted */ + pos[share->visible]= 0; /* Record deleted */ DBUG_RETURN(my_errno); } /* heap_write */ diff --git a/storage/innobase/buf/buf0buddy.c b/storage/innobase/buf/buf0buddy.c index fa2515eddc2..6382cf534e1 100644 --- a/storage/innobase/buf/buf0buddy.c +++ b/storage/innobase/buf/buf0buddy.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -438,7 +439,7 @@ buf_buddy_free_low( buf_pool->buddy_stat[i].used--; recombine: - UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i); + UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i); ((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE; if (i == BUF_BUDDY_SIZES) { diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index 09a136bfa59..c3911c255ad 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -1953,8 +1954,7 @@ buf_LRU_block_free_non_file_page( UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page)); ut_d(block->page.in_free_list = TRUE); - - UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE); + UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE); } /******************************************************************//** diff --git a/storage/innobase/data/data0type.c b/storage/innobase/data/data0type.c index 9f855d58adf..c278cc8821e 100644 --- a/storage/innobase/data/data0type.c +++ b/storage/innobase/data/data0type.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +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 @@ -49,8 +50,10 @@ ulint dtype_get_at_most_n_mbchars( /*========================*/ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a multi-byte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a multi-byte character, in bytes */ ulint prefix_len, /*!< in: length of the requested prefix, in characters, multiplied by dtype_get_mbmaxlen(dtype) */ @@ -58,9 +61,6 @@ dtype_get_at_most_n_mbchars( const char* str) /*!< in: the string whose prefix length is being determined */ { - ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); - ut_a(data_len != UNIV_SQL_NULL); ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen)); diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c index 87d03eff3c2..e3056df53a5 100644 --- a/storage/innobase/dict/dict0mem.c +++ b/storage/innobase/dict/dict0mem.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +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 @@ -251,7 +252,8 @@ dict_mem_fill_column_struct( column->len = (unsigned int) col_len; #ifndef UNIV_HOTBACKUP dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen); - dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen); + column->mbminlen = mbminlen; + column->mbmaxlen = mbmaxlen; #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c9eee5b4dcd..7aab200fed1 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -10508,8 +10508,10 @@ ha_innobase::start_stmt( case SQLCOM_INSERT: case SQLCOM_UPDATE: case SQLCOM_DELETE: + case SQLCOM_REPLACE: init_table_handle_for_HANDLER(); prebuilt->select_lock_type = LOCK_X; + prebuilt->stored_select_lock_type = LOCK_X; error = row_lock_table_for_mysql(prebuilt, NULL, 1); if (error != DB_SUCCESS) { @@ -12242,6 +12244,17 @@ ha_innobase::check_if_incompatible_data( return(COMPATIBLE_DATA_YES); } +UNIV_INTERN +uint +ha_innobase::alter_table_flags(uint flags) +{ + uint mask = 0; + if (prebuilt->table->n_mysql_handles_opened > 1) { + mask = HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE; + } + return innobase_alter_table_flags(flags) & ~mask; +} + /************************************************************//** Validate the file format name and return its corresponding id. @return valid file format id */ diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index f9b6d6ff582..f5660b79027 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -232,6 +232,7 @@ class ha_innobase: public handler /** @} */ bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); + uint alter_table_flags(uint flags); }; /* Some accessor functions which the InnoDB plugin needs, but which diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 9f0a0958912..e254b44f0ec 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -103,8 +104,7 @@ innobase_col_to_mysql( #ifdef UNIV_DEBUG case DATA_MYSQL: ut_ad(flen >= len); - ut_ad(DATA_MBMAXLEN(col->mbminmaxlen) - >= DATA_MBMINLEN(col->mbminmaxlen)); + ut_ad(col->mbmaxlen >= col->mbminlen); memcpy(dest, data, len); break; diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index 25d68de6646..852e18153c2 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +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 @@ -169,18 +170,7 @@ store the charset-collation number; one byte is left unused, though */ #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 /* Maximum multi-byte character length in bytes, plus 1 */ -#define DATA_MBMAX 5 - -/* Pack mbminlen, mbmaxlen to mbminmaxlen. */ -#define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \ - ((mbmaxlen) * DATA_MBMAX + (mbminlen)) -/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint -because in GCC it returns a long. */ -#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \ - UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \ - 1)) -/* Get mbmaxlen from mbminmaxlen. */ -#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX)) +#define DATA_MBMAX 8 #ifndef UNIV_HOTBACKUP /*********************************************************************//** @@ -201,8 +191,10 @@ ulint dtype_get_at_most_n_mbchars( /*========================*/ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a multi-byte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a multi-byte character, in bytes */ ulint prefix_len, /*!< in: length of the requested prefix, in characters, multiplied by dtype_get_mbmaxlen(dtype) */ @@ -347,19 +339,6 @@ dtype_get_mbmaxlen( /*===============*/ const dtype_t* type); /*!< in: type */ /*********************************************************************//** -Sets the minimum and maximum length of a character, in bytes. */ -UNIV_INLINE -void -dtype_set_mbminmaxlen( -/*==================*/ - dtype_t* type, /*!< in/out: type */ - ulint mbminlen, /*!< in: minimum length of a char, - in bytes, or 0 if this is not - a character type */ - ulint mbmaxlen); /*!< in: maximum length of a char, - in bytes, or 0 if this is not - a character type */ -/*********************************************************************//** Gets the padding character code for the type. @return padding character code, or ULINT_UNDEFINED if no padding specified */ UNIV_INLINE @@ -379,7 +358,9 @@ dtype_get_fixed_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of a + ulint mbminlen, /*!< in: minimum length of a + multibyte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of a multibyte character, in bytes */ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */ #ifndef UNIV_HOTBACKUP @@ -393,8 +374,8 @@ dtype_get_min_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen); /*!< in: minimum and maximum length of a - multibyte character */ + ulint mbminlen, /*!< in: minimum length of a character */ + ulint mbmaxlen); /*!< in: maximum length of a character */ /***********************************************************************//** Returns the maximum size of a data type. Note: types in system tables may be incomplete and return incorrect information. @@ -497,11 +478,10 @@ struct dtype_struct{ the string, MySQL uses 1 or 2 bytes to store the string length) */ #ifndef UNIV_HOTBACKUP - unsigned mbminmaxlen:5; /*!< minimum and maximum length of a - character, in bytes; - DATA_MBMINMAXLEN(mbminlen,mbmaxlen); - mbminlen=DATA_MBMINLEN(mbminmaxlen); - mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */ + unsigned mbminlen:3; /*!< minimum length of a character, + in bytes */ + unsigned mbmaxlen:3; /*!< maximum length of a character, + in bytes */ #endif /* !UNIV_HOTBACKUP */ }; diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic index 515b6b249ef..2b4ae7bcf54 100644 --- a/storage/innobase/include/data0type.ic +++ b/storage/innobase/include/data0type.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -101,27 +102,6 @@ dtype_get_mblen( } /*********************************************************************//** -Sets the minimum and maximum length of a character, in bytes. */ -UNIV_INLINE -void -dtype_set_mbminmaxlen( -/*==================*/ - dtype_t* type, /*!< in/out: type */ - ulint mbminlen, /*!< in: minimum length of a char, - in bytes, or 0 if this is not - a character type */ - ulint mbmaxlen) /*!< in: maximum length of a char, - in bytes, or 0 if this is not - a character type */ -{ - ut_ad(mbminlen < DATA_MBMAX); - ut_ad(mbmaxlen < DATA_MBMAX); - ut_ad(mbminlen <= mbmaxlen); - - type->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); -} - -/*********************************************************************//** Compute the mbminlen and mbmaxlen members of a data type structure. */ UNIV_INLINE void @@ -133,7 +113,8 @@ dtype_set_mblen( ulint mbmaxlen; dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen); - dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen); + type->mbminlen = mbminlen; + type->mbmaxlen = mbmaxlen; ut_ad(dtype_validate(type)); } @@ -229,8 +210,7 @@ dtype_get_mbminlen( /*===============*/ const dtype_t* type) /*!< in: type */ { - ut_ad(type); - return(DATA_MBMINLEN(type->mbminmaxlen)); + return type->mbminlen; } /*********************************************************************//** Gets the maximum length of a character, in bytes. @@ -242,8 +222,7 @@ dtype_get_mbmaxlen( /*===============*/ const dtype_t* type) /*!< in: type */ { - ut_ad(type); - return(DATA_MBMAXLEN(type->mbminmaxlen)); + return type->mbmaxlen; } /*********************************************************************//** @@ -424,8 +403,10 @@ dtype_get_fixed_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multibyte character, in bytes */ + ulint mbminlen, /*!< in: minimum length of a + multibyte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of a + multibyte character, in bytes */ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { switch (mtype) { @@ -466,11 +447,10 @@ dtype_get_fixed_size_low( dtype_get_charset_coll(prtype), &i_mbminlen, &i_mbmaxlen); - ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen) - == mbminmaxlen); + ut_ad(i_mbminlen == mbminlen); + ut_ad(i_mbmaxlen == mbmaxlen); #endif /* UNIV_DEBUG */ - if (DATA_MBMINLEN(mbminmaxlen) - == DATA_MBMAXLEN(mbminmaxlen)) { + if (mbminlen == mbmaxlen) { return(len); } } @@ -502,8 +482,8 @@ dtype_get_min_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen) /*!< in: minimum and maximum length of a - multi-byte character */ + ulint mbminlen, /*!< in: minimum length of a character */ + ulint mbmaxlen) /*!< in: maximum length of a character */ { switch (mtype) { case DATA_SYS: @@ -533,9 +513,6 @@ dtype_get_min_size_low( if (prtype & DATA_BINARY_TYPE) { return(len); } else { - ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); - if (mbminlen == mbmaxlen) { return(len); } @@ -606,9 +583,9 @@ dtype_get_sql_null_size( { #ifndef UNIV_HOTBACKUP return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - type->mbminmaxlen, comp)); + type->mbminlen, type->mbmaxlen, comp)); #else /* !UNIV_HOTBACKUP */ return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - 0, 0)); + 0, 0, 0)); #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index bb1119b3c19..4d6fd4a9b1e 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -119,17 +120,6 @@ dict_col_get_mbmaxlen( /*==================*/ const dict_col_t* col); /*!< in: column */ /*********************************************************************//** -Sets the minimum and maximum number of bytes per character. */ -UNIV_INLINE -void -dict_col_set_mbminmaxlen( -/*=====================*/ - dict_col_t* col, /*!< in/out: column */ - ulint mbminlen, /*!< in: minimum multi-byte - character size, in bytes */ - ulint mbmaxlen); /*!< in: minimum multi-byte - character size, in bytes */ -/*********************************************************************//** Gets the column data type. */ UNIV_INLINE void diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index dbc3ce99ab0..c17826548e4 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -38,7 +39,7 @@ dict_col_get_mbminlen( /*==================*/ const dict_col_t* col) /*!< in: column */ { - return(DATA_MBMINLEN(col->mbminmaxlen)); + return col->mbminlen; } /*********************************************************************//** Gets the maximum number of bytes per character. @@ -49,25 +50,7 @@ dict_col_get_mbmaxlen( /*==================*/ const dict_col_t* col) /*!< in: column */ { - return(DATA_MBMAXLEN(col->mbminmaxlen)); -} -/*********************************************************************//** -Sets the minimum and maximum number of bytes per character. */ -UNIV_INLINE -void -dict_col_set_mbminmaxlen( -/*=====================*/ - dict_col_t* col, /*!< in/out: column */ - ulint mbminlen, /*!< in: minimum multi-byte - character size, in bytes */ - ulint mbmaxlen) /*!< in: minimum multi-byte - character size, in bytes */ -{ - ut_ad(mbminlen < DATA_MBMAX); - ut_ad(mbmaxlen < DATA_MBMAX); - ut_ad(mbminlen <= mbmaxlen); - - col->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); + return col->mbmaxlen; } /*********************************************************************//** Gets the column data type. */ @@ -83,7 +66,8 @@ dict_col_copy_type( type->mtype = col->mtype; type->prtype = col->prtype; type->len = col->len; - type->mbminmaxlen = col->mbminmaxlen; + type->mbminlen = col->mbminlen; + type->mbmaxlen = col->mbmaxlen; } #endif /* !UNIV_HOTBACKUP */ @@ -105,7 +89,8 @@ dict_col_type_assert_equal( ut_ad(col->prtype == type->prtype); ut_ad(col->len == type->len); # ifndef UNIV_HOTBACKUP - ut_ad(col->mbminmaxlen == type->mbminmaxlen); + ut_ad(col->mbminlen == type->mbminlen); + ut_ad(col->mbmaxlen == type->mbmaxlen); # endif /* !UNIV_HOTBACKUP */ return(TRUE); @@ -123,7 +108,7 @@ dict_col_get_min_size( const dict_col_t* col) /*!< in: column */ { return(dtype_get_min_size_low(col->mtype, col->prtype, col->len, - col->mbminmaxlen)); + col->mbminlen, col->mbmaxlen)); } /***********************************************************************//** Returns the maximum size of the column. @@ -148,7 +133,7 @@ dict_col_get_fixed_size( ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len, - col->mbminmaxlen, comp)); + col->mbminlen, col->mbmaxlen, comp)); } /***********************************************************************//** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 0bffc14f9dd..c9e65fd07c3 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -294,11 +295,10 @@ struct dict_col_struct{ the string, MySQL uses 1 or 2 bytes to store the string length) */ - unsigned mbminmaxlen:5; /*!< minimum and maximum length of a - character, in bytes; - DATA_MBMINMAXLEN(mbminlen,mbmaxlen); - mbminlen=DATA_MBMINLEN(mbminmaxlen); - mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */ + unsigned mbminlen:3; /*!< minimum length of a + character, in bytes */ + unsigned mbmaxlen:3; /*!< maximum length of a + character, in bytes */ /*----------------------*/ /* End of definitions copied from dtype_t */ /* @} */ diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic index 6b2e35d7387..b0b24526031 100644 --- a/storage/innobase/include/mem0mem.ic +++ b/storage/innobase/include/mem0mem.ic @@ -297,6 +297,7 @@ mem_heap_free_heap_top( #ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); + UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top); /* In the debug version erase block from top up */ mem_erase_buf(old_top, (byte*)block + block->len - old_top); @@ -304,10 +305,8 @@ mem_heap_free_heap_top( mutex_enter(&mem_hash_mutex); mem_current_allocated_memory -= (total_size - size); mutex_exit(&mem_hash_mutex); -#else /* UNIV_MEM_DEBUG */ - UNIV_MEM_ASSERT_W(old_top, (byte*)block + block->len - old_top); #endif /* UNIV_MEM_DEBUG */ - UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top); + UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top); /* If free == start, we may free the block if it is not the first one */ @@ -388,11 +387,11 @@ mem_heap_free_top( /* Subtract the free field of block */ mem_block_set_free(block, mem_block_get_free(block) - MEM_SPACE_NEEDED(n)); - UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n); #ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); + UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n); /* In the debug version check the consistency, and erase field */ mem_field_erase((byte*)block + mem_block_get_free(block), n); #endif @@ -404,11 +403,7 @@ mem_heap_free_top( == mem_block_get_start(block))) { mem_heap_block_free(heap, block); } else { - /* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a - subsequent invocation of mem_heap_free_top(). - Originally, this was UNIV_MEM_FREE(), to catch writes - to freed memory. */ - UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n); + UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n); } } diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index c81388391d7..8138552d095 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -923,7 +924,7 @@ rec_offs_set_n_alloc( { ut_ad(offsets); ut_ad(n_alloc > REC_OFFS_HEADER_SIZE); - UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets); + UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets); offsets[0] = n_alloc; } diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index a9d75955550..25287a57b35 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -162,7 +162,7 @@ command. Not tested on Windows. */ #define UNIV_COMPILE_TEST_FUNCS */ -#if defined(HAVE_valgrind)&& defined(HAVE_VALGRIND_MEMCHECK_H) +#if defined(HAVE_VALGRIND) && defined(HAVE_valgrind) # define UNIV_DEBUG_VALGRIND #endif /* HAVE_VALGRIND */ #if 0 @@ -497,12 +497,17 @@ typedef void* os_thread_ret_t; #include "ut0dbg.h" #include "ut0ut.h" #include "db0err.h" + +#include <my_valgrind.h> +/* define UNIV macros in terms of my_valgrind.h */ +# define UNIV_MEM_INVALID(addr, size) MEM_UNDEFINED(addr, size) +# define UNIV_MEM_FREE(addr, size) MEM_NOACCESS(addr, size) +# define UNIV_MEM_ALLOC(addr, size) UNIV_MEM_INVALID(addr, size) + +/* macros below cannot be defined in terms of my_valgrind.h */ #ifdef UNIV_DEBUG_VALGRIND # include <valgrind/memcheck.h> # define UNIV_MEM_VALID(addr, size) VALGRIND_MAKE_MEM_DEFINED(addr, size) -# define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) -# define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size) -# define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) # define UNIV_MEM_DESC(addr, size, b) VALGRIND_CREATE_BLOCK(addr, size, b) # define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b) # define UNIV_MEM_ASSERT_RW(addr, size) do { \ @@ -525,21 +530,10 @@ typedef void* os_thread_ret_t; } while (0) #else # define UNIV_MEM_VALID(addr, size) do {} while(0) -# define UNIV_MEM_INVALID(addr, size) do {} while(0) -# define UNIV_MEM_FREE(addr, size) do {} while(0) -# define UNIV_MEM_ALLOC(addr, size) do {} while(0) # define UNIV_MEM_DESC(addr, size, b) do {} while(0) # define UNIV_MEM_UNDESC(b) do {} while(0) # define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0) # define UNIV_MEM_ASSERT_W(addr, size) do {} while(0) #endif -#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \ - UNIV_MEM_ASSERT_W(addr, size); \ - UNIV_MEM_FREE(addr, size); \ -} while (0) -#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \ - UNIV_MEM_ASSERT_W(addr, size); \ - UNIV_MEM_ALLOC(addr, size); \ -} while (0) #endif diff --git a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c index 159e9fc6b3c..924231470aa 100644 --- a/storage/innobase/mem/mem0mem.c +++ b/storage/innobase/mem/mem0mem.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. +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 @@ -403,6 +404,11 @@ mem_heap_create_block( heap->total_size += len; } + /* Poison all available memory. Individual chunks will be unpoisoned on + every mem_heap_alloc() call. */ + compile_time_assert(MEM_BLOCK_HEADER_SIZE >= sizeof *block); + UNIV_MEM_FREE(block + 1, len - sizeof *block); + ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len); return(block); @@ -502,13 +508,13 @@ mem_heap_block_free( #ifndef UNIV_HOTBACKUP if (!srv_use_sys_malloc) { #ifdef UNIV_MEM_DEBUG + UNIV_MEM_ALLOC(block, len); /* In the debug version we set the memory to a random combination of hex 0xDE and 0xAD. */ mem_erase_buf((byte*)block, len); -#else /* UNIV_MEM_DEBUG */ - UNIV_MEM_ASSERT_AND_FREE(block, len); #endif /* UNIV_MEM_DEBUG */ + UNIV_MEM_FREE(block, len); } if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) { @@ -522,13 +528,13 @@ mem_heap_block_free( } #else /* !UNIV_HOTBACKUP */ #ifdef UNIV_MEM_DEBUG + UNIV_MEM_ALLOC(block, len); /* In the debug version we set the memory to a random combination of hex 0xDE and 0xAD. */ mem_erase_buf((byte*)block, len); -#else /* UNIV_MEM_DEBUG */ - UNIV_MEM_ASSERT_AND_FREE(block, len); #endif /* UNIV_MEM_DEBUG */ + UNIV_MEM_FREE(block, len); ut_free(block); #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c index 84f04beb61d..358716d796b 100644 --- a/storage/innobase/rem/rem0rec.c +++ b/storage/innobase/rem/rem0rec.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -848,13 +849,10 @@ rec_get_converted_size_comp_prefix_low( if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); - ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!col->mbmaxlen || len >= col->mbminlen + * (fixed_len / col->mbmaxlen)); /* dict_index_add_col() should guarantee this */ ut_ad(!field->prefix_len @@ -1240,14 +1238,10 @@ rec_convert_dtuple_to_rec_comp( it is 128 or more, or when the field is stored externally. */ if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN( - ifield->col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN( - ifield->col->mbminmaxlen); - ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!ifield->col->mbmaxlen + || len >= ifield->col->mbminlen + * (fixed_len / ifield->col->mbmaxlen)); ut_ad(!dfield_is_ext(field)); #endif /* UNIV_DEBUG */ } else if (dfield_is_ext(field)) { diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 65e7676fd77..28cfcc582f3 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -527,7 +528,8 @@ row_ins_cascade_calc_update_vec( if (!dfield_is_null(&ufield->new_val) && dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, + col->mbminlen, col->mbmaxlen, col->len, ufield_len, dfield_get_data(&ufield->new_val)) @@ -2343,7 +2345,7 @@ row_ins_index_entry_set_vals( = dict_field_get_col(ind_field); len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ind_field->prefix_len, len, dfield_get_data(row_field)); diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c index a393254d145..22ba78a1ef3 100644 --- a/storage/innobase/row/row0merge.c +++ b/storage/innobase/row/row0merge.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -339,7 +340,7 @@ row_merge_buf_add( if (ifield->prefix_len) { len = dtype_get_at_most_n_mbchars( col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, ifield->prefix_len, len, dfield_get_data(field)); dfield_set_len(field, len); @@ -349,8 +350,7 @@ row_merge_buf_add( fixed_len = ifield->fixed_len; if (fixed_len && !dict_table_is_comp(index->table) - && DATA_MBMINLEN(col->mbminmaxlen) - != DATA_MBMAXLEN(col->mbminmaxlen)) { + && col->mbminlen != col->mbmaxlen) { /* CHAR in ROW_FORMAT=REDUNDANT is always fixed-length, but in the temporary file it is variable-length for variable-length character @@ -360,14 +360,11 @@ row_merge_buf_add( if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); - /* len should be between size calcualted base on mbmaxlen and mbminlen */ ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!col->mbmaxlen || len >= col->mbminlen + * (fixed_len / col->mbmaxlen)); ut_ad(!dfield_is_ext(field)); #endif /* UNIV_DEBUG */ diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c index c15e2bbf739..bacdcbfaac0 100644 --- a/storage/innobase/row/row0row.c +++ b/storage/innobase/row/row0row.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -164,7 +165,7 @@ row_build_index_entry( /* If a column prefix index, take only the prefix. */ if (ind_field->prefix_len) { len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ind_field->prefix_len, len, dfield_get_data(dfield)); dfield_set_len(dfield, len); @@ -546,7 +547,8 @@ row_build_row_ref( dfield_set_len(dfield, dtype_get_at_most_n_mbchars( dtype->prtype, - dtype->mbminmaxlen, + dtype->mbminlen, + dtype->mbmaxlen, clust_col_prefix_len, len, (char*) field)); } @@ -660,7 +662,8 @@ notfound: dfield_set_len(dfield, dtype_get_at_most_n_mbchars( dtype->prtype, - dtype->mbminmaxlen, + dtype->mbminlen, + dtype->mbmaxlen, clust_col_prefix_len, len, (char*) field)); } diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index d697fef3f52..9d163158b10 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2,6 +2,7 @@ Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2018, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -90,8 +91,10 @@ row_sel_sec_rec_is_for_blob( /*========================*/ ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a character, in bytes */ const byte* clust_field, /*!< in: the locally stored part of the clustered index column, including the BLOB pointer; the clustered @@ -141,7 +144,7 @@ row_sel_sec_rec_is_for_blob( return(FALSE); } - len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen, + len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen, prefix_len, len, (const char*) buf); return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len)); @@ -225,14 +228,14 @@ row_sel_sec_rec_is_for_clust_rec( } len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ifield->prefix_len, len, (char*) clust_field); if (rec_offs_nth_extern(clust_offs, clust_pos) && len < sec_len) { if (!row_sel_sec_rec_is_for_blob( col->mtype, col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, clust_field, clust_len, sec_field, sec_len, ifield->prefix_len, @@ -4273,6 +4276,7 @@ no_gap_lock: prebuilt->new_rec_locks = 1; } err = DB_SUCCESS; + /* fall through */ case DB_SUCCESS: break; case DB_LOCK_WAIT: diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index 74b0aad144c..6c3f07d6aff 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -1159,7 +1160,7 @@ row_upd_index_replace_new_col_val( } len = dtype_get_at_most_n_mbchars(col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, field->prefix_len, len, (const char*) data); diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c index c47da42b555..35a5040f09d 100644 --- a/storage/maria/ma_dynrec.c +++ b/storage/maria/ma_dynrec.c @@ -276,7 +276,7 @@ my_bool _ma_update_blob_record(MARIA_HA *info, MARIA_RECORD_POS pos, { uchar *rec_buff; int error; - ulong reclength,extra; + ulong reclength,reclength2,extra; extra= (ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER)+MARIA_SPLIT_LENGTH+ MARIA_DYN_DELETE_BLOCK_HEADER); @@ -289,17 +289,17 @@ my_bool _ma_update_blob_record(MARIA_HA *info, MARIA_RECORD_POS pos, return 1; } #endif - if (!(rec_buff=(uchar*) my_safe_alloca(reclength, - MARIA_MAX_RECORD_ON_STACK))) + if (!(rec_buff=(uchar*) my_safe_alloca(reclength, MARIA_MAX_RECORD_ON_STACK))) { my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */ return(1); } - reclength= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER), + reclength2= _ma_rec_pack(info,rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER), record); + DBUG_ASSERT(reclength2 <= reclength); error=update_dynamic_record(info,pos, rec_buff+ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER), - reclength); + reclength2); my_safe_afree(rec_buff, reclength, MARIA_MAX_RECORD_ON_STACK); return(error != 0); } diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c index 56329a18d7d..779128830dc 100644 --- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c @@ -234,7 +234,7 @@ int main(int argc __attribute__((unused)), char *argv[]) 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }; - uchar *long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2); + uchar *long_buffer; char **default_argv; PAGECACHE pagecache; LSN lsn, lsn_base, first_lsn; @@ -255,6 +255,7 @@ int main(int argc __attribute__((unused)), char *argv[]) } #endif + long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2); load_defaults("my", load_default_groups, &argc, &argv); get_options(&argc, &argv); default_argv= argv; @@ -758,6 +759,7 @@ err: if (maria_log_remove(maria_data_root)) exit(1); + free(long_buffer); return (test(exit_status())); } diff --git a/storage/maria/unittest/ma_test_loghandler_nologs-t.c b/storage/maria/unittest/ma_test_loghandler_nologs-t.c index 24c93e428e1..06529066305 100644 --- a/storage/maria/unittest/ma_test_loghandler_nologs-t.c +++ b/storage/maria/unittest/ma_test_loghandler_nologs-t.c @@ -191,6 +191,7 @@ int main(int argc __attribute__((unused)), char *argv[]) if (maria_log_remove(maria_data_root)) exit(1); + free(long_buffer); exit(0); } diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index c43cbc210a2..f01d06e41e5 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -1,6 +1,6 @@ # ft-index only supports x86-64 and cmake-2.8.9+ IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND - NOT CMAKE_VERSION VERSION_LESS "2.8.9") + NOT CMAKE_VERSION VERSION_LESS "2.8.9" AND HAVE_DLOPEN) CHECK_CXX_SOURCE_COMPILES( " struct a {int b; int c; }; diff --git a/storage/xtradb/buf/buf0buddy.c b/storage/xtradb/buf/buf0buddy.c index 493d0d2d41c..9e37ad2a7cb 100644 --- a/storage/xtradb/buf/buf0buddy.c +++ b/storage/xtradb/buf/buf0buddy.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -500,7 +501,7 @@ buf_buddy_free_low( buf_pool->buddy_stat[i].used--; recombine: - UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i); + UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i); ((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE; if (i == BUF_BUDDY_SIZES) { diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c index 8b74fd10c3d..9c0b171d3f6 100644 --- a/storage/xtradb/buf/buf0lru.c +++ b/storage/xtradb/buf/buf0lru.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -2146,7 +2147,7 @@ buf_LRU_block_free_non_file_page( ut_d(block->page.in_free_list = TRUE); mutex_exit(&buf_pool->free_list_mutex); - UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE); + UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE); } /******************************************************************//** diff --git a/storage/xtradb/data/data0type.c b/storage/xtradb/data/data0type.c index 9f855d58adf..c278cc8821e 100644 --- a/storage/xtradb/data/data0type.c +++ b/storage/xtradb/data/data0type.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +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 @@ -49,8 +50,10 @@ ulint dtype_get_at_most_n_mbchars( /*========================*/ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a multi-byte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a multi-byte character, in bytes */ ulint prefix_len, /*!< in: length of the requested prefix, in characters, multiplied by dtype_get_mbmaxlen(dtype) */ @@ -58,9 +61,6 @@ dtype_get_at_most_n_mbchars( const char* str) /*!< in: the string whose prefix length is being determined */ { - ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); - ut_a(data_len != UNIV_SQL_NULL); ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen)); diff --git a/storage/xtradb/dict/dict0mem.c b/storage/xtradb/dict/dict0mem.c index 18917a30ff6..253d766d5b3 100644 --- a/storage/xtradb/dict/dict0mem.c +++ b/storage/xtradb/dict/dict0mem.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +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 @@ -254,7 +255,8 @@ dict_mem_fill_column_struct( column->len = (unsigned int) col_len; #ifndef UNIV_HOTBACKUP dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen); - dict_col_set_mbminmaxlen(column, mbminlen, mbmaxlen); + column->mbminlen = mbminlen; + column->mbmaxlen = mbmaxlen; #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 04fbcd1a9fd..65c5ce69713 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -6268,8 +6268,8 @@ build_template_field( } templ->charset = dtype_get_charset_coll(col->prtype); - templ->mbminlen = DATA_MBMINLEN(col->mbminmaxlen); - templ->mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); + templ->mbminlen = col->mbminlen; + templ->mbmaxlen = col->mbmaxlen; templ->is_unsigned = col->prtype & DATA_UNSIGNED; if (!dict_index_is_clust(index) @@ -13576,6 +13576,17 @@ ha_innobase::check_if_incompatible_data( DBUG_RETURN(COMPATIBLE_DATA_YES); } +UNIV_INTERN +uint +ha_innobase::alter_table_flags(uint flags) +{ + uint mask = 0; + if (prebuilt->table->n_mysql_handles_opened > 1) { + mask = HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE; + } + return innobase_alter_table_flags(flags) & ~mask; +} + /************************************************************//** Validate the file format name and return its corresponding id. @return valid file format id */ diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 69a28905f22..f087a2d6ea0 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -234,6 +234,7 @@ class ha_innobase: public handler /** @} */ bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); + uint alter_table_flags(uint flags); bool check_if_supported_virtual_columns(void) { return TRUE; } private: diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index bdb4fa0c1b6..e2e845ab862 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -104,8 +105,7 @@ innobase_col_to_mysql( #ifdef UNIV_DEBUG case DATA_MYSQL: ut_ad(flen >= len); - ut_ad(DATA_MBMAXLEN(col->mbminmaxlen) - >= DATA_MBMINLEN(col->mbminmaxlen)); + ut_ad(col->mbmaxlen >= col->mbminlen); memcpy(dest, data, len); break; diff --git a/storage/xtradb/include/data0type.h b/storage/xtradb/include/data0type.h index 25d68de6646..852e18153c2 100644 --- a/storage/xtradb/include/data0type.h +++ b/storage/xtradb/include/data0type.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +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 @@ -169,18 +170,7 @@ store the charset-collation number; one byte is left unused, though */ #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 /* Maximum multi-byte character length in bytes, plus 1 */ -#define DATA_MBMAX 5 - -/* Pack mbminlen, mbmaxlen to mbminmaxlen. */ -#define DATA_MBMINMAXLEN(mbminlen, mbmaxlen) \ - ((mbmaxlen) * DATA_MBMAX + (mbminlen)) -/* Get mbminlen from mbminmaxlen. Cast the result of UNIV_EXPECT to ulint -because in GCC it returns a long. */ -#define DATA_MBMINLEN(mbminmaxlen) ((ulint) \ - UNIV_EXPECT(((mbminmaxlen) % DATA_MBMAX), \ - 1)) -/* Get mbmaxlen from mbminmaxlen. */ -#define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX)) +#define DATA_MBMAX 8 #ifndef UNIV_HOTBACKUP /*********************************************************************//** @@ -201,8 +191,10 @@ ulint dtype_get_at_most_n_mbchars( /*========================*/ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a multi-byte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a multi-byte character, in bytes */ ulint prefix_len, /*!< in: length of the requested prefix, in characters, multiplied by dtype_get_mbmaxlen(dtype) */ @@ -347,19 +339,6 @@ dtype_get_mbmaxlen( /*===============*/ const dtype_t* type); /*!< in: type */ /*********************************************************************//** -Sets the minimum and maximum length of a character, in bytes. */ -UNIV_INLINE -void -dtype_set_mbminmaxlen( -/*==================*/ - dtype_t* type, /*!< in/out: type */ - ulint mbminlen, /*!< in: minimum length of a char, - in bytes, or 0 if this is not - a character type */ - ulint mbmaxlen); /*!< in: maximum length of a char, - in bytes, or 0 if this is not - a character type */ -/*********************************************************************//** Gets the padding character code for the type. @return padding character code, or ULINT_UNDEFINED if no padding specified */ UNIV_INLINE @@ -379,7 +358,9 @@ dtype_get_fixed_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of a + ulint mbminlen, /*!< in: minimum length of a + multibyte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of a multibyte character, in bytes */ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */ #ifndef UNIV_HOTBACKUP @@ -393,8 +374,8 @@ dtype_get_min_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen); /*!< in: minimum and maximum length of a - multibyte character */ + ulint mbminlen, /*!< in: minimum length of a character */ + ulint mbmaxlen); /*!< in: maximum length of a character */ /***********************************************************************//** Returns the maximum size of a data type. Note: types in system tables may be incomplete and return incorrect information. @@ -497,11 +478,10 @@ struct dtype_struct{ the string, MySQL uses 1 or 2 bytes to store the string length) */ #ifndef UNIV_HOTBACKUP - unsigned mbminmaxlen:5; /*!< minimum and maximum length of a - character, in bytes; - DATA_MBMINMAXLEN(mbminlen,mbmaxlen); - mbminlen=DATA_MBMINLEN(mbminmaxlen); - mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */ + unsigned mbminlen:3; /*!< minimum length of a character, + in bytes */ + unsigned mbmaxlen:3; /*!< maximum length of a character, + in bytes */ #endif /* !UNIV_HOTBACKUP */ }; diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic index 5848e5d6548..0688b162387 100644 --- a/storage/xtradb/include/data0type.ic +++ b/storage/xtradb/include/data0type.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -101,27 +102,6 @@ dtype_get_mblen( } /*********************************************************************//** -Sets the minimum and maximum length of a character, in bytes. */ -UNIV_INLINE -void -dtype_set_mbminmaxlen( -/*==================*/ - dtype_t* type, /*!< in/out: type */ - ulint mbminlen, /*!< in: minimum length of a char, - in bytes, or 0 if this is not - a character type */ - ulint mbmaxlen) /*!< in: maximum length of a char, - in bytes, or 0 if this is not - a character type */ -{ - ut_ad(mbminlen < DATA_MBMAX); - ut_ad(mbmaxlen < DATA_MBMAX); - ut_ad(mbminlen <= mbmaxlen); - - type->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); -} - -/*********************************************************************//** Compute the mbminlen and mbmaxlen members of a data type structure. */ UNIV_INLINE void @@ -133,7 +113,8 @@ dtype_set_mblen( ulint mbmaxlen; dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen); - dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen); + type->mbminlen = mbminlen; + type->mbmaxlen = mbmaxlen; ut_ad(dtype_validate(type)); } @@ -229,8 +210,7 @@ dtype_get_mbminlen( /*===============*/ const dtype_t* type) /*!< in: type */ { - ut_ad(type); - return(DATA_MBMINLEN(type->mbminmaxlen)); + return type->mbminlen; } /*********************************************************************//** Gets the maximum length of a character, in bytes. @@ -242,8 +222,7 @@ dtype_get_mbmaxlen( /*===============*/ const dtype_t* type) /*!< in: type */ { - ut_ad(type); - return(DATA_MBMAXLEN(type->mbminmaxlen)); + return type->mbmaxlen; } /*********************************************************************//** @@ -424,8 +403,10 @@ dtype_get_fixed_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multibyte character, in bytes */ + ulint mbminlen, /*!< in: minimum length of a + multibyte character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of a + multibyte character, in bytes */ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { switch (mtype) { @@ -466,11 +447,10 @@ dtype_get_fixed_size_low( dtype_get_charset_coll(prtype), &i_mbminlen, &i_mbmaxlen); - ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen) - == mbminmaxlen); + ut_ad(i_mbminlen == mbminlen); + ut_ad(i_mbmaxlen == mbmaxlen); #endif /* UNIV_DEBUG */ - if (DATA_MBMINLEN(mbminmaxlen) - == DATA_MBMAXLEN(mbminmaxlen)) { + if (mbminlen == mbmaxlen) { return(len); } } @@ -502,8 +482,8 @@ dtype_get_min_size_low( ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ ulint len, /*!< in: length */ - ulint mbminmaxlen) /*!< in: minimum and maximum length of a - multi-byte character */ + ulint mbminlen, /*!< in: minimum length of a character */ + ulint mbmaxlen) /*!< in: maximum length of a character */ { switch (mtype) { case DATA_SYS: @@ -533,9 +513,6 @@ dtype_get_min_size_low( if (prtype & DATA_BINARY_TYPE) { return(len); } else { - ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); - if (mbminlen == mbmaxlen) { return(len); } @@ -606,9 +583,9 @@ dtype_get_sql_null_size( { #ifndef UNIV_HOTBACKUP return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - type->mbminmaxlen, comp)); + type->mbminlen, type->mbmaxlen, comp)); #else /* !UNIV_HOTBACKUP */ return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, - 0, 0)); + 0, 0, 0)); #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index d8c8e39b1bf..9f39a0b3e05 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -119,17 +120,6 @@ dict_col_get_mbmaxlen( /*==================*/ const dict_col_t* col); /*!< in: column */ /*********************************************************************//** -Sets the minimum and maximum number of bytes per character. */ -UNIV_INLINE -void -dict_col_set_mbminmaxlen( -/*=====================*/ - dict_col_t* col, /*!< in/out: column */ - ulint mbminlen, /*!< in: minimum multi-byte - character size, in bytes */ - ulint mbmaxlen); /*!< in: minimum multi-byte - character size, in bytes */ -/*********************************************************************//** Gets the column data type. */ UNIV_INLINE void diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic index 3410c945a80..3631dc38d81 100644 --- a/storage/xtradb/include/dict0dict.ic +++ b/storage/xtradb/include/dict0dict.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -38,7 +39,7 @@ dict_col_get_mbminlen( /*==================*/ const dict_col_t* col) /*!< in: column */ { - return(DATA_MBMINLEN(col->mbminmaxlen)); + return col->mbminlen; } /*********************************************************************//** Gets the maximum number of bytes per character. @@ -49,25 +50,7 @@ dict_col_get_mbmaxlen( /*==================*/ const dict_col_t* col) /*!< in: column */ { - return(DATA_MBMAXLEN(col->mbminmaxlen)); -} -/*********************************************************************//** -Sets the minimum and maximum number of bytes per character. */ -UNIV_INLINE -void -dict_col_set_mbminmaxlen( -/*=====================*/ - dict_col_t* col, /*!< in/out: column */ - ulint mbminlen, /*!< in: minimum multi-byte - character size, in bytes */ - ulint mbmaxlen) /*!< in: minimum multi-byte - character size, in bytes */ -{ - ut_ad(mbminlen < DATA_MBMAX); - ut_ad(mbmaxlen < DATA_MBMAX); - ut_ad(mbminlen <= mbmaxlen); - - col->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); + return col->mbmaxlen; } /*********************************************************************//** Gets the column data type. */ @@ -83,7 +66,8 @@ dict_col_copy_type( type->mtype = col->mtype; type->prtype = col->prtype; type->len = col->len; - type->mbminmaxlen = col->mbminmaxlen; + type->mbminlen = col->mbminlen; + type->mbmaxlen = col->mbmaxlen; } #endif /* !UNIV_HOTBACKUP */ @@ -105,7 +89,8 @@ dict_col_type_assert_equal( ut_ad(col->prtype == type->prtype); ut_ad(col->len == type->len); # ifndef UNIV_HOTBACKUP - ut_ad(col->mbminmaxlen == type->mbminmaxlen); + ut_ad(col->mbminlen == type->mbminlen); + ut_ad(col->mbmaxlen == type->mbmaxlen); # endif /* !UNIV_HOTBACKUP */ return(TRUE); @@ -123,7 +108,7 @@ dict_col_get_min_size( const dict_col_t* col) /*!< in: column */ { return(dtype_get_min_size_low(col->mtype, col->prtype, col->len, - col->mbminmaxlen)); + col->mbminlen, col->mbmaxlen)); } /***********************************************************************//** Returns the maximum size of the column. @@ -148,7 +133,7 @@ dict_col_get_fixed_size( ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len, - col->mbminmaxlen, comp)); + col->mbminlen, col->mbmaxlen, comp)); } /***********************************************************************//** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h index 81d5923a5fb..2a1e0a455b7 100644 --- a/storage/xtradb/include/dict0mem.h +++ b/storage/xtradb/include/dict0mem.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -294,11 +295,10 @@ struct dict_col_struct{ the string, MySQL uses 1 or 2 bytes to store the string length) */ - unsigned mbminmaxlen:5; /*!< minimum and maximum length of a - character, in bytes; - DATA_MBMINMAXLEN(mbminlen,mbmaxlen); - mbminlen=DATA_MBMINLEN(mbminmaxlen); - mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */ + unsigned mbminlen:3; /*!< minimum length of a + character, in bytes */ + unsigned mbmaxlen:3; /*!< maximum length of a + character, in bytes */ /*----------------------*/ /* End of definitions copied from dtype_t */ /* @} */ diff --git a/storage/xtradb/include/mem0mem.ic b/storage/xtradb/include/mem0mem.ic index 6b2e35d7387..b0b24526031 100644 --- a/storage/xtradb/include/mem0mem.ic +++ b/storage/xtradb/include/mem0mem.ic @@ -297,6 +297,7 @@ mem_heap_free_heap_top( #ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); + UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top); /* In the debug version erase block from top up */ mem_erase_buf(old_top, (byte*)block + block->len - old_top); @@ -304,10 +305,8 @@ mem_heap_free_heap_top( mutex_enter(&mem_hash_mutex); mem_current_allocated_memory -= (total_size - size); mutex_exit(&mem_hash_mutex); -#else /* UNIV_MEM_DEBUG */ - UNIV_MEM_ASSERT_W(old_top, (byte*)block + block->len - old_top); #endif /* UNIV_MEM_DEBUG */ - UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top); + UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top); /* If free == start, we may free the block if it is not the first one */ @@ -388,11 +387,11 @@ mem_heap_free_top( /* Subtract the free field of block */ mem_block_set_free(block, mem_block_get_free(block) - MEM_SPACE_NEEDED(n)); - UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n); #ifdef UNIV_MEM_DEBUG ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); + UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n); /* In the debug version check the consistency, and erase field */ mem_field_erase((byte*)block + mem_block_get_free(block), n); #endif @@ -404,11 +403,7 @@ mem_heap_free_top( == mem_block_get_start(block))) { mem_heap_block_free(heap, block); } else { - /* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a - subsequent invocation of mem_heap_free_top(). - Originally, this was UNIV_MEM_FREE(), to catch writes - to freed memory. */ - UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n); + UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n); } } diff --git a/storage/xtradb/include/rem0rec.ic b/storage/xtradb/include/rem0rec.ic index b99d076b500..b727523e1aa 100644 --- a/storage/xtradb/include/rem0rec.ic +++ b/storage/xtradb/include/rem0rec.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -923,7 +924,7 @@ rec_offs_set_n_alloc( { ut_ad(offsets); ut_ad(n_alloc > REC_OFFS_HEADER_SIZE); - UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets); + UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets); offsets[0] = n_alloc; } diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 6cc424ad0ba..ca51dc8de84 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -64,10 +64,10 @@ component, i.e. we show M.N.P as M.N */ (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 38.10 +#define PERCONA_INNODB_VERSION 38.11 #endif -#define INNODB_VERSION_STR "5.5.58-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION) +#define INNODB_VERSION_STR "5.5.59-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION) #define REFMAN "http://dev.mysql.com/doc/refman/" \ IB_TO_STR(MYSQL_MAJOR_VERSION) "." \ @@ -170,7 +170,7 @@ command. Not tested on Windows. */ #define UNIV_COMPILE_TEST_FUNCS */ -#if defined(HAVE_valgrind)&& defined(HAVE_VALGRIND_MEMCHECK_H) +#if defined(HAVE_VALGRIND) && defined(HAVE_valgrind) # define UNIV_DEBUG_VALGRIND #endif #if 0 @@ -511,12 +511,17 @@ typedef void* os_thread_ret_t; #include "ut0dbg.h" #include "ut0ut.h" #include "db0err.h" + +#include <my_valgrind.h> +/* define UNIV macros in terms of my_valgrind.h */ +# define UNIV_MEM_INVALID(addr, size) MEM_UNDEFINED(addr, size) +# define UNIV_MEM_FREE(addr, size) MEM_NOACCESS(addr, size) +# define UNIV_MEM_ALLOC(addr, size) UNIV_MEM_INVALID(addr, size) + +/* macros below cannot be defined in terms of my_valgrind.h */ #ifdef UNIV_DEBUG_VALGRIND # include <valgrind/memcheck.h> # define UNIV_MEM_VALID(addr, size) VALGRIND_MAKE_MEM_DEFINED(addr, size) -# define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) -# define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size) -# define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) # define UNIV_MEM_DESC(addr, size, b) VALGRIND_CREATE_BLOCK(addr, size, b) # define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b) # define UNIV_MEM_ASSERT_RW(addr, size) do { \ @@ -539,22 +544,11 @@ typedef void* os_thread_ret_t; } while (0) #else # define UNIV_MEM_VALID(addr, size) do {} while(0) -# define UNIV_MEM_INVALID(addr, size) do {} while(0) -# define UNIV_MEM_FREE(addr, size) do {} while(0) -# define UNIV_MEM_ALLOC(addr, size) do {} while(0) # define UNIV_MEM_DESC(addr, size, b) do {} while(0) # define UNIV_MEM_UNDESC(b) do {} while(0) # define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0) # define UNIV_MEM_ASSERT_W(addr, size) do {} while(0) #endif -#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \ - UNIV_MEM_ASSERT_W(addr, size); \ - UNIV_MEM_FREE(addr, size); \ -} while (0) -#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \ - UNIV_MEM_ASSERT_W(addr, size); \ - UNIV_MEM_ALLOC(addr, size); \ -} while (0) extern ulint srv_page_size_shift; extern ulint srv_page_size; diff --git a/storage/xtradb/mem/mem0mem.c b/storage/xtradb/mem/mem0mem.c index 159e9fc6b3c..924231470aa 100644 --- a/storage/xtradb/mem/mem0mem.c +++ b/storage/xtradb/mem/mem0mem.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. +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 @@ -403,6 +404,11 @@ mem_heap_create_block( heap->total_size += len; } + /* Poison all available memory. Individual chunks will be unpoisoned on + every mem_heap_alloc() call. */ + compile_time_assert(MEM_BLOCK_HEADER_SIZE >= sizeof *block); + UNIV_MEM_FREE(block + 1, len - sizeof *block); + ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len); return(block); @@ -502,13 +508,13 @@ mem_heap_block_free( #ifndef UNIV_HOTBACKUP if (!srv_use_sys_malloc) { #ifdef UNIV_MEM_DEBUG + UNIV_MEM_ALLOC(block, len); /* In the debug version we set the memory to a random combination of hex 0xDE and 0xAD. */ mem_erase_buf((byte*)block, len); -#else /* UNIV_MEM_DEBUG */ - UNIV_MEM_ASSERT_AND_FREE(block, len); #endif /* UNIV_MEM_DEBUG */ + UNIV_MEM_FREE(block, len); } if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) { @@ -522,13 +528,13 @@ mem_heap_block_free( } #else /* !UNIV_HOTBACKUP */ #ifdef UNIV_MEM_DEBUG + UNIV_MEM_ALLOC(block, len); /* In the debug version we set the memory to a random combination of hex 0xDE and 0xAD. */ mem_erase_buf((byte*)block, len); -#else /* UNIV_MEM_DEBUG */ - UNIV_MEM_ASSERT_AND_FREE(block, len); #endif /* UNIV_MEM_DEBUG */ + UNIV_MEM_FREE(block, len); ut_free(block); #endif /* !UNIV_HOTBACKUP */ } diff --git a/storage/xtradb/rem/rem0rec.c b/storage/xtradb/rem/rem0rec.c index 232033a3f23..cf332610445 100644 --- a/storage/xtradb/rem/rem0rec.c +++ b/storage/xtradb/rem/rem0rec.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -848,13 +849,10 @@ rec_get_converted_size_comp_prefix_low( if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); - ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!col->mbmaxlen || len >= col->mbminlen + * (fixed_len / col->mbmaxlen)); /* dict_index_add_col() should guarantee this */ ut_ad(!field->prefix_len @@ -1240,14 +1238,10 @@ rec_convert_dtuple_to_rec_comp( it is 128 or more, or when the field is stored externally. */ if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN( - ifield->col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN( - ifield->col->mbminmaxlen); - ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!ifield->col->mbmaxlen + || len >= ifield->col->mbminlen + * (fixed_len / ifield->col->mbmaxlen)); ut_ad(!dfield_is_ext(field)); #endif /* UNIV_DEBUG */ } else if (dfield_is_ext(field)) { diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c index 7d2b67d37ba..6187a1149f8 100644 --- a/storage/xtradb/row/row0ins.c +++ b/storage/xtradb/row/row0ins.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -528,7 +529,8 @@ row_ins_cascade_calc_update_vec( if (!dfield_is_null(&ufield->new_val) && dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, + col->mbminlen, col->mbmaxlen, col->len, ufield_len, dfield_get_data(&ufield->new_val)) @@ -2385,7 +2387,7 @@ row_ins_index_entry_set_vals( = dict_field_get_col(ind_field); len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ind_field->prefix_len, len, dfield_get_data(row_field)); diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c index 00a7decdce6..0d0b0e402d3 100644 --- a/storage/xtradb/row/row0merge.c +++ b/storage/xtradb/row/row0merge.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -350,7 +351,7 @@ row_merge_buf_add( if (ifield->prefix_len) { len = dtype_get_at_most_n_mbchars( col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, ifield->prefix_len, len, dfield_get_data(field)); dfield_set_len(field, len); @@ -360,8 +361,7 @@ row_merge_buf_add( fixed_len = ifield->fixed_len; if (fixed_len && !dict_table_is_comp(index->table) - && DATA_MBMINLEN(col->mbminmaxlen) - != DATA_MBMAXLEN(col->mbminmaxlen)) { + && col->mbminlen != col->mbmaxlen) { /* CHAR in ROW_FORMAT=REDUNDANT is always fixed-length, but in the temporary file it is variable-length for variable-length character @@ -371,14 +371,11 @@ row_merge_buf_add( if (fixed_len) { #ifdef UNIV_DEBUG - ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); - ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); - /* len should be between size calcualted base on mbmaxlen and mbminlen */ ut_ad(len <= fixed_len); - ut_ad(!mbmaxlen || len >= mbminlen - * (fixed_len / mbmaxlen)); + ut_ad(!col->mbmaxlen || len >= col->mbminlen + * (fixed_len / col->mbmaxlen)); ut_ad(!dfield_is_ext(field)); #endif /* UNIV_DEBUG */ diff --git a/storage/xtradb/row/row0row.c b/storage/xtradb/row/row0row.c index 2c33bdc4b15..0c1c1da3b2b 100644 --- a/storage/xtradb/row/row0row.c +++ b/storage/xtradb/row/row0row.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -164,7 +165,7 @@ row_build_index_entry( /* If a column prefix index, take only the prefix. */ if (ind_field->prefix_len) { len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ind_field->prefix_len, len, dfield_get_data(dfield)); dfield_set_len(dfield, len); @@ -562,7 +563,8 @@ row_build_row_ref( dfield_set_len(dfield, dtype_get_at_most_n_mbchars( dtype->prtype, - dtype->mbminmaxlen, + dtype->mbminlen, + dtype->mbmaxlen, clust_col_prefix_len, len, (char*) field)); } @@ -676,7 +678,8 @@ notfound: dfield_set_len(dfield, dtype_get_at_most_n_mbchars( dtype->prtype, - dtype->mbminmaxlen, + dtype->mbminlen, + dtype->mbmaxlen, clust_col_prefix_len, len, (char*) field)); } diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index 69b364600b2..67a9dfcae90 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -2,6 +2,7 @@ Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. +Copyright (c) 2018, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -92,8 +93,10 @@ row_sel_sec_rec_is_for_blob( /*========================*/ ulint mtype, /*!< in: main type */ ulint prtype, /*!< in: precise type */ - ulint mbminmaxlen, /*!< in: minimum and maximum length of - a multi-byte character */ + ulint mbminlen, /*!< in: minimum length of + a character, in bytes */ + ulint mbmaxlen, /*!< in: maximum length of + a character, in bytes */ const byte* clust_field, /*!< in: the locally stored part of the clustered index column, including the BLOB pointer; the clustered @@ -143,7 +146,7 @@ row_sel_sec_rec_is_for_blob( return(FALSE); } - len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen, + len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen, prefix_len, len, (const char*) buf); return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len)); @@ -227,14 +230,14 @@ row_sel_sec_rec_is_for_clust_rec( } len = dtype_get_at_most_n_mbchars( - col->prtype, col->mbminmaxlen, + col->prtype, col->mbminlen, col->mbmaxlen, ifield->prefix_len, len, (char*) clust_field); if (rec_offs_nth_extern(clust_offs, clust_pos) && len < sec_len) { if (!row_sel_sec_rec_is_for_blob( col->mtype, col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, clust_field, clust_len, sec_field, sec_len, ifield->prefix_len, @@ -4431,6 +4434,7 @@ no_gap_lock: prebuilt->new_rec_locks = 1; } err = DB_SUCCESS; + /* fall through */ case DB_SUCCESS: break; case DB_LOCK_WAIT: diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c index 18655546309..e4c2c0c2d37 100644 --- a/storage/xtradb/row/row0upd.c +++ b/storage/xtradb/row/row0upd.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +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 @@ -1177,7 +1178,7 @@ row_upd_index_replace_new_col_val( } len = dtype_get_at_most_n_mbchars(col->prtype, - col->mbminmaxlen, + col->mbminlen, col->mbmaxlen, field->prefix_len, len, (const char*) data); diff --git a/storage/xtradb/trx/trx0purge.c b/storage/xtradb/trx/trx0purge.c index 2a9e80fe66a..428ff10bfdf 100644 --- a/storage/xtradb/trx/trx0purge.c +++ b/storage/xtradb/trx/trx0purge.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. 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 diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index a1b43d99a05..28f0c2f041b 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -2,7 +2,7 @@ # Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB # This file is public domain and comes with NO WARRANTY of any kind -# MySQL daemon start/stop script. +# MariaDB daemon start/stop script. # Usually this is put in /etc/init.d (at least on machines SYSV R4 based # systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/K01mysql. @@ -21,8 +21,8 @@ # Required-Stop: $local_fs $network $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 -# Short-Description: start and stop MySQL -# Description: MySQL is a very fast and reliable SQL database engine. +# Short-Description: start and stop MariaDB +# Description: MariaDB is a very fast and reliable SQL database engine. ### END INIT INFO # Prevent OpenSUSE's init scripts from calling systemd, so that @@ -33,10 +33,9 @@ SYSTEMD_NO_WRAP=1 # Prevent Debian's init scripts from calling systemctl _SYSTEMCTL_SKIP_REDIRECT=true -# If you install MySQL on some other places than @prefix@, then you # have to do one of the following things for this script to work: # -# - Run this script from within the MySQL installation directory +# - Run this script from within the MariaDB installation directory # - Create a /etc/my.cnf file with the following information: # [mysqld] # basedir=<path-to-mysql-installation-directory> @@ -45,11 +44,11 @@ _SYSTEMCTL_SKIP_REDIRECT=true # - Add the path to the mysql-installation-directory to the basedir variable # below. # -# If you want to affect other MySQL variables, you should make your changes -# in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files. +# If you want to affect other MariaDB variables, you should make your changes +# in the /etc/my.cnf, ~/.my.cnf or other MariaDB configuration files. # If you change base dir, you must also change datadir. These may get -# overwritten by settings in the MySQL configuration files. +# overwritten by settings in the MariaDB configuration files. basedir= datadir= @@ -309,7 +308,7 @@ case "$mode" in # Safeguard (relative paths, core dumps..) cd $basedir - echo $echo_n "Starting MySQL" + echo $echo_n "Starting MariaDB" if test -x $bindir/mysqld_safe then # Give extra arguments to mysqld with the my.cnf file. This script @@ -325,7 +324,7 @@ case "$mode" in exit $return_value else - log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)" + log_failure_msg "Couldn't find MariaDB server ($bindir/mysqld_safe)" fi ;; @@ -339,12 +338,12 @@ case "$mode" in if (kill -0 $mysqld_pid 2>/dev/null) then - echo $echo_n "Shutting down MySQL" + echo $echo_n "Shutting down MariaDB" kill $mysqld_pid # mysqld should remove the pid file when it exits, so wait for it. wait_for_gone $mysqld_pid "$mysqld_pid_file_path"; return_value=$? else - log_failure_msg "MySQL server process #$mysqld_pid is not running!" + log_failure_msg "MariaDB server process #$mysqld_pid is not running!" rm "$mysqld_pid_file_path" fi @@ -355,7 +354,7 @@ case "$mode" in fi exit $return_value else - log_failure_msg "MySQL server PID file could not be found!" + log_failure_msg "MariaDB server PID file could not be found!" fi ;; @@ -376,10 +375,10 @@ case "$mode" in 'reload'|'force-reload') if test -s "$mysqld_pid_file_path" ; then read mysqld_pid < "$mysqld_pid_file_path" - kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL" + kill -HUP $mysqld_pid && log_success_msg "Reloading service MariaDB" touch "$mysqld_pid_file_path" else - log_failure_msg "MySQL PID file could not be found!" + log_failure_msg "MariaDB PID file could not be found!" exit 1 fi ;; @@ -388,10 +387,10 @@ case "$mode" in if test -s "$mysqld_pid_file_path" ; then read mysqld_pid < "$mysqld_pid_file_path" if kill -0 $mysqld_pid 2>/dev/null ; then - log_success_msg "MySQL running ($mysqld_pid)" + log_success_msg "MariaDB running ($mysqld_pid)" exit 0 else - log_failure_msg "MySQL is not running, but PID file exists" + log_failure_msg "MariaDB is not running, but PID file exists" exit 1 fi else @@ -401,17 +400,17 @@ case "$mode" in # test if multiple pids exist pid_count=`echo $mysqld_pid | wc -w` if test $pid_count -gt 1 ; then - log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)" + log_failure_msg "Multiple MariaDB running but PID file could not be found ($mysqld_pid)" exit 5 elif test -z $mysqld_pid ; then if test -f "$lock_file_path" ; then - log_failure_msg "MySQL is not running, but lock file ($lock_file_path) exists" + log_failure_msg "MariaDB is not running, but lock file ($lock_file_path) exists" exit 2 fi - log_failure_msg "MySQL is not running" + log_failure_msg "MariaDB is not running" exit 3 else - log_failure_msg "MySQL is running but PID file could not be found" + log_failure_msg "MariaDB is running but PID file could not be found" exit 4 fi fi @@ -419,7 +418,7 @@ case "$mode" in 'configtest') # Safeguard (relative paths, core dumps..) cd $basedir - echo $echo_n "Testing MySQL configuration syntax" + echo $echo_n "Testing MariaDB configuration syntax" daemon=$bindir/mysqld if test -x $libexecdir/mysqld then diff --git a/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c index ed19c4de851..f4496f570f9 100644 --- a/unittest/mysys/base64-t.c +++ b/unittest/mysys/base64-t.c @@ -91,6 +91,9 @@ main(int argc __attribute__((unused)),char *argv[]) diag("src length: %.8x, dst length: %.8x\n", (uint) src_len, (uint) dst_len); } + free(dst); + free(str); + free(src); } my_end(0); return exit_status(); |