diff options
141 files changed, 3019 insertions, 814 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 170d333fc37..4dc9e8e8912 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -352,6 +352,7 @@ MYSQL_CHECK_SSL() # Add readline or libedit. MYSQL_CHECK_READLINE() +SET(MALLOC_LIBRARY "system") CHECK_JEMALLOC() # diff --git a/cmake/jemalloc.cmake b/cmake/jemalloc.cmake index bc6bf60781d..3df17f362bc 100644 --- a/cmake/jemalloc.cmake +++ b/cmake/jemalloc.cmake @@ -53,6 +53,7 @@ MACRO (CHECK_JEMALLOC) CHECK_LIBRARY_EXISTS(jemalloc malloc_stats_print "" HAVE_JEMALLOC) IF (HAVE_JEMALLOC) SET(LIBJEMALLOC jemalloc) + SET(MALLOC_LIBRARY "system jemalloc") ELSEIF (WITH_JEMALLOC STREQUAL "system") MESSAGE(FATAL_ERROR "system jemalloc is not found") ELSEIF (WITH_JEMALLOC STREQUAL "yes") @@ -61,5 +62,6 @@ MACRO (CHECK_JEMALLOC) ENDIF() IF(WITH_JEMALLOC STREQUAL "bundled" OR trybundled) USE_BUNDLED_JEMALLOC() + SET(MALLOC_LIBRARY "bundled jemalloc") ENDIF() ENDMACRO() diff --git a/config.h.cmake b/config.h.cmake index d09be63894e..916ec34669a 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -636,6 +636,7 @@ #define VERSION "@VERSION@" #define PROTOCOL_VERSION 10 +#define MALLOC_LIBRARY "@MALLOC_LIBRARY@" /* time_t related defines */ diff --git a/extra/jemalloc/ChangeLog b/extra/jemalloc/ChangeLog index fc096d8f42f..4f03fc141cb 100644 --- a/extra/jemalloc/ChangeLog +++ b/extra/jemalloc/ChangeLog @@ -6,6 +6,15 @@ found in the git revision history: http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git git://canonware.com/jemalloc.git +* 3.3.1a (December 27, 2013) + + Bug fixes from 3.4.1 + - Fix Valgrind integration flaws that caused Valgrind warnings about reads of + uninitialized memory in: + + arena chunk headers + + internal zero-initialized data structures (relevant to tcache and prof + code) + * 3.3.1 (March 6, 2013) This version fixes bugs that are typically encountered only when utilizing diff --git a/extra/jemalloc/include/jemalloc/internal/arena.h b/extra/jemalloc/include/jemalloc/internal/arena.h index f2c18f43543..bbcfedacead 100644 --- a/extra/jemalloc/include/jemalloc/internal/arena.h +++ b/extra/jemalloc/include/jemalloc/internal/arena.h @@ -441,6 +441,7 @@ void arena_postfork_child(arena_t *arena); #ifndef JEMALLOC_ENABLE_INLINE arena_chunk_map_t *arena_mapp_get(arena_chunk_t *chunk, size_t pageind); size_t *arena_mapbitsp_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbitsp_read(size_t *mapbitsp); size_t arena_mapbits_get(arena_chunk_t *chunk, size_t pageind); size_t arena_mapbits_unallocated_size_get(arena_chunk_t *chunk, size_t pageind); @@ -451,6 +452,7 @@ size_t arena_mapbits_dirty_get(arena_chunk_t *chunk, size_t pageind); size_t arena_mapbits_unzeroed_get(arena_chunk_t *chunk, size_t pageind); size_t arena_mapbits_large_get(arena_chunk_t *chunk, size_t pageind); size_t arena_mapbits_allocated_get(arena_chunk_t *chunk, size_t pageind); +void arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits); void arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, size_t size, size_t flags); void arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind, @@ -498,10 +500,17 @@ arena_mapbitsp_get(arena_chunk_t *chunk, size_t pageind) } JEMALLOC_ALWAYS_INLINE size_t +arena_mapbitsp_read(size_t *mapbitsp) +{ + + return (*mapbitsp); +} + +JEMALLOC_ALWAYS_INLINE size_t arena_mapbits_get(arena_chunk_t *chunk, size_t pageind) { - return (*arena_mapbitsp_get(chunk, pageind)); + return (arena_mapbitsp_read(arena_mapbitsp_get(chunk, pageind))); } JEMALLOC_ALWAYS_INLINE size_t @@ -585,82 +594,89 @@ arena_mapbits_allocated_get(arena_chunk_t *chunk, size_t pageind) } JEMALLOC_ALWAYS_INLINE void +arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits) +{ + + *mapbitsp = mapbits; +} + +JEMALLOC_ALWAYS_INLINE void arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, size_t size, size_t flags) { - size_t *mapbitsp; + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); - mapbitsp = arena_mapbitsp_get(chunk, pageind); assert((size & PAGE_MASK) == 0); assert((flags & ~CHUNK_MAP_FLAGS_MASK) == 0); assert((flags & (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == flags); - *mapbitsp = size | CHUNK_MAP_BININD_INVALID | flags; + arena_mapbitsp_write(mapbitsp, size | CHUNK_MAP_BININD_INVALID | flags); } JEMALLOC_ALWAYS_INLINE void arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind, size_t size) { - size_t *mapbitsp; + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); - mapbitsp = arena_mapbitsp_get(chunk, pageind); assert((size & PAGE_MASK) == 0); - assert((*mapbitsp & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0); - *mapbitsp = size | (*mapbitsp & PAGE_MASK); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0); + arena_mapbitsp_write(mapbitsp, size | (mapbits & PAGE_MASK)); } JEMALLOC_ALWAYS_INLINE void arena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind, size_t size, size_t flags) { - size_t *mapbitsp; + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); size_t unzeroed; - mapbitsp = arena_mapbitsp_get(chunk, pageind); assert((size & PAGE_MASK) == 0); assert((flags & CHUNK_MAP_DIRTY) == flags); - unzeroed = *mapbitsp & CHUNK_MAP_UNZEROED; /* Preserve unzeroed. */ - *mapbitsp = size | CHUNK_MAP_BININD_INVALID | flags | unzeroed | - CHUNK_MAP_LARGE | CHUNK_MAP_ALLOCATED; + unzeroed = mapbits & CHUNK_MAP_UNZEROED; /* Preserve unzeroed. */ + arena_mapbitsp_write(mapbitsp, size | CHUNK_MAP_BININD_INVALID | flags + | unzeroed | CHUNK_MAP_LARGE | CHUNK_MAP_ALLOCATED); } JEMALLOC_ALWAYS_INLINE void arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind, size_t binind) { - size_t *mapbitsp; + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); assert(binind <= BININD_INVALID); - mapbitsp = arena_mapbitsp_get(chunk, pageind); assert(arena_mapbits_large_size_get(chunk, pageind) == PAGE); - *mapbitsp = (*mapbitsp & ~CHUNK_MAP_BININD_MASK) | (binind << - CHUNK_MAP_BININD_SHIFT); + arena_mapbitsp_write(mapbitsp, (mapbits & ~CHUNK_MAP_BININD_MASK) | + (binind << CHUNK_MAP_BININD_SHIFT)); } JEMALLOC_ALWAYS_INLINE void arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind, size_t runind, size_t binind, size_t flags) { - size_t *mapbitsp; + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); size_t unzeroed; assert(binind < BININD_INVALID); - mapbitsp = arena_mapbitsp_get(chunk, pageind); assert(pageind - runind >= map_bias); assert((flags & CHUNK_MAP_DIRTY) == flags); - unzeroed = *mapbitsp & CHUNK_MAP_UNZEROED; /* Preserve unzeroed. */ - *mapbitsp = (runind << LG_PAGE) | (binind << CHUNK_MAP_BININD_SHIFT) | - flags | unzeroed | CHUNK_MAP_ALLOCATED; + unzeroed = mapbits & CHUNK_MAP_UNZEROED; /* Preserve unzeroed. */ + arena_mapbitsp_write(mapbitsp, (runind << LG_PAGE) | (binind << + CHUNK_MAP_BININD_SHIFT) | flags | unzeroed | CHUNK_MAP_ALLOCATED); } JEMALLOC_ALWAYS_INLINE void arena_mapbits_unzeroed_set(arena_chunk_t *chunk, size_t pageind, size_t unzeroed) { - size_t *mapbitsp; + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); - mapbitsp = arena_mapbitsp_get(chunk, pageind); - *mapbitsp = (*mapbitsp & ~CHUNK_MAP_UNZEROED) | unzeroed; + arena_mapbitsp_write(mapbitsp, (mapbits & ~CHUNK_MAP_UNZEROED) | + unzeroed); } JEMALLOC_INLINE bool diff --git a/extra/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in b/extra/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in index 50d84cabf69..124ec34bddf 100644 --- a/extra/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in +++ b/extra/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in @@ -235,6 +235,7 @@ static const bool config_ivsalloc = #ifdef JEMALLOC_DEBUG /* Disable inlining to make debugging easier. */ # define JEMALLOC_ALWAYS_INLINE +# define JEMALLOC_ALWAYS_INLINE_C static # define JEMALLOC_INLINE # define inline #else @@ -242,8 +243,11 @@ static const bool config_ivsalloc = # ifdef JEMALLOC_HAVE_ATTR # define JEMALLOC_ALWAYS_INLINE \ static inline JEMALLOC_ATTR(unused) JEMALLOC_ATTR(always_inline) +# define JEMALLOC_ALWAYS_INLINE_C \ + static inline JEMALLOC_ATTR(always_inline) # else # define JEMALLOC_ALWAYS_INLINE static inline +# define JEMALLOC_ALWAYS_INLINE_C static inline # endif # define JEMALLOC_INLINE static inline # ifdef _MSC_VER diff --git a/extra/jemalloc/include/jemalloc/internal/private_namespace.h b/extra/jemalloc/include/jemalloc/internal/private_namespace.h index 65de3163fd3..cdb0b0eb1c4 100644 --- a/extra/jemalloc/include/jemalloc/internal/private_namespace.h +++ b/extra/jemalloc/include/jemalloc/internal/private_namespace.h @@ -33,6 +33,8 @@ #define arena_mapbits_unzeroed_get JEMALLOC_N(arena_mapbits_unzeroed_get) #define arena_mapbits_unzeroed_set JEMALLOC_N(arena_mapbits_unzeroed_set) #define arena_mapbitsp_get JEMALLOC_N(arena_mapbitsp_get) +#define arena_mapbitsp_read JEMALLOC_N(arena_mapbitsp_read) +#define arena_mapbitsp_write JEMALLOC_N(arena_mapbitsp_write) #define arena_mapp_get JEMALLOC_N(arena_mapp_get) #define arena_maxclass JEMALLOC_N(arena_maxclass) #define arena_new JEMALLOC_N(arena_new) diff --git a/extra/jemalloc/include/jemalloc/internal/tcache.h b/extra/jemalloc/include/jemalloc/internal/tcache.h index ba36204ff21..d4eecdee0dc 100644 --- a/extra/jemalloc/include/jemalloc/internal/tcache.h +++ b/extra/jemalloc/include/jemalloc/internal/tcache.h @@ -313,6 +313,7 @@ tcache_alloc_small(tcache_t *tcache, size_t size, bool zero) } else if (opt_zero) memset(ret, 0, size); } + VALGRIND_MAKE_MEM_UNDEFINED(ret, size); } else { if (config_fill && opt_junk) { arena_alloc_junk_small(ret, &arena_bin_info[binind], @@ -321,7 +322,6 @@ tcache_alloc_small(tcache_t *tcache, size_t size, bool zero) VALGRIND_MAKE_MEM_UNDEFINED(ret, size); memset(ret, 0, size); } - VALGRIND_MAKE_MEM_UNDEFINED(ret, size); if (config_stats) tbin->tstats.nrequests++; @@ -368,11 +368,11 @@ tcache_alloc_large(tcache_t *tcache, size_t size, bool zero) else if (opt_zero) memset(ret, 0, size); } + VALGRIND_MAKE_MEM_UNDEFINED(ret, size); } else { VALGRIND_MAKE_MEM_UNDEFINED(ret, size); memset(ret, 0, size); } - VALGRIND_MAKE_MEM_UNDEFINED(ret, size); if (config_stats) tbin->tstats.nrequests++; diff --git a/extra/jemalloc/src/arena.c b/extra/jemalloc/src/arena.c index 05a787f89d9..d28b629a1e1 100644 --- a/extra/jemalloc/src/arena.c +++ b/extra/jemalloc/src/arena.c @@ -369,13 +369,20 @@ arena_run_zero(arena_chunk_t *chunk, size_t run_ind, size_t npages) } static inline void +arena_run_page_mark_zeroed(arena_chunk_t *chunk, size_t run_ind) +{ + + VALGRIND_MAKE_MEM_DEFINED((void *)((uintptr_t)chunk + (run_ind << + LG_PAGE)), PAGE); +} + +static inline void arena_run_page_validate_zeroed(arena_chunk_t *chunk, size_t run_ind) { size_t i; UNUSED size_t *p = (size_t *)((uintptr_t)chunk + (run_ind << LG_PAGE)); - VALGRIND_MAKE_MEM_DEFINED((void *)((uintptr_t)chunk + (run_ind << - LG_PAGE)), PAGE); + arena_run_page_mark_zeroed(chunk, run_ind); for (i = 0; i < PAGE / sizeof(size_t); i++) assert(p[i] == 0); } @@ -458,6 +465,9 @@ arena_run_split(arena_t *arena, arena_run_t *run, size_t size, bool large, } else if (config_debug) { arena_run_page_validate_zeroed( chunk, run_ind+i); + } else { + arena_run_page_mark_zeroed( + chunk, run_ind+i); } } } else { @@ -467,6 +477,9 @@ arena_run_split(arena_t *arena, arena_run_t *run, size_t size, bool large, */ arena_run_zero(chunk, run_ind, need_pages); } + } else { + VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + + (run_ind << LG_PAGE)), (need_pages << LG_PAGE)); } /* @@ -508,9 +521,9 @@ arena_run_split(arena_t *arena, arena_run_t *run, size_t size, bool large, arena_run_page_validate_zeroed(chunk, run_ind+need_pages-1); } + VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + + (run_ind << LG_PAGE)), (need_pages << LG_PAGE)); } - VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + (run_ind << - LG_PAGE)), (need_pages << LG_PAGE)); } static arena_chunk_t * @@ -569,17 +582,24 @@ arena_chunk_alloc(arena_t *arena) * unless the chunk is not zeroed. */ if (zero == false) { + VALGRIND_MAKE_MEM_UNDEFINED( + (void *)arena_mapp_get(chunk, map_bias+1), + (size_t)((uintptr_t) arena_mapp_get(chunk, + chunk_npages-1) - (uintptr_t)arena_mapp_get(chunk, + map_bias+1))); for (i = map_bias+1; i < chunk_npages-1; i++) arena_mapbits_unzeroed_set(chunk, i, unzeroed); - } else if (config_debug) { + } else { VALGRIND_MAKE_MEM_DEFINED( (void *)arena_mapp_get(chunk, map_bias+1), - (void *)((uintptr_t) - arena_mapp_get(chunk, chunk_npages-1) - - (uintptr_t)arena_mapp_get(chunk, map_bias+1))); - for (i = map_bias+1; i < chunk_npages-1; i++) { - assert(arena_mapbits_unzeroed_get(chunk, i) == - unzeroed); + (size_t)((uintptr_t) arena_mapp_get(chunk, + chunk_npages-1) - (uintptr_t)arena_mapp_get(chunk, + map_bias+1))); + if (config_debug) { + for (i = map_bias+1; i < chunk_npages-1; i++) { + assert(arena_mapbits_unzeroed_get(chunk, + i) == unzeroed); + } } } arena_mapbits_unallocated_set(chunk, chunk_npages-1, @@ -1458,6 +1478,7 @@ arena_malloc_small(arena_t *arena, size_t size, bool zero) } else if (opt_zero) memset(ret, 0, size); } + VALGRIND_MAKE_MEM_UNDEFINED(ret, size); } else { if (config_fill && opt_junk) { arena_alloc_junk_small(ret, &arena_bin_info[binind], @@ -1466,7 +1487,6 @@ arena_malloc_small(arena_t *arena, size_t size, bool zero) VALGRIND_MAKE_MEM_UNDEFINED(ret, size); memset(ret, 0, size); } - VALGRIND_MAKE_MEM_UNDEFINED(ret, size); return (ret); } diff --git a/include/my_bitmap.h b/include/my_bitmap.h index ef3274a8269..9c9550e3141 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -41,9 +41,14 @@ typedef struct st_bitmap #ifdef __cplusplus extern "C" { #endif + +/* compatibility functions */ +#define bitmap_init(A,B,C,D) my_bitmap_init(A,B,C,D) +#define bitmap_free(A) my_bitmap_free(A) + extern void create_last_word_mask(MY_BITMAP *map); -extern my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, - my_bool thread_safe); +extern my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, + my_bool thread_safe); extern my_bool bitmap_is_clear_all(const MY_BITMAP *map); extern my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size); extern my_bool bitmap_is_set_all(const MY_BITMAP *map); @@ -64,7 +69,7 @@ extern uint bitmap_get_first(const MY_BITMAP *map); extern uint bitmap_get_first_set(const MY_BITMAP *map); extern uint bitmap_bits_set(const MY_BITMAP *map); extern uint bitmap_get_next_set(const MY_BITMAP *map, uint bitmap_bit); -extern void bitmap_free(MY_BITMAP *map); +extern void my_bitmap_free(MY_BITMAP *map); extern void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit); extern void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size); extern void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2); diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test index deff9d653e0..01e8497e4de 100644 --- a/mysql-test/extra/rpl_tests/rpl_log.test +++ b/mysql-test/extra/rpl_tests/rpl_log.test @@ -18,8 +18,12 @@ start slave; --source include/wait_for_slave_to_start.inc let $VERSION=`select version()`; - +# Lets run this test in STRICT MODE (DROP TABLE is not DROP TABLE IF EXISTS) +connection slave; +set @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; +set @@global.slave_ddl_exec_mode=STRICT; connection master; + eval create table t1(n int not null auto_increment primary key)ENGINE=$engine_type; insert into t1 values (NULL); drop table t1; @@ -141,3 +145,5 @@ drop table t1; # End of 4.1 tests sync_slave_with_master; +set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; +connection master; diff --git a/mysql-test/extra/rpl_tests/rpl_stop_slave.test b/mysql-test/extra/rpl_tests/rpl_stop_slave.test index b226f4f22f1..0f09faa0301 100644 --- a/mysql-test/extra/rpl_tests/rpl_stop_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_stop_slave.test @@ -59,3 +59,6 @@ source include/wait_for_slave_sql_to_stop.inc; connection slave; START SLAVE SQL_THREAD; source include/wait_for_slave_sql_to_start.inc; + +connection master; +sync_slave_with_master; diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc index bdb6f48f095..e72ebba8527 100644 --- a/mysql-test/include/commit.inc +++ b/mysql-test/include/commit.inc @@ -751,7 +751,7 @@ call p_verify_status_increment(4, 4, 4, 4); --echo # Sic: no table is created. create table if not exists t2 (a int) select 6 union select 7; --echo # Sic: first commits the statement, and then the transaction. -call p_verify_status_increment(2, 0, 2, 0); +call p_verify_status_increment(0, 0, 0, 0); create table t3 select a from t2; call p_verify_status_increment(2, 0, 4, 4); alter table t3 add column (b int); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5a5f2655fda..0e0dac16aa3 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -6188,6 +6188,13 @@ sub valgrind_arguments { mtr_add_arg($args, "--num-callers=16"); mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir) if -f "$glob_mysql_test_dir/valgrind.supp"; + + # Ensure the jemalloc works with mysqld + if ($mysqld_variables{'version-malloc-library'} ne "system" && + $$exe =~ /mysqld/) + { + mtr_add_arg($args, "--soname-synonyms=somalloc=NONE" ); + } } # Add valgrind options, can be overriden by user @@ -6318,7 +6325,20 @@ sub usage ($) { $0 [ OPTIONS ] [ TESTCASE ] -Options to control what engine/variation to run +Where test case can be specified as: + +testcase[.test] Runs the test case named 'testcase' from all suits +path-to-testcase +[suite.]testcase[,combination] + +Examples: + +alias +main.alias 'main' is the name of the suite for the 't' directory. +rpl.rpl_invoked_features,mix,xtradb_plugin +suite/rpl/t/rpl.rpl_invoked_features + +Options to control what engine/variation to run: embedded-server Use the embedded server, i.e. no mysqld daemons ps-protocol Use the binary protocol between client and server diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result index 3583e8ed396..1e173221b15 100644 --- a/mysql-test/r/commit_1innodb.result +++ b/mysql-test/r/commit_1innodb.result @@ -830,7 +830,7 @@ create table if not exists t2 (a int) select 6 union select 7; Warnings: Note 1050 Table 't2' already exists # Sic: first commits the statement, and then the transaction. -call p_verify_status_increment(2, 0, 2, 0); +call p_verify_status_increment(0, 0, 0, 0); SUCCESS create table t3 select a from t2; diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 7eba25d8ea3..41a2200c13f 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -2602,6 +2602,8 @@ create table t1 (a int, b int) select 2,2; ERROR 42S01: Table 't1' already exists create table t1 like t2; ERROR 42S01: Table 't1' already exists +create or replace table t1 (a int, b int) select 2,2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction select * from t1; a b 1 1 diff --git a/mysql-test/r/create_or_replace.result b/mysql-test/r/create_or_replace.result new file mode 100644 index 00000000000..e1586ff211c --- /dev/null +++ b/mysql-test/r/create_or_replace.result @@ -0,0 +1,327 @@ +drop table if exists t1,t2,t3; +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES(1),(2),(3); +# +# Check first syntax and wrong usage +# +CREATE OR REPLACE TABLE IF NOT EXISTS t1 (a int); +ERROR HY000: Incorrect usage of OR REPLACE and IF NOT EXISTS +create or replace trigger trg before insert on t1 for each row set @a:=1; +ERROR HY000: Incorrect usage of OR REPLACE and TRIGGERS / SP / EVENT +create or replace table mysql.general_log (a int); +ERROR HY000: You cannot 'CREATE OR REPLACE' a log table if logging is enabled +create or replace table mysql.slow_log (a int); +ERROR HY000: You cannot 'CREATE OR REPLACE' a log table if logging is enabled +# +# Usage when table doesn't exist +# +CREATE OR REPLACE TABLE t1 (a int); +CREATE TABLE t1 (a int); +ERROR 42S01: Table 't1' already exists +DROP TABLE t1; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int); +CREATE TEMPORARY TABLE t1 (a int, b int, c int); +ERROR 42S01: Table 't1' already exists +DROP TEMPORARY TABLE t1; +# +# Testing with temporary tables +# +CREATE OR REPLACE TABLE t1 (a int); +CREATE OR REPLACE TEMPORARY TABLE t1 (a int); +CREATE OR REPLACE TEMPORARY TABLE t1 (a int, b int); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TEMPORARY TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TEMPORARY TABLE t1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +create temporary table t1 (i int) engine=InnoDB; +create or replace temporary table t1 (a int, b int) engine=InnoDB; +create or replace temporary table t1 (j int); +show create table t1; +Table Create Table +t1 CREATE TEMPORARY TABLE `t1` ( + `j` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLES t1 write; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int); +CREATE OR REPLACE TEMPORARY TABLE t1 (a int, b int); +CREATE OR REPLACE TEMPORARY TABLE t1 (a int, b int) engine= innodb; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int) engine= innodb; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int, b int) engine=myisam; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TEMPORARY TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TEMPORARY TABLE t1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +CREATE OR REPLACE TABLE t2 (a int); +ERROR HY000: Table 't2' was not locked with LOCK TABLES +DROP TABLE t1; +UNLOCK TABLES; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int) SELECT * from t2; +SELECT * FROM t1; +a +1 +2 +3 +CREATE OR REPLACE TEMPORARY TABLE t1 (b int) SELECT * from t2; +SELECT * FROM t1; +b a +NULL 1 +NULL 2 +NULL 3 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TEMPORARY TABLE `t1` ( + `b` int(11) DEFAULT NULL, + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TEMPORARY TABLE t1 AS SELECT a FROM t2; +CREATE TEMPORARY TABLE IF NOT EXISTS t1(a int, b int) SELECT 1,2 FROM t2; +Warnings: +Note 1050 Table 't1' already exists +DROP TABLE t1; +CREATE TABLE t1 (a int); +CREATE OR REPLACE TABLE t1 AS SELECT 1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `1` int(1) NOT NULL DEFAULT '0' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +create table t1 (a int); +create or replace table t1 as select * from t1; +ERROR HY000: Table 't1' is specified twice, both as a target for 'CREATE' and as a separate source for data +create or replace table t1 as select a from (select a from t1) as t3; +ERROR HY000: Table 't1' is specified twice, both as a target for 'CREATE' and as a separate source for data +create or replace table t1 as select a from t2 where t2.a in (select a from t1); +ERROR HY000: Table 't1' is specified twice, both as a target for 'CREATE' and as a separate source for data +drop table t1; +# +# Testing with normal tables +# +CREATE OR REPLACE TABLE t1 (a int); +CREATE OR REPLACE TABLE t1 (a int, b int); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (a int) SELECT * from t2; +SELECT * FROM t1; +a +1 +2 +3 +TRUNCATE TABLE t1; +CREATE TABLE IF NOT EXISTS t1 (a int) SELECT * from t2; +Warnings: +Note 1050 Table 't1' already exists +SELECT * FROM t1; +a +DROP TABLE t1; +CREATE TABLE t1 (i int); +CREATE OR REPLACE TABLE t1 AS SELECT 1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `1` int(1) NOT NULL DEFAULT '0' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLES t1 write,t2 write; +CREATE OR REPLACE TABLE t1 (a int, b int); +SELECT * FROM t1; +a b +INSERT INTO t1 values(1,1); +CREATE OR REPLACE TABLE t1 (a int, b int, c int); +INSERT INTO t1 values(1,1,1); +CREATE OR REPLACE TABLE t3 (a int); +ERROR HY000: Table 't3' was not locked with LOCK TABLES +UNLOCK TABLES; +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLES t1 write,t2 write; +CREATE OR REPLACE TABLE t1 (a int, b int) select a,1 from t2; +SELECT * FROM t2; +a +1 +2 +3 +SELECT * FROM t1; +b a 1 +NULL 1 1 +NULL 2 1 +NULL 3 1 +SELECT * FROM t1; +b a 1 +NULL 1 1 +NULL 2 1 +NULL 3 1 +INSERT INTO t1 values(1,1,1); +CREATE OR REPLACE TABLE t1 (a int, b int, c int, d int); +INSERT INTO t1 values(1,1,1,1); +CREATE OR REPLACE TABLE t3 (a int); +ERROR HY000: Table 't3' was not locked with LOCK TABLES +UNLOCK TABLES; +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLES t1 write,t2 write, t1 as t1_read read; +CREATE OR REPLACE TABLE t1 (a int, b int) select a,1 from t2; +SELECT * FROM t1; +b a 1 +NULL 1 1 +NULL 2 1 +NULL 3 1 +SELECT * FROM t2; +a +1 +2 +3 +SELECT * FROM t1 as t1_read; +ERROR HY000: Table 't1_read' was not locked with LOCK TABLES +DROP TABLE t1; +UNLOCK TABLES; +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLE t1 WRITE; +CREATE OR REPLACE TABLE t1 AS SELECT 1; +SELECT * from t1; +1 +1 +SELECT * from t2; +ERROR HY000: Table 't2' was not locked with LOCK TABLES +DROP TABLE t1; +# +# Test also with InnoDB (transactional engine) +# +create table t1 (i int) engine=innodb; +lock table t1 write; +create or replace table t1 (j int); +unlock tables; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `j` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (i int) engine=InnoDB; +lock table t1 write, t2 write; +create or replace table t1 (j int) engine=innodb; +unlock tables; +drop table t1; +create table t1 (i int) engine=InnoDB; +create table t3 (i int) engine=InnoDB; +insert into t3 values(1),(2),(3); +lock table t1 write, t2 write, t3 write; +create or replace table t1 (a int, i int) engine=innodb select t2.a,t3.i from t2,t3; +unlock tables; +select * from t1 order by a,i; +a i +1 1 +1 2 +1 3 +2 1 +2 2 +2 3 +3 1 +3 2 +3 3 +drop table t1,t3; +# +# Testing CREATE .. LIKE +# +create or replace table t1 like t2; +create or replace table t1 like t2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (b int); +lock tables t1 write, t2 read; +create or replace table t1 like t2; +SELECT * FROM t1; +a +INSERT INTO t1 values(1); +CREATE OR REPLACE TABLE t1 like t2; +INSERT INTO t1 values(2); +unlock tables; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create or replace table t1 like t2; +create or replace table t1 like t1; +ERROR 42000: Not unique table/alias: 't1' +drop table t1; +CREATE TEMPORARY TABLE t1 like t2; +CREATE OR REPLACE TABLE t1 like t1; +ERROR 42000: Not unique table/alias: 't1' +CREATE OR REPLACE TABLE t1 like t1; +ERROR 42000: Not unique table/alias: 't1' +drop table t1; +CREATE TEMPORARY TABLE t1 like t2; +CREATE OR REPLACE TEMPORARY TABLE t3 like t1; +CREATE OR REPLACE TEMPORARY TABLE t3 like t3; +ERROR 42000: Not unique table/alias: 't3' +drop table t1,t3; +# +# Test with prepared statements +# +prepare stmt1 from 'create or replace table t1 select * from t2'; +execute stmt1; +select * from t1; +a +1 +2 +3 +execute stmt1; +select * from t1; +a +1 +2 +3 +drop table t1; +execute stmt1; +select * from t1; +a +1 +2 +3 +deallocate prepare stmt1; +drop table t1; +# +# Test with views +# +create view t1 as select 1; +create table if not exists t1 (a int); +Warnings: +Note 1050 Table 't1' already exists +create or replace table t1 (a int); +ERROR 42S02: 'test.t1' is a view +drop table t1; +ERROR 42S02: 'test.t1' is a view +drop view t1; +DROP TABLE t2; diff --git a/mysql-test/r/lowercase_view.result b/mysql-test/r/lowercase_view.result index 33c87ec101c..f43c39c4fc1 100644 --- a/mysql-test/r/lowercase_view.result +++ b/mysql-test/r/lowercase_view.result @@ -20,13 +20,13 @@ ERROR HY000: The definition of table 'v1Aa' prevents operation UPDATE on table ' update v2Aa set col1 = (select max(col1) from t1Aa); ERROR HY000: The definition of table 'v2Aa' prevents operation UPDATE on table 'v2Aa'. update v2aA set col1 = (select max(col1) from v2Aa); -ERROR HY000: You can't specify target table 'v2aA' for update in FROM clause +ERROR HY000: Table 'v2aA' is specified twice, both as a target for 'UPDATE' and as a separate source for data update v2aA,t2Aa set v2Aa.col1 = (select max(col1) from v1aA) where v2aA.col1 = t2aA.col1; ERROR HY000: The definition of table 'v1aA' prevents operation UPDATE on table 'v2aA'. update t1aA,t2Aa set t1Aa.col1 = (select max(col1) from v1Aa) where t1aA.col1 = t2aA.col1; ERROR HY000: The definition of table 'v1Aa' prevents operation UPDATE on table 't1aA'. update v1aA,t2Aa set v1Aa.col1 = (select max(col1) from v1aA) where v1Aa.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 'v1aA' for update in FROM clause +ERROR HY000: Table 'v1aA' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t2Aa,v2Aa set v2aA.col1 = (select max(col1) from v1aA) where v2Aa.col1 = t2aA.col1; ERROR HY000: The definition of table 'v1aA' prevents operation UPDATE on table 't2Aa'. update t2Aa,t1Aa set t1aA.col1 = (select max(col1) from v1Aa) where t1Aa.col1 = t2aA.col1; @@ -36,17 +36,17 @@ ERROR HY000: The definition of table 'v1aA' prevents operation UPDATE on table ' update v2aA,t2Aa set v2Aa.col1 = (select max(col1) from t1aA) where v2aA.col1 = t2aA.col1; ERROR HY000: The definition of table 'v2aA' prevents operation UPDATE on table 'v2aA'. update t1Aa,t2Aa set t1aA.col1 = (select max(col1) from t1Aa) where t1aA.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 't1Aa' for update in FROM clause +ERROR HY000: Table 't1Aa' is specified twice, both as a target for 'UPDATE' and as a separate source for data update v1aA,t2Aa set v1Aa.col1 = (select max(col1) from t1Aa) where v1aA.col1 = t2aA.col1; ERROR HY000: The definition of table 'v1aA' prevents operation UPDATE on table 'v1aA'. update t2Aa,v2Aa set v2aA.col1 = (select max(col1) from t1aA) where v2Aa.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 't2Aa' for update in FROM clause +ERROR HY000: Table 't2Aa' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t2Aa,t1Aa set t1aA.col1 = (select max(col1) from t1Aa) where t1aA.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 't2Aa' for update in FROM clause +ERROR HY000: Table 't2Aa' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t2Aa,v1Aa set v1aA.col1 = (select max(col1) from t1Aa) where v1Aa.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 't2Aa' for update in FROM clause +ERROR HY000: Table 't2Aa' is specified twice, both as a target for 'UPDATE' and as a separate source for data update v2aA,t2Aa set v2Aa.col1 = (select max(col1) from v2aA) where v2Aa.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 'v2aA' for update in FROM clause +ERROR HY000: Table 'v2aA' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t1aA,t2Aa set t1Aa.col1 = (select max(col1) from v2aA) where t1aA.col1 = t2aA.col1; ERROR HY000: The definition of table 'v2aA' prevents operation UPDATE on table 't1aA'. update v1aA,t2Aa set v1Aa.col1 = (select max(col1) from v2Aa) where v1aA.col1 = t2aA.col1; @@ -64,27 +64,27 @@ ERROR HY000: The definition of table 'v3aA' prevents operation UPDATE on table ' update v3aA set v3Aa.col1 = (select max(col1) from v2aA); ERROR HY000: The definition of table 'v2aA' prevents operation UPDATE on table 'v3aA'. update v3aA set v3Aa.col1 = (select max(col1) from v3aA); -ERROR HY000: You can't specify target table 'v3aA' for update in FROM clause +ERROR HY000: Table 'v3aA' is specified twice, both as a target for 'UPDATE' and as a separate source for data delete from v2Aa where col1 = (select max(col1) from v1Aa); ERROR HY000: The definition of table 'v1Aa' prevents operation DELETE on table 'v2Aa'. delete from v2aA where col1 = (select max(col1) from t1Aa); ERROR HY000: The definition of table 'v2aA' prevents operation DELETE on table 'v2aA'. delete from v2Aa where col1 = (select max(col1) from v2aA); -ERROR HY000: You can't specify target table 'v2Aa' for update in FROM clause +ERROR HY000: Table 'v2Aa' is specified twice, both as a target for 'DELETE' and as a separate source for data delete v2Aa from v2aA,t2Aa where (select max(col1) from v1aA) > 0 and v2Aa.col1 = t2aA.col1; ERROR HY000: The definition of table 'v1aA' prevents operation DELETE on table 'v2aA'. delete t1aA from t1Aa,t2Aa where (select max(col1) from v1Aa) > 0 and t1aA.col1 = t2aA.col1; ERROR HY000: The definition of table 'v1Aa' prevents operation DELETE on table 't1Aa'. delete v1aA from v1Aa,t2Aa where (select max(col1) from v1aA) > 0 and v1Aa.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 'v1Aa' for update in FROM clause +ERROR HY000: Table 'v1Aa' is specified twice, both as a target for 'DELETE' and as a separate source for data delete v2aA from v2Aa,t2Aa where (select max(col1) from t1Aa) > 0 and v2aA.col1 = t2aA.col1; ERROR HY000: The definition of table 'v2Aa' prevents operation DELETE on table 'v2Aa'. delete t1aA from t1Aa,t2Aa where (select max(col1) from t1aA) > 0 and t1Aa.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 't1Aa' for update in FROM clause +ERROR HY000: Table 't1Aa' is specified twice, both as a target for 'DELETE' and as a separate source for data delete v1aA from v1Aa,t2Aa where (select max(col1) from t1aA) > 0 and v1aA.col1 = t2aA.col1; ERROR HY000: The definition of table 'v1Aa' prevents operation DELETE on table 'v1Aa'. delete v2Aa from v2aA,t2Aa where (select max(col1) from v2Aa) > 0 and v2aA.col1 = t2aA.col1; -ERROR HY000: You can't specify target table 'v2aA' for update in FROM clause +ERROR HY000: Table 'v2aA' is specified twice, both as a target for 'DELETE' and as a separate source for data delete t1Aa from t1aA,t2Aa where (select max(col1) from v2Aa) > 0 and t1Aa.col1 = t2aA.col1; ERROR HY000: The definition of table 'v2Aa' prevents operation DELETE on table 't1aA'. delete v1Aa from v1aA,t2Aa where (select max(col1) from v2aA) > 0 and v1Aa.col1 = t2aA.col1; @@ -98,15 +98,15 @@ ERROR HY000: The definition of table 'v1aA' prevents operation INSERT on table ' insert into v2Aa values ((select max(col1) from t1Aa)); ERROR HY000: The definition of table 'v2Aa' prevents operation INSERT on table 'v2Aa'. insert into t1aA values ((select max(col1) from t1Aa)); -ERROR HY000: You can't specify target table 't1aA' for update in FROM clause +ERROR HY000: Table 't1aA' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into v2aA values ((select max(col1) from t1aA)); ERROR HY000: The definition of table 'v2aA' prevents operation INSERT on table 'v2aA'. insert into v2Aa values ((select max(col1) from v2aA)); -ERROR HY000: You can't specify target table 'v2Aa' for update in FROM clause +ERROR HY000: Table 'v2Aa' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into t1Aa values ((select max(col1) from v2Aa)); ERROR HY000: The definition of table 'v2Aa' prevents operation INSERT on table 't1Aa'. insert into v2aA values ((select max(col1) from v2Aa)); -ERROR HY000: You can't specify target table 'v2aA' for update in FROM clause +ERROR HY000: Table 'v2aA' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into v3Aa (col1) values ((select max(col1) from v1Aa)); ERROR HY000: The definition of table 'v1Aa' prevents operation INSERT on table 'v3Aa'. insert into v3aA (col1) values ((select max(col1) from t1aA)); diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 0feb1cdce98..89aaf48219e 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -3657,85 +3657,85 @@ insert into tmp (b) values (1); insert into t1 (a) values (1); insert into t3 (b) values (1); insert into m1 (a) values ((select max(a) from m1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from m2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from t1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from t2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from t3, m1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from t3, m2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from t3, t1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from t3, t2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from tmp, m1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from tmp, m2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from tmp, t1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from tmp, t2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into m1 (a) values ((select max(a) from v1)); ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'. insert into m1 (a) values ((select max(a) from tmp, v1)); ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'. update m1 set a = ((select max(a) from m1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from m2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from t1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from t2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from t3, m1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from t3, m2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from t3, t1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from t3, t2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from tmp, m1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from tmp, m2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from tmp, t1)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from tmp, t2)); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update m1 set a = ((select max(a) from v1)); ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'm1'. update m1 set a = ((select max(a) from tmp, v1)); ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'm1'. delete from m1 where a = (select max(a) from m1); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from m2); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from t1); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from t2); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from t3, m1); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from t3, m2); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from t3, t1); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from t3, t2); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from tmp, m1); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from tmp, m2); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from tmp, t1); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from tmp, t2); -ERROR HY000: You can't specify target table 'm1' for update in FROM clause +ERROR HY000: Table 'm1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from m1 where a = (select max(a) from v1); ERROR HY000: The definition of table 'v1' prevents operation DELETE on table 'm1'. delete from m1 where a = (select max(a) from tmp, v1); diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index f49998da5f4..ff0aa828636 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -439,9 +439,9 @@ drop table t1, t2, t3; create table t1 (col1 int); create table t2 (col1 int); update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1; -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2.col1; -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data drop table t1,t2; create table t1 ( aclid bigint not null primary key, @@ -457,7 +457,7 @@ drop table t1, t2; create table t1(a int); create table t2(a int); delete from t1,t2 using t1,t2 where t1.a=(select a from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data drop table t1, t2; create table t1 ( c char(8) not null ) engine=innodb; insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index e5d6cbc0e31..53048939fa9 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -860,13 +860,22 @@ The following options may be given as the first argument: --skip-slave-start If set, slave is not autostarted. --slave-compressed-protocol Use compression on master/slave protocol + --slave-ddl-exec-mode=name + Modes for how replication events should be executed. + Legal values are STRICT and IDEMPOTENT (default). In + IDEMPOTENT mode, replication will not stop for DDL + operations that are idempotent. This means that CREATE + TABLE is treated CREATE TABLE OR REPLACE and DROP TABLE + is threated as DROP TABLE IF EXISTS. --slave-exec-mode=name Modes for how replication events should be executed. Legal values are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, replication will not stop for operations - that are idempotent. In STRICT mode, replication will - stop on any unexpected difference between the master and - the slave + that are idempotent. For example, in row based + replication attempts to delete rows that doesn't exist + will be ignored.In STRICT mode, replication will stop on + any unexpected difference between the master and the + slave --slave-load-tmpdir=name The location where the slave should put its temporary files when replicating a LOAD DATA INFILE command @@ -1023,7 +1032,7 @@ auto-increment-increment 1 auto-increment-offset 1 autocommit TRUE automatic-sp-privileges TRUE -back-log 50 +back-log 150 big-tables FALSE bind-address (No default value) binlog-annotate-row-events FALSE @@ -1226,6 +1235,7 @@ port-open-timeout 0 preload-buffer-size 32768 profiling-history-size 15 progress-report-time 56 +protocol-version 10 query-alloc-block-size 8192 query-cache-limit 1048576 query-cache-min-res-unit 4096 @@ -1264,6 +1274,7 @@ skip-networking FALSE skip-show-database FALSE skip-slave-start FALSE slave-compressed-protocol FALSE +slave-ddl-exec-mode IDEMPOTENT slave-exec-mode STRICT slave-max-allowed-packet 1073741824 slave-net-timeout 3600 diff --git a/mysql-test/r/partition_exchange.result b/mysql-test/r/partition_exchange.result index 36499004869..fec08e99c72 100644 --- a/mysql-test/r/partition_exchange.result +++ b/mysql-test/r/partition_exchange.result @@ -1088,7 +1088,7 @@ ALTER TABLE t PARTITION BY RANGE (UNIX_TIMESTAMP(event_time) DIV 1) (PARTITION p0 VALUES LESS THAN (123456789), PARTITION pMAX VALUES LESS THAN MAXVALUE); ALTER TABLE t EXCHANGE PARTITION p0 WITH TABLE general_log; -ERROR HY000: Incorrect usage of PARTITION and log table +ERROR HY000: You cannot 'ALTER PARTITION' a log table if logging is enabled ALTER TABLE general_log ENGINE = CSV; SET @@global.general_log = @old_general_log_state; DROP TABLE t; diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index 8284e974574..dec0d12c455 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -1930,7 +1930,7 @@ SUCCESS execute stmt; ERROR 42S01: Table 't2' already exists -call p_verify_reprepare_count(1); +call p_verify_reprepare_count(0); SUCCESS execute stmt; @@ -1946,7 +1946,7 @@ SUCCESS execute stmt; ERROR 42S01: Table 't2' already exists -call p_verify_reprepare_count(1); +call p_verify_reprepare_count(0); SUCCESS drop temporary table t2; @@ -1964,7 +1964,7 @@ drop table t2; create view t2 as select 1; execute stmt; Got one of the listed errors -call p_verify_reprepare_count(1); +call p_verify_reprepare_count(0); SUCCESS execute stmt; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index fc98607e38a..effa77a5eb4 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -579,7 +579,7 @@ a b 1 11 2 12 update t1 set b= (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t1 set b= (select b from t2); ERROR 21000: Subquery returns more than 1 row update t1 set b= (select b from t2 where t1.a = t2.a); @@ -602,7 +602,7 @@ select * from t1 where b = (select b from t2 where t1.a = t2.a); a b 2 12 delete from t1 where b in (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from t1 where b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete from t1 where b = (select b from t2 where t1.a = t2.a); @@ -628,7 +628,7 @@ a b 22 11 2 12 delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); -ERROR HY000: You can't specify target table 't12' for update in FROM clause +ERROR HY000: Table 't12' is specified twice, both as a target for 'DELETE' and as a separate source for data delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); @@ -647,7 +647,7 @@ create table t3 (b int); insert into t2 values (1); insert into t3 values (1),(2); INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t1 (x) VALUES ((SELECT b FROM t3)); ERROR 21000: Subquery returns more than 1 row INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); @@ -697,7 +697,7 @@ insert into t3 values (1),(2); select * from t1; x y replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); ERROR 21000: Subquery returns more than 1 row replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); @@ -765,9 +765,9 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2); id 2 INSERT INTO t2 VALUES ((SELECT * FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t2 VALUES ((SELECT id FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data SELECT * FROM t2; id 1 diff --git a/mysql-test/r/subselect_exists_to_in.result b/mysql-test/r/subselect_exists_to_in.result index a70e6df3d00..bc9db36c8ce 100644 --- a/mysql-test/r/subselect_exists_to_in.result +++ b/mysql-test/r/subselect_exists_to_in.result @@ -583,7 +583,7 @@ a b 1 11 2 12 update t1 set b= (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t1 set b= (select b from t2); ERROR 21000: Subquery returns more than 1 row update t1 set b= (select b from t2 where t1.a = t2.a); @@ -606,7 +606,7 @@ select * from t1 where b = (select b from t2 where t1.a = t2.a); a b 2 12 delete from t1 where b in (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from t1 where b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete from t1 where b = (select b from t2 where t1.a = t2.a); @@ -632,7 +632,7 @@ a b 22 11 2 12 delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); -ERROR HY000: You can't specify target table 't12' for update in FROM clause +ERROR HY000: Table 't12' is specified twice, both as a target for 'DELETE' and as a separate source for data delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); @@ -651,7 +651,7 @@ create table t3 (b int); insert into t2 values (1); insert into t3 values (1),(2); INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t1 (x) VALUES ((SELECT b FROM t3)); ERROR 21000: Subquery returns more than 1 row INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); @@ -701,7 +701,7 @@ insert into t3 values (1),(2); select * from t1; x y replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); ERROR 21000: Subquery returns more than 1 row replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); @@ -769,9 +769,9 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2); id 2 INSERT INTO t2 VALUES ((SELECT * FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t2 VALUES ((SELECT id FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data SELECT * FROM t2; id 1 diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 16f67820e0e..975d90b8358 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -586,7 +586,7 @@ a b 1 11 2 12 update t1 set b= (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t1 set b= (select b from t2); ERROR 21000: Subquery returns more than 1 row update t1 set b= (select b from t2 where t1.a = t2.a); @@ -609,7 +609,7 @@ select * from t1 where b = (select b from t2 where t1.a = t2.a); a b 2 12 delete from t1 where b in (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from t1 where b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete from t1 where b = (select b from t2 where t1.a = t2.a); @@ -635,7 +635,7 @@ a b 22 11 2 12 delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); -ERROR HY000: You can't specify target table 't12' for update in FROM clause +ERROR HY000: Table 't12' is specified twice, both as a target for 'DELETE' and as a separate source for data delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); @@ -654,7 +654,7 @@ create table t3 (b int); insert into t2 values (1); insert into t3 values (1),(2); INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t1 (x) VALUES ((SELECT b FROM t3)); ERROR 21000: Subquery returns more than 1 row INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); @@ -704,7 +704,7 @@ insert into t3 values (1),(2); select * from t1; x y replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); ERROR 21000: Subquery returns more than 1 row replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); @@ -772,9 +772,9 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2); id 2 INSERT INTO t2 VALUES ((SELECT * FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t2 VALUES ((SELECT id FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data SELECT * FROM t2; id 1 diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index bc2cc71b0fa..f9ea3c45ee3 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -582,7 +582,7 @@ a b 1 11 2 12 update t1 set b= (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t1 set b= (select b from t2); ERROR 21000: Subquery returns more than 1 row update t1 set b= (select b from t2 where t1.a = t2.a); @@ -605,7 +605,7 @@ select * from t1 where b = (select b from t2 where t1.a = t2.a); a b 2 12 delete from t1 where b in (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from t1 where b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete from t1 where b = (select b from t2 where t1.a = t2.a); @@ -631,7 +631,7 @@ a b 22 11 2 12 delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); -ERROR HY000: You can't specify target table 't12' for update in FROM clause +ERROR HY000: Table 't12' is specified twice, both as a target for 'DELETE' and as a separate source for data delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); @@ -650,7 +650,7 @@ create table t3 (b int); insert into t2 values (1); insert into t3 values (1),(2); INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t1 (x) VALUES ((SELECT b FROM t3)); ERROR 21000: Subquery returns more than 1 row INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); @@ -700,7 +700,7 @@ insert into t3 values (1),(2); select * from t1; x y replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); ERROR 21000: Subquery returns more than 1 row replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); @@ -768,9 +768,9 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2); id 2 INSERT INTO t2 VALUES ((SELECT * FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t2 VALUES ((SELECT id FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data SELECT * FROM t2; id 1 diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 40a63afb1c6..2bc182ac6e9 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -585,7 +585,7 @@ a b 1 11 2 12 update t1 set b= (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t1 set b= (select b from t2); ERROR 21000: Subquery returns more than 1 row update t1 set b= (select b from t2 where t1.a = t2.a); @@ -608,7 +608,7 @@ select * from t1 where b = (select b from t2 where t1.a = t2.a); a b 2 12 delete from t1 where b in (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from t1 where b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete from t1 where b = (select b from t2 where t1.a = t2.a); @@ -634,7 +634,7 @@ a b 22 11 2 12 delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); -ERROR HY000: You can't specify target table 't12' for update in FROM clause +ERROR HY000: Table 't12' is specified twice, both as a target for 'DELETE' and as a separate source for data delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); @@ -653,7 +653,7 @@ create table t3 (b int); insert into t2 values (1); insert into t3 values (1),(2); INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t1 (x) VALUES ((SELECT b FROM t3)); ERROR 21000: Subquery returns more than 1 row INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); @@ -703,7 +703,7 @@ insert into t3 values (1),(2); select * from t1; x y replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); ERROR 21000: Subquery returns more than 1 row replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); @@ -771,9 +771,9 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2); id 2 INSERT INTO t2 VALUES ((SELECT * FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t2 VALUES ((SELECT id FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data SELECT * FROM t2; id 1 diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 1fc2d98c0e8..a41c7636038 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -582,7 +582,7 @@ a b 1 11 2 12 update t1 set b= (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t1 set b= (select b from t2); ERROR 21000: Subquery returns more than 1 row update t1 set b= (select b from t2 where t1.a = t2.a); @@ -605,7 +605,7 @@ select * from t1 where b = (select b from t2 where t1.a = t2.a); a b 2 12 delete from t1 where b in (select b from t1); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete from t1 where b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete from t1 where b = (select b from t2 where t1.a = t2.a); @@ -631,7 +631,7 @@ a b 22 11 2 12 delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); -ERROR HY000: You can't specify target table 't12' for update in FROM clause +ERROR HY000: Table 't12' is specified twice, both as a target for 'DELETE' and as a separate source for data delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); ERROR 21000: Subquery returns more than 1 row delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); @@ -650,7 +650,7 @@ create table t3 (b int); insert into t2 values (1); insert into t3 values (1),(2); INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t1 (x) VALUES ((SELECT b FROM t3)); ERROR 21000: Subquery returns more than 1 row INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); @@ -700,7 +700,7 @@ insert into t3 values (1),(2); select * from t1; x y replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); ERROR 21000: Subquery returns more than 1 row replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); @@ -768,9 +768,9 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2); id 2 INSERT INTO t2 VALUES ((SELECT * FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data INSERT INTO t2 VALUES ((SELECT id FROM t2)); -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data SELECT * FROM t2; id 1 diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 9b1c1b6955e..eb896082810 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1137,12 +1137,12 @@ ERROR HY000: Variable 'ft_stopword_file' is a read only variable # SHOW VARIABLES like 'back_log'; Variable_name Value -back_log 50 +back_log 150 SELECT @@session.back_log; ERROR HY000: Variable 'back_log' is a GLOBAL variable SELECT @@global.back_log; @@global.back_log -50 +150 SET @@session.back_log= 7; ERROR HY000: Variable 'back_log' is a read only variable SET @@global.back_log= 7; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 19fc1bda402..5b5410f4bd6 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -205,7 +205,7 @@ ERROR 42S02: Unknown table 'v100' drop view t1; ERROR HY000: 'test.t1' is not VIEW drop table v1; -ERROR 42S02: Unknown table 'test.v1' +ERROR 42S02: 'test.v1' is a view drop view v1,v2; drop table t1; create table t1 (a int); @@ -931,13 +931,13 @@ ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'v2 update v2 set col1 = (select max(col1) from t1); ERROR HY000: The definition of table 'v2' prevents operation UPDATE on table 'v2'. update v2 set col1 = (select max(col1) from v2); -ERROR HY000: You can't specify target table 'v2' for update in FROM clause +ERROR HY000: Table 'v2' is specified twice, both as a target for 'UPDATE' and as a separate source for data update v2,t2 set v2.col1 = (select max(col1) from v1) where v2.col1 = t2.col1; ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'v2'. update t1,t2 set t1.col1 = (select max(col1) from v1) where t1.col1 = t2.col1; ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 't1'. update v1,t2 set v1.col1 = (select max(col1) from v1) where v1.col1 = t2.col1; -ERROR HY000: You can't specify target table 'v1' for update in FROM clause +ERROR HY000: Table 'v1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t2,v2 set v2.col1 = (select max(col1) from v1) where v2.col1 = t2.col1; ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 't2'. update t2,t1 set t1.col1 = (select max(col1) from v1) where t1.col1 = t2.col1; @@ -947,17 +947,17 @@ ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 't2 update v2,t2 set v2.col1 = (select max(col1) from t1) where v2.col1 = t2.col1; ERROR HY000: The definition of table 'v2' prevents operation UPDATE on table 'v2'. update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1; -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'UPDATE' and as a separate source for data update v1,t2 set v1.col1 = (select max(col1) from t1) where v1.col1 = t2.col1; ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'v1'. update t2,v2 set v2.col1 = (select max(col1) from t1) where v2.col1 = t2.col1; -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t2,t1 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1; -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t2,v1 set v1.col1 = (select max(col1) from t1) where v1.col1 = t2.col1; -ERROR HY000: You can't specify target table 't2' for update in FROM clause +ERROR HY000: Table 't2' is specified twice, both as a target for 'UPDATE' and as a separate source for data update v2,t2 set v2.col1 = (select max(col1) from v2) where v2.col1 = t2.col1; -ERROR HY000: You can't specify target table 'v2' for update in FROM clause +ERROR HY000: Table 'v2' is specified twice, both as a target for 'UPDATE' and as a separate source for data update t1,t2 set t1.col1 = (select max(col1) from v2) where t1.col1 = t2.col1; ERROR HY000: The definition of table 'v2' prevents operation UPDATE on table 't1'. update v1,t2 set v1.col1 = (select max(col1) from v2) where v1.col1 = t2.col1; @@ -975,27 +975,27 @@ ERROR HY000: The definition of table 'v3' prevents operation UPDATE on table 'v3 update v3 set v3.col1 = (select max(col1) from v2); ERROR HY000: The definition of table 'v2' prevents operation UPDATE on table 'v3'. update v3 set v3.col1 = (select max(col1) from v3); -ERROR HY000: You can't specify target table 'v3' for update in FROM clause +ERROR HY000: Table 'v3' is specified twice, both as a target for 'UPDATE' and as a separate source for data delete from v2 where col1 = (select max(col1) from v1); ERROR HY000: The definition of table 'v1' prevents operation DELETE on table 'v2'. delete from v2 where col1 = (select max(col1) from t1); ERROR HY000: The definition of table 'v2' prevents operation DELETE on table 'v2'. delete from v2 where col1 = (select max(col1) from v2); -ERROR HY000: You can't specify target table 'v2' for update in FROM clause +ERROR HY000: Table 'v2' is specified twice, both as a target for 'DELETE' and as a separate source for data delete v2 from v2,t2 where (select max(col1) from v1) > 0 and v2.col1 = t2.col1; ERROR HY000: The definition of table 'v1' prevents operation DELETE on table 'v2'. delete t1 from t1,t2 where (select max(col1) from v1) > 0 and t1.col1 = t2.col1; ERROR HY000: The definition of table 'v1' prevents operation DELETE on table 't1'. delete v1 from v1,t2 where (select max(col1) from v1) > 0 and v1.col1 = t2.col1; -ERROR HY000: You can't specify target table 'v1' for update in FROM clause +ERROR HY000: Table 'v1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete v2 from v2,t2 where (select max(col1) from t1) > 0 and v2.col1 = t2.col1; ERROR HY000: The definition of table 'v2' prevents operation DELETE on table 'v2'. delete t1 from t1,t2 where (select max(col1) from t1) > 0 and t1.col1 = t2.col1; -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'DELETE' and as a separate source for data delete v1 from v1,t2 where (select max(col1) from t1) > 0 and v1.col1 = t2.col1; ERROR HY000: The definition of table 'v1' prevents operation DELETE on table 'v1'. delete v2 from v2,t2 where (select max(col1) from v2) > 0 and v2.col1 = t2.col1; -ERROR HY000: You can't specify target table 'v2' for update in FROM clause +ERROR HY000: Table 'v2' is specified twice, both as a target for 'DELETE' and as a separate source for data delete t1 from t1,t2 where (select max(col1) from v2) > 0 and t1.col1 = t2.col1; ERROR HY000: The definition of table 'v2' prevents operation DELETE on table 't1'. delete v1 from v1,t2 where (select max(col1) from v2) > 0 and v1.col1 = t2.col1; @@ -1009,15 +1009,15 @@ ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v2 insert into v2 values ((select max(col1) from t1)); ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v2'. insert into t1 values ((select max(col1) from t1)); -ERROR HY000: You can't specify target table 't1' for update in FROM clause +ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into v2 values ((select max(col1) from t1)); ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v2'. insert into v2 values ((select max(col1) from v2)); -ERROR HY000: You can't specify target table 'v2' for update in FROM clause +ERROR HY000: Table 'v2' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into t1 values ((select max(col1) from v2)); ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 't1'. insert into v2 values ((select max(col1) from v2)); -ERROR HY000: You can't specify target table 'v2' for update in FROM clause +ERROR HY000: Table 'v2' is specified twice, both as a target for 'INSERT' and as a separate source for data insert into v3 (col1) values ((select max(col1) from v1)); ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v3'. insert into v3 (col1) values ((select max(col1) from t1)); diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index c4f4bb4104f..726c8712917 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -135,4 +135,7 @@ select * from t1; a flush tables; create table t1 (a int) engine=archive; +ERROR 42S01: Table 't1' already exists +flush tables; +create table t1 (a int) engine=archive; drop table t1; diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 8dfe09f7b33..144a5dbdcf9 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -125,6 +125,10 @@ create table t1 (a int) engine=archive; select * from t1; flush tables; remove_file $mysqld_datadir/test/t1.ARZ; +--error ER_TABLE_EXISTS_ERROR +create table t1 (a int) engine=archive; +remove_file $mysqld_datadir/test/t1.frm; +flush tables; create table t1 (a int) engine=archive; drop table t1; diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result index 96b6d3171f0..e6d98159b39 100644 --- a/mysql-test/suite/funcs_1/r/innodb_views.result +++ b/mysql-test/suite/funcs_1/r/innodb_views.result @@ -7579,7 +7579,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT * FROM test.tb2 limit 2' at line 1 CREATE OR REPLACE TEMPORARY VIEW test.v1 AS SELECT * FROM test.tb2 limit 2 ; -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 'TEMPORARY VIEW test.v1 AS +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 'VIEW test.v1 AS SELECT * FROM test.tb2 limit 2' at line 1 Drop view if exists test.v1 ; Use test; diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result index ddde31b76d1..21990c2bd9d 100644 --- a/mysql-test/suite/funcs_1/r/memory_views.result +++ b/mysql-test/suite/funcs_1/r/memory_views.result @@ -7580,7 +7580,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT * FROM test.tb2 limit 2' at line 1 CREATE OR REPLACE TEMPORARY VIEW test.v1 AS SELECT * FROM test.tb2 limit 2 ; -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 'TEMPORARY VIEW test.v1 AS +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 'VIEW test.v1 AS SELECT * FROM test.tb2 limit 2' at line 1 Drop view if exists test.v1 ; Use test; diff --git a/mysql-test/suite/funcs_1/r/myisam_views-big.result b/mysql-test/suite/funcs_1/r/myisam_views-big.result index 39782f8d2c5..55704135530 100644 --- a/mysql-test/suite/funcs_1/r/myisam_views-big.result +++ b/mysql-test/suite/funcs_1/r/myisam_views-big.result @@ -8400,7 +8400,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT * FROM test.tb2 limit 2' at line 1 CREATE OR REPLACE TEMPORARY VIEW test.v1 AS SELECT * FROM test.tb2 limit 2 ; -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 'TEMPORARY VIEW test.v1 AS +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 'VIEW test.v1 AS SELECT * FROM test.tb2 limit 2' at line 1 Drop view if exists test.v1 ; Use test; diff --git a/mysql-test/suite/rpl/disabled.def b/mysql-test/suite/rpl/disabled.def index 5cc3916b614..de3091a56e5 100644 --- a/mysql-test/suite/rpl/disabled.def +++ b/mysql-test/suite/rpl/disabled.def @@ -10,7 +10,6 @@ # ############################################################################## -rpl_row_create_table : Bug#11759274 2010-02-27 andrei failed different way than earlier with bug#45576 rpl_spec_variables : BUG#11755836 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition with archive table diff --git a/mysql-test/suite/rpl/r/create_or_replace_mix.result b/mysql-test/suite/rpl/r/create_or_replace_mix.result new file mode 100644 index 00000000000..096379c13ea --- /dev/null +++ b/mysql-test/suite/rpl/r/create_or_replace_mix.result @@ -0,0 +1,162 @@ +include/rpl_init.inc [topology=1->2] +create table t2 (a int) engine=myisam; +insert into t2 values (0),(1),(2),(2); +create temporary table t3 (a_in_temporary int) engine=myisam; +# +# Check how create table and create or replace table are logged +# +create table t1 (to_be_deleted int); +CREATE TABLE t1 AS SELECT 1 AS f1; +CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1; +CREATE OR REPLACE table t1 like t2; +CREATE OR REPLACE table t1 like t3; +drop table t1; +binlog from server 1 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t2 (a int) engine=myisam +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; insert into t2 values (0),(1),(2),(2) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create temporary table t3 (a_in_temporary int) engine=myisam +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 AS SELECT 1 AS f1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t2 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t3 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t2 (a int) engine=myisam +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; insert into t2 values (0),(1),(2),(2) +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create temporary table t3 (a_in_temporary int) engine=myisam +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (to_be_deleted int) +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE TABLE t1 AS SELECT 1 AS f1 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t2 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t3 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ +# +# Ensure that also failed create_or_replace are logged +# +create table t1 (a int); +create or replace table t1; +ERROR 42000: A table must have at least 1 column +drop table if exists t1; +Warnings: +Note 1051 Unknown table 'test.t1' +create or replace table t1 (a int primary key) select a from t2; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +create table t1 (a int); +create or replace table t1 (a int primary key) select a from t2; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +binlog from server 1 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create or replace table t1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +show tables; +Tables_in_test +t1 +t2 +drop table if exists t1,t2; +Warnings: +Note 1051 Unknown table 'test.t1' +# +# Ensure that CREATE are run as CREATE OR REPLACE on slave +# +create table t1 (server_2_to_be_delete int); +create table t1 (new_table int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `new_table` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# +# Ensure that DROP TABLE is run as DROP IF NOT EXISTS +# +create table t1 (server_1_ver_1 int); +create table t4 (server_1_ver_2 int); +drop table t1; +drop table t1,t4; +create table t1 (server_2_ver_2 int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `server_2_ver_2` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t4` /* generated by server */ +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (server_2_ver_2 int) +drop table t1; +# +# Ensure that CREATE ... SELECT is recorded as one GTID on the slave +# +create table t1 (a int); +insert into t1 values (0),(1),(2); +create table t2 engine=myisam select * from t1; +create or replace table t2 engine=innodb select * from t1; +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (a int) +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM +slave-bin.000001 # Table_map # # table_id: # (test.t2) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB +slave-bin.000001 # Table_map # # table_id: # (test.t2) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Xid # # COMMIT /* XID */ +drop table t1; +drop table t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/create_or_replace_row.result b/mysql-test/suite/rpl/r/create_or_replace_row.result new file mode 100644 index 00000000000..beb4976953e --- /dev/null +++ b/mysql-test/suite/rpl/r/create_or_replace_row.result @@ -0,0 +1,184 @@ +include/rpl_init.inc [topology=1->2] +create table t2 (a int) engine=myisam; +insert into t2 values (0),(1),(2),(2); +create temporary table t3 (a_in_temporary int) engine=myisam; +# +# Check how create table and create or replace table are logged +# +create table t1 (to_be_deleted int); +CREATE TABLE t1 AS SELECT 1 AS f1; +CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1; +CREATE OR REPLACE table t1 like t2; +CREATE OR REPLACE table t1 like t3; +drop table t1; +binlog from server 1 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t2 (a int) engine=myisam +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE `t1` ( + `f1` int(1) NOT NULL DEFAULT '0' +) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` ( + `f1` int(1) NOT NULL DEFAULT '0' +) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t2 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` ( + `a_in_temporary` int(11) DEFAULT NULL +) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t2 (a int) engine=myisam +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Table_map # # table_id: # (test.t2) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (to_be_deleted int) +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE TABLE `t1` ( + `f1` int(1) NOT NULL DEFAULT '0' +) +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` ( + `f1` int(1) NOT NULL DEFAULT '0' +) +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t2 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` ( + `a_in_temporary` int(11) DEFAULT NULL +) +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ +# +# Ensure that also failed create_or_replace are logged +# +create table t1 (a int); +create or replace table t1; +ERROR 42000: A table must have at least 1 column +drop table if exists t1; +Warnings: +Note 1051 Unknown table 'test.t1' +create or replace table t1 (a int primary key) select a from t2; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +create table t1 (a int); +create or replace table t1 (a int primary key) select a from t2; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +binlog from server 1 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create or replace table t1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t1` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +show tables; +Tables_in_test +t1 +t2 +drop table if exists t1,t2; +Warnings: +Note 1051 Unknown table 'test.t1' +# +# Ensure that CREATE are run as CREATE OR REPLACE on slave +# +create table t1 (server_2_to_be_delete int); +create table t1 (new_table int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `new_table` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# +# Ensure that DROP TABLE is run as DROP IF NOT EXISTS +# +create table t1 (server_1_ver_1 int); +create table t4 (server_1_ver_2 int); +drop table t1; +drop table t1,t4; +create table t1 (server_2_ver_2 int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `server_2_ver_2` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t4` /* generated by server */ +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (server_2_ver_2 int) +drop table t1; +# +# Ensure that CREATE ... SELECT is recorded as one GTID on the slave +# +create table t1 (a int); +insert into t1 values (0),(1),(2); +create table t2 engine=myisam select * from t1; +create or replace table t2 engine=innodb select * from t1; +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (a int) +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Table_map # # table_id: # (test.t1) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM +slave-bin.000001 # Table_map # # table_id: # (test.t2) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB +slave-bin.000001 # Table_map # # table_id: # (test.t2) +slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +slave-bin.000001 # Xid # # COMMIT /* XID */ +drop table t1; +drop table t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/create_or_replace_statement.result b/mysql-test/suite/rpl/r/create_or_replace_statement.result new file mode 100644 index 00000000000..de139ff0f7b --- /dev/null +++ b/mysql-test/suite/rpl/r/create_or_replace_statement.result @@ -0,0 +1,144 @@ +include/rpl_init.inc [topology=1->2] +create table t2 (a int) engine=myisam; +insert into t2 values (0),(1),(2),(2); +create temporary table t3 (a_in_temporary int) engine=myisam; +# +# Check how create table and create or replace table are logged +# +create table t1 (to_be_deleted int); +CREATE TABLE t1 AS SELECT 1 AS f1; +CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1; +CREATE OR REPLACE table t1 like t2; +CREATE OR REPLACE table t1 like t3; +drop table t1; +binlog from server 1 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t2 (a int) engine=myisam +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `test`; insert into t2 values (0),(1),(2),(2) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create temporary table t3 (a_in_temporary int) engine=myisam +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 AS SELECT 1 AS f1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t2 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t3 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t2 (a int) engine=myisam +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; insert into t2 values (0),(1),(2),(2) +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create temporary table t3 (a_in_temporary int) engine=myisam +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (to_be_deleted int) +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE TABLE t1 AS SELECT 1 AS f1 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t2 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE table t1 like t3 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ +# +# Ensure that also failed create_or_replace are logged +# +create table t1 (a int); +create or replace table t1; +ERROR 42000: A table must have at least 1 column +drop table if exists t1; +Warnings: +Note 1051 Unknown table 'test.t1' +create or replace table t1 (a int primary key) select a from t2; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +create table t1 (a int); +create or replace table t1 (a int primary key) select a from t2; +ERROR 23000: Duplicate entry '2' for key 'PRIMARY' +binlog from server 1 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create or replace table t1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t1 (a int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create or replace table t1 (a int primary key) select a from t2 +show tables; +Tables_in_test +t2 +drop table if exists t1,t2; +Warnings: +Note 1051 Unknown table 'test.t1' +# +# Ensure that CREATE are run as CREATE OR REPLACE on slave +# +create table t1 (server_2_to_be_delete int); +create table t1 (new_table int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `new_table` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +# +# Ensure that DROP TABLE is run as DROP IF NOT EXISTS +# +create table t1 (server_1_ver_1 int); +create table t4 (server_1_ver_2 int); +drop table t1; +drop table t1,t4; +create table t1 (server_2_ver_2 int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `server_2_ver_2` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t1`,`t4` /* generated by server */ +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (server_2_ver_2 int) +drop table t1; +# +# Ensure that CREATE ... SELECT is recorded as one GTID on the slave +# +create table t1 (a int); +insert into t1 values (0),(1),(2); +create table t2 engine=myisam select * from t1; +create or replace table t2 engine=innodb select * from t1; +binlog from server 2 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t1 (a int) +slave-bin.000001 # Gtid # # BEGIN GTID #-#-# +slave-bin.000001 # Query # # use `test`; insert into t1 values (0),(1),(2) +slave-bin.000001 # Query # # COMMIT +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create table t2 engine=myisam select * from t1 +slave-bin.000001 # Gtid # # GTID #-#-# +slave-bin.000001 # Query # # use `test`; create or replace table t2 engine=innodb select * from t1 +drop table t1; +drop table t2; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_gtid_startpos.result b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result index 9be5903b2e9..1c9f771b5cc 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_startpos.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result @@ -110,6 +110,8 @@ DROP TABLE t1; SET SQL_LOG_BIN=1; RESET SLAVE; SET GLOBAL gtid_slave_pos=""; +SET @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; +SET GLOBAL slave_ddl_exec_mode=STRICT; include/start_slave.inc SELECT * FROM t1 ORDER BY a; a @@ -225,4 +227,5 @@ a 1 2 DROP TABLE t1; +set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_create_table.result b/mysql-test/suite/rpl/r/rpl_row_create_table.result index 393e2fdb851..07822a39b46 100644 --- a/mysql-test/suite/rpl/r/rpl_row_create_table.result +++ b/mysql-test/suite/rpl/r/rpl_row_create_table.result @@ -1,23 +1,24 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -**** Resetting master and slave **** -include/stop_slave.inc -RESET SLAVE; -RESET MASTER; -include/start_slave.inc -CREATE TABLE t1 (a INT, b INT); +include/master-slave.inc +[connection master] +include/wait_for_slave_to_stop.inc +include/wait_for_slave_to_start.inc +include/rpl_reset.inc +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 (a INT, b INT); CREATE TABLE t2 (a INT, b INT) ENGINE=Merge; CREATE TABLE t3 (a INT, b INT) CHARSET=utf8; CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8; -show binlog events from <binlog_start>; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE t1 (a INT, b INT) +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a INT, b INT) ENGINE=Merge +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE t3 (a INT, b INT) CHARSET=utf8 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8 **** On Master **** SHOW CREATE TABLE t1; @@ -111,15 +112,10 @@ NULL 3 6 NULL 4 2 NULL 5 10 NULL 6 12 -**** Resetting master and slave **** -include/stop_slave.inc -RESET SLAVE; -RESET MASTER; -include/start_slave.inc +include/rpl_reset.inc CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; ERROR 23000: Duplicate entry '2' for key 'b' -show binlog events from <binlog_start>; -Log_name Pos Event_type Server_id End_log_pos Info +include/show_binlog_events.inc CREATE TABLE t7 (a INT, b INT UNIQUE); INSERT INTO t7 SELECT a,b FROM tt3; ERROR 23000: Duplicate entry '2' for key 'b' @@ -128,23 +124,20 @@ a b 1 2 2 4 3 6 -show binlog events from <binlog_start>; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE) -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.t7) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT SELECT * FROM t7 ORDER BY a,b; a b 1 2 2 4 3 6 -**** Resetting master and slave **** -include/stop_slave.inc -RESET SLAVE; -RESET MASTER; -include/start_slave.inc +include/rpl_reset.inc CREATE TEMPORARY TABLE tt4 (a INT, b INT); INSERT INTO tt4 VALUES (4,8), (5,10), (6,12); BEGIN; @@ -152,11 +145,11 @@ INSERT INTO t7 SELECT a,b FROM tt4; ROLLBACK; Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back -show binlog events from <binlog_start>; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.t7) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT SELECT * FROM t7 ORDER BY a,b; a b @@ -174,11 +167,7 @@ a b 4 8 5 10 6 12 -**** Resetting master and slave **** -include/stop_slave.inc -RESET SLAVE; -RESET MASTER; -include/start_slave.inc +include/rpl_reset.inc CREATE TABLE t8 LIKE t4; CREATE TABLE t9 LIKE tt4; CREATE TEMPORARY TABLE tt5 LIKE t4; @@ -197,9 +186,11 @@ Create Table CREATE TABLE `t9` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -show binlog events from <binlog_start>; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE t8 LIKE t4 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE `t9` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL @@ -219,15 +210,12 @@ Create Table CREATE TABLE `t9` ( ) ENGINE=MEMORY DEFAULT CHARSET=latin1 DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9; STOP SLAVE; +include/wait_for_slave_to_stop.inc SET GLOBAL storage_engine=@storage_engine; START SLAVE; +include/wait_for_slave_to_start.inc ================ BUG#22864 ================ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; +include/rpl_reset.inc SET AUTOCOMMIT=0; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2),(3); @@ -270,37 +258,38 @@ a 1 2 3 -show binlog events from <binlog_start>; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT) -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB master-bin.000001 # Table_map # # table_id: # (test.t3) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE `t4` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB master-bin.000001 # Table_map # # table_id: # (test.t4) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT SHOW TABLES; Tables_in_test @@ -333,10 +322,7 @@ a 3 DROP TABLE IF EXISTS t1,t2,t3,t4; SET AUTOCOMMIT=1; -STOP SLAVE; -RESET SLAVE; -RESET MASTER; -START SLAVE; +include/rpl_reset.inc CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2),(3); CREATE TABLE t2 (a INT) ENGINE=INNODB; @@ -355,19 +341,21 @@ a 4 6 9 -show binlog events from <binlog_start>; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT) -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.t1) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Table_map # # table_id: # (test.t2) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Xid # # COMMIT /* XID */ SELECT * FROM t2 ORDER BY a; a @@ -377,11 +365,7 @@ a 6 9 TRUNCATE TABLE t2; -**** Resetting master and slave **** -include/stop_slave.inc -RESET SLAVE; -RESET MASTER; -include/start_slave.inc +include/rpl_reset.inc BEGIN; INSERT INTO t2 SELECT a*a FROM t1; CREATE TEMPORARY TABLE tt2 @@ -394,8 +378,14 @@ Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back SELECT * FROM t2 ORDER BY a; a -show binlog events from <binlog_start>; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK SELECT * FROM t2 ORDER BY a; a DROP TABLE t1,t2; @@ -412,35 +402,28 @@ a 1 2 DROP TABLE t1; -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; +include/rpl_reset.inc DROP DATABASE IF EXISTS mysqltest1; CREATE DATABASE mysqltest1; CREATE TABLE mysqltest1.without_select (f1 BIGINT); CREATE TABLE mysqltest1.with_select AS SELECT 1 AS f1; -show binlog events from <binlog_start>; +include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP DATABASE IF EXISTS mysqltest1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # CREATE DATABASE mysqltest1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE mysqltest1.without_select (f1 BIGINT) -master-bin.000001 # Query # # BEGIN +master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; CREATE TABLE `mysqltest1`.`with_select` ( `f1` int(1) NOT NULL DEFAULT '0' ) master-bin.000001 # Table_map # # table_id: # (mysqltest1.with_select) -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT DROP DATABASE mysqltest1; -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; +include/rpl_reset.inc CREATE TEMPORARY TABLE t7(c1 INT); CREATE TABLE t5(c1 INT); CREATE TABLE t4(c1 INT); @@ -461,4 +444,5 @@ DROP VIEW IF EXISTS bug48506_t1, bug48506_t2, bug48506_t3; DROP TEMPORARY TABLES t7; DROP TABLES t4, t5; DROP TABLES IF EXISTS bug48506_t4; +include/rpl_end.inc end of the tests diff --git a/mysql-test/suite/rpl/r/rpl_row_log.result b/mysql-test/suite/rpl/r/rpl_row_log.result index d3d5b42c80a..83ec26486e0 100644 --- a/mysql-test/suite/rpl/r/rpl_row_log.result +++ b/mysql-test/suite/rpl/r/rpl_row_log.result @@ -6,6 +6,8 @@ reset master; reset slave; start slave; include/wait_for_slave_to_start.inc +set @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; +set @@global.slave_ddl_exec_mode=STRICT; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM; insert into t1 values (NULL); drop table t1; @@ -287,4 +289,5 @@ a b 5 1 6 1 drop table t1; +set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result index 5dd5ff1b4ff..3b9733a18e8 100644 --- a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result @@ -6,6 +6,8 @@ reset master; reset slave; start slave; include/wait_for_slave_to_start.inc +set @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; +set @@global.slave_ddl_exec_mode=STRICT; create table t1(n int not null auto_increment primary key)ENGINE=InnoDB; insert into t1 values (NULL); drop table t1; @@ -287,4 +289,5 @@ a b 5 1 6 1 drop table t1; +set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result b/mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result index 9872316dc97..a132b50a471 100644 --- a/mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result +++ b/mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result @@ -172,7 +172,7 @@ include/show_events.inc Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 slave-bin.000002 # Gtid # # GTID #-#-# -slave-bin.000002 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ ******** [slave] SHOW BINLOG EVENTS IN <FILE> LIMIT 2 ******** include/show_events.inc Log_name Pos Event_type Server_id End_log_pos Info @@ -181,7 +181,7 @@ slave-bin.000002 # Gtid # # GTID #-#-# ******** [slave] SHOW BINLOG EVENTS IN <FILE> LIMIT 2,3 ******** include/show_events.inc Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000002 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ ******** [slave] SHOW BINLOG EVENTS ******** include/show_events.inc Log_name Pos Event_type Server_id End_log_pos Info diff --git a/mysql-test/suite/rpl/r/rpl_stm_log.result b/mysql-test/suite/rpl/r/rpl_stm_log.result index 360a0e526de..da925035c9c 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_log.result +++ b/mysql-test/suite/rpl/r/rpl_stm_log.result @@ -6,6 +6,8 @@ reset master; reset slave; start slave; include/wait_for_slave_to_start.inc +set @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; +set @@global.slave_ddl_exec_mode=STRICT; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM; insert into t1 values (NULL); drop table t1; @@ -286,4 +288,5 @@ a b 5 1 6 1 drop table t1; +set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result b/mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result index 57d84eef52e..69e144b5cd1 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result +++ b/mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result @@ -154,7 +154,7 @@ include/show_events.inc Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 slave-bin.000002 # Gtid # # GTID #-#-# -slave-bin.000002 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ ******** [slave] SHOW BINLOG EVENTS IN <FILE> LIMIT 2 ******** include/show_events.inc Log_name Pos Event_type Server_id End_log_pos Info @@ -163,7 +163,7 @@ slave-bin.000002 # Gtid # # GTID #-#-# ******** [slave] SHOW BINLOG EVENTS IN <FILE> LIMIT 2,3 ******** include/show_events.inc Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000002 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-bin.000002 # Query # # use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ ******** [slave] SHOW BINLOG EVENTS ******** include/show_events.inc Log_name Pos Event_type Server_id End_log_pos Info diff --git a/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result b/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result index a0102baacfe..1933b0b82f8 100644 --- a/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result +++ b/mysql-test/suite/rpl/r/rpl_temp_table_mix_row.result @@ -62,7 +62,7 @@ slave-bin.000001 # Query # # use `test`; ALTER TABLE t1_tmp ADD COLUMN b INT slave-bin.000001 # Gtid # # GTID #-#-# slave-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t1_tmp` /* generated by server */ slave-bin.000001 # Gtid # # GTID #-#-# -slave-bin.000001 # Query # # use `test`; DROP TABLE `t2` /* generated by server */ +slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t2` /* generated by server */ slave-bin.000001 # Gtid # # BEGIN GTID #-#-# slave-bin.000001 # Table_map # # table_id: # (test.t1) slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F @@ -73,7 +73,7 @@ slave-bin.000001 # Gtid # # BEGIN GTID #-#-# slave-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (2) slave-bin.000001 # Xid # # COMMIT /* XID */ slave-bin.000001 # Gtid # # GTID #-#-# -slave-bin.000001 # Query # # use `test`; DROP TABLE `t3`,`t1` /* generated by server */ +slave-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS `t3`,`t1` /* generated by server */ # Bug#55478 Row events wrongly apply on the temporary table of the same name # ========================================================================== diff --git a/mysql-test/suite/rpl/t/create_or_replace.inc b/mysql-test/suite/rpl/t/create_or_replace.inc new file mode 100644 index 00000000000..8cabd8f12bf --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace.inc @@ -0,0 +1,137 @@ +# Test CREATE OR REPLACE TABLE in replication +--source include/have_innodb.inc + +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +# Create help tables +create table t2 (a int) engine=myisam; +insert into t2 values (0),(1),(2),(2); +create temporary table t3 (a_in_temporary int) engine=myisam; + +--echo # +--echo # Check how create table and create or replace table are logged +--echo # + +save_master_pos; +connection server_2; +sync_with_master; +create table t1 (to_be_deleted int); + +connection server_1; +CREATE TABLE t1 AS SELECT 1 AS f1; +CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1; +CREATE OR REPLACE table t1 like t2; +CREATE OR REPLACE table t1 like t3; +drop table t1; + +--echo binlog from server 1 +--source include/show_binlog_events.inc +save_master_pos; +connection server_2; +sync_with_master; +--echo binlog from server 2 +--source include/show_binlog_events.inc + +connection server_1; + +--echo # +--echo # Ensure that also failed create_or_replace are logged +--echo # + +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) + +create table t1 (a int); +--error ER_TABLE_MUST_HAVE_COLUMNS +create or replace table t1; +drop table if exists t1; +# The following is not logged as t1 does not exists; +--error ER_DUP_ENTRY +create or replace table t1 (a int primary key) select a from t2; + +create table t1 (a int); +# This should be logged as we will delete t1 +--error ER_DUP_ENTRY +create or replace table t1 (a int primary key) select a from t2; + +--echo binlog from server 1 +--source include/show_binlog_events.inc +save_master_pos; +connection server_2; +sync_with_master; +show tables; +connection server_1; + +drop table if exists t1,t2; + +--echo # +--echo # Ensure that CREATE are run as CREATE OR REPLACE on slave +--echo # + +save_master_pos; +connection server_2; +sync_with_master; +create table t1 (server_2_to_be_delete int); +connection server_1; +create table t1 (new_table int); + +save_master_pos; +connection server_2; +sync_with_master; + +show create table t1; +connection server_1; +drop table t1; + +--echo # +--echo # Ensure that DROP TABLE is run as DROP IF NOT EXISTS +--echo # + +create table t1 (server_1_ver_1 int); +create table t4 (server_1_ver_2 int); + +save_master_pos; +connection server_2; +sync_with_master; +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) + +# Drop the table on the slave +drop table t1; +connection server_1; +drop table t1,t4; +create table t1 (server_2_ver_2 int); +save_master_pos; +connection server_2; +sync_with_master; +show create table t1; +--echo binlog from server 2 +--source include/show_binlog_events.inc +connection server_1; +drop table t1; + +--echo # +--echo # Ensure that CREATE ... SELECT is recorded as one GTID on the slave +--echo # + +save_master_pos; +connection server_2; +sync_with_master; +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) +connection server_1; + +create table t1 (a int); +insert into t1 values (0),(1),(2); +create table t2 engine=myisam select * from t1; +create or replace table t2 engine=innodb select * from t1; +save_master_pos; +connection server_2; +sync_with_master; +--echo binlog from server 2 +--source include/show_binlog_events.inc +connection server_1; +drop table t1; + +# Clean up +drop table t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/create_or_replace_mix.cnf b/mysql-test/suite/rpl/t/create_or_replace_mix.cnf new file mode 100644 index 00000000000..03d69b2864f --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_mix.cnf @@ -0,0 +1,9 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb diff --git a/mysql-test/suite/rpl/t/create_or_replace_mix.test b/mysql-test/suite/rpl/t/create_or_replace_mix.test new file mode 100644 index 00000000000..0cabef15ad7 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_mix.test @@ -0,0 +1,4 @@ +# Testing create or replace table in mixed mode. + +--source include/have_binlog_format_mixed.inc +--source create_or_replace.inc diff --git a/mysql-test/suite/rpl/t/create_or_replace_row.cnf b/mysql-test/suite/rpl/t/create_or_replace_row.cnf new file mode 100644 index 00000000000..03d69b2864f --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_row.cnf @@ -0,0 +1,9 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb diff --git a/mysql-test/suite/rpl/t/create_or_replace_row.test b/mysql-test/suite/rpl/t/create_or_replace_row.test new file mode 100644 index 00000000000..88dd8fd2d74 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_row.test @@ -0,0 +1,4 @@ +# Testing create or replace table in mixed mode. + +--source include/have_binlog_format_row.inc +--source create_or_replace.inc diff --git a/mysql-test/suite/rpl/t/create_or_replace_statement.cnf b/mysql-test/suite/rpl/t/create_or_replace_statement.cnf new file mode 100644 index 00000000000..03d69b2864f --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_statement.cnf @@ -0,0 +1,9 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb diff --git a/mysql-test/suite/rpl/t/create_or_replace_statement.test b/mysql-test/suite/rpl/t/create_or_replace_statement.test new file mode 100644 index 00000000000..2709e4142f4 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_statement.test @@ -0,0 +1,4 @@ +# Testing create or replace table in mixed mode. + +--source include/have_binlog_format_statement.inc +--source create_or_replace.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test index 72f1201c93c..b27250f908f 100644 --- a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test +++ b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test @@ -52,6 +52,8 @@ CREATE DATABASE IF NOT EXISTS mysqltest; USE mysqltest; CREATE TABLE IF NOT EXISTS t(c1 int); CREATE TABLE IF NOT EXISTS t1 LIKE t; +# The following will not be logged because t2 existed and we will not +# put the data of SELECT into the binary log CREATE TABLE IF NOT EXISTS t2 SELECT * FROM t; CREATE EVENT IF NOT EXISTS e ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR @@ -104,7 +106,7 @@ SELECT * FROM t1; SELECT * FROM t2; sync_slave_with_master; -# In these two statements, t1 and t2 are the base table. The recoreds of t2 +# In these two statements, t1 and t2 are the base table. The records of t2 # are inserted into it when CREATE TABLE ... SELECT was executed. SELECT * FROM t1; SELECT * FROM t2; diff --git a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test index 0797eead0ee..323e86426ce 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test @@ -165,7 +165,7 @@ SET GLOBAL gtid_slave_pos=""; SELECT * FROM t1 ORDER BY a; -# Same thing, but this time using SQL_LOG_BIN=0 to avoid polliting the +# Same thing, but this time using SQL_LOG_BIN=0 to avoid polluting the # slave binlog. --connection server_2 @@ -175,6 +175,9 @@ DROP TABLE t1; SET SQL_LOG_BIN=1; RESET SLAVE; SET GLOBAL gtid_slave_pos=""; +# Ensure that the slave fails because of missing table to be dropped +SET @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; +SET GLOBAL slave_ddl_exec_mode=STRICT; --source include/start_slave.inc --sync_with_master @@ -349,6 +352,7 @@ SELECT * FROM t1 ORDER BY a; # Clean up. --connection server_1 DROP TABLE t1; - +--connection server_2 +set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_create_table.test b/mysql-test/suite/rpl/t/rpl_row_create_table.test index ef3c0758643..da73d753dcd 100644 --- a/mysql-test/suite/rpl/t/rpl_row_create_table.test +++ b/mysql-test/suite/rpl/t/rpl_row_create_table.test @@ -28,7 +28,8 @@ START SLAVE; --source include/rpl_reset.inc connection master; -CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 (a INT, b INT); CREATE TABLE t2 (a INT, b INT) ENGINE=Merge; CREATE TABLE t3 (a INT, b INT) CHARSET=utf8; CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8; diff --git a/mysql-test/suite/rpl/t/rpl_stm_log.test b/mysql-test/suite/rpl/t/rpl_stm_log.test index 7e7e1d4033f..23130528465 100644 --- a/mysql-test/suite/rpl/t/rpl_stm_log.test +++ b/mysql-test/suite/rpl/t/rpl_stm_log.test @@ -4,7 +4,5 @@ let $engine_type=MyISAM; -- source extra/rpl_tests/rpl_log.test - # End of 4.1 tests -# Adding comment for force manual merge 5.0 -> wl1012: Delete me --source include/rpl_end.inc diff --git a/mysql-test/suite/sys_vars/r/back_log_basic.result b/mysql-test/suite/sys_vars/r/back_log_basic.result index 5cfb0da65d6..d68e72a8a4a 100644 --- a/mysql-test/suite/sys_vars/r/back_log_basic.result +++ b/mysql-test/suite/sys_vars/r/back_log_basic.result @@ -1,20 +1,20 @@ select @@global.back_log; @@global.back_log -50 +150 select @@session.back_log; ERROR HY000: Variable 'back_log' is a GLOBAL variable show global variables like 'back_log'; Variable_name Value -back_log 50 +back_log 150 show session variables like 'back_log'; Variable_name Value -back_log 50 +back_log 150 select * from information_schema.global_variables where variable_name='back_log'; VARIABLE_NAME VARIABLE_VALUE -BACK_LOG 50 +BACK_LOG 150 select * from information_schema.session_variables where variable_name='back_log'; VARIABLE_NAME VARIABLE_VALUE -BACK_LOG 50 +BACK_LOG 150 set global back_log=1; ERROR HY000: Variable 'back_log' is a read only variable set session back_log=1; diff --git a/mysql-test/suite/sys_vars/r/slave_ddl_exec_mode_basic.result b/mysql-test/suite/sys_vars/r/slave_ddl_exec_mode_basic.result new file mode 100644 index 00000000000..e758e61f648 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/slave_ddl_exec_mode_basic.result @@ -0,0 +1,39 @@ +SET @start_value = @@global.slave_ddl_exec_mode; +SELECT @@global.slave_ddl_exec_mode; +@@global.slave_ddl_exec_mode +IDEMPOTENT +SELECT @@slave_ddl_exec_mode = @@GLOBAL.slave_ddl_exec_mode; +@@slave_ddl_exec_mode = @@GLOBAL.slave_ddl_exec_mode +1 +1 Expected +SELECT COUNT(@@slave_ddl_exec_mode); +COUNT(@@slave_ddl_exec_mode) +1 +1 Expected +SELECT COUNT(@@local.slave_ddl_exec_mode); +ERROR HY000: Variable 'slave_ddl_exec_mode' is a GLOBAL variable +Expected error 'Variable is a GLOBAL variable' +SELECT COUNT(@@SESSION.slave_ddl_exec_mode); +ERROR HY000: Variable 'slave_ddl_exec_mode' is a GLOBAL variable +Expected error 'Variable is a GLOBAL variable' +SELECT COUNT(@@GLOBAL.slave_ddl_exec_mode); +COUNT(@@GLOBAL.slave_ddl_exec_mode) +1 +1 Expected +SELECT slave_ddl_exec_mode = @@SESSION.version; +ERROR 42S22: Unknown column 'slave_ddl_exec_mode' in 'field list' +Expected error 'Readonly variable' +SET @@GLOBAL.slave_ddl_exec_mode=STRICT; +SELECT @@GLOBAL.slave_ddl_exec_mode; +@@GLOBAL.slave_ddl_exec_mode +STRICT +SET @@GLOBAL.slave_ddl_exec_mode=IDEMPOTENT; +SELECT @@GLOBAL.slave_ddl_exec_mode; +@@GLOBAL.slave_ddl_exec_mode +IDEMPOTENT +SET @@GLOBAL.slave_ddl_exec_mode=XXX; +ERROR 42000: Variable 'slave_ddl_exec_mode' can't be set to the value of 'XXX' +SELECT @@GLOBAL.slave_ddl_exec_mode; +@@GLOBAL.slave_ddl_exec_mode +IDEMPOTENT +SET @@global.slave_ddl_exec_mode= @start_value; diff --git a/mysql-test/suite/sys_vars/r/version_malloc_library_basic.result b/mysql-test/suite/sys_vars/r/version_malloc_library_basic.result new file mode 100644 index 00000000000..5895b8122d9 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/version_malloc_library_basic.result @@ -0,0 +1,53 @@ +'#---------------------BS_STVARS_053_01----------------------#' +SELECT COUNT(@@GLOBAL.version_malloc_library); +COUNT(@@GLOBAL.version_malloc_library) +1 +1 Expected +'#---------------------BS_STVARS_053_02----------------------#' +SET @@GLOBAL.version_malloc_library=1; +ERROR HY000: Variable 'version_malloc_library' is a read only variable +Expected error 'Read only variable' +SELECT COUNT(@@GLOBAL.version_malloc_library); +COUNT(@@GLOBAL.version_malloc_library) +1 +1 Expected +'#---------------------BS_STVARS_053_03----------------------#' +SELECT @@GLOBAL.version_malloc_library = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='version_malloc_library'; +@@GLOBAL.version_malloc_library = VARIABLE_VALUE +1 +1 Expected +SELECT COUNT(@@GLOBAL.version_malloc_library); +COUNT(@@GLOBAL.version_malloc_library) +1 +1 Expected +SELECT COUNT(VARIABLE_VALUE) +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='version_malloc_library'; +COUNT(VARIABLE_VALUE) +1 +1 Expected +'#---------------------BS_STVARS_053_04----------------------#' +SELECT @@version_malloc_library = @@GLOBAL.version_malloc_library; +@@version_malloc_library = @@GLOBAL.version_malloc_library +1 +1 Expected +'#---------------------BS_STVARS_053_05----------------------#' +SELECT COUNT(@@version_malloc_library); +COUNT(@@version_malloc_library) +1 +1 Expected +SELECT COUNT(@@local.version_malloc_library); +ERROR HY000: Variable 'version_malloc_library' is a GLOBAL variable +Expected error 'Variable is a GLOBAL variable' +SELECT COUNT(@@SESSION.version_malloc_library); +ERROR HY000: Variable 'version_malloc_library' is a GLOBAL variable +Expected error 'Variable is a GLOBAL variable' +SELECT COUNT(@@GLOBAL.version_malloc_library); +COUNT(@@GLOBAL.version_malloc_library) +1 +1 Expected +SELECT version_malloc_library = @@SESSION.version; +ERROR 42S22: Unknown column 'version_malloc_library' in 'field list' +Expected error 'Readonly variable' diff --git a/mysql-test/suite/sys_vars/t/slave_ddl_exec_mode_basic.test b/mysql-test/suite/sys_vars/t/slave_ddl_exec_mode_basic.test new file mode 100644 index 00000000000..64f8a75f443 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/slave_ddl_exec_mode_basic.test @@ -0,0 +1,67 @@ +############## mysql-test\t\slave_ddl_exec_mode_basic.test #################### +# # +# Variable Name: slave_ddl_exec_mode # +# Scope: GLOBAL & SESSION # +# Access Type: Dynamic # +# Data Type: Numeric # +# Default Value: 1 # +# Range: 1 - 65536 # +# # +# # +# Description: Test Cases of Dynamic System Variable slave_ddl_exec_mode # +# that checks the behavior of this variable in the following ways# +# * Default Value # +# * Valid & Invalid values # +# * Scope & Access method # +# * Data Integrity # +# # +############################################################################### + +--source include/not_embedded.inc +--source include/load_sysvars.inc + +######################################################################## +# START OF slave_ddl_exec_mode TESTS # +######################################################################## + +SET @start_value = @@global.slave_ddl_exec_mode; + +SELECT @@global.slave_ddl_exec_mode; + +SELECT @@slave_ddl_exec_mode = @@GLOBAL.slave_ddl_exec_mode; +--echo 1 Expected + +SELECT COUNT(@@slave_ddl_exec_mode); +--echo 1 Expected + +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@local.slave_ddl_exec_mode); +--echo Expected error 'Variable is a GLOBAL variable' + +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@SESSION.slave_ddl_exec_mode); +--echo Expected error 'Variable is a GLOBAL variable' + +SELECT COUNT(@@GLOBAL.slave_ddl_exec_mode); +--echo 1 Expected + +--Error ER_BAD_FIELD_ERROR +SELECT slave_ddl_exec_mode = @@SESSION.version; +--echo Expected error 'Readonly variable' + + +SET @@GLOBAL.slave_ddl_exec_mode=STRICT; +SELECT @@GLOBAL.slave_ddl_exec_mode; + +SET @@GLOBAL.slave_ddl_exec_mode=IDEMPOTENT; +SELECT @@GLOBAL.slave_ddl_exec_mode; + +--error ER_WRONG_VALUE_FOR_VAR +SET @@GLOBAL.slave_ddl_exec_mode=XXX; +SELECT @@GLOBAL.slave_ddl_exec_mode; + +SET @@global.slave_ddl_exec_mode= @start_value; + +######################################################################## +# END OF slave_ddl_exec_mode TESTS # +######################################################################## diff --git a/mysql-test/suite/sys_vars/t/version_malloc_library_basic.test b/mysql-test/suite/sys_vars/t/version_malloc_library_basic.test new file mode 100644 index 00000000000..6318ca4abd5 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/version_malloc_library_basic.test @@ -0,0 +1,90 @@ +################## mysql-test\t\version_malloc_library.test ################### +# # +# Variable Name: version_malloc_library # +# Scope: Global # +# Access Type: Static # +# Data Type: String # +# # +# Description:Test Cases of Dynamic System Variable version # +# that checks the behavior of this variable in the following ways # +# * Value Check # +# * Scope Check # +# # +############################################################################### + +--echo '#---------------------BS_STVARS_053_01----------------------#' +#################################################################### +# Displaying default value # +#################################################################### +SELECT COUNT(@@GLOBAL.version_malloc_library); +--echo 1 Expected + + +--echo '#---------------------BS_STVARS_053_02----------------------#' +#################################################################### +# Check if Value can set # +#################################################################### + +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@GLOBAL.version_malloc_library=1; +--echo Expected error 'Read only variable' + +SELECT COUNT(@@GLOBAL.version_malloc_library); +--echo 1 Expected + + + + +--echo '#---------------------BS_STVARS_053_03----------------------#' +################################################################# +# Check if the value in GLOBAL Table matches value in variable # +################################################################# + +SELECT @@GLOBAL.version_malloc_library = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='version_malloc_library'; +--echo 1 Expected + +SELECT COUNT(@@GLOBAL.version_malloc_library); +--echo 1 Expected + +SELECT COUNT(VARIABLE_VALUE) +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='version_malloc_library'; +--echo 1 Expected + + + +--echo '#---------------------BS_STVARS_053_04----------------------#' +############################################################################### +# Check if accessing variable with and without GLOBAL point to same variable # +############################################################################### +SELECT @@version_malloc_library = @@GLOBAL.version_malloc_library; +--echo 1 Expected + + + +--echo '#---------------------BS_STVARS_053_05----------------------#' +############################################################################### +# Check if version_malloc_library can be accessed with and without @@ sign # +############################################################################### + +SELECT COUNT(@@version_malloc_library); +--echo 1 Expected + +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@local.version_malloc_library); +--echo Expected error 'Variable is a GLOBAL variable' + +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT COUNT(@@SESSION.version_malloc_library); +--echo Expected error 'Variable is a GLOBAL variable' + +SELECT COUNT(@@GLOBAL.version_malloc_library); +--echo 1 Expected + +--Error ER_BAD_FIELD_ERROR +SELECT version_malloc_library = @@SESSION.version; +--echo Expected error 'Readonly variable' + + diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index ebcad5f4af4..8bb7339ce83 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -2014,6 +2014,8 @@ create table t1 (a int, b int); create table t1 (a int, b int) select 2,2; --error ER_TABLE_EXISTS_ERROR create table t1 like t2; +--error ER_LOCK_WAIT_TIMEOUT +create or replace table t1 (a int, b int) select 2,2; disconnect user1; connection default; select * from t1; diff --git a/mysql-test/t/create_or_replace-master.opt b/mysql-test/t/create_or_replace-master.opt new file mode 100644 index 00000000000..e94228f2f33 --- /dev/null +++ b/mysql-test/t/create_or_replace-master.opt @@ -0,0 +1 @@ +--log-output=TABLE,FILE --general-log=1 --slow-query-log=1 diff --git a/mysql-test/t/create_or_replace.test b/mysql-test/t/create_or_replace.test new file mode 100644 index 00000000000..7d6841ab9d2 --- /dev/null +++ b/mysql-test/t/create_or_replace.test @@ -0,0 +1,271 @@ +# +# Check CREATE OR REPLACE ALTER TABLE +# + +--source include/have_innodb.inc +--disable_warnings +drop table if exists t1,t2,t3; +--enable_warnings + +# +# Create help table +# + +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES(1),(2),(3); + +--echo # +--echo # Check first syntax and wrong usage +--echo # + +--error ER_WRONG_USAGE +CREATE OR REPLACE TABLE IF NOT EXISTS t1 (a int); +--error ER_WRONG_USAGE +create or replace trigger trg before insert on t1 for each row set @a:=1; + +# check that we don't try to create a log table in use +--error ER_BAD_LOG_STATEMENT +create or replace table mysql.general_log (a int); +--error ER_BAD_LOG_STATEMENT +create or replace table mysql.slow_log (a int); + +--echo # +--echo # Usage when table doesn't exist +--echo # + +CREATE OR REPLACE TABLE t1 (a int); +--error ER_TABLE_EXISTS_ERROR +CREATE TABLE t1 (a int); +DROP TABLE t1; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int); +--error ER_TABLE_EXISTS_ERROR +CREATE TEMPORARY TABLE t1 (a int, b int, c int); +DROP TEMPORARY TABLE t1; + +--echo # +--echo # Testing with temporary tables +--echo # + +CREATE OR REPLACE TABLE t1 (a int); +CREATE OR REPLACE TEMPORARY TABLE t1 (a int); +CREATE OR REPLACE TEMPORARY TABLE t1 (a int, b int); +SHOW CREATE TABLE t1; +DROP TEMPORARY TABLE t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +# Test also with InnoDB +create temporary table t1 (i int) engine=InnoDB; +create or replace temporary table t1 (a int, b int) engine=InnoDB; +create or replace temporary table t1 (j int); +show create table t1; +drop table t1; + +# Using lock tables on normal tables with create or replace on temp tables +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLES t1 write; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int); +CREATE OR REPLACE TEMPORARY TABLE t1 (a int, b int); +CREATE OR REPLACE TEMPORARY TABLE t1 (a int, b int) engine= innodb; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int) engine= innodb; +CREATE OR REPLACE TEMPORARY TABLE t1 (a int, b int) engine=myisam; +SHOW CREATE TABLE t1; +DROP TEMPORARY TABLE t1; +SHOW CREATE TABLE t1; +# Verify that table is still locked +--error ER_TABLE_NOT_LOCKED +CREATE OR REPLACE TABLE t2 (a int); +DROP TABLE t1; +UNLOCK TABLES; + +# +# Using CREATE SELECT +# + +CREATE OR REPLACE TEMPORARY TABLE t1 (a int) SELECT * from t2; +SELECT * FROM t1; +CREATE OR REPLACE TEMPORARY TABLE t1 (b int) SELECT * from t2; +SELECT * FROM t1; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TEMPORARY TABLE t1 AS SELECT a FROM t2; +CREATE TEMPORARY TABLE IF NOT EXISTS t1(a int, b int) SELECT 1,2 FROM t2; +DROP TABLE t1; + +CREATE TABLE t1 (a int); +CREATE OR REPLACE TABLE t1 AS SELECT 1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +create table t1 (a int); +--error ER_UPDATE_TABLE_USED +create or replace table t1 as select * from t1; +--error ER_UPDATE_TABLE_USED +create or replace table t1 as select a from (select a from t1) as t3; +--error ER_UPDATE_TABLE_USED +create or replace table t1 as select a from t2 where t2.a in (select a from t1); +drop table t1; + +--echo # +--echo # Testing with normal tables +--echo # + +CREATE OR REPLACE TABLE t1 (a int); +CREATE OR REPLACE TABLE t1 (a int, b int); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (a int) SELECT * from t2; +SELECT * FROM t1; +TRUNCATE TABLE t1; +CREATE TABLE IF NOT EXISTS t1 (a int) SELECT * from t2; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (i int); +CREATE OR REPLACE TABLE t1 AS SELECT 1; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +# Using lock tables with CREATE OR REPLACE +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLES t1 write,t2 write; +CREATE OR REPLACE TABLE t1 (a int, b int); +# Verify if table is still locked +SELECT * FROM t1; +INSERT INTO t1 values(1,1); +CREATE OR REPLACE TABLE t1 (a int, b int, c int); +INSERT INTO t1 values(1,1,1); +--error ER_TABLE_NOT_LOCKED +CREATE OR REPLACE TABLE t3 (a int); +UNLOCK TABLES; +DROP TABLE t1; + +# Using lock tables with CREATE OR REPLACE ... SELECT +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLES t1 write,t2 write; +CREATE OR REPLACE TABLE t1 (a int, b int) select a,1 from t2; +# Verify if table is still locked +SELECT * FROM t2; +SELECT * FROM t1; +SELECT * FROM t1; +INSERT INTO t1 values(1,1,1); +CREATE OR REPLACE TABLE t1 (a int, b int, c int, d int); +INSERT INTO t1 values(1,1,1,1); +--error ER_TABLE_NOT_LOCKED +CREATE OR REPLACE TABLE t3 (a int); +UNLOCK TABLES; +DROP TABLE t1; + +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLES t1 write,t2 write, t1 as t1_read read; +CREATE OR REPLACE TABLE t1 (a int, b int) select a,1 from t2; +SELECT * FROM t1; +SELECT * FROM t2; +--error ER_TABLE_NOT_LOCKED +SELECT * FROM t1 as t1_read; +DROP TABLE t1; +UNLOCK TABLES; + +CREATE OR REPLACE TABLE t1 (a int); +LOCK TABLE t1 WRITE; +CREATE OR REPLACE TABLE t1 AS SELECT 1; +SELECT * from t1; +--error ER_TABLE_NOT_LOCKED +SELECT * from t2; +DROP TABLE t1; + +--echo # +--echo # Test also with InnoDB (transactional engine) +--echo # + +create table t1 (i int) engine=innodb; +lock table t1 write; +create or replace table t1 (j int); +unlock tables; +show create table t1; +drop table t1; + +create table t1 (i int) engine=InnoDB; +lock table t1 write, t2 write; +create or replace table t1 (j int) engine=innodb; +unlock tables; +drop table t1; + +create table t1 (i int) engine=InnoDB; +create table t3 (i int) engine=InnoDB; +insert into t3 values(1),(2),(3); +lock table t1 write, t2 write, t3 write; +create or replace table t1 (a int, i int) engine=innodb select t2.a,t3.i from t2,t3; +unlock tables; +select * from t1 order by a,i; +drop table t1,t3; + +--echo # +--echo # Testing CREATE .. LIKE +--echo # + +create or replace table t1 like t2; +create or replace table t1 like t2; +show create table t1; +drop table t1; +create table t1 (b int); +lock tables t1 write, t2 read; +create or replace table t1 like t2; +SELECT * FROM t1; +INSERT INTO t1 values(1); +CREATE OR REPLACE TABLE t1 like t2; +INSERT INTO t1 values(2); +unlock tables; +show create table t1; +drop table t1; + +create or replace table t1 like t2; +--error ER_NONUNIQ_TABLE +create or replace table t1 like t1; +drop table t1; + +CREATE TEMPORARY TABLE t1 like t2; +--error ER_NONUNIQ_TABLE +CREATE OR REPLACE TABLE t1 like t1; +--error ER_NONUNIQ_TABLE +CREATE OR REPLACE TABLE t1 like t1; +drop table t1; + +CREATE TEMPORARY TABLE t1 like t2; +CREATE OR REPLACE TEMPORARY TABLE t3 like t1; +--error ER_NONUNIQ_TABLE +CREATE OR REPLACE TEMPORARY TABLE t3 like t3; +drop table t1,t3; + +--echo # +--echo # Test with prepared statements +--echo # + +prepare stmt1 from 'create or replace table t1 select * from t2'; +execute stmt1; +select * from t1; +execute stmt1; +select * from t1; +drop table t1; +execute stmt1; +select * from t1; +deallocate prepare stmt1; +drop table t1; + +--echo # +--echo # Test with views +--echo # + +create view t1 as select 1; +create table if not exists t1 (a int); +--error ER_IT_IS_A_VIEW +create or replace table t1 (a int); +--error ER_IT_IS_A_VIEW +drop table t1; +drop view t1; + +# +# Cleanup +# +DROP TABLE t2; diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index 1b119ca7ea6..c27fa58f935 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -20,7 +20,9 @@ perl; # their paths may vary: @skipvars=qw/basedir open-files-limit general-log-file log plugin-dir log-slow-queries pid-file slow-query-log-file log-basename - datadir slave-load-tmpdir tmpdir socket thread-pool-size/; + datadir slave-load-tmpdir tmpdir socket thread-pool-size + large-files-support lower-case-file-system system-time-zone + version.*/; # Plugins which may or may not be there: @plugins=qw/innodb ndb archive blackhole federated partition ndbcluster diff --git a/mysql-test/t/partition_exchange.test b/mysql-test/t/partition_exchange.test index d7dfd6f543e..e538bee16cd 100644 --- a/mysql-test/t/partition_exchange.test +++ b/mysql-test/t/partition_exchange.test @@ -439,7 +439,7 @@ CREATE TABLE t LIKE general_log; ALTER TABLE t PARTITION BY RANGE (UNIX_TIMESTAMP(event_time) DIV 1) (PARTITION p0 VALUES LESS THAN (123456789), PARTITION pMAX VALUES LESS THAN MAXVALUE); ---error ER_WRONG_USAGE +--error ER_BAD_LOG_STATEMENT ALTER TABLE t EXCHANGE PARTITION p0 WITH TABLE general_log; ALTER TABLE general_log ENGINE = CSV; SET @@global.general_log = @old_general_log_state; diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index c34800976c7..21355ca42b7 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -1610,7 +1610,7 @@ call p_verify_reprepare_count(0); # Base table with name of table to be created exists --error ER_TABLE_EXISTS_ERROR execute stmt; -call p_verify_reprepare_count(1); +call p_verify_reprepare_count(0); --error ER_TABLE_EXISTS_ERROR execute stmt; call p_verify_reprepare_count(0); @@ -1622,7 +1622,7 @@ execute stmt; call p_verify_reprepare_count(0); --error ER_TABLE_EXISTS_ERROR execute stmt; -call p_verify_reprepare_count(1); +call p_verify_reprepare_count(0); drop temporary table t2; --error ER_TABLE_EXISTS_ERROR execute stmt; @@ -1641,7 +1641,7 @@ drop table t2; create view t2 as select 1; --error ER_TABLE_EXISTS_ERROR,9999 execute stmt; -call p_verify_reprepare_count(1); +call p_verify_reprepare_count(0); --error ER_TABLE_EXISTS_ERROR,9999 execute stmt; call p_verify_reprepare_count(0); diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index c7a7e332236..633624bf4bf 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -141,7 +141,7 @@ drop view v100; drop view t1; # try to drop VIEW with DROP TABLE --- error ER_BAD_TABLE_ERROR +-- error ER_IT_IS_A_VIEW drop table v1; # try to drop table with DROP VIEW diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 754991e9014..fa9e37022d4 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -118,6 +118,15 @@ } { + pthread memalign memory loss2 + Memcheck:Leak + fun:memalign + fun:tls_get_addr_tail + ... + fun:*ha_initialize_handlerton* +} + +{ pthread pthread_key_create Memcheck:Leak fun:malloc diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index 3105f4b1daf..67c478659b5 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -167,10 +167,10 @@ static inline uint get_first_set(my_bitmap_map value, uint word_pos) } -my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, - my_bool thread_safe __attribute__((unused))) +my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, + my_bool thread_safe __attribute__((unused))) { - DBUG_ENTER("bitmap_init"); + DBUG_ENTER("my_bitmap_init"); if (!buf) { uint size_in_bytes= bitmap_buffer_size(n_bits); @@ -202,9 +202,9 @@ my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, } -void bitmap_free(MY_BITMAP *map) +void my_bitmap_free(MY_BITMAP *map) { - DBUG_ENTER("bitmap_free"); + DBUG_ENTER("my_bitmap_free"); if (map->bitmap) { if (map->mutex) diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc index 0ddde226553..f5d892d4a07 100644 --- a/plugin/metadata_lock_info/metadata_lock_info.cc +++ b/plugin/metadata_lock_info/metadata_lock_info.cc @@ -37,6 +37,7 @@ static const LEX_STRING metadata_lock_info_lock_mode[] = { { C_STRING_WITH_LEN("MDL_SHARED_HIGH_PRIO") }, { C_STRING_WITH_LEN("MDL_SHARED_READ") }, { C_STRING_WITH_LEN("MDL_SHARED_WRITE") }, + { C_STRING_WITH_LEN("MDL_SHARED_UPGRADABLE") }, { C_STRING_WITH_LEN("MDL_SHARED_NO_WRITE") }, { C_STRING_WITH_LEN("MDL_SHARED_NO_READ_WRITE") }, { C_STRING_WITH_LEN("MDL_EXCLUSIVE") }, diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index fc53183ca7a..531211eb175 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -446,7 +446,7 @@ int ndbcluster_binlog_init_share(NDB_SHARE *share, TABLE *_table) alloc_root(mem_root, no_nodes * sizeof(MY_BITMAP)); for (i= 0; i < no_nodes; i++) { - bitmap_init(&share->subscriber_bitmap[i], + my_bitmap_init(&share->subscriber_bitmap[i], (Uint32*)alloc_root(mem_root, max_ndb_nodes/8), max_ndb_nodes, FALSE); bitmap_clear_all(&share->subscriber_bitmap[i]); @@ -1119,7 +1119,7 @@ ndbcluster_update_slock(THD *thd, MY_BITMAP slock; uint32 bitbuf[SCHEMA_SLOCK_SIZE/4]; - bitmap_init(&slock, bitbuf, sizeof(bitbuf)*8, false); + my_bitmap_init(&slock, bitbuf, sizeof(bitbuf)*8, false); if (ndbtab == 0) { @@ -1370,7 +1370,7 @@ int ndbcluster_log_schema_op(THD *thd, NDB_SHARE *share, { int i, updated= 0; int no_storage_nodes= g_ndb_cluster_connection->no_db_nodes(); - bitmap_init(&schema_subscribers, bitbuf, sizeof(bitbuf)*8, FALSE); + my_bitmap_init(&schema_subscribers, bitbuf, sizeof(bitbuf)*8, FALSE); bitmap_set_all(&schema_subscribers); /* begin protect ndb_schema_share */ @@ -1908,7 +1908,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb, Cluster_schema *schema= (Cluster_schema *) sql_alloc(sizeof(Cluster_schema)); MY_BITMAP slock; - bitmap_init(&slock, schema->slock, 8*SCHEMA_SLOCK_SIZE, FALSE); + my_bitmap_init(&slock, schema->slock, 8*SCHEMA_SLOCK_SIZE, FALSE); uint node_id= g_ndb_cluster_connection->node_id(); { ndbcluster_get_schema(tmp_share, schema); @@ -3353,7 +3353,7 @@ ndb_binlog_thread_handle_data_event(Ndb *ndb, NdbEventOperation *pOp, MY_BITMAP b; /* Potential buffer for the bitmap */ uint32 bitbuf[128 / (sizeof(uint32) * 8)]; - bitmap_init(&b, n_fields <= sizeof(bitbuf) * 8 ? bitbuf : NULL, + my_bitmap_init(&b, n_fields <= sizeof(bitbuf) * 8 ? bitbuf : NULL, n_fields, FALSE); bitmap_set_all(&b); @@ -3573,7 +3573,7 @@ static NDB_SCHEMA_OBJECT *ndb_get_schema_object(const char *key, break; } mysql_mutex_init(key_ndb_schema_object_mutex, &ndb_schema_object->mutex, MY_MUTEX_INIT_FAST); - bitmap_init(&ndb_schema_object->slock_bitmap, ndb_schema_object->slock, + my_bitmap_init(&ndb_schema_object->slock_bitmap, ndb_schema_object->slock, sizeof(ndb_schema_object->slock)*8, FALSE); bitmap_clear_all(&ndb_schema_object->slock_bitmap); break; diff --git a/sql/ha_ndbcluster_cond.h b/sql/ha_ndbcluster_cond.h index 27675588ed7..9ea0438a348 100644 --- a/sql/ha_ndbcluster_cond.h +++ b/sql/ha_ndbcluster_cond.h @@ -350,18 +350,18 @@ class Ndb_cond_traverse_context : public Sql_alloc skip(0), collation(NULL), rewrite_stack(NULL) { // Allocate type checking bitmaps - bitmap_init(&expect_mask, 0, 512, FALSE); - bitmap_init(&expect_field_type_mask, 0, 512, FALSE); - bitmap_init(&expect_field_result_mask, 0, 512, FALSE); + my_bitmap_init(&expect_mask, 0, 512, FALSE); + my_bitmap_init(&expect_field_type_mask, 0, 512, FALSE); + my_bitmap_init(&expect_field_result_mask, 0, 512, FALSE); if (stack) cond_ptr= stack->ndb_cond; }; ~Ndb_cond_traverse_context() { - bitmap_free(&expect_mask); - bitmap_free(&expect_field_type_mask); - bitmap_free(&expect_field_result_mask); + my_bitmap_free(&expect_mask); + my_bitmap_free(&expect_field_type_mask); + my_bitmap_free(&expect_field_result_mask); if (rewrite_stack) delete rewrite_stack; } void expect(Item::Type type) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 672348a5c45..6fe3c826913 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3318,10 +3318,10 @@ err: void ha_partition::free_partition_bitmaps() { /* Initialize the bitmap we use to minimize ha_start_bulk_insert calls */ - bitmap_free(&m_bulk_insert_started); - bitmap_free(&m_locked_partitions); - bitmap_free(&m_partitions_to_reset); - bitmap_free(&m_key_not_found_partitions); + my_bitmap_free(&m_bulk_insert_started); + my_bitmap_free(&m_locked_partitions); + my_bitmap_free(&m_partitions_to_reset); + my_bitmap_free(&m_key_not_found_partitions); } @@ -3333,14 +3333,14 @@ bool ha_partition::init_partition_bitmaps() { DBUG_ENTER("ha_partition::init_partition_bitmaps"); /* Initialize the bitmap we use to minimize ha_start_bulk_insert calls */ - if (bitmap_init(&m_bulk_insert_started, NULL, m_tot_parts + 1, FALSE)) + if (my_bitmap_init(&m_bulk_insert_started, NULL, m_tot_parts + 1, FALSE)) DBUG_RETURN(true); bitmap_clear_all(&m_bulk_insert_started); /* Initialize the bitmap we use to keep track of locked partitions */ - if (bitmap_init(&m_locked_partitions, NULL, m_tot_parts, FALSE)) + if (my_bitmap_init(&m_locked_partitions, NULL, m_tot_parts, FALSE)) { - bitmap_free(&m_bulk_insert_started); + my_bitmap_free(&m_bulk_insert_started); DBUG_RETURN(true); } bitmap_clear_all(&m_locked_partitions); @@ -3349,10 +3349,10 @@ bool ha_partition::init_partition_bitmaps() Initialize the bitmap we use to keep track of partitions which may have something to reset in ha_reset(). */ - if (bitmap_init(&m_partitions_to_reset, NULL, m_tot_parts, FALSE)) + if (my_bitmap_init(&m_partitions_to_reset, NULL, m_tot_parts, FALSE)) { - bitmap_free(&m_bulk_insert_started); - bitmap_free(&m_locked_partitions); + my_bitmap_free(&m_bulk_insert_started); + my_bitmap_free(&m_locked_partitions); DBUG_RETURN(true); } bitmap_clear_all(&m_partitions_to_reset); @@ -3361,11 +3361,11 @@ bool ha_partition::init_partition_bitmaps() Initialize the bitmap we use to keep track of partitions which returned HA_ERR_KEY_NOT_FOUND from index_read_map. */ - if (bitmap_init(&m_key_not_found_partitions, NULL, m_tot_parts, FALSE)) + if (my_bitmap_init(&m_key_not_found_partitions, NULL, m_tot_parts, FALSE)) { - bitmap_free(&m_bulk_insert_started); - bitmap_free(&m_locked_partitions); - bitmap_free(&m_partitions_to_reset); + my_bitmap_free(&m_bulk_insert_started); + my_bitmap_free(&m_locked_partitions); + my_bitmap_free(&m_partitions_to_reset); DBUG_RETURN(true); } bitmap_clear_all(&m_key_not_found_partitions); diff --git a/sql/handler.cc b/sql/handler.cc index 521723e4049..5b1e0ed58d1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1251,7 +1251,8 @@ int ha_commit_trans(THD *thd, bool all) the changes are not durable as they might be rolled back if the enclosing 'all' transaction is rolled back. */ - bool is_real_trans= all || thd->transaction.all.ha_list == 0; + bool is_real_trans= ((all || thd->transaction.all.ha_list == 0) && + !(thd->variables.option_bits & OPTION_GTID_BEGIN)); Ha_trx_info *ha_info= trans->ha_list; bool need_prepare_ordered, need_commit_ordered; my_xid xid; @@ -1266,7 +1267,7 @@ int ha_commit_trans(THD *thd, bool all) ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));); DBUG_PRINT("info", - ("all: %d thd->in_sub_stmt: %d ha_info: %p is_real_trans: %d", + ("all: %d thd->in_sub_stmt: %d ha_info: %p is_real_trans: %d", all, thd->in_sub_stmt, ha_info, is_real_trans)); /* We must not commit the normal transaction if a statement @@ -1476,7 +1477,8 @@ int ha_commit_one_phase(THD *thd, bool all) ha_commit_one_phase() can be called with an empty transaction.all.ha_list, see why in trans_register_ha()). */ - bool is_real_trans=all || thd->transaction.all.ha_list == 0; + bool is_real_trans= ((all || thd->transaction.all.ha_list == 0) && + !(thd->variables.option_bits & OPTION_GTID_BEGIN)); int res; DBUG_ENTER("ha_commit_one_phase"); if (is_real_trans) @@ -5731,7 +5733,7 @@ static int binlog_log_row(TABLE* table, the first row handled in this statement. In that case, we need to write table maps for all locked tables to the binary log. */ - if (likely(!(error= bitmap_init(&cols, + if (likely(!(error= my_bitmap_init(&cols, use_bitbuf ? bitbuf : NULL, (n_fields + 7) & ~7UL, FALSE)))) @@ -5753,7 +5755,7 @@ static int binlog_log_row(TABLE* table, before_record, after_record); } if (!use_bitbuf) - bitmap_free(&cols); + my_bitmap_free(&cols); } } return error ? HA_ERR_RBR_LOGGING_FAILED : 0; diff --git a/sql/handler.h b/sql/handler.h index 0202fedb1eb..ffb12d11648 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -32,6 +32,7 @@ #include "sql_cache.h" #include "structs.h" /* SHOW_COMP_OPTION */ #include "sql_array.h" /* Dynamic_array<> */ +#include "mdl.h" #include <my_compare.h> #include <ft_global.h> @@ -387,6 +388,7 @@ enum enum_alter_inplace_result { #define HA_LEX_CREATE_IF_NOT_EXISTS 2 #define HA_LEX_CREATE_TABLE_LIKE 4 #define HA_CREATE_TMP_ALTER 8 +#define HA_LEX_CREATE_REPLACE 16 #define HA_MAX_REC_LENGTH 65535 /* Table caching type */ @@ -1582,9 +1584,15 @@ struct HA_CREATE_INFO ulong avg_row_length; ulong used_fields; ulong key_block_size; - uint stats_sample_pages; /* number of pages to sample during - stats estimation, if used, otherwise 0. */ - enum_stats_auto_recalc stats_auto_recalc; + /* + number of pages to sample during + stats estimation, if used, otherwise 0. + */ + uint stats_sample_pages; + uint null_bits; /* NULL bits at start of record */ + uint options; /* OR of HA_CREATE_ options */ + uint merge_insert_method; + uint extra_size; /* length of extra data segment */ SQL_I_List<TABLE_LIST> merge_list; handlerton *db_type; /** @@ -1597,21 +1605,23 @@ struct HA_CREATE_INFO If nothing speficied inherits the value of the original table (if present). */ enum row_type row_type; - uint null_bits; /* NULL bits at start of record */ - uint options; /* OR of HA_CREATE_ options */ - uint merge_insert_method; - uint extra_size; /* length of extra data segment */ enum ha_choice transactional; - bool varchar; ///< 1 if table has a VARCHAR enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY enum ha_choice page_checksum; ///< If we have page_checksums engine_option_value *option_list; ///< list of table create options + enum_stats_auto_recalc stats_auto_recalc; + bool varchar; ///< 1 if table has a VARCHAR /* the following three are only for ALTER TABLE, check_if_incompatible_data() */ ha_table_option_struct *option_struct; ///< structure with parsed table options ha_field_option_struct **fields_option_struct; ///< array of field option structures ha_index_option_struct **indexes_option_struct; ///< array of index option structures + /* The following is used to remember the old state for CREATE OR REPLACE */ + TABLE *table; + TABLE_LIST *pos_in_locked_tables; + MDL_ticket *mdl_ticket; + bool tmp_table() { return options & HA_LEX_CREATE_TMP_TABLE; } }; diff --git a/sql/hostname.cc b/sql/hostname.cc index 1200dd2c185..21e652a346f 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -149,7 +149,7 @@ bool hostname_cache_init() Host_entry tmp; uint key_offset= (uint) ((char*) (&tmp.ip_key) - (char*) &tmp); - if (!(hostname_cache= new hash_filo(HOST_CACHE_SIZE, + if (!(hostname_cache= new hash_filo(host_cache_size, key_offset, HOST_ENTRY_KEY_SIZE, NULL, (my_hash_free_key) free, &my_charset_bin))) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 81c4f0f51e5..88cae108039 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -4685,13 +4685,13 @@ ulonglong subselect_hash_sj_engine::rowid_merge_buff_size( */ static my_bool -bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root) +my_bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root) { my_bitmap_map *bitmap_buf; if (!(bitmap_buf= (my_bitmap_map*) alloc_root(mem_root, bitmap_buffer_size(n_bits))) || - bitmap_init(map, bitmap_buf, n_bits, FALSE)) + my_bitmap_init(map, bitmap_buf, n_bits, FALSE)) return TRUE; bitmap_clear_all(map); return FALSE; @@ -4729,9 +4729,9 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id) DBUG_ENTER("subselect_hash_sj_engine::init"); - if (bitmap_init_memroot(&non_null_key_parts, tmp_columns->elements, + if (my_bitmap_init_memroot(&non_null_key_parts, tmp_columns->elements, thd->mem_root) || - bitmap_init_memroot(&partial_match_key_parts, tmp_columns->elements, + my_bitmap_init_memroot(&partial_match_key_parts, tmp_columns->elements, thd->mem_root)) DBUG_RETURN(TRUE); @@ -5453,7 +5453,7 @@ Ordered_key::Ordered_key(uint keyid_arg, TABLE *tbl_arg, Item *search_key_arg, Ordered_key::~Ordered_key() { my_free(key_buff); - bitmap_free(&null_key); + my_bitmap_free(&null_key); } @@ -5563,7 +5563,7 @@ bool Ordered_key::alloc_keys_buffers() lookup offset. */ /* Notice that max_null_row is max array index, we need count, so +1. */ - if (bitmap_init(&null_key, NULL, (uint)(max_null_row + 1), FALSE)) + if (my_bitmap_init(&null_key, NULL, (uint)(max_null_row + 1), FALSE)) return TRUE; cur_key_idx= HA_POS_ERROR; @@ -6002,8 +6002,8 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts, */ if (!has_covering_null_columns) { - if (bitmap_init_memroot(&matching_keys, merge_keys_count, thd->mem_root) || - bitmap_init_memroot(&matching_outer_cols, merge_keys_count, thd->mem_root)) + if (my_bitmap_init_memroot(&matching_keys, merge_keys_count, thd->mem_root) || + my_bitmap_init_memroot(&matching_outer_cols, merge_keys_count, thd->mem_root)) return TRUE; /* diff --git a/sql/log.cc b/sql/log.cc index f531d301b63..f2fc7eb1554 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -525,35 +525,57 @@ bool LOGGER::is_log_table_enabled(uint log_table_type) } -/* Check if a given table is opened log table */ -int check_if_log_table(size_t db_len, const char *db, size_t table_name_len, - const char *table_name, bool check_if_opened) +/** + Check if a given table is opened log table + + @param table Table to check + @param check_if_opened Only fail if it's a log table in use + @param error_msg String to put in error message if not ok. + No error message if 0 + @return 0 ok + @return # Type of log file + */ + +int check_if_log_table(const TABLE_LIST *table, + bool check_if_opened, + const char *error_msg) { - if (db_len == 5 && + int result= 0; + if (table->db_length == 5 && !(lower_case_table_names ? - my_strcasecmp(system_charset_info, db, "mysql") : - strcmp(db, "mysql"))) + my_strcasecmp(system_charset_info, table->db, "mysql") : + strcmp(table->db, "mysql"))) { - if (table_name_len == 11 && !(lower_case_table_names ? - my_strcasecmp(system_charset_info, - table_name, "general_log") : - strcmp(table_name, "general_log"))) + const char *table_name= table->table_name; + + if (table->table_name_length == 11 && + !(lower_case_table_names ? + my_strcasecmp(system_charset_info, + table_name, "general_log") : + strcmp(table_name, "general_log"))) { - if (!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_GENERAL)) - return QUERY_LOG_GENERAL; - return 0; + result= QUERY_LOG_GENERAL; + goto end; } - if (table_name_len == 8 && !(lower_case_table_names ? + if (table->table_name_length == 8 && !(lower_case_table_names ? my_strcasecmp(system_charset_info, table_name, "slow_log") : strcmp(table_name, "slow_log"))) { - if (!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_SLOW)) - return QUERY_LOG_SLOW; - return 0; + result= QUERY_LOG_SLOW; + goto end; } } return 0; + +end: + if (!check_if_opened || logger.is_log_table_enabled(result)) + { + if (error_msg) + my_error(ER_BAD_LOG_STATEMENT, MYF(0), error_msg); + return result; + } + return 0; } @@ -1657,6 +1679,7 @@ static int binlog_close_connection(handlerton *hton, THD *thd) contain updates to non-transactional tables. Or it can be a flush of a statement cache. */ + static int binlog_flush_cache(THD *thd, binlog_cache_mngr *cache_mngr, Log_event *end_ev, bool all, bool using_stmt, @@ -1664,6 +1687,7 @@ binlog_flush_cache(THD *thd, binlog_cache_mngr *cache_mngr, { int error= 0; DBUG_ENTER("binlog_flush_cache"); + DBUG_PRINT("enter", ("end_ev: %p", end_ev)); if ((using_stmt && !cache_mngr->stmt_cache.empty()) || (using_trx && !cache_mngr->trx_cache.empty())) @@ -1722,9 +1746,10 @@ static inline int binlog_commit_flush_stmt_cache(THD *thd, bool all, binlog_cache_mngr *cache_mngr) { + DBUG_ENTER("binlog_commit_flush_stmt_cache"); Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"), FALSE, TRUE, TRUE, 0); - return (binlog_flush_cache(thd, cache_mngr, &end_evt, all, TRUE, FALSE)); + DBUG_RETURN(binlog_flush_cache(thd, cache_mngr, &end_evt, all, TRUE, FALSE)); } /** @@ -1739,9 +1764,10 @@ binlog_commit_flush_stmt_cache(THD *thd, bool all, static inline int binlog_commit_flush_trx_cache(THD *thd, bool all, binlog_cache_mngr *cache_mngr) { + DBUG_ENTER("binlog_commit_flush_trx_cache"); Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, TRUE, 0); - return (binlog_flush_cache(thd, cache_mngr, &end_evt, all, FALSE, TRUE)); + DBUG_RETURN(binlog_flush_cache(thd, cache_mngr, &end_evt, all, FALSE, TRUE)); } /** @@ -5248,6 +5274,10 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional, (long) table, table->s->table_name.str, table->s->table_map_id)); + /* Ensure that all events in a GTID group are in the same cache */ + if (variables.option_bits & OPTION_GTID_BEGIN) + is_transactional= 1; + /* Pre-conditions */ DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open()); DBUG_ASSERT(table->s->table_map_id != ULONG_MAX); @@ -5265,7 +5295,7 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional, cache_mngr->get_binlog_cache_log(use_trans_cache(this, is_transactional)); if (with_annotate && *with_annotate) { - Annotate_rows_log_event anno(current_thd, is_transactional, false); + Annotate_rows_log_event anno(table->in_use, is_transactional, false); /* Annotate event should be written not more than once */ *with_annotate= 0; if ((error= anno.write(file))) @@ -5428,6 +5458,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, /* Generate a new global transaction ID, and write it to the binlog */ + bool MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone, bool is_transactional, uint64 commit_id) @@ -5437,6 +5468,16 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone, uint32 server_id= thd->variables.server_id; uint64 seq_no= thd->variables.gtid_seq_no; int err; + DBUG_ENTER("write_gtid_event"); + DBUG_PRINT("enter", ("standalone: %d", standalone)); + + if (thd->variables.option_bits & OPTION_GTID_BEGIN) + { + DBUG_PRINT("error", ("OPTION_GTID_BEGIN is set. " + "Master and slave will have different GTID values")); + /* Reset the flag, as we will write out a GTID anyway */ + thd->variables.option_bits&= ~OPTION_GTID_BEGIN; + } /* Reset the session variable gtid_seq_no, to reduce the risk of accidentally @@ -5461,7 +5502,7 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone, seq_no= gtid.seq_no; } if (err) - return true; + DBUG_RETURN(true); Gtid_log_event gtid_event(thd, seq_no, domain_id, standalone, LOG_EVENT_SUPPRESS_USE_F, is_transactional, @@ -5469,10 +5510,10 @@ MYSQL_BIN_LOG::write_gtid_event(THD *thd, bool standalone, /* Write the event to the binary log. */ if (gtid_event.write(&mysql_bin_log.log_file)) - return true; + DBUG_RETURN(true); status_var_add(thd->status_var.binlog_bytes_written, gtid_event.data_written); - return false; + DBUG_RETURN(false); } @@ -5654,14 +5695,22 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate) { THD *thd= event_info->thd; bool error= 1; - DBUG_ENTER("MYSQL_BIN_LOG::write(Log_event *)"); binlog_cache_data *cache_data= 0; bool is_trans_cache= FALSE; bool using_trans= event_info->use_trans_cache(); bool direct= event_info->use_direct_logging(); ulong prev_binlog_id; + DBUG_ENTER("MYSQL_BIN_LOG::write(Log_event *)"); LINT_INIT(prev_binlog_id); + if (thd->variables.option_bits & OPTION_GTID_BEGIN) + { + DBUG_PRINT("info", ("OPTION_GTID_BEGIN was set")); + /* Wait for commit from binary log before we commit */ + direct= 0; + using_trans= 1; + } + if (thd->binlog_evt_union.do_union) { /* @@ -5709,6 +5758,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate) if (direct) { + DBUG_PRINT("info", ("direct is set")); file= &log_file; my_org_b_tell= my_b_tell(file); mysql_mutex_lock(&LOCK_log); @@ -7299,16 +7349,17 @@ MYSQL_BIN_LOG::write_transaction_or_stmt(group_commit_entry *entry, uint64 commit_id) { binlog_cache_mngr *mngr= entry->cache_mngr; + DBUG_ENTER("MYSQL_BIN_LOG::write_transaction_or_stmt"); if (write_gtid_event(entry->thd, false, entry->using_trx_cache, commit_id)) - return ER_ERROR_ON_WRITE; + DBUG_RETURN(ER_ERROR_ON_WRITE); if (entry->using_stmt_cache && !mngr->stmt_cache.empty() && write_cache(entry->thd, mngr->get_binlog_cache_log(FALSE))) { entry->error_cache= &mngr->stmt_cache.cache_log; entry->commit_errno= errno; - return ER_ERROR_ON_WRITE; + DBUG_RETURN(ER_ERROR_ON_WRITE); } if (entry->using_trx_cache && !mngr->trx_cache.empty()) @@ -7329,7 +7380,7 @@ MYSQL_BIN_LOG::write_transaction_or_stmt(group_commit_entry *entry, { entry->error_cache= &mngr->trx_cache.cache_log; entry->commit_errno= errno; - return ER_ERROR_ON_WRITE; + DBUG_RETURN(ER_ERROR_ON_WRITE); } } @@ -7337,7 +7388,7 @@ MYSQL_BIN_LOG::write_transaction_or_stmt(group_commit_entry *entry, { entry->error_cache= NULL; entry->commit_errno= errno; - return ER_ERROR_ON_WRITE; + DBUG_RETURN(ER_ERROR_ON_WRITE); } status_var_add(entry->thd->status_var.binlog_bytes_written, entry->end_event->data_written); @@ -7348,7 +7399,7 @@ MYSQL_BIN_LOG::write_transaction_or_stmt(group_commit_entry *entry, { entry->error_cache= NULL; entry->commit_errno= errno; - return ER_ERROR_ON_WRITE; + DBUG_RETURN(ER_ERROR_ON_WRITE); } } @@ -7356,16 +7407,16 @@ MYSQL_BIN_LOG::write_transaction_or_stmt(group_commit_entry *entry, { entry->error_cache= &mngr->stmt_cache.cache_log; entry->commit_errno= errno; - return ER_ERROR_ON_READ; + DBUG_RETURN(ER_ERROR_ON_WRITE); } if (mngr->get_binlog_cache_log(TRUE)->error) // Error on read { entry->error_cache= &mngr->trx_cache.cache_log; entry->commit_errno= errno; - return ER_ERROR_ON_READ; + DBUG_RETURN(ER_ERROR_ON_WRITE); } - return 0; + DBUG_RETURN(0); } diff --git a/sql/log.h b/sql/log.h index 45381152d97..d6ae7bbb1bb 100644 --- a/sql/log.h +++ b/sql/log.h @@ -833,8 +833,8 @@ public: }; -int check_if_log_table(size_t db_len, const char *db, size_t table_name_len, - const char *table_name, bool check_if_opened); +int check_if_log_table(const TABLE_LIST *table, bool check_if_opened, + const char *errmsg); class Log_to_csv_event_handler: public Log_event_handler { diff --git a/sql/log_event.cc b/sql/log_event.cc index 0af7a2ed344..d2d82da4ede 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3984,6 +3984,8 @@ bool test_if_equal_repl_errors(int expected_error, int actual_error) case ER_AUTOINC_READ_FAILED: return (actual_error == ER_AUTOINC_READ_FAILED || actual_error == HA_ERR_AUTOINC_ERANGE); + case ER_UNKNOWN_TABLE: + return actual_error == ER_IT_IS_A_VIEW; default: break; } @@ -4018,6 +4020,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, rpl_gtid gtid; Relay_log_info const *rli= rgi->rli; Rpl_filter *rpl_filter= rli->mi->rpl_filter; + bool current_stmt_is_commit; DBUG_ENTER("Query_log_event::do_apply_event"); /* @@ -4044,7 +4047,9 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos)); clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); - if (strcmp("COMMIT", query) == 0 && rgi->tables_to_lock) + current_stmt_is_commit= is_commit(); + + if (current_stmt_is_commit && rgi->tables_to_lock) { /* Cleaning-up the last statement context: @@ -4093,9 +4098,11 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, thd->variables.pseudo_thread_id= thread_id; // for temp tables DBUG_PRINT("query",("%s", thd->query())); - if (ignored_error_code((expected_error= error_code)) || - !unexpected_error_code(expected_error)) + if (!(expected_error= error_code) || + ignored_error_code(expected_error) || + !unexpected_error_code(expected_error)) { + thd->slave_expected_error= expected_error; if (flags2_inited) /* all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG @@ -4197,12 +4204,13 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, Record any GTID in the same transaction, so slave state is transactionally consistent. */ - if (strcmp("COMMIT", query) == 0 && (sub_id= rgi->gtid_sub_id)) + if (current_stmt_is_commit && (sub_id= rgi->gtid_sub_id)) { /* Clear the GTID from the RLI so we don't accidentally reuse it. */ rgi->gtid_sub_id= 0; gtid= rgi->current_gtid; + thd->variables.option_bits&= ~OPTION_GTID_BEGIN; if (rpl_global_gtid_slave_state.record_gtid(thd, >id, sub_id, true, false)) { rli->report(ERROR_LEVEL, ER_CANNOT_UPDATE_GTID_STATE, @@ -4232,6 +4240,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, concurrency_error_code(expected_error))) { thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR; + thd->variables.option_bits&= ~OPTION_GTID_BEGIN; } /* Execute the query (note that we bypass dispatch_command()) */ Parser_state parser_state; @@ -4395,8 +4404,7 @@ Default database: '%s'. Query: '%s'", to shutdown trying to finish incomplete events group. */ DBUG_EXECUTE_IF("stop_slave_middle_group", - if (strcmp("COMMIT", query) != 0 && - strcmp("BEGIN", query) != 0) + if (!current_stmt_is_commit && is_begin() == 0) { if (thd->transaction.all.modified_non_trans_table) const_cast<Relay_log_info*>(rli)->abort_slave= 1; @@ -4457,7 +4465,7 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi) { Relay_log_info *rli= rgi->rli; DBUG_ENTER("Query_log_event::do_shall_skip"); - DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len)); + DBUG_PRINT("debug", ("query: '%s' q_len: %d", query, q_len)); DBUG_ASSERT(query && q_len > 0); DBUG_ASSERT(thd == rgi->thd); @@ -4473,13 +4481,13 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi) { if (is_begin()) { - thd->variables.option_bits|= OPTION_BEGIN; + thd->variables.option_bits|= OPTION_BEGIN | OPTION_GTID_BEGIN; DBUG_RETURN(Log_event::continue_group(rgi)); } if (is_commit() || is_rollback()) { - thd->variables.option_bits&= ~OPTION_BEGIN; + thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_GTID_BEGIN); DBUG_RETURN(Log_event::EVENT_SKIP_COUNT); } } @@ -5906,6 +5914,7 @@ error: thd->reset_query(); thd->get_stmt_da()->set_overwrite_status(true); thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd); + thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_GTID_BEGIN); thd->get_stmt_da()->set_overwrite_status(false); close_thread_tables(thd); /* @@ -6408,8 +6417,7 @@ Gtid_log_event::make_compatible_event(String *packet, bool *need_dummy_event, { if (*need_dummy_event) return Query_log_event::dummy_event(packet, ev_offset, checksum_alg); - else - return 0; + return 0; } *need_dummy_event= true; @@ -6456,10 +6464,16 @@ Gtid_log_event::do_apply_event(rpl_group_info *rgi) this->server_id, this->seq_no)) return 1; } + + DBUG_ASSERT((thd->variables.option_bits & OPTION_GTID_BEGIN) == 0); if (flags2 & FL_STANDALONE) return 0; /* Execute this like a BEGIN query event. */ + thd->variables.option_bits|= OPTION_BEGIN | OPTION_GTID_BEGIN; + DBUG_PRINT("info", ("Set OPTION_GTID_BEGIN")); + trans_begin(thd, 0); + thd->set_query_and_id(gtid_begin_string, sizeof(gtid_begin_string)-1, &my_charset_bin, next_query_id()); Parser_state parser_state; @@ -7250,6 +7264,7 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi) /* For a slave Xid_log_event is COMMIT */ general_log_print(thd, COM_QUERY, "COMMIT /* implicit, from Xid_log_event */"); + thd->variables.option_bits&= ~OPTION_GTID_BEGIN; res= trans_commit(thd); /* Automatically rolls back on error. */ thd->mdl_context.release_transactional_locks(); @@ -7271,7 +7286,7 @@ Xid_log_event::do_shall_skip(rpl_group_info *rgi) if (rgi->rli->slave_skip_counter > 0) { DBUG_ASSERT(!rgi->rli->get_flag(Relay_log_info::IN_TRANSACTION)); - thd->variables.option_bits&= ~OPTION_BEGIN; + thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_GTID_BEGIN); DBUG_RETURN(Log_event::EVENT_SKIP_COUNT); } DBUG_RETURN(Log_event::do_shall_skip(rgi)); @@ -9112,8 +9127,8 @@ Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, set_flags(NO_FOREIGN_KEY_CHECKS_F); if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS) set_flags(RELAXED_UNIQUE_CHECKS_F); - /* if bitmap_init fails, caught in is_valid() */ - if (likely(!bitmap_init(&m_cols, + /* if my_bitmap_init fails, caught in is_valid() */ + if (likely(!my_bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, m_width, false))) @@ -9127,7 +9142,7 @@ Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, } else { - // Needed because bitmap_init() does not set it to null on failure + // Needed because my_bitmap_init() does not set it to null on failure m_cols.bitmap= 0; } } @@ -9228,8 +9243,8 @@ 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)); - /* if bitmap_init fails, catched in is_valid() */ - if (likely(!bitmap_init(&m_cols, + /* if my_bitmap_init fails, catched in is_valid() */ + if (likely(!my_bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, m_width, false))) @@ -9242,7 +9257,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, } else { - // Needed because bitmap_init() does not set it to null on failure + // Needed because my_bitmap_init() does not set it to null on failure m_cols.bitmap= NULL; DBUG_VOID_RETURN; } @@ -9254,8 +9269,8 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, { DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); - /* if bitmap_init fails, caught in is_valid() */ - if (likely(!bitmap_init(&m_cols_ai, + /* if my_bitmap_init fails, caught in is_valid() */ + if (likely(!my_bitmap_init(&m_cols_ai, m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL, m_width, false))) @@ -9269,7 +9284,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, } else { - // Needed because bitmap_init() does not set it to null on failure + // Needed because my_bitmap_init() does not set it to null on failure m_cols_ai.bitmap= 0; DBUG_VOID_RETURN; } @@ -9300,8 +9315,8 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, Rows_log_event::~Rows_log_event() { if (m_cols.bitmap == m_bitbuf) // no my_malloc happened - m_cols.bitmap= 0; // so no my_free in bitmap_free - bitmap_free(&m_cols); // To pair with bitmap_init(). + m_cols.bitmap= 0; // so no my_free in my_bitmap_free + my_bitmap_free(&m_cols); // To pair with my_bitmap_init(). my_free(m_rows_buf); my_free(m_extra_row_data); } @@ -11960,8 +11975,8 @@ Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg, void Update_rows_log_event::init(MY_BITMAP const *cols) { - /* if bitmap_init fails, caught in is_valid() */ - if (likely(!bitmap_init(&m_cols_ai, + /* if my_bitmap_init fails, caught in is_valid() */ + if (likely(!my_bitmap_init(&m_cols_ai, m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL, m_width, false))) @@ -11980,8 +11995,8 @@ void Update_rows_log_event::init(MY_BITMAP const *cols) Update_rows_log_event::~Update_rows_log_event() { if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened - m_cols_ai.bitmap= 0; // so no my_free in bitmap_free - bitmap_free(&m_cols_ai); // To pair with bitmap_init(). + m_cols_ai.bitmap= 0; // so no my_free in my_bitmap_free + my_bitmap_free(&m_cols_ai); // To pair with my_bitmap_init(). } diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 7b89d5bdf08..0cb78686243 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1244,8 +1244,8 @@ Old_rows_log_event::Old_rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, set_flags(NO_FOREIGN_KEY_CHECKS_F); if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS) set_flags(RELAXED_UNIQUE_CHECKS_F); - /* if bitmap_init fails, caught in is_valid() */ - if (likely(!bitmap_init(&m_cols, + /* if my_bitmap_init fails, caught in is_valid() */ + if (likely(!my_bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, m_width, false))) @@ -1259,7 +1259,7 @@ Old_rows_log_event::Old_rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, } else { - // Needed because bitmap_init() does not set it to null on failure + // Needed because my_bitmap_init() does not set it to null on failure m_cols.bitmap= 0; } } @@ -1313,8 +1313,8 @@ 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)); - /* if bitmap_init fails, catched in is_valid() */ - if (likely(!bitmap_init(&m_cols, + /* if my_bitmap_init fails, catched in is_valid() */ + if (likely(!my_bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, m_width, false))) @@ -1327,7 +1327,7 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len, } else { - // Needed because bitmap_init() does not set it to null on failure + // Needed because my_bitmap_init() does not set it to null on failure m_cols.bitmap= NULL; DBUG_VOID_RETURN; } @@ -1358,8 +1358,8 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len, Old_rows_log_event::~Old_rows_log_event() { if (m_cols.bitmap == m_bitbuf) // no my_malloc happened - m_cols.bitmap= 0; // so no my_free in bitmap_free - bitmap_free(&m_cols); // To pair with bitmap_init(). + m_cols.bitmap= 0; // so no my_free in my_bitmap_free + my_bitmap_free(&m_cols); // To pair with my_bitmap_init(). my_free(m_rows_buf); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 984d9cbc968..808a0d47ac9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -366,7 +366,8 @@ static DYNAMIC_ARRAY all_options; /* Global variables */ bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0; -my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table= 0, opt_help= 0, opt_abort; +my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table= 0, opt_help= 0; +static my_bool opt_abort; ulonglong log_output_options; my_bool opt_userstat_running; my_bool opt_log_queries_not_using_indexes= 0; @@ -478,6 +479,7 @@ ulong open_files_limit, max_binlog_size; ulong slave_trans_retries; uint slave_net_timeout; ulong slave_exec_mode_options; +ulong slave_ddl_exec_mode_options= SLAVE_EXEC_MODE_IDEMPOTENT; ulonglong slave_type_conversions_options; ulong thread_cache_size=0; ulonglong binlog_cache_size=0; @@ -1964,7 +1966,7 @@ void clean_up(bool print_message) // We must call end_slave() as clean_up may have been called during startup end_slave(); if (use_slave_mask) - bitmap_free(&slave_error_mask); + my_bitmap_free(&slave_error_mask); #endif stop_handle_manager(); release_ddl_log(); @@ -2018,7 +2020,7 @@ void clean_up(bool print_message) if (defaults_argv) free_defaults(defaults_argv); free_tmpdir(&mysql_tmpdir_list); - bitmap_free(&temp_pool); + my_bitmap_free(&temp_pool); free_max_user_conn(); free_global_user_stats(); free_global_client_stats(); @@ -4252,7 +4254,7 @@ static int init_common_variables() #endif /* defined(ENABLED_DEBUG_SYNC) */ #if (ENABLE_TEMP_POOL) - if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1)) + if (use_temp_pool && my_bitmap_init(&temp_pool,0,1024,1)) return 1; #else use_temp_pool= 0; @@ -7966,7 +7968,6 @@ static int option_cmp(my_option *a, my_option *b) return 1; } } - DBUG_ASSERT(a->name == b->name); return 0; } @@ -7981,9 +7982,16 @@ static void print_help() sys_var_add_options(&all_options, sys_var::PARSE_EARLY); add_plugin_options(&all_options, &mem_root); sort_dynamic(&all_options, (qsort_cmp) option_cmp); + sort_dynamic(&all_options, (qsort_cmp) option_cmp); add_terminator(&all_options); my_print_help((my_option*) all_options.buffer); + + /* Add variables that can be shown but not changed, like version numbers */ + pop_dynamic(&all_options); + sys_var_add_options(&all_options, sys_var::SHOW_VALUE_IN_HELP); + sort_dynamic(&all_options, (qsort_cmp) option_cmp); + add_terminator(&all_options); my_print_variables((my_option*) all_options.buffer); free_root(&mem_root, MYF(0)); @@ -8944,6 +8952,13 @@ static int get_options(int *argc_ptr, char ***argv_ptr) max_binlog_size_var->option.def_value; } } + + /* Ensure that some variables are not set higher than needed */ + if (back_log > max_connections) + back_log= max_connections; + if (thread_cache_size > max_connections) + thread_cache_size= max_connections; + return 0; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 1b34c485101..dd80a6cf423 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -96,7 +96,7 @@ extern uint connection_count; extern my_bool opt_safe_user_create; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; extern my_bool opt_slave_compressed_protocol, use_temp_pool; -extern ulong slave_exec_mode_options; +extern ulong slave_exec_mode_options, slave_ddl_exec_mode_options; extern ulong slave_retried_transactions; extern ulonglong slave_type_conversions_options; extern my_bool read_only, opt_readonly; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 16f32eb9252..1ced92952c2 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1823,7 +1823,7 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, *create_error= 1; } else - bitmap_init(&column_bitmap, bitmap, head->s->fields, FALSE); + my_bitmap_init(&column_bitmap, bitmap, head->s->fields, FALSE); DBUG_VOID_RETURN; } @@ -2847,7 +2847,7 @@ static int fill_used_fields_bitmap(PARAM *param) param->fields_bitmap_size= table->s->column_bitmap_size; if (!(tmp= (my_bitmap_map*) alloc_root(param->mem_root, param->fields_bitmap_size)) || - bitmap_init(¶m->needed_fields, tmp, table->s->fields, FALSE)) + my_bitmap_init(¶m->needed_fields, tmp, table->s->fields, FALSE)) return 1; bitmap_copy(¶m->needed_fields, table->read_set); @@ -4104,7 +4104,7 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar, */ return find_used_partitions_imerge(ppar, merges.head()); } - bitmap_init(&all_merges, bitmap_buf, n_bits, FALSE); + my_bitmap_init(&all_merges, bitmap_buf, n_bits, FALSE); bitmap_set_prefix(&all_merges, n_bits); List_iterator<SEL_IMERGE> it(merges); @@ -4751,7 +4751,7 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar) uint32 bufsize= bitmap_buffer_size(ppar->part_info->num_subparts); if (!(buf= (my_bitmap_map*) alloc_root(alloc, bufsize))) return TRUE; - bitmap_init(&ppar->subparts_bitmap, buf, ppar->part_info->num_subparts, + my_bitmap_init(&ppar->subparts_bitmap, buf, ppar->part_info->num_subparts, FALSE); } range_par->key_parts= key_part; @@ -5511,7 +5511,7 @@ bool create_fields_bitmap(PARAM *param, MY_BITMAP *fields_bitmap) if (!(bitmap_buf= (my_bitmap_map *) alloc_root(param->mem_root, param->fields_bitmap_size))) return TRUE; - if (bitmap_init(fields_bitmap, bitmap_buf, param->table->s->fields, FALSE)) + if (my_bitmap_init(fields_bitmap, bitmap_buf, param->table->s->fields, FALSE)) return TRUE; return FALSE; @@ -6329,7 +6329,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) param->fields_bitmap_size))) DBUG_RETURN(NULL); - if (bitmap_init(&ror_scan->covered_fields, bitmap_buf, + if (my_bitmap_init(&ror_scan->covered_fields, bitmap_buf, param->table->s->fields, FALSE)) DBUG_RETURN(NULL); bitmap_clear_all(&ror_scan->covered_fields); @@ -6447,7 +6447,7 @@ ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param) if (!(buf= (my_bitmap_map*) alloc_root(param->mem_root, param->fields_bitmap_size))) return NULL; - if (bitmap_init(&info->covered_fields, buf, param->table->s->fields, + if (my_bitmap_init(&info->covered_fields, buf, param->table->s->fields, FALSE)) return NULL; info->is_covering= FALSE; @@ -7024,7 +7024,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, covered_fields->bitmap= (my_bitmap_map*)alloc_root(param->mem_root, param->fields_bitmap_size); if (!covered_fields->bitmap || - bitmap_init(covered_fields, covered_fields->bitmap, + my_bitmap_init(covered_fields, covered_fields->bitmap, param->table->s->fields, FALSE)) DBUG_RETURN(0); bitmap_clear_all(covered_fields); diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index 46bed0e60e7..9b58f5f3126 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -1042,7 +1042,7 @@ bool Dep_analysis_context::setup_equality_modules_deps(List<Dep_module> void *buf; if (!(buf= current_thd->alloc(bitmap_buffer_size(offset))) || - bitmap_init(&expr_deps, (my_bitmap_map*)buf, offset, FALSE)) + my_bitmap_init(&expr_deps, (my_bitmap_map*)buf, offset, FALSE)) { DBUG_RETURN(TRUE); /* purecov: inspected */ } diff --git a/sql/partition_info.cc b/sql/partition_info.cc index ca455c0d7bc..1ae62011b43 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -385,7 +385,7 @@ bool partition_info::can_prune_insert(THD* thd, DBUG_RETURN(true); } /* Also clears all bits. */ - if (bitmap_init(used_partitions, bitmap_buf, num_partitions, false)) + if (my_bitmap_init(used_partitions, bitmap_buf, num_partitions, false)) { /* purecov: begin deadcode */ /* Cannot happen, due to pre-alloc. */ diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index 3f79a0cb528..a36a15b3c27 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -352,7 +352,8 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id, { DBUG_PRINT("info", ("resetting OPTION_BEGIN")); thd->variables.option_bits&= - ~(ulonglong)(OPTION_NOT_AUTOCOMMIT|OPTION_BEGIN|OPTION_BIN_LOG); + ~(ulonglong)(OPTION_NOT_AUTOCOMMIT |OPTION_BEGIN |OPTION_BIN_LOG | + OPTION_GTID_BEGIN); } else thd->variables.option_bits&= ~(ulonglong)OPTION_BIN_LOG; diff --git a/sql/rpl_injector.h b/sql/rpl_injector.h index f4790cc963a..98788955e24 100644 --- a/sql/rpl_injector.h +++ b/sql/rpl_injector.h @@ -94,13 +94,13 @@ public: injector::transaction::table tbl(share->table, true); MY_BITMAP cols; - bitmap_init(&cols, NULL, (i + 7) / 8, false); + my_bitmap_init(&cols, NULL, (i + 7) / 8, false); inj->write_row(::server_id, tbl, &cols, row_data); or MY_BITMAP cols; - bitmap_init(&cols, NULL, (i + 7) / 8, false); + my_bitmap_init(&cols, NULL, (i + 7) / 8, false); inj->write_row(::server_id, injector::transaction::table(share->table, true), &cols, row_data); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index ac93f9640e8..c5c59f3aebb 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1583,6 +1583,7 @@ void rpl_group_info::cleanup_context(THD *thd, bool error) if (error) { trans_rollback_stmt(thd); // if a "statement transaction" + /* trans_rollback() also resets OPTION_GTID_BEGIN */ trans_rollback(thd); // if a "real transaction" } m_table_map.clear_tables(); diff --git a/sql/set_var.h b/sql/set_var.h index a6c3b9daccd..88c5013e28e 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -60,7 +60,7 @@ public: sys_var *next; LEX_CSTRING name; enum flag_enum { GLOBAL, SESSION, ONLY_SESSION, SCOPE_MASK=1023, - READONLY=1024, ALLOCATED=2048, PARSE_EARLY=4096 }; + READONLY=1024, ALLOCATED=2048, PARSE_EARLY=4096, SHOW_VALUE_IN_HELP=8192 }; /** Enumeration type to indicate for a system variable whether it will be written to the binlog or not. @@ -142,8 +142,9 @@ public: } bool register_option(DYNAMIC_ARRAY *array, int parse_flags) { - return (option.id != -1) && ((flags & PARSE_EARLY) == parse_flags) && - insert_dynamic(array, (uchar*)&option); + return ((((option.id != -1) && ((flags & PARSE_EARLY) == parse_flags)) || + (flags & parse_flags)) && + insert_dynamic(array, (uchar*)&option)); } void do_deprecated_warning(THD *thd); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 25017cef42c..160bf2e6c87 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -2118,13 +2118,9 @@ ER_INSERT_INFO spa "Registros: %ld Duplicados: %ld Peligros: %ld" swe "Rader: %ld Dubletter: %ld Varningar: %ld" ukr "Записів: %ld Дублікатів: %ld Застережень: %ld" -ER_UPDATE_TABLE_USED - eng "You can't specify target table '%-.192s' for update in FROM clause" - ger "Die Verwendung der zu aktualisierenden Zieltabelle '%-.192s' ist in der FROM-Klausel nicht zulässig." - jpn "FROM句にある表 '%-.192s' はUPDATEの対象にできません。" - rus "Не допускается указание таблицы '%-.192s' в списке таблиц FROM для внесения в нее изменений" - swe "INSERT-table '%-.192s' får inte finnas i FROM tabell-listan" - ukr "Таблиця '%-.192s' що змінюється не дозволена у переліку таблиць FROM" +ER_UPDATE_TABLE_USED + eng "Table '%-.192s' is specified twice, both as a target for '%s' and as a separate source for data" + swe "Table '%-.192s' är använd två gånger. Både för '%s' och för att hämta data" ER_NO_SUCH_THREAD cze "Neznámá identifikace threadu: %lu" dan "Ukendt tråd id: %lu" @@ -7067,3 +7063,5 @@ ER_CHANGE_SLAVE_PARALLEL_THREADS_ACTIVE eng "Cannot change @@slave_parallel_threads while another change is in progress" ER_PRIOR_COMMIT_FAILED eng "Commit failed due to failure of an earlier commit on which this one depends" +ER_IT_IS_A_VIEW 42S02 + eng "'%-.192s' is a view" diff --git a/sql/slave.cc b/sql/slave.cc index 6854d2bd6de..a2ed89e0c9c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -573,7 +573,7 @@ void init_slave_skip_errors(const char* arg) const char *p; DBUG_ENTER("init_slave_skip_errors"); - if (bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0)) + if (my_bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0)) { fprintf(stderr, "Badly out of memory, please check your system status\n"); exit(1); @@ -1047,9 +1047,10 @@ static bool sql_slave_killed(rpl_group_info *rgi) "documentation for details)."; DBUG_PRINT("info", ("modified_non_trans_table: %d OPTION_BEGIN: %d " - "is_in_group: %d", + "OPTION_KEEP_LOG: %d is_in_group: %d", thd->transaction.all.modified_non_trans_table, test(thd->variables.option_bits & OPTION_BEGIN), + test(thd->variables.option_bits & OPTION_KEEP_LOG), rli->is_in_group())); if (rli->abort_slave) @@ -3128,9 +3129,10 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)", ev->get_type_str(), ev->get_type_code(), ev->server_id)); - DBUG_PRINT("info", ("thd->options: %s%s; rgi->last_event_start_time: %lu", + DBUG_PRINT("info", ("thd->options: '%s%s%s' rgi->last_event_start_time: %lu", FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT), FLAGSTR(thd->variables.option_bits, OPTION_BEGIN), + FLAGSTR(thd->variables.option_bits, OPTION_GTID_BEGIN), (ulong) rgi->last_event_start_time)); /* diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 01bffaf132f..97b9c127c22 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -338,19 +338,8 @@ bool Sql_cmd_discard_import_tablespace::execute(THD *thd) it is the case. TODO: this design is obsolete and will be removed. */ - int table_kind= check_if_log_table(table_list->db_length, table_list->db, - table_list->table_name_length, - table_list->table_name, false); - - if (table_kind) - { - /* Disable alter of enabled log tables */ - if (logger.is_log_table_enabled(table_kind)) - { - my_error(ER_BAD_LOG_STATEMENT, MYF(0), "ALTER"); - return true; - } - } + if (check_if_log_table(table_list, TRUE, "ALTER")) + return true; return mysql_discard_or_import_tablespace(thd, table_list, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 44d68f35ab2..e72a56bb4fc 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -784,12 +784,18 @@ static void close_open_tables(THD *thd) access the table cache key @param[in] extra - HA_EXTRA_PREPRE_FOR_DROP if the table is being dropped - HA_EXTRA_PREPARE_FOR_REANME if the table is being renamed - HA_EXTRA_NOT_USED no drop/rename - In case of drop/reanme the documented behaviour is to + HA_EXTRA_PREPARE_FOR_DROP + - The table is dropped + HA_EXTRA_PREPARE_FOR_RENAME + - The table is renamed + HA_EXTRA_NOT_USED + - The table is marked as closed in the + locked_table_list but kept there so one can call + locked_table_list->reopen_tables() to put it back. + + In case of drop/rename the documented behavior is to implicitly remove the table from LOCK TABLES - list. + list. @pre Must be called with an X MDL lock on the table. */ @@ -1477,7 +1483,7 @@ void update_non_unique_table_error(TABLE_LIST *update, return; } } - my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias); + my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias, operation); } @@ -1588,26 +1594,21 @@ TABLE *find_temporary_table(THD *thd, thd->temporary_tables list, it's impossible to tell here whether we're dealing with an internal or a user temporary table. - If is_trans is not null, we return the type of the table: - either transactional (e.g. innodb) as TRUE or non-transactional - (e.g. myisam) as FALSE. + @param thd Thread handler + @param table Temporary table to be deleted + @param is_trans Is set to the type of the table: + transactional (e.g. innodb) as TRUE or non-transactional + (e.g. myisam) as FALSE. @retval 0 the table was found and dropped successfully. - @retval 1 the table was not found in the list of temporary tables - of this thread @retval -1 the table is in use by a outer query */ -int drop_temporary_table(THD *thd, TABLE_LIST *table_list, bool *is_trans) +int drop_temporary_table(THD *thd, TABLE *table, bool *is_trans) { DBUG_ENTER("drop_temporary_table"); DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", - table_list->db, table_list->table_name)); - - if (!is_temporary_table(table_list)) - DBUG_RETURN(1); - - TABLE *table= table_list->table; + table->s->db.str, table->s->table_name.str)); /* Table might be in use by some outer statement. */ if (table->query_id && table->query_id != thd->query_id) @@ -1627,10 +1628,10 @@ int drop_temporary_table(THD *thd, TABLE_LIST *table_list, bool *is_trans) */ mysql_lock_remove(thd, thd->lock, table); close_temporary_table(thd, table, 1, 1); - table_list->table= NULL; DBUG_RETURN(0); } + /* unlink from thd->temporary tables and close temporary table */ @@ -2612,9 +2613,9 @@ Locked_tables_list::init_locked_tables(THD *thd) { TABLE_LIST *src_table_list= table->pos_in_table_list; char *db, *table_name, *alias; - size_t db_len= src_table_list->db_length; - size_t table_name_len= src_table_list->table_name_length; - size_t alias_len= strlen(src_table_list->alias); + size_t db_len= table->s->db.length; + size_t table_name_len= table->s->table_name.length; + size_t alias_len= table->alias.length(); TABLE_LIST *dst_table_list; if (! multi_alloc_root(&m_locked_tables_root, @@ -2624,23 +2625,15 @@ Locked_tables_list::init_locked_tables(THD *thd) &alias, alias_len + 1, NullS)) { - unlock_locked_tables(0); + reset(); return TRUE; } - memcpy(db, src_table_list->db, db_len + 1); - memcpy(table_name, src_table_list->table_name, table_name_len + 1); - memcpy(alias, src_table_list->alias, alias_len + 1); - /** - Sic: remember the *actual* table level lock type taken, to - acquire the exact same type in reopen_tables(). - E.g. if the table was locked for write, src_table_list->lock_type is - TL_WRITE_DEFAULT, whereas reginfo.lock_type has been updated from - thd->update_lock_default. - */ + memcpy(db, table->s->db.str, db_len + 1); + memcpy(table_name, table->s->table_name.str, table_name_len + 1); + strmake(alias, table->alias.ptr(), alias_len); dst_table_list->init_one_table(db, db_len, table_name, table_name_len, - alias, - src_table_list->table->reginfo.lock_type); + alias, table->reginfo.lock_type); dst_table_list->table= table; dst_table_list->mdl_request.ticket= src_table_list->mdl_request.ticket; @@ -2661,7 +2654,7 @@ Locked_tables_list::init_locked_tables(THD *thd) (m_locked_tables_count+1)); if (m_reopen_array == NULL) { - unlock_locked_tables(0); + reset(); return TRUE; } } @@ -2682,42 +2675,50 @@ Locked_tables_list::init_locked_tables(THD *thd) void Locked_tables_list::unlock_locked_tables(THD *thd) { - if (thd) + DBUG_ASSERT(!thd->in_sub_stmt && + !(thd->state_flags & Open_tables_state::BACKUPS_AVAIL)); + /* + Sic: we must be careful to not close open tables if + we're not in LOCK TABLES mode: unlock_locked_tables() is + sometimes called implicitly, expecting no effect on + open tables, e.g. from begin_trans(). + */ + if (thd->locked_tables_mode != LTM_LOCK_TABLES) + return; + + for (TABLE_LIST *table_list= m_locked_tables; + table_list; table_list= table_list->next_global) { - DBUG_ASSERT(!thd->in_sub_stmt && - !(thd->state_flags & Open_tables_state::BACKUPS_AVAIL)); /* - Sic: we must be careful to not close open tables if - we're not in LOCK TABLES mode: unlock_locked_tables() is - sometimes called implicitly, expecting no effect on - open tables, e.g. from begin_trans(). + Clear the position in the list, the TABLE object will be + returned to the table cache. */ - if (thd->locked_tables_mode != LTM_LOCK_TABLES) - return; + if (table_list->table) // If not closed + table_list->table->pos_in_locked_tables= NULL; + } + thd->leave_locked_tables_mode(); - for (TABLE_LIST *table_list= m_locked_tables; - table_list; table_list= table_list->next_global) - { - /* - Clear the position in the list, the TABLE object will be - returned to the table cache. - */ - if (table_list->table) // If not closed - table_list->table->pos_in_locked_tables= NULL; - } - thd->leave_locked_tables_mode(); + DBUG_ASSERT(thd->transaction.stmt.is_empty()); + close_thread_tables(thd); + + /* + We rely on the caller to implicitly commit the + transaction and release transactional locks. + */ - DBUG_ASSERT(thd->transaction.stmt.is_empty()); - close_thread_tables(thd); - /* - We rely on the caller to implicitly commit the - transaction and release transactional locks. - */ - } /* After closing tables we can free memory used for storing lock request for metadata locks and TABLE_LIST elements. */ + reset(); +} + +/* + Free memory allocated for storing locks +*/ + +void Locked_tables_list::reset() +{ free_root(&m_locked_tables_root, MYF(0)); m_locked_tables= NULL; m_locked_tables_last= &m_locked_tables; @@ -2782,6 +2783,7 @@ void Locked_tables_list::unlink_from_list(THD *thd, m_locked_tables_last= table_list->prev_global; else table_list->next_global->prev_global= table_list->prev_global; + m_locked_tables_count--; } } @@ -2835,8 +2837,13 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count) m_locked_tables_last= table_list->prev_global; else table_list->next_global->prev_global= table_list->prev_global; + m_locked_tables_count--; } } + + /* If no tables left, do an automatic UNLOCK TABLES */ + if (thd->lock && thd->lock->table_count == 0) + unlock_locked_tables(thd); } @@ -2909,6 +2916,57 @@ Locked_tables_list::reopen_tables(THD *thd) return FALSE; } +/** + Add back a locked table to the locked list that we just removed from it. + This is needed in CREATE OR REPLACE TABLE where we are dropping, creating + and re-opening a locked table. + + @return 0 0k + @return 1 error +*/ + +bool Locked_tables_list::restore_lock(THD *thd, TABLE_LIST *dst_table_list, + TABLE *table, MYSQL_LOCK *lock) +{ + MYSQL_LOCK *merged_lock; + DBUG_ENTER("restore_lock"); + DBUG_ASSERT(!strcmp(dst_table_list->table_name, table->s->table_name.str)); + + /* Ensure we have the memory to add the table back */ + if (!(merged_lock= mysql_lock_merge(thd->lock, lock))) + DBUG_RETURN(1); + thd->lock= merged_lock; + + /* Link to the new table */ + dst_table_list->table= table; + /* + The lock type may have changed (normally it should not as create + table will lock the table in write mode + */ + dst_table_list->lock_type= table->reginfo.lock_type; + table->pos_in_locked_tables= dst_table_list; + + add_back_last_deleted_lock(dst_table_list); + + DBUG_RETURN(0); +} + +/* + Add back the last deleted lock structure. + This should be followed by a call to reopen_tables() to + open the table. +*/ + +void Locked_tables_list::add_back_last_deleted_lock(TABLE_LIST *dst_table_list) +{ + /* Link the lock back in the locked tables list */ + dst_table_list->prev_global= m_locked_tables_last; + *m_locked_tables_last= dst_table_list; + m_locked_tables_last= &dst_table_list->next_global; + dst_table_list->next_global= 0; + m_locked_tables_count++; +} + #ifndef DBUG_OFF /* Cause a spurious statement reprepare for debug purposes. */ @@ -4046,9 +4104,9 @@ lock_table_names(THD *thd, if (mdl_requests.is_empty()) DBUG_RETURN(FALSE); - /* Check if CREATE TABLE was used */ - create_table= (tables_start && tables_start->open_strategy == - TABLE_LIST::OPEN_IF_EXISTS); + /* Check if CREATE TABLE without REPLACE was used */ + create_table= (thd->lex->sql_command == SQLCOM_CREATE_TABLE && + !(thd->lex->create_info.options & HA_LEX_CREATE_REPLACE)); if (!(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK)) { @@ -5294,6 +5352,39 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, } +/* + Restart transaction for tables + + This is used when we had to do an implicit commit after tables are opened + and want to restart transactions on tables. + + This is used in case of: + LOCK TABLES xx + CREATE OR REPLACE TABLE xx; +*/ + +bool restart_trans_for_tables(THD *thd, TABLE_LIST *table) +{ + DBUG_ENTER("restart_trans_for_tables"); + + if (!thd->locked_tables_mode) + DBUG_RETURN(FALSE); + + for (; table; table= table->next_global) + { + if (table->placeholder()) + continue; + + if (check_lock_and_start_stmt(thd, thd->lex, table)) + { + DBUG_ASSERT(0); // Should never happen + DBUG_RETURN(TRUE); + } + } + DBUG_RETURN(FALSE); +} + + /** Prepare statement for reopening of tables and recalculation of set of prelocked tables. diff --git a/sql/sql_base.h b/sql/sql_base.h index 3e633fad084..61442843a39 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -248,7 +248,7 @@ void close_thread_table(THD *thd, TABLE **table_ptr); bool close_temporary_tables(THD *thd); TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, bool check_alias); -int drop_temporary_table(THD *thd, TABLE_LIST *table_list, bool *is_trans); +int drop_temporary_table(THD *thd, TABLE *table, bool *is_trans); void close_temporary_table(THD *thd, TABLE *table, bool free_share, bool delete_table); void close_temporary(TABLE *table, bool free_share, bool delete_table); @@ -486,6 +486,8 @@ inline bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, } +bool restart_trans_for_tables(THD *thd, TABLE_LIST *table); + /** A context of open_tables() function, used to recover from a failed open_table() or open_routine() attempt. diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 7e163b0dbcc..2e07695f605 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -34,7 +34,7 @@ public: Bitmap() { init(); } Bitmap(const Bitmap& from) { *this=from; } explicit Bitmap(uint prefix_to_set) { init(prefix_to_set); } - void init() { bitmap_init(&map, buffer, default_width, 0); } + void init() { my_bitmap_init(&map, buffer, default_width, 0); } void init(uint prefix_to_set) { init(); set_prefix(prefix_to_set); } uint length() const { return default_width; } Bitmap& operator=(const Bitmap& map2) @@ -52,7 +52,7 @@ public: void intersect(ulonglong map2buff) { MY_BITMAP map2; - bitmap_init(&map2, (uint32 *)&map2buff, sizeof(ulonglong)*8, 0); + my_bitmap_init(&map2, (uint32 *)&map2buff, sizeof(ulonglong)*8, 0); bitmap_intersect(&map, &map2); } /* Use highest bit for all bits above sizeof(ulonglong)*8. */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index bcaea00b081..ee0cc43dca2 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5391,6 +5391,10 @@ THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id, /* Fetch the type code for the RowsEventT template parameter */ int const general_type_code= RowsEventT::TYPE_CODE; + /* Ensure that all events in a GTID group are in the same cache */ + if (variables.option_bits & OPTION_GTID_BEGIN) + is_transactional= 1; + /* There is no good place to set up the transactional data, so we have to do it here. @@ -5586,6 +5590,10 @@ int THD::binlog_write_row(TABLE* table, bool is_trans, size_t const len= pack_row(table, cols, row_data, record); + /* Ensure that all events in a GTID group are in the same cache */ + if (variables.option_bits & OPTION_GTID_BEGIN) + is_trans= 1; + Rows_log_event* const ev= binlog_prepare_pending_rows_event(table, variables.server_id, cols, colcnt, len, is_trans, @@ -5619,6 +5627,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans, size_t const after_size= pack_row(table, cols, after_row, after_record); + /* Ensure that all events in a GTID group are in the same cache */ + if (variables.option_bits & OPTION_GTID_BEGIN) + is_trans= 1; + /* Don't print debug messages when running valgrind since they can trigger false warnings. @@ -5661,6 +5673,10 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans, size_t const len= pack_row(table, cols, row_data, record); + /* Ensure that all events in a GTID group are in the same cache */ + if (variables.option_bits & OPTION_GTID_BEGIN) + is_trans= 1; + Rows_log_event* const ev= binlog_prepare_pending_rows_event(table, variables.server_id, cols, colcnt, len, is_trans, @@ -5681,6 +5697,10 @@ int THD::binlog_remove_pending_rows_event(bool clear_maps, if (!mysql_bin_log.is_open()) DBUG_RETURN(0); + /* Ensure that all events in a GTID group are in the same cache */ + if (variables.option_bits & OPTION_GTID_BEGIN) + is_transactional= 1; + mysql_bin_log.remove_pending_rows_event(this, is_transactional); if (clear_maps) @@ -5700,6 +5720,10 @@ int THD::binlog_flush_pending_rows_event(bool stmt_end, bool is_transactional) if (!mysql_bin_log.is_open()) DBUG_RETURN(0); + /* Ensure that all events in a GTID group are in the same cache */ + if (variables.option_bits & OPTION_GTID_BEGIN) + is_transactional= 1; + /* Mark the event as the last event of a statement if the stmt_end flag is set. @@ -5947,6 +5971,14 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, show_query_type(qtype), (int) query_len, query_arg)); DBUG_ASSERT(query_arg && mysql_bin_log.is_open()); + /* If this is withing a BEGIN ... COMMIT group, don't log it */ + if (variables.option_bits & OPTION_GTID_BEGIN) + { + direct= 0; + is_trans= 1; + } + DBUG_PRINT("info", ("is_trans: %d direct: %d", is_trans, direct)); + if (get_binlog_local_stmt_filter() == BINLOG_FILTER_SET) { /* diff --git a/sql/sql_class.h b/sql/sql_class.h index 5c0684f5d68..e3668321bec 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1518,8 +1518,9 @@ public: void unlock_locked_tables(THD *thd); ~Locked_tables_list() { - unlock_locked_tables(0); + reset(); } + void reset(); bool init_locked_tables(THD *thd); TABLE_LIST *locked_tables() { return m_locked_tables; } void unlink_from_list(THD *thd, TABLE_LIST *table_list, @@ -1528,6 +1529,9 @@ public: MYSQL_LOCK *lock, size_t reopen_count); bool reopen_tables(THD *thd); + bool restore_lock(THD *thd, TABLE_LIST *dst_table_list, TABLE *table, + MYSQL_LOCK *lock); + void add_back_last_deleted_lock(TABLE_LIST *dst_table_list); }; @@ -1971,7 +1975,10 @@ public: uint in_sub_stmt; /* True when opt_userstat_running is set at start of query */ bool userstat_running; - /* True if we want to log all errors */ + /* + True if we have to log all errors. Are set by some engines to temporary + force errors to the error log. + */ bool log_all_errors; /* Do not set socket timeouts for wait_timeout (used with threadpool) */ @@ -2562,12 +2569,12 @@ public: */ LEX_STRING connection_name; char default_master_connection_buff[MAX_CONNECTION_NAME+1]; + uint8 password; /* 0, 1 or 2 */ + uint8 failed_com_change_user; bool slave_thread, one_shot_set; bool extra_port; /* If extra connection */ bool no_errors; - uint8 password; - uint8 failed_com_change_user; /** Set to TRUE if execution of the current compound statement @@ -2600,13 +2607,6 @@ public: /* for IS NULL => = last_insert_id() fix in remove_eq_conds() */ bool substitute_null_with_insert_id; bool in_lock_tables; - /** - True if a slave error. Causes the slave to stop. Not the same - as the statement execution error (is_error()), since - a statement may be expected to return an error, e.g. because - it returned an error on master, and this is OK on the slave. - */ - bool is_slave_error; bool bootstrap, cleanup_done; /** is set if some thread specific value(s) used in a statement. */ @@ -2623,6 +2623,20 @@ public: /* set during loop of derived table processing */ bool derived_tables_processing; bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ + /* True if we have to log the current statement */ + bool log_current_statement; + /** + True if a slave error. Causes the slave to stop. Not the same + as the statement execution error (is_error()), since + a statement may be expected to return an error, e.g. because + it returned an error on master, and this is OK on the slave. + */ + bool is_slave_error; + /* + In case of a slave, set to the error code the master got when executing + the query. 0 if no error on the master. + */ + int slave_expected_error; sp_rcontext *spcont; // SP runtime context sp_cache *sp_proc_cache; @@ -4014,6 +4028,8 @@ class select_create: public select_insert { MYSQL_LOCK *m_lock; /* m_lock or thd->extra_lock */ MYSQL_LOCK **m_plock; + bool exit_done; + public: select_create (TABLE_LIST *table_arg, HA_CREATE_INFO *create_info_par, @@ -4025,7 +4041,7 @@ public: create_info(create_info_par), select_tables(select_tables_arg), alter_info(alter_info_arg), - m_plock(NULL) + m_plock(NULL), exit_done(0) {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 8068901ebec..fcde2b4acbd 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -798,14 +798,8 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if ((my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db) == 0)) { for (table= tables; table; table= table->next_local) - { - if (check_if_log_table(table->db_length, table->db, - table->table_name_length, table->table_name, true)) - { - my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); + if (check_if_log_table(table, TRUE, "DROP")) goto exit; - } - } } /* Lock all tables and stored routines about to be dropped. */ @@ -835,7 +829,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) thd->push_internal_handler(&err_handler); if (!thd->killed && !(tables && - mysql_rm_table_no_locks(thd, tables, true, false, true, true))) + mysql_rm_table_no_locks(thd, tables, true, false, true, true, false))) { /* We temporarily disable the binary log while dropping the objects diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index e0ecfcac72e..899e0dead6b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1229,7 +1229,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view) DBUG_ASSERT(view->table != 0 && view->field_translation != 0); - (void) bitmap_init(&used_fields, used_fields_buff, table->s->fields, 0); + (void) my_bitmap_init(&used_fields, used_fields_buff, table->s->fields, 0); bitmap_clear_all(&used_fields); view->contain_auto_increment= 0; @@ -3803,7 +3803,8 @@ void select_insert::abort_result_set() { */ changed= (info.copied || info.deleted || info.updated); transactional_table= table->file->has_transactions(); - if (thd->transaction.stmt.modified_non_trans_table) + if (thd->transaction.stmt.modified_non_trans_table || + thd->log_current_statement) { if (!can_rollback_data()) thd->transaction.all.modified_non_trans_table= TRUE; @@ -3925,6 +3926,16 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, DEBUG_SYNC(thd,"create_table_select_before_create"); + /* Check if LOCK TABLES + CREATE OR REPLACE of existing normal table*/ + if (thd->locked_tables_mode && create_table->table && + !create_info->tmp_table()) + { + /* Remember information about the locked table */ + create_info->pos_in_locked_tables= + create_table->table->pos_in_locked_tables; + create_info->mdl_ticket= create_table->table->mdl_ticket; + } + /* Create and lock table. @@ -3941,52 +3952,63 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE, which is a wrong order. So we keep binary logging disabled when we open_table(). */ + + if (!mysql_create_table_no_lock(thd, create_table->db, + create_table->table_name, + create_info, alter_info, NULL, + select_field_count)) { - if (!mysql_create_table_no_lock(thd, create_table->db, - create_table->table_name, - create_info, alter_info, NULL, - select_field_count)) + DEBUG_SYNC(thd,"create_table_select_before_open"); + + /* + If we had a temporary table or a table used with LOCK TABLES, + it was closed by mysql_create() + */ + create_table->table= 0; + + if (!create_info->tmp_table()) { - DEBUG_SYNC(thd,"create_table_select_before_open"); + Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); + TABLE_LIST::enum_open_strategy save_open_strategy; - if (!create_info->tmp_table()) - { - Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); - /* - Here we open the destination table, on which we already have - an exclusive metadata lock. - */ - if (open_table(thd, create_table, thd->mem_root, &ot_ctx)) - { - quick_rm_table(thd, create_info->db_type, create_table->db, - table_case_name(create_info, create_table->table_name), - 0); - } - else - table= create_table->table; - } - else + /* Force the newly created table to be opened */ + save_open_strategy= create_table->open_strategy; + create_table->open_strategy= TABLE_LIST::OPEN_NORMAL; + /* + Here we open the destination table, on which we already have + an exclusive metadata lock. + */ + if (open_table(thd, create_table, thd->mem_root, &ot_ctx)) { - if (open_temporary_table(thd, create_table)) - { - /* - This shouldn't happen as creation of temporary table should make - it preparable for open. Anyway we can't drop temporary table if - we are unable to find it. - */ - DBUG_ASSERT(0); - } - else - table= create_table->table; + quick_rm_table(thd, create_info->db_type, create_table->db, + table_case_name(create_info, create_table->table_name), + 0); } + /* Restore */ + create_table->open_strategy= save_open_strategy; } - if (!table) // open failed + else { - if (!thd->is_error()) // CREATE ... IF NOT EXISTS - my_ok(thd); // succeed, but did nothing - DBUG_RETURN(0); + if (open_temporary_table(thd, create_table)) + { + /* + This shouldn't happen as creation of temporary table should make + it preparable for open. Anyway we can't drop temporary table if + we are unable to find it. + */ + DBUG_ASSERT(0); + } } } + else + create_table->table= 0; // Create failed + + if (!(table= create_table->table)) + { + if (!thd->is_error()) // CREATE ... IF NOT EXISTS + my_ok(thd); // succeed, but did nothing + DBUG_RETURN(0); + } DEBUG_SYNC(thd,"create_table_select_before_lock"); @@ -4003,7 +4025,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, /* purecov: begin tested */ /* This can happen in innodb when you get a deadlock when using same table - in insert and select + in insert and select or when you run out of memory. */ my_error(ER_CANT_LOCK, MYF(0), my_errno); if (*lock) @@ -4101,8 +4123,6 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) thd->binlog_start_trans_and_stmt(); } - DBUG_ASSERT(create_table->table == NULL); - DEBUG_SYNC(thd,"create_table_select_before_check_if_exists"); if (!(table= create_table_from_items(thd, create_info, create_table, @@ -4190,7 +4210,9 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) query.length(0); // Have to zero it since constructor doesn't result= store_create_info(thd, &tmp_table_list, &query, create_info, - /* show_database */ TRUE); + /* show_database */ TRUE, + test(create_info->options & + HA_LEX_CREATE_REPLACE)); DBUG_ASSERT(result == 0); /* store_create_info() always return 0 */ if (mysql_bin_log.is_open()) @@ -4245,39 +4267,67 @@ void select_create::send_error(uint errcode,const char *err) bool select_create::send_eof() { - bool tmp=select_insert::send_eof(); - if (tmp) + if (select_insert::send_eof()) + { abort_result_set(); - else + return 1; + } + + exit_done= 1; // Avoid double calls + /* + Do an implicit commit at end of statement for non-temporary + tables. This can fail, but we should unlock the table + nevertheless. + */ + if (!table->s->tmp_table) { - /* - Do an implicit commit at end of statement for non-temporary - tables. This can fail, but we should unlock the table - nevertheless. - */ - if (!table->s->tmp_table) - { - trans_commit_stmt(thd); + trans_commit_stmt(thd); + if (!(thd->variables.option_bits & OPTION_GTID_BEGIN)) trans_commit_implicit(thd); - } + } - table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); - table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); - if (m_plock) + table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); + table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); + + if (m_plock) + { + MYSQL_LOCK *lock= *m_plock; + *m_plock= NULL; + m_plock= NULL; + + if (create_info->pos_in_locked_tables) { - mysql_unlock_tables(thd, *m_plock); - *m_plock= NULL; - m_plock= NULL; + /* + If we are under lock tables, we have created a table that was + originally locked. We should add back the lock to ensure that + all tables in the thd->open_list are locked! + */ + table->mdl_ticket= create_info->mdl_ticket; + + /* The following should never fail, except if out of memory */ + if (!thd->locked_tables_list.restore_lock(thd, + create_info-> + pos_in_locked_tables, + table, lock)) + return 0; // ok + /* Fail. Continue without locking the table */ } + mysql_unlock_tables(thd, lock); } - return tmp; + return 0; } void select_create::abort_result_set() { + ulonglong save_option_bits; DBUG_ENTER("select_create::abort_result_set"); + /* Avoid double calls, could happen in case of out of memory on cleanup */ + if (exit_done) + DBUG_VOID_RETURN; + exit_done= 1; + /* In select_insert::abort_result_set() we roll back the statement, including truncating the transaction cache of the binary log. To do this, we @@ -4292,11 +4342,18 @@ void select_create::abort_result_set() We also roll back the statement regardless of whether the creation of the table succeeded or not, since we need to reset the binary log state. + + However if there was an orignal table that was deleted, as part of + create or replace table, then we must log the statement. */ - tmp_disable_binlog(thd); + + save_option_bits= thd->variables.option_bits; + if (!(thd->log_current_statement)) + thd->variables.option_bits&= ~OPTION_BIN_LOG; select_insert::abort_result_set(); thd->transaction.stmt.modified_non_trans_table= FALSE; - reenable_binlog(thd); + thd->variables.option_bits= save_option_bits; + /* possible error of writing binary log is ignored deliberately */ (void) thd->binlog_flush_pending_rows_event(TRUE, TRUE); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 281d1de7877..a0959bdd278 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -258,7 +258,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, */ if (unique_table(thd, table_list, table_list->next_global, 0)) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name, + "LOAD DATA"); DBUG_RETURN(TRUE); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 15d7e19188e..0de3609e932 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -195,6 +195,8 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables) @param thd Thread handle. @param mask Bitmask used for the SQL command match. + @return 0 No implicit commit + @return 1 Do a commit */ static bool stmt_causes_implicit_commit(THD *thd, uint mask) { @@ -207,12 +209,22 @@ static bool stmt_causes_implicit_commit(THD *thd, uint mask) switch (lex->sql_command) { case SQLCOM_DROP_TABLE: - skip= lex->drop_temporary; + skip= (lex->drop_temporary || + (thd->variables.option_bits & OPTION_GTID_BEGIN)); break; case SQLCOM_ALTER_TABLE: + /* If ALTER TABLE of non-temporary table, do implicit commit */ + skip= (lex->create_info.tmp_table()); + break; case SQLCOM_CREATE_TABLE: - /* If CREATE TABLE of non-temporary table, do implicit commit */ - skip= lex->create_info.tmp_table(); + /* + If CREATE TABLE of non-temporary table and the table is not part + if a BEGIN GTID ... COMMIT group, do a implicit commit. + This ensures that CREATE ... SELECT will in the same GTID group on the + master and slave. + */ + skip= (lex->create_info.tmp_table() || + (thd->variables.option_bits & OPTION_GTID_BEGIN)); break; case SQLCOM_SET_OPTION: skip= lex->autocommit ? FALSE : TRUE; @@ -2440,11 +2452,14 @@ mysql_execute_command(THD *thd) DBUG_ASSERT(! thd->in_sub_stmt); /* Statement transaction still should not be started. */ DBUG_ASSERT(thd->transaction.stmt.is_empty()); - /* Commit the normal transaction if one is active. */ - if (trans_commit_implicit(thd)) - goto error; - /* Release metadata locks acquired in this transaction. */ - thd->mdl_context.release_transactional_locks(); + if (!(thd->variables.option_bits & OPTION_GTID_BEGIN)) + { + /* Commit the normal transaction if one is active. */ + if (trans_commit_implicit(thd)) + goto error; + /* Release metadata locks acquired in this transaction. */ + thd->mdl_context.release_transactional_locks(); + } } #ifndef DBUG_OFF @@ -2829,6 +2844,7 @@ case SQLCOM_PREPARE: goto end_with_restore_list; } + /* Check privileges */ if ((res= create_table_precheck(thd, select_tables, create_table))) goto end_with_restore_list; @@ -2863,6 +2879,23 @@ case SQLCOM_PREPARE: create_info.table_charset= 0; } + /* + For CREATE TABLE we should not open the table even if it exists. + If the table exists, we should either not create it or replace it + */ + lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB; + + /* + If we are a slave, we should add OR REPLACE if we don't have + IF EXISTS. This will help a slave to recover from + CREATE TABLE OR EXISTS failures by dropping the table and + retrying the create. + */ + if (thd->slave_thread && + slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT && + !(lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)) + create_info.options|= HA_LEX_CREATE_REPLACE; + #ifdef WITH_PARTITION_STORAGE_ENGINE { partition_info *part_info= thd->lex->part_info; @@ -2951,28 +2984,25 @@ case SQLCOM_PREPARE: /* Got error or warning. Set res to 1 if error */ if (!(res= thd->is_error())) my_ok(thd); // CREATE ... IF NOT EXISTS + goto end_with_restore_list; } - else + + /* Ensure we don't try to create something from which we select from */ + if ((create_info.options & HA_LEX_CREATE_REPLACE) && + !create_info.tmp_table()) { - /* The table already exists */ - if (create_table->table) + TABLE_LIST *duplicate; + if ((duplicate= unique_table(thd, lex->query_tables, + lex->query_tables->next_global, + 0))) { - if (create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS) - { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_TABLE_EXISTS_ERROR, - ER(ER_TABLE_EXISTS_ERROR), - create_info.alias); - my_ok(thd); - } - else - { - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_info.alias); - res= 1; - } + update_non_unique_table_error(lex->query_tables, "CREATE", + duplicate); + res= TRUE; goto end_with_restore_list; } - + } + { /* Remove target table from main select and name resolution context. This can't be done earlier as it will break view merging in @@ -2980,9 +3010,8 @@ case SQLCOM_PREPARE: */ lex->unlink_first_table(&link_to_local); - /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */ - if (create_info.tmp_table()) - thd->variables.option_bits|= OPTION_KEEP_LOG; + /* Store reference to table in case of LOCK TABLES */ + create_info.table= create_table->table; /* select_create is currently not re-execution friendly and @@ -3000,18 +3029,18 @@ case SQLCOM_PREPARE: CREATE from SELECT give its SELECT_LEX for SELECT, and item_list belong to SELECT */ - res= handle_select(thd, lex, result, 0); + if (!(res= handle_select(thd, lex, result, 0))) + { + if (create_info.tmp_table()) + thd->variables.option_bits|= OPTION_KEEP_LOG; + } delete result; } - lex->link_first_table_back(create_table, link_to_local); } } else { - /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */ - if (create_info.tmp_table()) - thd->variables.option_bits|= OPTION_KEEP_LOG; /* regular create */ if (create_info.options & HA_LEX_CREATE_TABLE_LIKE) { @@ -3026,7 +3055,12 @@ case SQLCOM_PREPARE: &create_info, &alter_info); } if (!res) + { + /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */ + if (create_info.tmp_table()) + thd->variables.option_bits|= OPTION_KEEP_LOG; my_ok(thd); + } } end_with_restore_list: @@ -3652,6 +3686,16 @@ end_with_restore_list: /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */ thd->variables.option_bits|= OPTION_KEEP_LOG; } + /* + If we are a slave, we should add IF EXISTS if the query executed + on the master without an error. This will help a slave to + recover from multi-table DROP TABLE that was aborted in the + middle. + */ + if (thd->slave_thread && !thd->slave_expected_error && + slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT) + lex->check_exists= 1; + /* DDL and binlog write order are protected by metadata locks. */ res= mysql_rm_table(thd, first_table, lex->check_exists, lex->drop_temporary); @@ -4402,6 +4446,7 @@ end_with_restore_list: bool tx_release= (lex->tx_release == TVL_YES || (thd->variables.completion_type == 2 && lex->tx_release != TVL_NO)); + if (trans_rollback(thd)) goto error; thd->mdl_context.release_transactional_locks(); @@ -5153,12 +5198,15 @@ finish: { /* No transaction control allowed in sub-statements. */ DBUG_ASSERT(! thd->in_sub_stmt); - /* If commit fails, we should be able to reset the OK status. */ - thd->get_stmt_da()->set_overwrite_status(true); - /* Commit the normal transaction if one is active. */ - trans_commit_implicit(thd); - thd->get_stmt_da()->set_overwrite_status(false); - thd->mdl_context.release_transactional_locks(); + if (!(thd->variables.option_bits & OPTION_GTID_BEGIN)) + { + /* If commit fails, we should be able to reset the OK status. */ + thd->get_stmt_da()->set_overwrite_status(true); + /* Commit the normal transaction if one is active. */ + trans_commit_implicit(thd); + thd->get_stmt_da()->set_overwrite_status(false); + thd->mdl_context.release_transactional_locks(); + } } else if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode()) { @@ -6101,6 +6149,8 @@ void THD::reset_for_next_command() thd->query_start_used= 0; thd->query_start_sec_part_used= 0; thd->is_fatal_error= thd->time_zone_used= 0; + thd->log_current_statement= 0; + /* Clear the status flag that are expected to be cleared at the beginning of each SQL statement. @@ -7961,6 +8011,11 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, want_priv= lex->create_info.tmp_table() ? CREATE_TMP_ACL : (CREATE_ACL | (select_lex->item_list.elements ? INSERT_ACL : 0)); + /* CREATE OR REPLACE on not temporary tables require DROP_ACL */ + if ((lex->create_info.options & HA_LEX_CREATE_REPLACE) && + !lex->create_info.tmp_table()) + want_priv|= DROP_ACL; + if (check_access(thd, want_priv, create_table->db, &create_table->grant.privilege, &create_table->grant.m_internal, @@ -7997,8 +8052,8 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, - For temporary MERGE tables we do not track if their child tables are base or temporary. As result we can't guarantee that privilege check - which was done in presence of temporary child will stay relevant later - as this temporary table might be removed. + which was done in presence of temporary child will stay relevant + later as this temporary table might be removed. If SELECT_ACL | UPDATE_ACL | DELETE_ACL privileges were not checked for the underlying *base* tables, it would create a security breach as in @@ -8029,6 +8084,12 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, } error= FALSE; + /* + For CREATE TABLE we should not open the table even if it exists. + If the table exists, we should either not create it or replace it + */ + lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB; + err: DBUG_RETURN(error); } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 5e256522119..782a49af813 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -651,7 +651,7 @@ static bool create_full_part_field_array(THD *thd, TABLE *table, result= TRUE; goto end; } - if (bitmap_init(&part_info->full_part_field_set, bitmap_buf, + if (my_bitmap_init(&part_info->full_part_field_set, bitmap_buf, table->s->fields, FALSE)) { mem_alloc_error(table->s->fields); @@ -1230,9 +1230,9 @@ static bool set_up_partition_bitmaps(THD *thd, partition_info *part_info) mem_alloc_error(bitmap_bytes * 2); DBUG_RETURN(TRUE); } - bitmap_init(&part_info->read_partitions, bitmap_buf, bitmap_bits, FALSE); + my_bitmap_init(&part_info->read_partitions, bitmap_buf, bitmap_bits, FALSE); /* Use the second half of the allocated buffer for lock_partitions */ - bitmap_init(&part_info->lock_partitions, bitmap_buf + (bitmap_bytes / 4), + my_bitmap_init(&part_info->lock_partitions, bitmap_buf + (bitmap_bytes / 4), bitmap_bits, FALSE); part_info->bitmaps_are_initialized= TRUE; part_info->set_partition_bitmaps(NULL); diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 29ca86fa274..b2a8bca72db 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -506,13 +506,8 @@ bool Sql_cmd_alter_table_exchange_partition:: /* Don't allow to exchange with log table */ swap_table_list= table_list->next_local; - if (check_if_log_table(swap_table_list->db_length, swap_table_list->db, - swap_table_list->table_name_length, - swap_table_list->table_name, 0)) - { - my_error(ER_WRONG_USAGE, MYF(0), "PARTITION", "log table"); + if (check_if_log_table(swap_table_list, FALSE, "ALTER PARTITION")) DBUG_RETURN(TRUE); - } /* Currently no MDL lock that allows both read and write and is upgradeable diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 383888bac30..5e3b80ab7a9 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -110,6 +110,8 @@ /* The following is used to detect a conflict with DISTINCT */ #define SELECT_ALL (1ULL << 24) // SELECT, user, parser +#define OPTION_GTID_BEGIN (1ULL << 25) // GTID BEGIN found in log + /** The following can be set when importing tables in a 'wrong order' to suppress foreign key checks */ #define OPTION_NO_FOREIGN_KEY_CHECKS (1ULL << 26) // THD, user, binlog diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 6babdd7c636..897aa183b60 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -84,12 +84,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) for (to_table= 0, ren_table= table_list; ren_table; to_table= 1 - to_table, ren_table= ren_table->next_local) { - int log_table_rename= 0; - - if ((log_table_rename= - check_if_log_table(ren_table->db_length, ren_table->db, - ren_table->table_name_length, - ren_table->table_name, 1))) + int log_table_rename; + if ((log_table_rename= check_if_log_table(ren_table, TRUE, NullS))) { /* as we use log_table_rename as an array index, we need it to start diff --git a/sql/sql_select.cc b/sql/sql_select.cc index dd23400f387..5c2c9ba1e38 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15354,18 +15354,18 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) { uint field_count= table->s->fields; - bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count, + my_bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count, FALSE); - bitmap_init(&table->def_vcol_set, + my_bitmap_init(&table->def_vcol_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, FALSE); - bitmap_init(&table->tmp_set, + my_bitmap_init(&table->tmp_set, (my_bitmap_map*) (bitmaps+ 2*bitmap_buffer_size(field_count)), field_count, FALSE); - bitmap_init(&table->eq_join_set, + my_bitmap_init(&table->eq_join_set, (my_bitmap_map*) (bitmaps+ 3*bitmap_buffer_size(field_count)), field_count, FALSE); - bitmap_init(&table->cond_set, + my_bitmap_init(&table->cond_set, (my_bitmap_map*) (bitmaps+ 4*bitmap_buffer_size(field_count)), field_count, FALSE); /* write_set and all_set are copies of read_set */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2ab34ece903..738384d599f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1041,7 +1041,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if ((table_list->view ? view_store_create_info(thd, table_list, &buffer) : store_create_info(thd, table_list, &buffer, NULL, - FALSE /* show_database */))) + FALSE /* show_database */, FALSE))) goto exit; if (table_list->view) @@ -1526,6 +1526,8 @@ static void append_create_options(THD *thd, String *packet, to tailor the format of the statement. Can be NULL, in which case only SQL_MODE is considered when building the statement. + show_database Add database name to table name + create_or_replace Use CREATE OR REPLACE syntax NOTE Currently always return 0, but might return error code in the @@ -1536,7 +1538,8 @@ static void append_create_options(THD *thd, String *packet, */ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, - HA_CREATE_INFO *create_info_arg, bool show_database) + HA_CREATE_INFO *create_info_arg, bool show_database, + bool create_or_replace) { List<Item> field_list; char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH]; @@ -1569,10 +1572,12 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, restore_record(table, s->default_values); // Get empty record + packet->append(STRING_WITH_LEN("CREATE ")); + if (create_or_replace) + packet->append(STRING_WITH_LEN("OR REPLACE ")); if (share->tmp_table) - packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE ")); - else - packet->append(STRING_WITH_LEN("CREATE TABLE ")); + packet->append(STRING_WITH_LEN("TEMPORARY ")); + packet->append(STRING_WITH_LEN("TABLE ")); if (create_info_arg && (create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS)) packet->append(STRING_WITH_LEN("IF NOT EXISTS ")); @@ -7681,7 +7686,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(0); my_bitmap_map* bitmaps= (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count)); - bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count, + my_bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count, FALSE); table->read_set= &table->def_read_set; bitmap_clear_all(table->read_set); diff --git a/sql/sql_show.h b/sql/sql_show.h index 10276e8b65e..0416f2fdaba 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -75,7 +75,8 @@ typedef struct system_status_var STATUS_VAR; #define IS_FILES_EXTRA 37 int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, - HA_CREATE_INFO *create_info_arg, bool show_database); + HA_CREATE_INFO *create_info_arg, bool show_database, + bool create_or_replace); int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff); int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 45d9c5dc091..67d6795ecce 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2031,33 +2031,29 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, bool error; Drop_table_error_handler err_handler; TABLE_LIST *table; - DBUG_ENTER("mysql_rm_table"); /* Disable drop of enabled log tables, must be done before name locking */ for (table= tables; table; table= table->next_local) { - if (check_if_log_table(table->db_length, table->db, - table->table_name_length, table->table_name, true)) - { - my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); + if (check_if_log_table(table, TRUE, "DROP")) DBUG_RETURN(true); - } } - if (!in_bootstrap) + if (!drop_temporary) { - for (table= tables; table; table= table->next_local) + if (!in_bootstrap) { - LEX_STRING db_name= { table->db, table->db_length }; - LEX_STRING table_name= { table->table_name, table->table_name_length }; - if (table->open_type == OT_BASE_ONLY || !find_temporary_table(thd, table)) - (void) delete_statistics_for_table(thd, &db_name, &table_name); + for (table= tables; table; table= table->next_local) + { + LEX_STRING db_name= { table->db, table->db_length }; + LEX_STRING table_name= { table->table_name, table->table_name_length }; + if (table->open_type == OT_BASE_ONLY || + !find_temporary_table(thd, table)) + (void) delete_statistics_for_table(thd, &db_name, &table_name); + } } - } - if (!drop_temporary) - { if (!thd->locked_tables_mode) { if (lock_table_names(thd, tables, NULL, @@ -2107,7 +2103,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, /* mark for close and remove all cached entries */ thd->push_internal_handler(&err_handler); error= mysql_rm_table_no_locks(thd, tables, if_exists, drop_temporary, - false, false); + false, false, false); thd->pop_internal_handler(); if (error) @@ -2172,6 +2168,8 @@ static uint32 comment_length(THD *thd, uint32 comment_pos, @param drop_view Allow to delete VIEW .frm @param dont_log_query Don't write query to log files. This will also not generate warnings if the handler files doesn't exists + @param dont_free_locks Don't do automatic UNLOCK TABLE if no more locked + tables @retval 0 ok @retval 1 Error @@ -2194,7 +2192,8 @@ static uint32 comment_length(THD *thd, uint32 comment_pos, int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, bool drop_temporary, bool drop_view, - bool dont_log_query) + bool dont_log_query, + bool dont_free_locks) { TABLE_LIST *table; char path[FN_REFLEN + 1], wrong_tables_buff[160], *alias= NULL; @@ -2208,6 +2207,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0; bool non_tmp_table_deleted= 0; bool is_drop_tmp_if_exists_added= 0; + bool one_table= tables->next_local == 0; + bool was_view= 0; String built_query; String built_trans_tmp_query, built_non_trans_tmp_query; DBUG_ENTER("mysql_rm_table_no_locks"); @@ -2286,7 +2287,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, for (table= tables; table; table= table->next_local) { - bool is_trans; + bool is_trans= 0; char *db=table->db; size_t db_length= table->db_length; handlerton *table_type= 0; @@ -2311,12 +2312,16 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, . 1 - a temporary table was not found. . -1 - a temporary table is used by an outer statement. */ - if (table->open_type == OT_BASE_ONLY) + if (table->open_type == OT_BASE_ONLY || !is_temporary_table(table)) error= 1; - else if ((error= drop_temporary_table(thd, table, &is_trans)) == -1) + else { - DBUG_ASSERT(thd->in_sub_stmt); - goto err; + if ((error= drop_temporary_table(thd, table->table, &is_trans)) == -1) + { + DBUG_ASSERT(thd->in_sub_stmt); + goto err; + } + table->table= 0; } if ((drop_temporary && if_exists) || !error) @@ -2413,7 +2418,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table"); error= 0; if ((drop_temporary || !ha_table_exists(thd, db, alias, &table_type) || - (!drop_view && table_type == view_pseudo_hton))) + (!drop_view && (was_view= (table_type == view_pseudo_hton))))) { /* One of the following cases happened: @@ -2544,7 +2549,10 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, err: if (wrong_tables.length()) { - if (!foreign_key_error) + if (one_table && was_view) + my_printf_error(ER_IT_IS_A_VIEW, ER(ER_IT_IS_A_VIEW), MYF(0), + wrong_tables.c_ptr_safe()); + else if (!foreign_key_error) my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), wrong_tables.c_ptr_safe()); else @@ -2610,7 +2618,8 @@ err: */ if (thd->locked_tables_mode) { - if (thd->lock && thd->lock->table_count == 0 && non_temp_tables_count > 0) + if (thd->lock && thd->lock->table_count == 0 && + non_temp_tables_count > 0 && !dont_free_locks) { thd->locked_tables_list.unlock_locked_tables(thd); goto end; @@ -4517,12 +4526,13 @@ err: way to ensure that concurrent operations won't intervene. mysql_create_table() is a wrapper that can be used for this. - @retval false OK - @retval true error + @retval 0 OK + @retval 1 error + @retval -1 table existed but IF EXISTS was used */ static -bool create_table_impl(THD *thd, +int create_table_impl(THD *thd, const char *db, const char *table_name, const char *path, HA_CREATE_INFO *create_info, @@ -4535,7 +4545,7 @@ bool create_table_impl(THD *thd, { const char *alias; handler *file= 0; - bool error= TRUE; + int error= 1; bool frm_only= create_table_mode == C_ALTER_TABLE_FRM_ONLY; bool internal_tmp_table= create_table_mode == C_ALTER_TABLE || frm_only; DBUG_ENTER("mysql_create_table_no_lock"); @@ -4565,22 +4575,74 @@ bool create_table_impl(THD *thd, /* Check if table exists */ if (create_info->tmp_table()) { - if (find_temporary_table(thd, db, table_name)) + TABLE *tmp_table; + if ((tmp_table= find_temporary_table(thd, db, table_name))) { - if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) + if (create_info->options & HA_LEX_CREATE_REPLACE) + { + bool is_trans; + /* + We are using CREATE OR REPLACE on an existing temporary table + Remove the old table so that we can re-create it. + */ + if (drop_temporary_table(thd, tmp_table, &is_trans)) + goto err; + } + else if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) goto warn; - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); - goto err; + else + { + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); + goto err; + } } } - else + else { if (!internal_tmp_table && ha_table_exists(thd, db, table_name)) { - if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) + if (create_info->options & HA_LEX_CREATE_REPLACE) + { + TABLE_LIST table_list; + table_list.init_one_table(db, strlen(db), table_name, + strlen(table_name), table_name, + TL_WRITE_ALLOW_WRITE); + table_list.table= create_info->table; + + if (check_if_log_table(&table_list, TRUE, "CREATE OR REPLACE")) + goto err; + + /* + Rollback the empty transaction started in mysql_create_table() + call to open_and_lock_tables() when we are using LOCK TABLES. + */ + (void) trans_rollback_stmt(thd); + /* Remove normal table without logging. Keep tables locked */ + if (mysql_rm_table_no_locks(thd, &table_list, 0, 0, 0, 1, 1)) + goto err; + + /* + We have to log this query, even if it failed later to ensure the + drop is done. + */ + thd->variables.option_bits|= OPTION_KEEP_LOG; + thd->log_current_statement= 1; + + /* + The test of query_tables is to ensure we have any tables in the + select part + */ + if (thd->lex->query_tables && + restart_trans_for_tables(thd, thd->lex->query_tables->next_global)) + goto err; + } + else if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) goto warn; - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); - goto err; + else + { + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); + goto err; + } } } @@ -4702,14 +4764,14 @@ bool create_table_impl(THD *thd, } #endif - error= FALSE; + error= 0; err: THD_STAGE_INFO(thd, stage_after_create); delete file; DBUG_RETURN(error); warn: - error= FALSE; + error= -1; push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), alias); @@ -4720,7 +4782,8 @@ warn: Simple wrapper around create_table_impl() to be used in various version of CREATE TABLE statement. */ -bool mysql_create_table_no_lock(THD *thd, + +int mysql_create_table_no_lock(THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *create_info, Alter_info *alter_info, bool *is_trans, @@ -4728,6 +4791,7 @@ bool mysql_create_table_no_lock(THD *thd, { KEY *not_used_1; uint not_used_2; + int res; char path[FN_REFLEN + 1]; LEX_CUSTRING frm= {0,0}; @@ -4747,9 +4811,9 @@ bool mysql_create_table_no_lock(THD *thd, } } - bool res= create_table_impl(thd, db, table_name, path, create_info, - alter_info, create_table_mode, is_trans, - ¬_used_1, ¬_used_2, &frm); + res= create_table_impl(thd, db, table_name, path, create_info, + alter_info, create_table_mode, is_trans, + ¬_used_1, ¬_used_2, &frm); my_free(const_cast<uchar*>(frm.str)); return res; } @@ -4771,16 +4835,23 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, const char *db= create_table->db; const char *table_name= create_table->table_name; bool is_trans= FALSE; + bool result= 0; int create_table_mode; + TABLE_LIST *pos_in_locked_tables= 0; DBUG_ENTER("mysql_create_table"); + DBUG_ASSERT(create_table == thd->lex->query_tables); + /* Open or obtain an exclusive metadata lock on table being created */ if (open_and_lock_tables(thd, thd->lex->query_tables, FALSE, 0)) { /* is_error() may be 0 if table existed and we generated a warning */ DBUG_RETURN(thd->is_error()); } - + /* The following is needed only in case of lock tables */ + if ((create_info->table= thd->lex->query_tables->table)) + pos_in_locked_tables= create_info->table->pos_in_locked_tables; + /* Got lock. */ DEBUG_SYNC(thd, "locked_table_name"); @@ -4791,15 +4862,37 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, promote_first_timestamp_column(&alter_info->create_list); if (mysql_create_table_no_lock(thd, db, table_name, create_info, alter_info, - &is_trans, create_table_mode)) - DBUG_RETURN(1); + &is_trans, create_table_mode) > 0) + { + result= 1; + goto err; + } + + /* + Check if we are doing CREATE OR REPLACE TABLE under LOCK TABLES + on a non temporary table + */ + if (thd->locked_tables_mode && pos_in_locked_tables && + (create_info->options & HA_LEX_CREATE_REPLACE)) + { + /* + Add back the deleted table and re-created table as a locked table + This should always work as we have a meta lock on the table. + */ + thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables); + if (thd->locked_tables_list.reopen_tables(thd)) + thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); + } +err: /* In RBR we don't need to log CREATE TEMPORARY TABLE */ if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table()) - DBUG_RETURN(0); - - bool result; - result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans); + DBUG_RETURN(result); + /* Write log if no error or if we already deleted a table */ + if (!result || thd->log_current_statement) + if (write_bin_log(thd, result ? FALSE : TRUE, thd->query(), + thd->query_length(), is_trans)) + result= 1; DBUG_RETURN(result); } @@ -4986,18 +5079,20 @@ mysql_rename_table(handlerton *base, const char *old_db, TRUE error */ -bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, +bool mysql_create_like_table(THD* thd, TABLE_LIST* table, + TABLE_LIST* src_table, HA_CREATE_INFO *create_info) { HA_CREATE_INFO local_create_info; + TABLE_LIST *pos_in_locked_tables= 0; Alter_info local_alter_info; Alter_table_ctx local_alter_ctx; // Not used bool res= TRUE; bool is_trans= FALSE; + bool do_logging= FALSE; uint not_used; DBUG_ENTER("mysql_create_like_table"); - /* We the open source table to get its description in HA_CREATE_INFO and Alter_info objects. This also acquires a shared metadata lock @@ -5014,6 +5109,18 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, res= thd->is_error(); goto err; } + /* Ensure we don't try to create something from which we select from */ + if ((create_info->options & HA_LEX_CREATE_REPLACE) && + !create_info->tmp_table()) + { + TABLE_LIST *duplicate; + if ((duplicate= unique_table(thd, table, src_table, 0))) + { + update_non_unique_table_error(src_table, "CREATE", duplicate); + goto err; + } + } + src_table->table->use_all_columns(); DEBUG_SYNC(thd, "create_table_like_after_open"); @@ -5041,7 +5148,9 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, if (src_table->schema_table) local_create_info.max_rows= 0; /* Set IF NOT EXISTS option as in the CREATE TABLE LIKE statement. */ - local_create_info.options|= create_info->options&HA_LEX_CREATE_IF_NOT_EXISTS; + local_create_info.options|= (create_info->options & + (HA_LEX_CREATE_IF_NOT_EXISTS | + HA_LEX_CREATE_REPLACE)); /* Replace type of source table with one specified in the statement. */ local_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE; local_create_info.options|= create_info->tmp_table(); @@ -5053,12 +5162,43 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, */ local_create_info.data_file_name= local_create_info.index_file_name= NULL; - if ((res= mysql_create_table_no_lock(thd, table->db, table->table_name, - &local_create_info, &local_alter_info, - &is_trans, C_ORDINARY_CREATE))) + /* The following is needed only in case of lock tables */ + if ((local_create_info.table= thd->lex->query_tables->table)) + pos_in_locked_tables= local_create_info.table->pos_in_locked_tables; + + res= (mysql_create_table_no_lock(thd, table->db, table->table_name, + &local_create_info, &local_alter_info, + &is_trans, C_ORDINARY_CREATE) > 0); + /* Remember to log if we deleted something */ + do_logging= thd->log_current_statement; + if (res) goto err; /* + Check if we are doing CREATE OR REPLACE TABLE under LOCK TABLES + on a non temporary table + */ + if (thd->locked_tables_mode && pos_in_locked_tables && + (create_info->options & HA_LEX_CREATE_REPLACE)) + { + /* + Add back the deleted table and re-created table as a locked table + This should always work as we have a meta lock on the table. + */ + thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables); + if (thd->locked_tables_list.reopen_tables(thd)) + thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); + else + { + /* + Get pointer to the newly opened table. We need this to ensure we + don't reopen the table when doing statment logging below. + */ + table->table= pos_in_locked_tables->table; + } + } + + /* Ensure that we have an exclusive lock on target table if we are creating non-temporary table. */ @@ -5108,6 +5248,11 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, { if (!table->table) { + TABLE_LIST::enum_open_strategy save_open_strategy; + int open_res; + /* Force the newly created table to be opened */ + save_open_strategy= table->open_strategy; + table->open_strategy= TABLE_LIST::OPEN_NORMAL; /* In order for store_create_info() to work we need to open @@ -5117,18 +5262,36 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, lock on this table. The table will be closed by close_thread_table() at the end of this branch. */ - if (open_table(thd, table, thd->mem_root, &ot_ctx)) + open_res= open_table(thd, table, thd->mem_root, &ot_ctx); + /* Restore */ + table->open_strategy= save_open_strategy; + if (open_res) + { + res= 1; goto err; + } new_table= TRUE; } - + } + /* + We have to re-test if the table was a view as the view may not + have been opened until just above. + */ + if (!table->view) + { int result __attribute__((unused))= store_create_info(thd, table, &query, - create_info, FALSE /* show_database */); + create_info, FALSE /* show_database */, + test(create_info->options & + HA_LEX_CREATE_REPLACE)); DBUG_ASSERT(result == 0); // store_create_info() always return 0 + do_logging= FALSE; if (write_bin_log(thd, TRUE, query.ptr(), query.length())) + { + res= 1; goto err; + } if (new_table) { @@ -5143,17 +5306,20 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, } } else // Case 1 - if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) - goto err; + do_logging= TRUE; } /* Case 3 and 4 does nothing under RBR */ } - else if (write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans)) - goto err; + else + do_logging= TRUE; err: + if (do_logging && + write_bin_log(thd, res ? FALSE : TRUE, thd->query(), + thd->query_length(), is_trans)) + res= 1; DBUG_RETURN(res); } @@ -7726,9 +7892,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, it is the case. TODO: this design is obsolete and will be removed. */ - int table_kind= check_if_log_table(table_list->db_length, table_list->db, - table_list->table_name_length, - table_list->table_name, false); + int table_kind= check_if_log_table(table_list, FALSE, NullS); if (table_kind) { diff --git a/sql/sql_table.h b/sql/sql_table.h index c42f8aaa39e..fc7eb775bef 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -187,11 +187,11 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, #define C_ALTER_TABLE_FRM_ONLY -2 #define C_ASSISTED_DISCOVERY -3 -bool mysql_create_table_no_lock(THD *thd, const char *db, - const char *table_name, - HA_CREATE_INFO *create_info, - Alter_info *alter_info, bool *is_trans, - int create_table_mode); +int mysql_create_table_no_lock(THD *thd, const char *db, + const char *table_name, + HA_CREATE_INFO *create_info, + Alter_info *alter_info, bool *is_trans, + int create_table_mode); handler *mysql_create_frm_image(THD *thd, const char *db, const char *table_name, @@ -238,7 +238,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, my_bool drop_temporary); int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, bool drop_temporary, bool drop_view, - bool log_query); + bool log_query, bool dont_free_locks); bool quick_rm_table(THD *thd, handlerton *base, const char *db, const char *table_name, uint flags); void close_cached_table(THD *thd, TABLE *table); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 889eaf5fceb..ccdc91e10df 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -191,7 +191,7 @@ static void prepare_record_for_error_message(int error, TABLE *table) DBUG_VOID_RETURN; /* Create unique_map with all fields used by that index. */ - bitmap_init(&unique_map, unique_map_buf, table->s->fields, FALSE); + my_bitmap_init(&unique_map, unique_map_buf, table->s->fields, FALSE); table->mark_columns_used_by_index_no_reset(keynr, &unique_map); /* Subtract read_set and write_set. */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3315c2d4d17..b206874c68d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1665,7 +1665,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <num> type type_with_opt_collate int_type real_type order_dir lock_option udf_type opt_if_exists opt_local opt_table_options table_options - table_option opt_if_not_exists opt_no_write_to_binlog + table_option opt_if_not_exists create_or_replace opt_no_write_to_binlog opt_temporary all_or_any opt_distinct opt_ignore_leaves fulltext_options spatial_type union_option field_def @@ -1844,7 +1844,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); statement sp_suid sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa opt_field_or_var_spec fields_or_vars opt_load_data_set_spec - view_replace_or_algorithm view_replace view_algorithm view_or_trigger_or_sp_or_event definer_tail no_definer_tail view_suid view_tail view_list_opt view_list view_select @@ -2342,25 +2341,29 @@ connection_name: /* create a table */ create: - CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident + create_or_replace opt_table_options TABLE_SYM opt_if_not_exists table_ident { LEX *lex= thd->lex; lex->sql_command= SQLCOM_CREATE_TABLE; + if ($1 && $4) + { + my_error(ER_WRONG_USAGE, MYF(0), "OR REPLACE", "IF NOT EXISTS"); + MYSQL_YYABORT; + } if (!lex->select_lex.add_table_to_list(thd, $5, NULL, TL_OPTION_UPDATING, TL_WRITE, MDL_EXCLUSIVE)) MYSQL_YYABORT; - /* - For CREATE TABLE, an non-existing table is not an error. - Instruct open_tables() to just take an MDL lock if the - table does not exist. - */ - lex->query_tables->open_strategy= TABLE_LIST::OPEN_IF_EXISTS; lex->alter_info.reset(); lex->col_list.empty(); lex->change=NullS; bzero((char*) &lex->create_info,sizeof(lex->create_info)); - lex->create_info.options=$2 | $4; + /* + For CREATE TABLE we should not open the table even if it exists. + If the table exists, we should either not create it or replace it + */ + lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB; + lex->create_info.options= ($1 | $2 | $4); lex->create_info.default_table_charset= NULL; lex->name.str= 0; lex->name.length= 0; @@ -2429,14 +2432,22 @@ create: lex->name= $4; lex->create_info.options=$3; } - | CREATE + | create_or_replace { - Lex->create_view_mode= VIEW_CREATE_NEW; + Lex->create_view_mode= ($1 == 0 ? VIEW_CREATE_NEW : + VIEW_CREATE_OR_REPLACE); Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; Lex->create_view_suid= TRUE; } view_or_trigger_or_sp_or_event - {} + { + if ($1 && Lex->sql_command != SQLCOM_CREATE_VIEW) + { + my_error(ER_WRONG_USAGE, MYF(0), "OR REPLACE", + "TRIGGERS / SP / EVENT"); + MYSQL_YYABORT; + } + } | CREATE USER clear_privileges grant_list { Lex->sql_command = SQLCOM_CREATE_USER; @@ -5516,6 +5527,17 @@ opt_if_not_exists: } ; +create_or_replace: + CREATE /* empty */ + { + $$= 0; + } + | CREATE OR_SYM REPLACE + { + $$= HA_LEX_CREATE_REPLACE; + } + ; + opt_create_table_options: /* empty */ | create_table_options @@ -15821,7 +15843,7 @@ view_or_trigger_or_sp_or_event: {} | no_definer no_definer_tail {} - | view_replace_or_algorithm definer_opt view_tail + | view_algorithm definer_opt view_tail {} ; @@ -15880,20 +15902,6 @@ definer: **************************************************************************/ -view_replace_or_algorithm: - view_replace - {} - | view_replace view_algorithm - {} - | view_algorithm - {} - ; - -view_replace: - OR_SYM REPLACE - { Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; } - ; - view_algorithm: ALGORITHM_SYM EQ UNDEFINED_SYM { Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 77f437243c8..d7c30f532e0 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -364,7 +364,7 @@ static Sys_var_ulong Sys_back_log( "MySQL can have. This comes into play when the main MySQL thread " "gets very many connection requests in a very short time", READ_ONLY GLOBAL_VAR(back_log), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(1, 65535), DEFAULT(50), BLOCK_SIZE(1)); + VALID_RANGE(1, 65535), DEFAULT(150), BLOCK_SIZE(1)); static Sys_var_charptr Sys_basedir( "basedir", "Path to installation directory. All paths are " @@ -593,7 +593,7 @@ static bool check_charset_db(sys_var *self, THD *thd, set_var *var) } static Sys_var_struct Sys_character_set_database( "character_set_database", - " The character set used by the default database", + "The character set used by the default database", SESSION_VAR(collation_database), NO_CMD_LINE, offsetof(CHARSET_INFO, csname), DEFAULT(&default_charset_info), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_charset_db)); @@ -1062,7 +1062,7 @@ static Sys_var_keycache Sys_key_cache_age_threshold( static Sys_var_mybool Sys_large_files_support( "large_files_support", "Whether mysqld was compiled with options for large file support", - READ_ONLY GLOBAL_VAR(opt_large_files), + READ_ONLY SHOW_VALUE_IN_HELP GLOBAL_VAR(opt_large_files), NO_CMD_LINE, DEFAULT(sizeof(my_off_t) > 4)); static Sys_var_uint Sys_large_page_size( @@ -1184,7 +1184,8 @@ static Sys_var_mybool Sys_lower_case_file_system( "lower_case_file_system", "Case sensitivity of file names on the file system where the " "data directory is located", - READ_ONLY GLOBAL_VAR(lower_case_file_system), NO_CMD_LINE, + READ_ONLY SHOW_VALUE_IN_HELP GLOBAL_VAR(lower_case_file_system), + NO_CMD_LINE, DEFAULT(FALSE)); static Sys_var_uint Sys_lower_case_table_names( @@ -2145,7 +2146,7 @@ static Sys_var_ulong Sys_preload_buff_size( static Sys_var_uint Sys_protocol_version( "protocol_version", "The version of the client/server protocol used by the MySQL server", - READ_ONLY GLOBAL_VAR(protocol_version), NO_CMD_LINE, + READ_ONLY SHOW_VALUE_IN_HELP GLOBAL_VAR(protocol_version), NO_CMD_LINE, VALID_RANGE(0, ~0), DEFAULT(PROTOCOL_VERSION), BLOCK_SIZE(1)); static Sys_var_proxy_user Sys_proxy_user( @@ -2604,11 +2605,23 @@ static Sys_var_enum Slave_exec_mode( "Modes for how replication events should be executed. Legal values " "are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, " "replication will not stop for operations that are idempotent. " + "For example, in row based replication attempts to delete rows that " + "doesn't exist will be ignored." "In STRICT mode, replication will stop on any unexpected difference " "between the master and the slave", GLOBAL_VAR(slave_exec_mode_options), CMD_LINE(REQUIRED_ARG), slave_exec_mode_names, DEFAULT(SLAVE_EXEC_MODE_STRICT)); +static Sys_var_enum Slave_ddl_exec_mode( + "slave_ddl_exec_mode", + "Modes for how replication events should be executed. Legal values " + "are STRICT and IDEMPOTENT (default). In IDEMPOTENT mode, " + "replication will not stop for DDL operations that are idempotent. " + "This means that CREATE TABLE is treated CREATE TABLE OR REPLACE and " + "DROP TABLE is threated as DROP TABLE IF EXISTS. ", + GLOBAL_VAR(slave_ddl_exec_mode_options), CMD_LINE(REQUIRED_ARG), + slave_exec_mode_names, DEFAULT(SLAVE_EXEC_MODE_IDEMPOTENT)); + static const char *slave_type_conversions_name[]= {"ALL_LOSSY", "ALL_NON_LOSSY", 0}; static Sys_var_set Slave_type_conversions( "slave_type_conversions", @@ -2881,7 +2894,8 @@ static Sys_var_mybool Sys_sync_frm( static char *system_time_zone_ptr; static Sys_var_charptr Sys_system_time_zone( "system_time_zone", "The server system time zone", - READ_ONLY GLOBAL_VAR(system_time_zone_ptr), NO_CMD_LINE, + READ_ONLY SHOW_VALUE_IN_HELP GLOBAL_VAR(system_time_zone_ptr), + NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(system_time_zone)); static Sys_var_ulong Sys_table_def_size( @@ -3091,27 +3105,37 @@ static Sys_var_mybool Sys_timed_mutexes( static char *server_version_ptr; static Sys_var_charptr Sys_version( "version", "Server version", - READ_ONLY GLOBAL_VAR(server_version_ptr), NO_CMD_LINE, + READ_ONLY SHOW_VALUE_IN_HELP GLOBAL_VAR(server_version_ptr), + NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(server_version)); static char *server_version_comment_ptr; static Sys_var_charptr Sys_version_comment( "version_comment", "version_comment", - READ_ONLY GLOBAL_VAR(server_version_comment_ptr), NO_CMD_LINE, + READ_ONLY SHOW_VALUE_IN_HELP GLOBAL_VAR(server_version_comment_ptr), + NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(MYSQL_COMPILATION_COMMENT)); static char *server_version_compile_machine_ptr; static Sys_var_charptr Sys_version_compile_machine( "version_compile_machine", "version_compile_machine", - READ_ONLY GLOBAL_VAR(server_version_compile_machine_ptr), NO_CMD_LINE, + READ_ONLY SHOW_VALUE_IN_HELP + GLOBAL_VAR(server_version_compile_machine_ptr), NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(MACHINE_TYPE)); static char *server_version_compile_os_ptr; static Sys_var_charptr Sys_version_compile_os( "version_compile_os", "version_compile_os", - READ_ONLY GLOBAL_VAR(server_version_compile_os_ptr), NO_CMD_LINE, + READ_ONLY SHOW_VALUE_IN_HELP GLOBAL_VAR(server_version_compile_os_ptr), + NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(SYSTEM_TYPE)); +static char *malloc_library; +static Sys_var_charptr Sys_malloc_library( + "version_malloc_library", "Version of the used malloc library", + READ_ONLY SHOW_VALUE_IN_HELP GLOBAL_VAR(malloc_library), NO_CMD_LINE, + IN_SYSTEM_CHARSET, DEFAULT(MALLOC_LIBRARY)); + static Sys_var_ulong Sys_net_wait_timeout( "wait_timeout", "The number of seconds the server waits for activity on a " @@ -3190,10 +3214,10 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type) return false; } - if (thd->variables.option_bits & OPTION_AUTOCOMMIT && - thd->variables.option_bits & OPTION_NOT_AUTOCOMMIT) - { // activating autocommit - + if (test_all_bits(thd->variables.option_bits, + (OPTION_AUTOCOMMIT | OPTION_NOT_AUTOCOMMIT))) + { + // activating autocommit if (trans_commit_stmt(thd) || trans_commit(thd)) { thd->variables.option_bits&= ~OPTION_AUTOCOMMIT; @@ -3210,16 +3234,17 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type) transaction implicitly at the end (@sa stmt_causes_implicitcommit()). */ thd->variables.option_bits&= - ~(OPTION_BEGIN | OPTION_KEEP_LOG | OPTION_NOT_AUTOCOMMIT); + ~(OPTION_BEGIN | OPTION_KEEP_LOG | OPTION_NOT_AUTOCOMMIT | + OPTION_GTID_BEGIN); thd->transaction.all.modified_non_trans_table= false; thd->server_status|= SERVER_STATUS_AUTOCOMMIT; return false; } - if (!(thd->variables.option_bits & OPTION_AUTOCOMMIT) && - !(thd->variables.option_bits & OPTION_NOT_AUTOCOMMIT)) - { // disabling autocommit - + if ((thd->variables.option_bits & + (OPTION_AUTOCOMMIT |OPTION_NOT_AUTOCOMMIT)) == 0) + { + // disabling autocommit thd->transaction.all.modified_non_trans_table= false; thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT; thd->variables.option_bits|= OPTION_NOT_AUTOCOMMIT; @@ -3228,6 +3253,7 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type) return false; // autocommit value wasn't changed } + static Sys_var_bit Sys_autocommit( "autocommit", "autocommit", SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_AUTOCOMMIT, DEFAULT(TRUE), diff --git a/sql/sys_vars.h b/sql/sys_vars.h index bef5fbdd126..6c0228fd6a0 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -56,6 +56,7 @@ // this means that Sys_var_charptr initial value was malloc()ed #define PREALLOCATED sys_var::ALLOCATED+ #define PARSED_EARLY sys_var::PARSE_EARLY+ +#define SHOW_VALUE_IN_HELP sys_var::SHOW_VALUE_IN_HELP+ /* Sys_var_bit meaning is reversed, like in diff --git a/sql/table.cc b/sql/table.cc index 87cd2adc542..2e1d18b5da1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2010,7 +2010,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root, share->column_bitmap_size))) goto err; - bitmap_init(&share->all_set, bitmaps, share->fields, FALSE); + my_bitmap_init(&share->all_set, bitmaps, share->fields, FALSE); bitmap_set_all(&share->all_set); delete handler_file; @@ -2818,17 +2818,17 @@ partititon_err: bitmap_size= share->column_bitmap_size; if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*6))) goto err; - bitmap_init(&outparam->def_read_set, + my_bitmap_init(&outparam->def_read_set, (my_bitmap_map*) bitmaps, share->fields, FALSE); - bitmap_init(&outparam->def_write_set, + my_bitmap_init(&outparam->def_write_set, (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, FALSE); - bitmap_init(&outparam->def_vcol_set, + my_bitmap_init(&outparam->def_vcol_set, (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE); - bitmap_init(&outparam->tmp_set, + my_bitmap_init(&outparam->tmp_set, (my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields, FALSE); - bitmap_init(&outparam->eq_join_set, + my_bitmap_init(&outparam->eq_join_set, (my_bitmap_map*) (bitmaps+bitmap_size*4), share->fields, FALSE); - bitmap_init(&outparam->cond_set, + my_bitmap_init(&outparam->cond_set, (my_bitmap_map*) (bitmaps+bitmap_size*5), share->fields, FALSE); outparam->default_column_bitmaps(); diff --git a/sql/table.h b/sql/table.h index 6d8be8f948a..260ff7cf6ba 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1065,7 +1065,6 @@ public: ORDER *group; String alias; /* alias or table name */ uchar *null_flags; - my_bitmap_map *bitmap_init_value; MY_BITMAP def_read_set, def_write_set, def_vcol_set, tmp_set; MY_BITMAP eq_join_set; /* used to mark equi-joined fields */ MY_BITMAP cond_set; /* used to mark fields from sargable conditions*/ @@ -1950,7 +1949,7 @@ struct TABLE_LIST Indicates that if TABLE_LIST object corresponds to the table/view which requires special handling. */ - enum + enum enum_open_strategy { /* Normal open. */ OPEN_NORMAL= 0, diff --git a/sql/table_cache.cc b/sql/table_cache.cc index 6f51ac8276c..6b24f4348ee 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -196,6 +196,7 @@ static void check_unused(THD *thd) TABLE *entry; TABLE_SHARE *share; TDC_iterator tdc_it; + DBUG_ENTER("check_unused"); tdc_it.init(); mysql_mutex_lock(&LOCK_open); @@ -221,6 +222,7 @@ static void check_unused(THD *thd) } mysql_mutex_unlock(&LOCK_open); tdc_it.deinit(); + DBUG_VOID_RETURN; } #else #define check_unused(A) diff --git a/sql/transaction.cc b/sql/transaction.cc index 256351ee373..213b6c1a4d8 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -251,6 +251,10 @@ bool trans_commit_implicit(THD *thd) if (trans_check(thd)) DBUG_RETURN(TRUE); + if (thd->variables.option_bits & OPTION_GTID_BEGIN) + DBUG_PRINT("error", ("OPTION_GTID_BEGIN is set. " + "Master and slave will have different GTID values")); + if (thd->in_multi_stmt_transaction_mode() || (thd->variables.option_bits & OPTION_TABLE_LOCK)) { @@ -302,6 +306,8 @@ bool trans_rollback(THD *thd) res= ha_rollback_trans(thd, TRUE); (void) RUN_HOOK(transaction, after_rollback, (thd, FALSE)); thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); + /* Reset the binlog transaction marker */ + thd->variables.option_bits&= ~OPTION_GTID_BEGIN; thd->transaction.all.modified_non_trans_table= FALSE; thd->lex->start_transaction_opt= 0; diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 9e49e93a837..bec953819e7 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -3959,7 +3959,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd, cls= GetListOption(g, "class", topt->oplist); #endif // WIN32 port= atoi(GetListOption(g, "port", topt->oplist, "0")); +#if defined(ODBC_SUPPORT) mxr= atoi(GetListOption(g,"maxres", topt->oplist, "0")); +#endif mxe= atoi(GetListOption(g,"maxerr", topt->oplist, "0")); #if defined(PROMPT_OK) cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0")); diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index eb0dc5f9def..a1d4e215118 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -153,8 +153,8 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name, info.lock_type= F_WRLCK; _ma_set_data_pagecache_callbacks(&info.dfile, share); - bitmap_init(&info.changed_fields, changed_fields_bitmap, - share->base.fields, 0); + my_bitmap_init(&info.changed_fields, changed_fields_bitmap, + share->base.fields, 0); if ((*share->init)(&info)) goto err; diff --git a/storage/oqgraph/CMakeLists.txt b/storage/oqgraph/CMakeLists.txt index 74d05873f6f..3f592133969 100644 --- a/storage/oqgraph/CMakeLists.txt +++ b/storage/oqgraph/CMakeLists.txt @@ -3,14 +3,14 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") MESSAGE(STATUS "Configuring OQGraph") FIND_PACKAGE(Boost) IF(NOT Boost_FOUND) - MESSAGE(STATUS "Boost not found") + MESSAGE(STATUS "Boost not found. OQGraph will not be compiled") RETURN() ENDIF() INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS}) FIND_PACKAGE(Judy) IF(NOT Judy_FOUND) - MESSAGE(STATUS "Judy not found") + MESSAGE(STATUS "Judy not found. OQGraph will not be compiled") RETURN() ENDIF() INCLUDE_DIRECTORIES(${Judy_INCLUDE_DIR}) @@ -53,6 +53,7 @@ IF(BOOST_OK) MODULE_ONLY COMPONENT oqgraph-engine LINK_LIBRARIES ${Judy_LIBRARIES}) + MESSAGE(STATUS "OQGraph OK") ELSE(BOOST_OK) - MESSAGE(STATUS "Requisites for OQGraph not met") + MESSAGE(STATUS "Requisites for OQGraph not met. OQGraph will not be compiled") ENDIF(BOOST_OK) diff --git a/storage/oqgraph/mysql-test/oqgraph/boundary_conditions.result b/storage/oqgraph/mysql-test/oqgraph/boundary_conditions.result index 9aa806eace9..7cb65bc07ea 100644 --- a/storage/oqgraph/mysql-test/oqgraph/boundary_conditions.result +++ b/storage/oqgraph/mysql-test/oqgraph/boundary_conditions.result @@ -1,6 +1,7 @@ DROP TABLE IF EXISTS graph_base; DROP TABLE IF EXISTS graph; DROP TABLE IF EXISTS graph2; +call mtr.add_suppression("graph_base is open on delete"); CREATE TABLE graph2 ( latch VARCHAR(32) NULL, origid BIGINT UNSIGNED NULL, diff --git a/storage/oqgraph/mysql-test/oqgraph/boundary_conditions.test b/storage/oqgraph/mysql-test/oqgraph/boundary_conditions.test index 869994aa208..a6dae0e2678 100644 --- a/storage/oqgraph/mysql-test/oqgraph/boundary_conditions.test +++ b/storage/oqgraph/mysql-test/oqgraph/boundary_conditions.test @@ -4,6 +4,8 @@ DROP TABLE IF EXISTS graph; DROP TABLE IF EXISTS graph2; --enable_warnings +call mtr.add_suppression("graph_base is open on delete"); + CREATE TABLE graph2 ( latch VARCHAR(32) NULL, origid BIGINT UNSIGNED NULL, diff --git a/storage/oqgraph/mysql-test/oqgraph/invalid_operations.result b/storage/oqgraph/mysql-test/oqgraph/invalid_operations.result index 046c468b768..49639c278d0 100644 --- a/storage/oqgraph/mysql-test/oqgraph/invalid_operations.result +++ b/storage/oqgraph/mysql-test/oqgraph/invalid_operations.result @@ -1,5 +1,6 @@ DROP TABLE IF EXISTS graph_base; DROP TABLE IF EXISTS graph; +call mtr.add_suppression("graph_base is open on delete"); CREATE TABLE graph_base ( from_id INT UNSIGNED NOT NULL, to_id INT UNSIGNED NOT NULL, diff --git a/storage/oqgraph/mysql-test/oqgraph/invalid_operations.test b/storage/oqgraph/mysql-test/oqgraph/invalid_operations.test index 8f79b23ed43..cab99ec5018 100644 --- a/storage/oqgraph/mysql-test/oqgraph/invalid_operations.test +++ b/storage/oqgraph/mysql-test/oqgraph/invalid_operations.test @@ -3,6 +3,8 @@ DROP TABLE IF EXISTS graph_base; DROP TABLE IF EXISTS graph; --enable_warnings +call mtr.add_suppression("graph_base is open on delete"); + # Create the backing store CREATE TABLE graph_base ( from_id INT UNSIGNED NOT NULL, diff --git a/storage/oqgraph/mysql-test/oqgraph/isnull.result b/storage/oqgraph/mysql-test/oqgraph/isnull.result index 38ebf12413c..d9af33222dc 100644 --- a/storage/oqgraph/mysql-test/oqgraph/isnull.result +++ b/storage/oqgraph/mysql-test/oqgraph/isnull.result @@ -38,5 +38,5 @@ NULL 1 NULL 1 1 2 select * from graph where latch is null and destid=2; latch origid destid weight seq linkid NULL NULL 2 1 1 1 -DROP TABLE graph_base; DROP TABLE graph; +DROP TABLE graph_base; diff --git a/storage/oqgraph/mysql-test/oqgraph/isnull.test b/storage/oqgraph/mysql-test/oqgraph/isnull.test index 93105887834..dc7622daa0d 100644 --- a/storage/oqgraph/mysql-test/oqgraph/isnull.test +++ b/storage/oqgraph/mysql-test/oqgraph/isnull.test @@ -34,6 +34,5 @@ select * from graph where latch is null; select * from graph where latch is null and origid=1; select * from graph where latch is null and destid=2; -DROP TABLE graph_base; DROP TABLE graph; - +DROP TABLE graph_base; diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_1233113.result b/storage/oqgraph/mysql-test/oqgraph/regression_1233113.result index 415b2181bbb..2b0ea4b2acb 100644 --- a/storage/oqgraph/mysql-test/oqgraph/regression_1233113.result +++ b/storage/oqgraph/mysql-test/oqgraph/regression_1233113.result @@ -1,5 +1,6 @@ DROP TABLE IF EXISTS graph_base; DROP TABLE IF EXISTS graph; +call mtr.add_suppression("graph_base is open on delete"); CREATE TABLE graph_base ( from_id INT UNSIGNED NOT NULL, to_id INT UNSIGNED NOT NULL, diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_1233113.test b/storage/oqgraph/mysql-test/oqgraph/regression_1233113.test index 26e6656eea5..db53b2b39ae 100644 --- a/storage/oqgraph/mysql-test/oqgraph/regression_1233113.test +++ b/storage/oqgraph/mysql-test/oqgraph/regression_1233113.test @@ -3,6 +3,8 @@ DROP TABLE IF EXISTS graph_base; DROP TABLE IF EXISTS graph; --enable_warnings +call mtr.add_suppression("graph_base is open on delete"); + # Create the backing store CREATE TABLE graph_base ( from_id INT UNSIGNED NOT NULL, diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_drop_after.result b/storage/oqgraph/mysql-test/oqgraph/regression_drop_after.result index 84902676ef2..cace2c40564 100644 --- a/storage/oqgraph/mysql-test/oqgraph/regression_drop_after.result +++ b/storage/oqgraph/mysql-test/oqgraph/regression_drop_after.result @@ -1,5 +1,6 @@ DROP TABLE IF EXISTS graph_base; DROP TABLE IF EXISTS graph; +call mtr.add_suppression("graph_base is open on delete"); CREATE TABLE graph_base ( from_id INT UNSIGNED NOT NULL, to_id INT UNSIGNED NOT NULL, diff --git a/storage/oqgraph/mysql-test/oqgraph/regression_drop_after.test b/storage/oqgraph/mysql-test/oqgraph/regression_drop_after.test index b6f4418112c..673eb867032 100644 --- a/storage/oqgraph/mysql-test/oqgraph/regression_drop_after.test +++ b/storage/oqgraph/mysql-test/oqgraph/regression_drop_after.test @@ -3,6 +3,8 @@ DROP TABLE IF EXISTS graph_base; DROP TABLE IF EXISTS graph; --enable_warnings +call mtr.add_suppression("graph_base is open on delete"); + # Create the backing store CREATE TABLE graph_base ( from_id INT UNSIGNED NOT NULL, diff --git a/storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result b/storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result index cf70de29376..f67c5bccd6b 100644 --- a/storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result +++ b/storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result @@ -182,14 +182,14 @@ a b c d e f 3 30 200 2000 20000 200000 explain select * from t1 where b > 0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index b b NULL NULL NULL; Using where; Using index +1 SIMPLE t1 index_or_range b b NULL NULL NULL; Using where; Using index_or_range select * from t1 where b > 0; a b c d e f 2 20 100 1000 10000 100000 3 30 200 2000 20000 200000 explain select * from t1 where d > "0"; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index d d NULL NULL NULL; Using where; Using index +1 SIMPLE t1 index_or_range d d NULL NULL NULL; Using where; Using index_or_range select * from t1 where d > "0"; a b c d e f 2 20 100 1000 10000 100000 diff --git a/storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test b/storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test index c90994f325a..f5b600e501a 100644 --- a/storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test +++ b/storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test @@ -83,10 +83,12 @@ explain select * from t1; select * from t1; --replace_column 7 NULL 9 NULL; +--replace_result index index_or_range range index_or_range explain select * from t1 where b > 0; select * from t1 where b > 0; --replace_column 7 NULL 9 NULL; +--replace_result index index_or_range range index_or_range explain select * from t1 where d > "0"; select * from t1 where d > "0"; diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/r/compression.result b/storage/tokudb/mysql-test/tokudb_mariadb/r/compression.result index f465fe5df65..ea8a0b521b9 100644 --- a/storage/tokudb/mysql-test/tokudb_mariadb/r/compression.result +++ b/storage/tokudb/mysql-test/tokudb_mariadb/r/compression.result @@ -1,3 +1,4 @@ +drop table if exists t1,t2,t3,t4,t5,t6; create table t1 (a text) engine=tokudb compression=tokudb_uncompressed; create table t2 (a text) engine=tokudb compression=tokudb_zlib; create table t3 (a text) engine=tokudb compression=tokudb_quicklz; diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/t/compression.test b/storage/tokudb/mysql-test/tokudb_mariadb/t/compression.test index 1bac772437d..00478aed1c7 100644 --- a/storage/tokudb/mysql-test/tokudb_mariadb/t/compression.test +++ b/storage/tokudb/mysql-test/tokudb_mariadb/t/compression.test @@ -1,3 +1,10 @@ +# +# Initial cleanup from previous tests +# +--disable_warnings +drop table if exists t1,t2,t3,t4,t5,t6; +--enable_warnings + create table t1 (a text) engine=tokudb compression=tokudb_uncompressed; create table t2 (a text) engine=tokudb compression=tokudb_zlib; create table t3 (a text) engine=tokudb compression=tokudb_quicklz; diff --git a/unittest/mysys/bitmap-t.c b/unittest/mysys/bitmap-t.c index 0666f4eaa15..c4588779c9b 100644 --- a/unittest/mysys/bitmap-t.c +++ b/unittest/mysys/bitmap-t.c @@ -129,8 +129,8 @@ my_bool test_compare_operators(MY_BITMAP *map, uint bitsize) MY_BITMAP *map2= &map2_obj, *map3= &map3_obj; my_bitmap_map map2buf[MAX_TESTED_BITMAP_SIZE]; my_bitmap_map map3buf[MAX_TESTED_BITMAP_SIZE]; - bitmap_init(&map2_obj, map2buf, bitsize, FALSE); - bitmap_init(&map3_obj, map3buf, bitsize, FALSE); + my_bitmap_init(&map2_obj, map2buf, bitsize, FALSE); + my_bitmap_init(&map3_obj, map3buf, bitsize, FALSE); bitmap_clear_all(map2); bitmap_clear_all(map3); for (i=0; i < no_loops; i++) @@ -374,7 +374,7 @@ my_bool test_compare(MY_BITMAP *map, uint bitsize) uint32 map2buf[MAX_TESTED_BITMAP_SIZE]; uint i, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; - if (bitmap_init(&map2, map2buf, bitsize, FALSE)) + if (my_bitmap_init(&map2, map2buf, bitsize, FALSE)) { diag("init error for bitsize %d", bitsize); return TRUE; @@ -433,7 +433,7 @@ my_bool test_intersect(MY_BITMAP *map, uint bitsize) MY_BITMAP map2; uint32 map2buf[MAX_TESTED_BITMAP_SIZE]; uint i, test_bit1, test_bit2, test_bit3; - if (bitmap_init(&map2, map2buf, bitsize2, FALSE)) + if (my_bitmap_init(&map2, map2buf, bitsize2, FALSE)) { diag("init error for bitsize %d", bitsize2); return TRUE; @@ -481,7 +481,7 @@ my_bool do_test(uint bitsize) { MY_BITMAP map; my_bitmap_map buf[MAX_TESTED_BITMAP_SIZE]; - if (bitmap_init(&map, buf, bitsize, FALSE)) + if (my_bitmap_init(&map, buf, bitsize, FALSE)) { diag("init error for bitsize %d", bitsize); goto error; |