1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge branch '10.1' of github.com:MariaDB/server into 10.1

This commit is contained in:
Jan Lindström
2014-06-26 20:47:08 +03:00
17 changed files with 262 additions and 167 deletions

View File

@ -175,72 +175,21 @@ OPTION (WITH_UNIT_TESTS "Compile MySQL with unit tests" ON)
MARK_AS_ADVANCED(CYBOZU) MARK_AS_ADVANCED(CYBOZU)
OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system libraries. Only set it you never plan to distribute the resulting binaries" OFF) OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system libraries. Only set it you never plan to distribute the resulting binaries" OFF)
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
# We need some extra FAIL_REGEX patterns
# Note that CHECK_C_SOURCE_COMPILES is a misnomer, it will also link.
MACRO (MY_CHECK_C_COMPILER_FLAG FLAG RESULT)
SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}")
CHECK_C_SOURCE_COMPILES("int main(void) { return 0; }" ${RESULT}
FAIL_REGEX "argument unused during compilation"
FAIL_REGEX "unsupported .*option"
FAIL_REGEX "unknown .*option"
FAIL_REGEX "unrecognized .*option"
FAIL_REGEX "ignoring unknown option"
FAIL_REGEX "[Ww]arning: [Oo]ption"
)
SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}")
ENDMACRO()
MACRO (MY_CHECK_CXX_COMPILER_FLAG FLAG RESULT) INCLUDE(check_compiler_flag)
SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}")
CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${RESULT}
FAIL_REGEX "argument unused during compilation"
FAIL_REGEX "unsupported .*option"
FAIL_REGEX "unknown .*option"
FAIL_REGEX "unrecognized .*option"
FAIL_REGEX "ignoring unknown option"
FAIL_REGEX "[Ww]arning: [Oo]ption"
)
SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}")
ENDMACRO()
OPTION(WITH_ASAN "Enable address sanitizer" OFF) OPTION(WITH_ASAN "Enable address sanitizer" OFF)
IF (WITH_ASAN) IF (WITH_ASAN)
# gcc 4.8.1 and new versions of clang # gcc 4.8.1 and new versions of clang
MY_CHECK_C_COMPILER_FLAG("-fsanitize=address" HAVE_C_FSANITIZE) MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=address -O1 -Wno-error -fPIC"
MY_CHECK_CXX_COMPILER_FLAG("-fsanitize=address" HAVE_CXX_FSANITIZE) DEBUG RELWITHDEBINFO)
IF(HAVE_C_FSANITIZE AND HAVE_CXX_FSANITIZE) IF(HAVE_C_FSANITIZE AND HAVE_CXX_FSANITIZE)
# We switch on basic optimization also for debug builds.
# With optimization we may get some warnings, so we switch off -Werror
SET(CMAKE_C_FLAGS_DEBUG
"${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -O1 -Wno-error -fPIC")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO
"${CMAKE_C_FLAGS_RELWITHDEBINFO} -fsanitize=address -fPIC")
SET(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -O1 -Wno-error -fPIC")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fsanitize=address -fPIC")
SET(WITH_ASAN_OK 1) SET(WITH_ASAN_OK 1)
ELSE() ELSE()
# older versions of clang # older versions of clang
MY_CHECK_C_COMPILER_FLAG("-faddress-sanitizer" HAVE_C_FADDRESS) MY_CHECK_AND_SET_COMPILER_FLAG("-faddress-sanitizer -O1 -fPIC"
MY_CHECK_CXX_COMPILER_FLAG("-faddress-sanitizer" HAVE_CXX_FFADDRESS) DEBUG RELWITHDEBINFO)
IF(HAVE_C_FADDRESS AND HAVE_CXX_FADDRESS)
IF(HAVE_C_FADDRESS AND HAVE_CXX_FFADDRESS)
# We switch on basic optimization also for debug builds.
SET(CMAKE_C_FLAGS_DEBUG
"${CMAKE_C_FLAGS_DEBUG} -faddress-sanitizer -O1 -fPIC")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO
"${CMAKE_C_FLAGS_RELWITHDEBINFO} -faddress-sanitizer -fPIC")
SET(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} -faddress-sanitizer -O1 -fPIC")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -faddress-sanitizer -fPIC")
SET(WITH_ASAN_OK 1) SET(WITH_ASAN_OK 1)
ENDIF() ENDIF()
ENDIF() ENDIF()
@ -250,6 +199,22 @@ IF (WITH_ASAN)
ENDIF() ENDIF()
ENDIF() ENDIF()
# enable security hardening features, like most distributions do
# in our benchmarks that costs about ~1% of performance, depending on the load
OPTION(SECURITY_HARDENED "Use security-enhancing compiler features (stack protector, relro, etc)" ON)
IF(SECURITY_HARDENED)
# security-enhancing flags
MY_CHECK_AND_SET_COMPILER_FLAG("-pie -fPIC")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wl,-z,relro,-z,now")
MY_CHECK_AND_SET_COMPILER_FLAG("-fstack-protector --param=ssp-buffer-size=4")
# sometimes _FORTIFY_SOURCE is predefined
INCLUDE(CheckSymbolExists)
CHECK_SYMBOL_EXISTS(_FORTIFY_SOURCE "" HAVE_FORTIFY_SOURCE)
IF(NOT HAVE_FORTIFY_SOURCE)
ADD_DEFINITIONS(-D_FORTIFY_SOURCE=2)
ENDIF()
ENDIF()
OPTION(ENABLE_DEBUG_SYNC "Enable debug sync (debug builds only)" ON) OPTION(ENABLE_DEBUG_SYNC "Enable debug sync (debug builds only)" ON)
IF(ENABLE_DEBUG_SYNC) IF(ENABLE_DEBUG_SYNC)
@ -258,15 +223,11 @@ IF(ENABLE_DEBUG_SYNC)
ENDIF() ENDIF()
OPTION(ENABLE_GCOV "Enable gcov (debug, Linux builds only)" OFF) OPTION(ENABLE_GCOV "Enable gcov (debug, Linux builds only)" OFF)
IF (ENABLE_GCOV AND NOT WIN32 AND NOT APPLE) IF (ENABLE_GCOV)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage") MY_CHECK_AND_SET_COMPILER_FLAG("-fprofile-arcs -ftest-coverage -lgcov" DEBUG)
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -lgcov")
ENDIF() ENDIF()
MY_CHECK_C_COMPILER_FLAG(-ggdb3 HAVE_GGDB3) MY_CHECK_AND_SET_COMPILER_FLAG(-ggdb3 DEBUG)
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb3")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3")
OPTION(ENABLED_LOCAL_INFILE OPTION(ENABLED_LOCAL_INFILE
"If we should should enable LOAD DATA LOCAL by default" ${IF_WIN}) "If we should should enable LOAD DATA LOCAL by default" ${IF_WIN})

View File

@ -0,0 +1,51 @@
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
# We need some extra FAIL_REGEX patterns
# Note that CHECK_C_SOURCE_COMPILES is a misnomer, it will also link.
SET(fail_patterns
FAIL_REGEX "argument unused during compilation"
FAIL_REGEX "unsupported .*option"
FAIL_REGEX "unknown .*option"
FAIL_REGEX "unrecognized .*option"
FAIL_REGEX "ignoring unknown option"
FAIL_REGEX "warning:.*ignored"
FAIL_REGEX "[Ww]arning: [Oo]ption"
)
MACRO (MY_CHECK_C_COMPILER_FLAG flag result)
SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}")
CHECK_C_SOURCE_COMPILES("int main(void) { return 0; }" ${result}
${fail_patterns})
SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}")
ENDMACRO()
MACRO (MY_CHECK_CXX_COMPILER_FLAG flag result)
SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${flag}")
CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${result}
${fail_patterns})
SET(CMAKE_REQUIRED_FLAGS "${SAVE_CMAKE_REQUIRED_FLAGS}")
ENDMACRO()
FUNCTION(MY_CHECK_AND_SET_COMPILER_FLAG flag)
# At the moment this is gcc-only.
# Let's avoid expensive compiler tests on Windows:
IF(WIN32)
RETURN()
ENDIF()
MY_CHECK_C_COMPILER_FLAG(${flag} HAVE_C_${flag})
MY_CHECK_CXX_COMPILER_FLAG(${flag} HAVE_CXX_${flag})
IF (HAVE_C_${flag} AND HAVE_CXX_${flag})
IF(ARGN)
FOREACH(type ${ARGN})
SET(CMAKE_C_FLAGS_${type} "${CMAKE_C_FLAGS_${type}} ${flag}" PARENT_SCOPE)
SET(CMAKE_CXX_FLAGS_${type} "${CMAKE_CXX_FLAGS_${type}} ${flag}" PARENT_SCOPE)
ENDFOREACH()
ELSE()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
ENDIF()
ENDIF()
ENDFUNCTION()

View File

@ -124,13 +124,7 @@ FUNCTION(INSTALL_SCRIPT)
SET(COMP) SET(COMP)
ENDIF() ENDIF()
INSTALL(FILES INSTALL(PROGRAMS ${script} DESTINATION ${ARG_DESTINATION} ${COMP})
${script}
DESTINATION ${ARG_DESTINATION}
PERMISSIONS OWNER_READ OWNER_WRITE
OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE ${COMP}
)
INSTALL_MANPAGE(${script}) INSTALL_MANPAGE(${script})
ENDFUNCTION() ENDFUNCTION()

View File

@ -20,7 +20,6 @@ INCLUDE (CheckCXXSourceCompiles)
INCLUDE (CheckStructHasMember) INCLUDE (CheckStructHasMember)
INCLUDE (CheckLibraryExists) INCLUDE (CheckLibraryExists)
INCLUDE (CheckFunctionExists) INCLUDE (CheckFunctionExists)
INCLUDE (CheckCCompilerFlag)
INCLUDE (CheckCSourceRuns) INCLUDE (CheckCSourceRuns)
INCLUDE (CheckSymbolExists) INCLUDE (CheckSymbolExists)
INCLUDE (CheckTypeSize) INCLUDE (CheckTypeSize)

View File

@ -370,5 +370,4 @@ SET(HAVE_SYS_UTSNAME_H CACHE INTERNAL "")
SET(HAVE_PTHREAD_ATTR_GETGUARDSIZE CACHE INTERNAL "") SET(HAVE_PTHREAD_ATTR_GETGUARDSIZE CACHE INTERNAL "")
SET(HAVE_UCONTEXT_H CACHE INTERNAL "") SET(HAVE_UCONTEXT_H CACHE INTERNAL "")
SET(HAVE_SOCKPEERCRED CACHE INTERNAL "") SET(HAVE_SOCKPEERCRED CACHE INTERNAL "")
SET(HAVE_GGDB3 CACHE INTERNAL "")
ENDIF(MSVC) ENDIF(MSVC)

View File

@ -16,7 +16,7 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f
# ANALYZE DELETE will delete rows: # ANALYZE DELETE will delete rows:
analyze delete from t1 where a in (2,3,4); analyze delete from t1 where a in (2,3,4);
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 NULL 100.00 30.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10 100.00 30.00 Using where
select * from t1; select * from t1;
a a
0 0
@ -32,7 +32,7 @@ create table t1(a int, b int);
insert into t1 select a,a from t0; insert into t1 select a,a from t0;
analyze update t1 set b=100+b where a in (6,7,8); analyze update t1 set b=100+b where a in (6,7,8);
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 NULL 100.00 30.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10 100.00 30.00 Using where
select * from t1; select * from t1;
a b a b
0 0 0 0
@ -197,3 +197,57 @@ select * from t1;
a b a b
6 6 6 6
drop table t0, t1; drop table t0, t1;
#
# MDEV-6393: ANALYZE SELECT crashes in Explain_query::print_explain with a non-existing column
#
create table t1 (i int);
insert into t1 values (1),(2);
analyze select a from t1;
ERROR 42S22: Unknown column 'a' in 'field list'
analyze delete from t1 where a=2;
ERROR 42S22: Unknown column 'a' in 'where clause'
analyze update t1 set a=2;
ERROR 42S22: Unknown column 'a' in 'field list'
create table t2 like t1;
insert into t2 select * from t1;
analyze update t2,t1 set t2.i=5 where t2.a=t1.a;
ERROR 42S22: Unknown column 't2.a' in 'where clause'
analyze delete t1 from t2,t1 where t2.a=t1.a;
ERROR 42S22: Unknown column 't2.a' in 'where clause'
drop table t1, t2;
#
# MDEV-6395: ANALYZE UPDATE/DELETE with impossible where does not produce any output
#
create table t1 (a int, b int, key(a));
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
analyze delete from t1 where 1 > 2;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
analyze delete from t1 where a > 30 and a < 10;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
analyze update t1 set b=12345 where 1 > 2;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
analyze update t1 set b=12345 where a > 30 and a < 10;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
drop table t1;
#
# MDEV-6398: ANALYZE UPDATE does not populate r_rows
#
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
analyze update t1 set i=8;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 4 100.00 100.00
drop table t1;
#
# Check ANALYZE SELECT INTO
#
create table t1 (i int);
insert into t1 values (1);
analyze select * from t1 into @var;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1 NULL 100.00 NULL
drop table t1;

View File

@ -1,5 +1,5 @@
# #
# Tests for "ANALYZE $statement" feature (PostgreSQL's analog is called EXPLAIN ANALYZE) # Tests for "ANALYZE $statement" feature
# #
--disable_warnings --disable_warnings
drop table if exists t0,t1,t2,t3; drop table if exists t0,t1,t2,t3;
@ -146,3 +146,55 @@ select * from t1;
drop table t0, t1; drop table t0, t1;
--echo #
--echo # MDEV-6393: ANALYZE SELECT crashes in Explain_query::print_explain with a non-existing column
--echo #
create table t1 (i int);
insert into t1 values (1),(2);
--error ER_BAD_FIELD_ERROR
analyze select a from t1;
--error ER_BAD_FIELD_ERROR
analyze delete from t1 where a=2;
--error ER_BAD_FIELD_ERROR
analyze update t1 set a=2;
create table t2 like t1;
insert into t2 select * from t1;
--error ER_BAD_FIELD_ERROR
analyze update t2,t1 set t2.i=5 where t2.a=t1.a;
--error ER_BAD_FIELD_ERROR
analyze delete t1 from t2,t1 where t2.a=t1.a;
drop table t1, t2;
--echo #
--echo # MDEV-6395: ANALYZE UPDATE/DELETE with impossible where does not produce any output
--echo #
create table t1 (a int, b int, key(a));
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5);
analyze delete from t1 where 1 > 2;
analyze delete from t1 where a > 30 and a < 10;
analyze update t1 set b=12345 where 1 > 2;
analyze update t1 set b=12345 where a > 30 and a < 10;
drop table t1;
--echo #
--echo # MDEV-6398: ANALYZE UPDATE does not populate r_rows
--echo #
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
analyze update t1 set i=8;
drop table t1;
--echo #
--echo # Check ANALYZE SELECT INTO
--echo #
create table t1 (i int);
insert into t1 values (1);
analyze select * from t1 into @var;
drop table t1;

View File

@ -30,7 +30,6 @@ FOREACH(script postinstall-solaris)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${script}.sh CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${script}.sh
${CMAKE_CURRENT_BINARY_DIR}/${script} COPYONLY ) ${CMAKE_CURRENT_BINARY_DIR}/${script} COPYONLY )
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${script} INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${script}
DESTINATION ${inst_location}/solaris COMPONENT Server_Scripts DESTINATION ${inst_location}/solaris COMPONENT Server_Scripts)
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
ENDFOREACH() ENDFOREACH()

View File

@ -364,6 +364,5 @@ ENDIF(WIN32)
INSTALL(DIRECTORY . DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development INSTALL(DIRECTORY . DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development
FILES_MATCHING PATTERN "*.h" FILES_MATCHING PATTERN "*.h"
PATTERN examples EXCLUDE
PATTERN share EXCLUDE PATTERN share EXCLUDE
PATTERN CMakeFiles EXCLUDE) PATTERN CMakeFiles EXCLUDE)

View File

@ -1,23 +0,0 @@
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/extra/yassl/include
${CMAKE_SOURCE_DIR}/regex)
IF(WITH_EXAMPLE_STORAGE_ENGINE)
ADD_LIBRARY(example ha_example.cc)
ADD_DEPENDENCIES(example GenError)
ENDIF(WITH_EXAMPLE_STORAGE_ENGINE)

View File

@ -281,7 +281,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
setup_order(thd, select_lex->ref_pointer_array, &tables, setup_order(thd, select_lex->ref_pointer_array, &tables,
fields, all_fields, order)) fields, all_fields, order))
{ {
delete select;
free_underlaid_joins(thd, &thd->lex->select_lex); free_underlaid_joins(thd, &thd->lex->select_lex);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -332,8 +331,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_PRINT("debug", ("Trying to use delete_all_rows()")); DBUG_PRINT("debug", ("Trying to use delete_all_rows()"));
query_plan.set_delete_all_rows(maybe_deleted); query_plan.set_delete_all_rows(maybe_deleted);
if (thd->lex->describe) if (thd->lex->describe || thd->lex->analyze_stmt)
goto exit_without_my_ok; goto produce_explain_and_leave;
if (!(error=table->file->ha_delete_all_rows())) if (!(error=table->file->ha_delete_all_rows()))
{ {
@ -362,8 +361,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
{ {
limit= 0; limit= 0;
query_plan.set_impossible_where(); query_plan.set_impossible_where();
if (thd->lex->describe) if (thd->lex->describe || thd->lex->analyze_stmt)
goto exit_without_my_ok; goto produce_explain_and_leave;
} }
} }
@ -373,8 +372,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
query_plan.set_no_partitions(); query_plan.set_no_partitions();
if (thd->lex->describe) if (thd->lex->describe || thd->lex->analyze_stmt)
goto exit_without_my_ok; goto produce_explain_and_leave;
my_ok(thd, 0); my_ok(thd, 0);
DBUG_RETURN(0); DBUG_RETURN(0);
@ -393,8 +392,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if ((select && select->check_quick(thd, safe_update, limit)) || !limit) if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
{ {
query_plan.set_impossible_where(); query_plan.set_impossible_where();
if (thd->lex->describe) if (thd->lex->describe || thd->lex->analyze_stmt)
goto exit_without_my_ok; goto produce_explain_and_leave;
delete select; delete select;
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
@ -458,7 +457,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
- otherwise, execute the query plan - otherwise, execute the query plan
*/ */
if (thd->lex->describe) if (thd->lex->describe)
goto exit_without_my_ok; goto produce_explain_and_leave;
query_plan.save_explain_data(thd->lex->explain); query_plan.save_explain_data(thd->lex->explain);
@ -540,10 +539,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
} }
explain= (Explain_delete*)thd->lex->explain->get_upd_del_plan(); explain= (Explain_delete*)thd->lex->explain->get_upd_del_plan();
explain->tracker.on_scan_init();
while (!(error=info.read_record(&info)) && !thd->killed && while (!(error=info.read_record(&info)) && !thd->killed &&
! thd->is_error()) ! thd->is_error())
{ {
explain->on_record_read(); explain->tracker.on_record_read();
if (table->vfield) if (table->vfield)
update_virtual_fields(thd, table, update_virtual_fields(thd, table,
table->triggers ? VCOL_UPDATE_ALL : table->triggers ? VCOL_UPDATE_ALL :
@ -552,7 +553,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
// thd->is_error() is tested to disallow delete row on error // thd->is_error() is tested to disallow delete row on error
if (!select || select->skip_record(thd) > 0) if (!select || select->skip_record(thd) > 0)
{ {
explain->on_record_after_where(); explain->tracker.on_record_after_where();
if (table->triggers && if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE, table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE)) TRG_ACTION_BEFORE, FALSE))
@ -634,6 +635,7 @@ cleanup:
} }
delete select; delete select;
select= NULL;
transactional_table= table->file->has_transactions(); transactional_table= table->file->has_transactions();
if (!transactional_table && deleted > 0) if (!transactional_table && deleted > 0)
@ -669,12 +671,11 @@ cleanup:
} }
} }
DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table); DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
free_underlaid_joins(thd, select_lex);
if (thd->lex->analyze_stmt) if (thd->lex->analyze_stmt)
{ goto emit_explain_and_leave;
error= thd->lex->explain->send_explain(thd);
} free_underlaid_joins(thd, select_lex);
else
if (error < 0 || if (error < 0 ||
(thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error)) (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error))
{ {
@ -687,8 +688,14 @@ cleanup:
DBUG_RETURN(error >= 0 || thd->is_error()); DBUG_RETURN(error >= 0 || thd->is_error());
/* Special exits */ /* Special exits */
exit_without_my_ok: produce_explain_and_leave:
/*
We come here for various "degenerate" query plans: impossible WHERE,
no-partitions-used, impossible-range, etc.
*/
query_plan.save_explain_data(thd->lex->explain); query_plan.save_explain_data(thd->lex->explain);
emit_explain_and_leave:
int err2= thd->lex->explain->send_explain(thd); int err2= thd->lex->explain->send_explain(thd);
delete select; delete select;

View File

@ -957,7 +957,8 @@ int Explain_update::print_explain(Explain_query *query,
Single-table DELETE commands do not do "Using temporary". Single-table DELETE commands do not do "Using temporary".
"Using index condition" is also not possible (which is an unjustified limitation) "Using index condition" is also not possible (which is an unjustified limitation)
*/ */
double r_filtered= 100 * (r_rows?((double)r_rows_after_where/r_rows):1.0); double r_filtered= 100 * tracker.get_filtered_after_where();
ha_rows r_rows= tracker.get_avg_rows();
print_explain_row(output, explain_flags, is_analyze, print_explain_row(output, explain_flags, is_analyze,
1, /* id */ 1, /* id */
@ -970,7 +971,7 @@ int Explain_update::print_explain(Explain_query *query,
key_len_buf.length() ? key_len_buf.c_ptr() : NULL, key_len_buf.length() ? key_len_buf.c_ptr() : NULL,
NULL, /* 'ref' is always NULL in single-table EXPLAIN DELETE */ NULL, /* 'ref' is always NULL in single-table EXPLAIN DELETE */
&rows, &rows,
&r_rows, tracker.has_scans()? &r_rows : NULL,
r_filtered, r_filtered,
extra_str.c_ptr_safe()); extra_str.c_ptr_safe());

View File

@ -44,6 +44,10 @@ public:
return r_filtered; return r_filtered;
} }
inline void on_scan_init() { r_scans++; }
inline void on_record_read() { r_rows++; }
inline void on_record_after_where() { r_rows_after_where++; }
}; };
@ -576,14 +580,8 @@ public:
bool using_io_buffer; bool using_io_buffer;
/* ANALYZE members and methods */ /* ANALYZE members and methods */
ha_rows r_rows; Table_access_tracker tracker;
ha_rows r_rows_after_where;
inline void on_record_read() { r_rows++; }
inline void on_record_after_where() { r_rows_after_where++; }
Explain_update() :
r_rows(0), r_rows_after_where(0)
{}
virtual int print_explain(Explain_query *query, select_result_sink *output, virtual int print_explain(Explain_query *query, select_result_sink *output,
uint8 explain_flags, bool is_analyze); uint8 explain_flags, bool is_analyze);
}; };

View File

@ -5256,11 +5256,9 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
} }
else else
{ {
select_result *save_result;
Protocol *save_protocol; Protocol *save_protocol;
if (lex->analyze_stmt) if (lex->analyze_stmt)
{ {
save_result= result;
result= new select_send_analyze(); result= new select_send_analyze();
save_protocol= thd->protocol; save_protocol= thd->protocol;
thd->protocol= new Protocol_discard(thd); thd->protocol= new Protocol_discard(thd);
@ -5277,15 +5275,10 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
if (lex->analyze_stmt) if (lex->analyze_stmt)
{ {
result= save_result;
if (!result && !(result= new select_send()))
return 1;
delete thd->protocol; delete thd->protocol;
thd->protocol= save_protocol; thd->protocol= save_protocol;
thd->lex->explain->send_explain(thd); if (!res)
res= thd->lex->explain->send_explain(thd);
if (result != lex->result)
delete result;
} }
} }
} }

View File

@ -23131,7 +23131,15 @@ int print_explain_row(select_result_sink *result,
/* 'r_rows' */ /* 'r_rows' */
if (is_analyze) if (is_analyze)
item_list.push_back(item_null); {
if (r_rows)
{
item_list.push_back(new Item_int(*r_rows,
MY_INT64_NUM_DECIMAL_DIGITS));
}
else
item_list.push_back(item_null);
}
/* 'filtered' */ /* 'filtered' */
const double filtered=100.0; const double filtered=100.0;

View File

@ -382,8 +382,8 @@ int mysql_update(THD *thd,
{ {
limit= 0; // Impossible WHERE limit= 0; // Impossible WHERE
query_plan.set_impossible_where(); query_plan.set_impossible_where();
if (thd->lex->describe) if (thd->lex->describe || thd->lex->analyze_stmt)
goto exit_without_my_ok; goto produce_explain_and_leave;
} }
} }
@ -404,8 +404,8 @@ int mysql_update(THD *thd,
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
query_plan.set_no_partitions(); query_plan.set_no_partitions();
if (thd->lex->describe) if (thd->lex->describe || thd->lex->analyze_stmt)
goto exit_without_my_ok; goto produce_explain_and_leave;
my_ok(thd); // No matching records my_ok(thd); // No matching records
DBUG_RETURN(0); DBUG_RETURN(0);
@ -420,8 +420,8 @@ int mysql_update(THD *thd,
(select && select->check_quick(thd, safe_update, limit))) (select && select->check_quick(thd, safe_update, limit)))
{ {
query_plan.set_impossible_where(); query_plan.set_impossible_where();
if (thd->lex->describe) if (thd->lex->describe || thd->lex->analyze_stmt)
goto exit_without_my_ok; goto produce_explain_and_leave;
delete select; delete select;
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
@ -516,7 +516,7 @@ int mysql_update(THD *thd,
- otherwise, execute the query plan - otherwise, execute the query plan
*/ */
if (thd->lex->describe) if (thd->lex->describe)
goto exit_without_my_ok; goto produce_explain_and_leave;
query_plan.save_explain_data(thd->lex->explain); query_plan.save_explain_data(thd->lex->explain);
DBUG_EXECUTE_IF("show_explain_probe_update_exec_start", DBUG_EXECUTE_IF("show_explain_probe_update_exec_start",
@ -725,9 +725,11 @@ int mysql_update(THD *thd,
if all updated columns are read if all updated columns are read
*/ */
can_compare_record= records_are_comparable(table); can_compare_record= records_are_comparable(table);
explain->tracker.on_scan_init();
while (!(error=info.read_record(&info)) && !thd->killed) while (!(error=info.read_record(&info)) && !thd->killed)
{ {
explain->on_record_read(); explain->tracker.on_record_read();
if (table->vfield) if (table->vfield)
update_virtual_fields(thd, table, update_virtual_fields(thd, table,
table->triggers ? VCOL_UPDATE_ALL : table->triggers ? VCOL_UPDATE_ALL :
@ -738,7 +740,7 @@ int mysql_update(THD *thd,
if (table->file->was_semi_consistent_read()) if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */ continue; /* repeat the read of the same row if it still exists */
explain->on_record_after_where(); explain->tracker.on_record_after_where();
store_record(table,record[1]); store_record(table,record[1]);
if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0, if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0,
TRG_EVENT_UPDATE)) TRG_EVENT_UPDATE))
@ -947,6 +949,7 @@ int mysql_update(THD *thd,
end_read_record(&info); end_read_record(&info);
delete select; delete select;
select= NULL;
THD_STAGE_INFO(thd, stage_end); THD_STAGE_INFO(thd, stage_end);
(void) table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); (void) table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
@ -996,11 +999,7 @@ int mysql_update(THD *thd,
id= thd->arg_of_last_insert_id_function ? id= thd->arg_of_last_insert_id_function ?
thd->first_successful_insert_id_in_prev_stmt : 0; thd->first_successful_insert_id_in_prev_stmt : 0;
if (thd->lex->analyze_stmt) if (error < 0 && !thd->lex->analyze_stmt)
{
error= thd->lex->explain->send_explain(thd);
}
else if (error < 0)
{ {
char buff[MYSQL_ERRMSG_SIZE]; char buff[MYSQL_ERRMSG_SIZE];
my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found,
@ -1019,19 +1018,28 @@ int mysql_update(THD *thd,
} }
*found_return= found; *found_return= found;
*updated_return= updated; *updated_return= updated;
if (thd->lex->analyze_stmt)
goto emit_explain_and_leave;
DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0); DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
err: err:
delete select; delete select;
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
table->disable_keyread(); table->disable_keyread();
thd->abort_on_warning= 0; thd->abort_on_warning= 0;
DBUG_RETURN(1); DBUG_RETURN(1);
exit_without_my_ok: produce_explain_and_leave:
/*
We come here for various "degenerate" query plans: impossible WHERE,
no-partitions-used, impossible-range, etc.
*/
query_plan.save_explain_data(thd->lex->explain); query_plan.save_explain_data(thd->lex->explain);
emit_explain_and_leave:
int err2= thd->lex->explain->send_explain(thd); int err2= thd->lex->explain->send_explain(thd);
delete select; delete select;

View File

@ -59,9 +59,8 @@ IF(UNIX)
ELSE() ELSE()
SET(comp Server_Scripts) SET(comp Server_Scripts)
ENDIF() ENDIF()
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${script} INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${script}
DESTINATION ${inst_location} COMPONENT ${comp} DESTINATION ${inst_location} COMPONENT ${comp})
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
ENDFOREACH() ENDFOREACH()
IF(INSTALL_SUPPORTFILESDIR) IF(INSTALL_SUPPORTFILESDIR)
INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles) INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
@ -88,19 +87,15 @@ IF(UNIX)
SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR}) SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql.server.sh CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/mysql.server.sh
${CMAKE_CURRENT_BINARY_DIR}/mysql.server @ONLY) ${CMAKE_CURRENT_BINARY_DIR}/mysql.server @ONLY)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql.server INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/mysql.server
DESTINATION ${inst_location} COMPONENT SupportFiles DESTINATION ${inst_location} COMPONENT SupportFiles)
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
IF (INSTALL_SYSCONFDIR) IF (INSTALL_SYSCONFDIR)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql-log-rotate DESTINATION ${INSTALL_SYSCONFDIR}/logrotate.d INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql-log-rotate DESTINATION ${INSTALL_SYSCONFDIR}/logrotate.d
RENAME mysql COMPONENT SupportFiles) RENAME mysql COMPONENT SupportFiles)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql.server INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/mysql.server
DESTINATION ${INSTALL_SYSCONFDIR}/init.d DESTINATION ${INSTALL_SYSCONFDIR}/init.d
RENAME mysql COMPONENT SupportFiles RENAME mysql COMPONENT SupportFiles)
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
INSTALL(FILES rpm/my.cnf DESTINATION ${INSTALL_SYSCONFDIR} INSTALL(FILES rpm/my.cnf DESTINATION ${INSTALL_SYSCONFDIR}
COMPONENT Common) COMPONENT Common)