summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rwxr-xr-xsql/CMakeLists.txt28
-rw-r--r--sql/Makefile.am16
-rw-r--r--sql/authors.h2
-rw-r--r--sql/debug_sync.cc5
-rw-r--r--sql/debug_sync.h2
-rw-r--r--sql/derror.cc2
-rw-r--r--sql/event_data_objects.cc6
-rw-r--r--sql/event_db_repository.cc2
-rw-r--r--sql/event_db_repository.h2
-rw-r--r--sql/event_parse_data.cc2
-rw-r--r--sql/event_parse_data.h2
-rw-r--r--sql/event_queue.cc7
-rwxr-xr-xsql/event_scheduler.cc8
-rw-r--r--sql/events.cc33
-rwxr-xr-xsql/examples/CMakeLists.txt3
-rw-r--r--sql/field.cc61
-rw-r--r--sql/field.h9
-rw-r--r--sql/field_conv.cc30
-rw-r--r--sql/filesort.cc33
-rw-r--r--sql/gen_lex_hash.cc31
-rw-r--r--sql/ha_ndbcluster.cc10
-rw-r--r--sql/ha_ndbcluster_binlog.cc6
-rw-r--r--sql/ha_partition.cc108
-rw-r--r--sql/ha_partition.h4
-rw-r--r--sql/handler.cc161
-rw-r--r--sql/handler.h105
-rw-r--r--sql/hash_filo.cc5
-rw-r--r--sql/hostname.cc5
-rw-r--r--sql/item.cc104
-rw-r--r--sql/item.h113
-rw-r--r--sql/item_buff.cc2
-rw-r--r--sql/item_cmpfunc.cc71
-rw-r--r--sql/item_cmpfunc.h3
-rw-r--r--sql/item_create.cc558
-rw-r--r--sql/item_create.h8
-rw-r--r--sql/item_func.cc45
-rw-r--r--sql/item_func.h22
-rw-r--r--sql/item_geofunc.h2
-rw-r--r--sql/item_row.cc2
-rw-r--r--sql/item_row.h2
-rw-r--r--sql/item_strfunc.cc169
-rw-r--r--sql/item_strfunc.h17
-rw-r--r--sql/item_subselect.cc65
-rw-r--r--sql/item_subselect.h17
-rw-r--r--sql/item_sum.cc35
-rw-r--r--sql/item_sum.h22
-rw-r--r--sql/item_timefunc.cc29
-rw-r--r--sql/item_timefunc.h3
-rw-r--r--sql/item_xmlfunc.cc4
-rw-r--r--sql/lex.h2
-rw-r--r--sql/lock.cc120
-rw-r--r--sql/log.cc228
-rw-r--r--sql/log.h2
-rw-r--r--sql/log_event.cc110
-rw-r--r--sql/log_event.h8
-rw-r--r--sql/log_event_old.cc14
-rw-r--r--sql/log_event_old.h2
-rw-r--r--sql/log_slow.h107
-rw-r--r--sql/message.h4
-rw-r--r--sql/mf_iocache.cc6
-rw-r--r--sql/my_decimal.cc14
-rw-r--r--sql/my_decimal.h7
-rw-r--r--sql/my_lock.c45
-rw-r--r--sql/mysql_priv.h90
-rw-r--r--sql/mysql_priv.h.pp10977
-rw-r--r--sql/mysqld.cc1240
-rw-r--r--sql/net_serv.cc26
-rw-r--r--sql/opt_range.cc221
-rw-r--r--sql/opt_range.h45
-rw-r--r--sql/opt_sum.cc28
-rw-r--r--sql/opt_table_elimination.cc1861
-rw-r--r--sql/parse_file.cc2
-rw-r--r--sql/partition_element.h6
-rw-r--r--sql/partition_info.cc2
-rw-r--r--sql/password.c44
-rw-r--r--sql/protocol.cc99
-rw-r--r--sql/protocol.h2
-rw-r--r--sql/records.cc18
-rw-r--r--sql/repl_failsafe.cc7
-rw-r--r--sql/rpl_filter.cc12
-rw-r--r--sql/rpl_injector.cc3
-rw-r--r--sql/rpl_injector.h2
-rw-r--r--sql/rpl_mi.cc26
-rw-r--r--sql/rpl_mi.h2
-rw-r--r--sql/rpl_record.cc5
-rw-r--r--sql/rpl_record.h3
-rw-r--r--sql/rpl_record_old.h2
-rw-r--r--sql/rpl_rli.cc9
-rw-r--r--sql/rpl_rli.h4
-rw-r--r--sql/rpl_utility.cc2
-rw-r--r--sql/rpl_utility.h2
-rw-r--r--sql/scheduler.cc676
-rw-r--r--sql/scheduler.h42
-rw-r--r--sql/set_var.cc318
-rw-r--r--sql/set_var.h38
-rw-r--r--sql/share/Makefile.am5
-rw-r--r--sql/share/charsets/languages.html16
-rw-r--r--sql/share/errmsg.txt84
-rw-r--r--sql/slave.cc87
-rw-r--r--sql/slave.h7
-rw-r--r--sql/sp.cc8
-rw-r--r--sql/sp_cache.cc6
-rw-r--r--sql/sp_cache.h1
-rw-r--r--sql/sp_head.cc21
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/sp_rcontext.cc6
-rw-r--r--sql/sp_rcontext.h2
-rw-r--r--sql/spatial.cc2
-rw-r--r--sql/spatial.h2
-rw-r--r--sql/sql_acl.cc37
-rw-r--r--sql/sql_analyse.cc19
-rw-r--r--sql/sql_base.cc199
-rw-r--r--sql/sql_binlog.cc6
-rw-r--r--sql/sql_bitmap.h33
-rw-r--r--sql/sql_builtin.cc.in1
-rw-r--r--sql/sql_cache.cc46
-rw-r--r--sql/sql_class.cc231
-rw-r--r--sql/sql_class.h163
-rw-r--r--sql/sql_connect.cc454
-rw-r--r--sql/sql_crypt.cc2
-rw-r--r--sql/sql_crypt.h2
-rw-r--r--sql/sql_cursor.cc4
-rw-r--r--sql/sql_db.cc21
-rw-r--r--sql/sql_delete.cc40
-rw-r--r--sql/sql_derived.cc2
-rw-r--r--sql/sql_error.cc2
-rw-r--r--sql/sql_handler.cc19
-rw-r--r--sql/sql_help.cc5
-rw-r--r--sql/sql_insert.cc130
-rw-r--r--sql/sql_lex.cc79
-rw-r--r--sql/sql_lex.h7
-rw-r--r--sql/sql_list.h41
-rw-r--r--sql/sql_load.cc18
-rw-r--r--sql/sql_olap.cc2
-rw-r--r--sql/sql_parse.cc339
-rw-r--r--sql/sql_partition.cc11
-rw-r--r--sql/sql_partition.h2
-rw-r--r--sql/sql_plugin.cc192
-rw-r--r--sql/sql_plugin.h11
-rw-r--r--sql/sql_prepare.cc26
-rw-r--r--sql/sql_profile.cc65
-rw-r--r--sql/sql_profile.h16
-rw-r--r--sql/sql_rename.cc18
-rw-r--r--sql/sql_repl.cc13
-rw-r--r--sql/sql_select.cc1226
-rw-r--r--sql/sql_select.h61
-rw-r--r--sql/sql_show.cc349
-rw-r--r--sql/sql_sort.h12
-rw-r--r--sql/sql_string.cc87
-rw-r--r--sql/sql_string.h7
-rw-r--r--sql/sql_table.cc407
-rw-r--r--sql/sql_tablespace.cc13
-rw-r--r--sql/sql_trigger.cc12
-rw-r--r--sql/sql_trigger.h2
-rw-r--r--sql/sql_udf.cc6
-rw-r--r--sql/sql_union.cc16
-rw-r--r--sql/sql_update.cc127
-rw-r--r--sql/sql_view.cc8
-rw-r--r--sql/sql_yacc.yy76
-rw-r--r--sql/strfunc.cc20
-rw-r--r--sql/table.cc149
-rw-r--r--sql/table.h57
-rw-r--r--sql/thr_malloc.cc2
-rw-r--r--sql/time.cc2
-rw-r--r--sql/tztime.cc4
-rw-r--r--sql/udf_example.c4
-rw-r--r--sql/udf_example.def2
-rw-r--r--sql/uniques.cc7
-rw-r--r--sql/unireg.cc7
-rw-r--r--sql/unireg.h4
170 files changed, 8739 insertions, 14897 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index c050b329787..535f53335be 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2010, Oracle and/or its affiliates.
#
# 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
@@ -14,17 +14,14 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
-SET(CMAKE_CXX_FLAGS_DEBUG
- "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi")
-SET(CMAKE_C_FLAGS_DEBUG
- "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi")
-SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /MAP /MAPINFO:EXPORTS")
+ADD_DEFINITIONS(-DUSE_SYMDIR)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/extra/yassl/include
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/zlib
+ ${CMAKE_SOURCE_DIR}/extra/libevent
)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/sql_yacc.h
@@ -38,7 +35,9 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/sql_yacc.h
PROPERTIES GENERATED 1)
ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN -DHAVE_EVENT_SCHEDULER)
-
+IF(WITH_FEEDBACK_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-DWITH_FEEDBACK_PLUGIN)
+ENDIF()
SET (SQL_SOURCE
../sql-common/client.c derror.cc des_key_file.cc
@@ -75,7 +74,7 @@ SET (SQL_SOURCE
partition_info.cc rpl_utility.cc rpl_injector.cc sql_locale.cc
rpl_rli.cc rpl_mi.cc sql_servers.cc
sql_connect.cc scheduler.cc
- sql_profile.cc event_parse_data.cc
+ sql_profile.cc event_parse_data.cc opt_table_elimination.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
@@ -94,9 +93,9 @@ ADD_EXECUTABLE(mysqld cmake_dummy.cc message.rc)
SET_TARGET_PROPERTIES(mysqld PROPERTIES OUTPUT_NAME mysqld${MYSQLD_EXE_SUFFIX})
SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
-SET (MYSQLD_CORE_LIBS mysys zlib dbug strings yassl taocrypt vio regex sql)
+SET (MYSQLD_CORE_LIBS mysys zlib dbug strings yassl taocrypt vio regex sql libevent)
TARGET_LINK_LIBRARIES(mysqld ${MYSQLD_CORE_LIBS} ${MYSQLD_STATIC_ENGINE_LIBS})
-TARGET_LINK_LIBRARIES(mysqld ws2_32.lib)
+TARGET_LINK_LIBRARIES(mysqld ws2_32.lib psapi.lib)
IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
@@ -129,7 +128,7 @@ ADD_CUSTOM_COMMAND(
# Gen_lex_hash
ADD_EXECUTABLE(gen_lex_hash gen_lex_hash.cc)
-TARGET_LINK_LIBRARIES(gen_lex_hash debug dbug mysqlclient wsock32)
+TARGET_LINK_LIBRARIES(gen_lex_hash debug dbug mysqlclient strings wsock32)
GET_TARGET_PROPERTY(GEN_LEX_HASH_EXE gen_lex_hash LOCATION)
ADD_CUSTOM_COMMAND(
OUTPUT ${PROJECT_SOURCE_DIR}/sql/lex_hash.h
@@ -144,7 +143,7 @@ ADD_CUSTOM_TARGET(
${PROJECT_SOURCE_DIR}/sql/message.rc
${PROJECT_SOURCE_DIR}/sql/lex_hash.h)
-ADD_DEPENDENCIES(mysqld GenServerSource)
+ADD_DEPENDENCIES(sql GenServerSource)
# Remove the auto-generated files as part of 'Clean Solution'
SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
@@ -153,3 +152,8 @@ SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
ADD_LIBRARY(udf_example MODULE udf_example.c udf_example.def)
ADD_DEPENDENCIES(udf_example strings GenError)
TARGET_LINK_LIBRARIES(udf_example strings wsock32)
+
+INSTALL(TARGETS mysqld
+ RUNTIME DESTINATION bin COMPONENT runtime
+ LIBRARY DESTINATION lib COMPONENT runtime
+ ARCHIVE DESTINATION lib COMPONENT runtime)
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 6040e4d498d..c413f8ce771 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2010, Oracle and/or its affiliates.
#
# 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
@@ -22,7 +22,8 @@ MYSQLLIBdir= $(pkglibdir)
pkgplugindir = $(pkglibdir)/plugin
INCLUDES = @ZLIB_INCLUDES@ \
-I$(top_builddir)/include -I$(top_srcdir)/include \
- -I$(top_srcdir)/regex -I$(srcdir) $(openssl_includes)
+ -I$(top_srcdir)/regex -I$(srcdir) $(openssl_includes) \
+ $(libevent_includes)
WRAPLIBS= @WRAPLIBS@
SUBDIRS = share
libexec_PROGRAMS = mysqld
@@ -35,12 +36,13 @@ noinst_LTLIBRARIES= libndb.la \
SUPPORTING_LIBS = $(top_builddir)/vio/libvio.a \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/dbug/libdbug.a \
- $(top_builddir)/regex/libregex.a \
+ $(top_builddir)/regex/libregex.la \
$(top_builddir)/strings/libmystrings.a
mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la
LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@
mysqld_LDADD = libndb.la \
@MYSQLD_EXTRA_LDFLAGS@ \
+ $(libevent_libs) \
@mysql_plugin_libs@ \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
@@ -60,7 +62,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
debug_sync.h \
opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \
rpl_reporting.h \
- log.h sql_show.h rpl_rli.h rpl_mi.h \
+ log.h log_slow.h sql_show.h rpl_rli.h rpl_mi.h \
sql_select.h structs.h table.h sql_udf.h hash_filo.h \
lex.h lex_symbol.h sql_acl.h sql_crypt.h \
sql_repl.h slave.h rpl_filter.h rpl_injector.h \
@@ -121,7 +123,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
event_queue.cc event_db_repository.cc events.cc \
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
- sql_servers.cc event_parse_data.cc
+ sql_servers.cc event_parse_data.cc \
+ opt_table_elimination.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
@@ -188,6 +191,3 @@ install-exec-hook:
test ! -x mysqld-debug$(EXEEXT) || $(INSTALL_PROGRAM) mysqld-debug$(EXEEXT) $(DESTDIR)$(libexecdir)
test ! -f mysqld-debug.sym.gz || $(INSTALL_DATA) mysqld-debug.sym.gz $(DESTDIR)$(pkglibdir)
test ! -f mysqld.sym.gz || $(INSTALL_DATA) mysqld.sym.gz $(DESTDIR)$(pkglibdir)
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/sql/authors.h b/sql/authors.h
index 4b91e879d57..9f88b97c3ad 100644
--- a/sql/authors.h
+++ b/sql/authors.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index aef73116956..74f6256df25 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
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
@@ -1718,7 +1718,8 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
if (action->execute)
{
- const char *UNINIT_VAR(old_proc_info);
+ const char *old_proc_info;
+ LINT_INIT(old_proc_info);
action->execute--;
diff --git a/sql/debug_sync.h b/sql/debug_sync.h
index af5be4b422e..5cd838ec359 100644
--- a/sql/debug_sync.h
+++ b/sql/debug_sync.h
@@ -1,7 +1,7 @@
#ifndef DEBUG_SYNC_INCLUDED
#define DEBUG_SYNC_INCLUDED
-/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/derror.cc b/sql/derror.cc
index fa10a22dca4..55e9b49dddc 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index ef910cda081..5c4d9e94a6e 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
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
@@ -729,7 +729,6 @@ bool get_next_time(const Time_zone *time_zone, my_time_t *next,
would give an error then.
*/
DBUG_RETURN(1);
- break;
case INTERVAL_LAST:
DBUG_ASSERT(0);
}
@@ -1457,8 +1456,7 @@ Event_job_data::execute(THD *thd, bool drop)
DBUG_ASSERT(sphead);
- if (thd->enable_slow_log)
- sphead->m_flags|= sp_head::LOG_SLOW_STATEMENTS;
+ sphead->m_flags|= sp_head::LOG_SLOW_STATEMENTS;
sphead->m_flags|= sp_head::LOG_GENERAL_LOG;
sphead->set_info(0, 0, &thd->lex->sp_chistics, sql_mode);
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 73d02894f50..7560d490641 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h
index cfa6d32ea07..e25cb6b85a4 100644
--- a/sql/event_db_repository.h
+++ b/sql/event_db_repository.h
@@ -1,6 +1,6 @@
#ifndef _EVENT_DB_REPOSITORY_H_
#define _EVENT_DB_REPOSITORY_H_
-/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc
index 61686fd565f..695c6b8650c 100644
--- a/sql/event_parse_data.cc
+++ b/sql/event_parse_data.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2008, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_parse_data.h b/sql/event_parse_data.h
index f7a88dbda74..228ca1bb0c9 100644
--- a/sql/event_parse_data.h
+++ b/sql/event_parse_data.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2008, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index 04d4f858b43..d68dc8ef479 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -94,7 +94,12 @@ Event_queue::Event_queue()
mutex_queue_data_attempting_lock(FALSE),
waiting_on_cond(FALSE)
{
- pthread_mutex_init(&LOCK_event_queue, MY_MUTEX_INIT_FAST);
+ /*
+ Inconsisent usage between LOCK_event_queue and LOCK_scheduler_state and
+ LOCK_open
+ */
+ my_pthread_mutex_init(&LOCK_event_queue, MY_MUTEX_INIT_FAST,
+ "LOCK_event_queue", MYF_NO_DEADLOCK_DETECTION);
pthread_cond_init(&COND_queue_state, NULL);
}
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index a24c70a8494..fb66a50ee7f 100755
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -342,6 +342,14 @@ Event_scheduler::Event_scheduler(Event_queue *queue_arg)
{
pthread_mutex_init(&LOCK_scheduler_state, MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_state, NULL);
+
+#ifdef SAFE_MUTEX
+ /* Ensure right mutex order */
+ pthread_mutex_lock(&LOCK_scheduler_state);
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ pthread_mutex_unlock(&LOCK_scheduler_state);
+#endif
}
diff --git a/sql/events.cc b/sql/events.cc
index 1820b594555..6eaa27b3212 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
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
@@ -321,7 +321,6 @@ common_1_lev_code:
case INTERVAL_MICROSECOND:
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND");
return 1;
- break;
case INTERVAL_QUARTER:
expr/= 3;
close_quote= FALSE;
@@ -457,8 +456,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
parse_data->name,
new_element)))
{
- if (!db_repository->drop_event(thd, parse_data->dbname, parse_data->name,
- TRUE))
+ if (!db_repository->drop_event(thd, parse_data->dbname,
+ parse_data->name, TRUE))
dropped= 1;
delete new_element;
}
@@ -480,16 +479,19 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
String log_query;
if (create_query_string(thd, &log_query))
{
- sql_print_error("Event Error: An error occurred while creating query string, "
- "before writing it into binary log.");
+ sql_print_error("Event Error: An error occurred while creating query "
+ "string, before writing it into binary log.");
ret= true;
}
else
+ {
/*
- If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
- will be written into the binary log as the definer for the SQL thread.
+ If the definer is not set or set to CURRENT_USER, the value
+ of CURRENT_USER will be written into the binary log as the
+ definer for the SQL thread.
*/
ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
+ }
}
}
pthread_mutex_unlock(&LOCK_event_metadata);
@@ -757,8 +759,7 @@ send_show_create_event(THD *thd, Event_timed *et, Protocol *protocol)
field_list.push_back(new Item_empty_string("Event", NAME_CHAR_LEN));
- if (sys_var_thd_sql_mode::symbolic_mode_representation(thd, et->sql_mode,
- &sql_mode))
+ if (sys_var::make_set(thd, et->sql_mode, &sql_mode_typelib, &sql_mode))
DBUG_RETURN(TRUE);
field_list.push_back(new Item_empty_string("sql_mode", (uint) sql_mode.length));
@@ -1066,7 +1067,12 @@ Events::deinit()
void
Events::init_mutexes()
{
- pthread_mutex_init(&LOCK_event_metadata, MY_MUTEX_INIT_FAST);
+ /*
+ Inconsisent usage between LOCK_event_metadata and LOCK_scheduler_state
+ and LOCK_open
+ */
+ my_pthread_mutex_init(&LOCK_event_metadata, MY_MUTEX_INIT_FAST,
+ "LOCK_event_metadata", MYF_NO_DEADLOCK_DETECTION);
}
@@ -1270,8 +1276,9 @@ Events::load_events_from_db(THD *thd)
}
}
}
- sql_print_information("Event Scheduler: Loaded %d event%s",
- count, (count == 1) ? "" : "s");
+ if (global_system_variables.log_warnings)
+ sql_print_information("Event Scheduler: Loaded %d event%s",
+ count, (count == 1) ? "" : "s");
ret= FALSE;
end:
diff --git a/sql/examples/CMakeLists.txt b/sql/examples/CMakeLists.txt
index 1a22e9a3efd..47a64c88c68 100755
--- a/sql/examples/CMakeLists.txt
+++ b/sql/examples/CMakeLists.txt
@@ -13,9 +13,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/extra/yassl/include
${CMAKE_SOURCE_DIR}/regex)
diff --git a/sql/field.cc b/sql/field.cc
index f398642fdb0..a8bb59ca417 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1166,7 +1167,8 @@ bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len,
if (unsigned_flag)
{
- if ((((ulonglong) *rnd > unsigned_max) && (*rnd= (longlong) unsigned_max)) ||
+ if ((((ulonglong) *rnd > unsigned_max) &&
+ (*rnd= (longlong) unsigned_max)) ||
error == MY_ERRNO_ERANGE)
{
goto out_of_range;
@@ -2278,7 +2280,7 @@ int Field_decimal::store(double nr)
snprintf(buff,sizeof(buff)-1, "%.*f",(int) dec,nr);
length= strlen(buff);
#else
- length= sprintf(buff, "%.*f", dec, nr);
+ length= my_sprintf(buff,(buff,"%.*f",dec,nr));
#endif
if (length > field_length)
@@ -2995,18 +2997,18 @@ int Field_tiny::store(double nr)
}
else if (nr > 255.0)
{
- *ptr=(char) 255;
+ *ptr= (uchar) 255;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
- *ptr=(char) nr;
+ *ptr= (uchar) nr;
}
else
{
if (nr < -128.0)
{
- *ptr= (char) -128;
+ *ptr= (uchar) -128;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
@@ -3017,7 +3019,7 @@ int Field_tiny::store(double nr)
error= 1;
}
else
- *ptr=(char) (int) nr;
+ *ptr=(uchar) (int) nr;
}
return error;
}
@@ -4124,7 +4126,7 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
char *end;
double nr= my_strntod(cs,(char*) from,len,&end,&error);
if (error || (!len || ((uint) (end-from) != len &&
- table->in_use->count_cuted_fields)))
+ table->in_use->count_cuted_fields)))
{
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
@@ -4260,7 +4262,7 @@ String *Field_float::val_str(String *val_buffer,
snprintf(to,to_length-1,"%.*f",dec,nr);
to=strend(to);
#else
- to+= sprintf(to, "%.*f", dec, nr);
+ to+= my_sprintf(to,(to,"%.*f",dec,nr));
#endif
#endif
}
@@ -4386,7 +4388,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
char *end;
double nr= my_strntod(cs,(char*) from, len, &end, &error);
if (error || (!len || ((uint) (end-from) != len &&
- table->in_use->count_cuted_fields)))
+ table->in_use->count_cuted_fields)))
{
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
@@ -4618,7 +4620,7 @@ String *Field_double::val_str(String *val_buffer,
snprintf(to,to_length-1,"%.*f",dec,nr);
to=strend(to);
#else
- to+= sprintf(to, "%.*f", dec, nr);
+ to+= my_sprintf(to,(to,"%.*f",dec,nr));
#endif
#endif
}
@@ -5389,7 +5391,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
int error;
longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
- if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155 ||
+ if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155 ||
error == MY_ERRNO_ERANGE)
{
*ptr=0;
@@ -5421,7 +5423,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
int Field_year::store(double nr)
{
- if (nr < 0.0 || nr >= 2155.0)
+ if (nr < 0.0 || nr > 2155.0)
{
(void) Field_year::store((longlong) -1, FALSE);
return 1;
@@ -6424,16 +6426,22 @@ int Field_str::store(double nr)
/* Calculate the exponent from the 'e'-format conversion */
if (anr < 1.0 && anr > 0)
{
- for (exp= 0; anr < 1e-100; exp-= 100, anr*= 1e100) ;
- for (; anr < 1e-10; exp-= 10, anr*= 1e10) ;
- for (i= 1; anr < 1 / log_10[i]; exp--, i++) ;
+ for (exp= 0; anr < 1e-100; exp-= 100, anr*= 1e100)
+ ;
+ for (; anr < 1e-10; exp-= 10, anr*= 1e10)
+ ;
+ for (i= 1; anr < 1 / log_10[i]; exp--, i++)
+ ;
exp--;
}
else
{
- for (exp= 0; anr > 1e100; exp+= 100, anr/= 1e100) ;
- for (; anr > 1e10; exp+= 10, anr/= 1e10) ;
- for (i= 1; anr > log_10[i]; exp++, i++) ;
+ for (exp= 0; anr > 1e100; exp+= 100, anr/= 1e100)
+ ;
+ for (; anr > 1e10; exp+= 10, anr/= 1e10)
+ ;
+ for (i= 1; anr > log_10[i]; exp++, i++)
+ ;
}
max_length= local_char_length - neg;
@@ -6462,7 +6470,7 @@ int Field_str::store(double nr)
/* Limit precision to DBL_DIG to avoid garbage past significant digits */
set_if_smaller(digits, DBL_DIG);
- length= (uint) sprintf(buff, "%-.*g", digits, nr);
+ length= (uint) my_sprintf(buff, (buff, "%-.*g", digits, nr));
#ifdef __WIN__
/*
@@ -9012,7 +9020,8 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
ASSERT_COLUMN_MARKED_FOR_WRITE;
int delta;
- for (; length && !*from; from++, length--) ; // skip left 0's
+ for (; length && !*from; from++, length--) // skip left 0's
+ ;
delta= bytes_in_rec - length;
if (delta < -1 ||
@@ -9434,7 +9443,8 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
int delta;
uchar bits= (uchar) (field_length & 7);
- for (; length && !*from; from++, length--) ; // skip left 0's
+ for (; length && !*from; from++, length--) // skip left 0's
+ ;
delta= bytes_in_rec - length;
if (delta < 0 ||
@@ -9831,9 +9841,8 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
}
break;
case MYSQL_TYPE_DATE:
- /* Old date type. */
- if (protocol_version != PROTOCOL_VERSION-1)
- sql_type= MYSQL_TYPE_NEWDATE;
+ /* We don't support creation of MYSQL_TYPE_DATE anymore */
+ sql_type= MYSQL_TYPE_NEWDATE;
/* fall trough */
case MYSQL_TYPE_NEWDATE:
length= MAX_DATE_WIDTH;
@@ -10421,7 +10430,7 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
{
/* DBL_DIG is enough to print '-[digits].E+###' */
char str_nr[DBL_DIG + 8];
- uint str_len= sprintf(str_nr, "%g", nr);
+ uint str_len= my_sprintf(str_nr, (str_nr, "%g", nr));
make_truncated_value_warning(thd, level, str_nr, str_len, ts_type,
field_name);
}
diff --git a/sql/field.h b/sql/field.h
index 8db965a8270..7f17f8dad77 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -257,11 +258,11 @@ public:
return test(record[(uint) (null_ptr -table->record[0])] &
null_bit);
}
- inline bool is_null_in_record_with_offset(my_ptrdiff_t offset)
+ inline bool is_null_in_record_with_offset(my_ptrdiff_t col_offset)
{
if (!null_ptr)
return 0;
- return test(null_ptr[offset] & null_bit);
+ return test(null_ptr[col_offset] & null_bit);
}
inline void set_null(my_ptrdiff_t row_offset= 0)
{ if (null_ptr) null_ptr[row_offset]|= null_bit; }
@@ -360,7 +361,7 @@ public:
Number of copied bytes (excluding padded zero bytes -- see above).
*/
- virtual uint get_key_image(uchar *buff, uint length, imagetype type)
+ virtual uint get_key_image(uchar *buff, uint length, imagetype type_arg)
{
get_image(buff, length, &my_charset_bin);
return length;
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 1dc7ec57944..5a1b3dc80fd 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -677,10 +677,10 @@ Copy_field::get_copy_func(Field *to,Field *from)
*/
if (to->real_type() != from->real_type() ||
!compatible_db_low_byte_first ||
- (((to->table->in_use->variables.sql_mode &
+ ((to->table->in_use->variables.sql_mode &
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) &&
- to->type() == MYSQL_TYPE_DATE) ||
- to->type() == MYSQL_TYPE_DATETIME))
+ (to->type() == MYSQL_TYPE_DATE ||
+ to->type() == MYSQL_TYPE_DATETIME)))
{
if (from->real_type() == MYSQL_TYPE_ENUM ||
from->real_type() == MYSQL_TYPE_SET)
@@ -696,8 +696,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
if (from->real_type() == MYSQL_TYPE_ENUM &&
to->real_type() == MYSQL_TYPE_ENUM)
return do_field_enum;
- else
- return do_field_string;
+ return do_field_string;
}
}
else if (to->charset() != from->charset())
@@ -721,10 +720,8 @@ Copy_field::get_copy_func(Field *to,Field *from)
{
if (to->charset() == &my_charset_bin)
return do_expand_binary;
- else
- return do_expand_string;
+ return do_expand_string;
}
-
}
else if (to->real_type() != from->real_type() ||
to_length != from_length ||
@@ -750,7 +747,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
}
}
}
- /* Eq fields */
+ /* Identical field types */
switch (to_length) {
case 1: return do_field_1;
case 2: return do_field_2;
@@ -776,8 +773,8 @@ int field_conv(Field *to,Field *from)
to->real_type() != MYSQL_TYPE_SET &&
to->real_type() != MYSQL_TYPE_BIT &&
(to->real_type() != MYSQL_TYPE_NEWDECIMAL ||
- (to->field_length == from->field_length &&
- (((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
+ ((to->field_length == from->field_length &&
+ (((Field_num*)to)->dec == ((Field_num*)from)->dec)))) &&
from->charset() == to->charset() &&
to->table->s->db_low_byte_first == from->table->s->db_low_byte_first &&
(!(to->table->in_use->variables.sql_mode &
@@ -788,8 +785,13 @@ int field_conv(Field *to,Field *from)
((Field_varstring*)from)->length_bytes ==
((Field_varstring*)to)->length_bytes))
{ // Identical fields
- // to->ptr==from->ptr may happen if one does 'UPDATE ... SET x=x'
- memmove(to->ptr, from->ptr, to->pack_length());
+ /*
+ This may happen if one does 'UPDATE ... SET x=x'
+ The test is here mostly for valgrind, but can also be relevant
+ if memcpy() is implemented with prefetch-write
+ */
+ if (to->ptr != from->ptr)
+ memcpy(to->ptr,from->ptr,to->pack_length());
return 0;
}
}
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 715528bcd52..e95ff08fcdd 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -190,6 +190,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
{
status_var_increment(thd->status_var.filesort_scan_count);
}
+ thd->query_plan_flags|= QPLAN_FILESORT;
#ifdef CAN_TRUST_RANGE
if (select && select->quick && select->quick->records > 0L)
{
@@ -255,9 +256,9 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
}
else
{
+ thd->query_plan_flags|= QPLAN_FILESORT_DISK;
/* filesort cannot handle zero-length records during merge. */
DBUG_ASSERT(param.sort_length != 0);
-
if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
{
x_free(table_sort.buffpek);
@@ -517,7 +518,6 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
volatile THD::killed_state *killed= &thd->killed;
handler *file;
MY_BITMAP *save_read_set, *save_write_set;
- bool skip_record;
DBUG_ENTER("find_all_keys");
DBUG_PRINT("info",("using: %s",
(select ? select->quick ? "ranges" : "where":
@@ -531,7 +531,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
ref_pos= ref_buff;
quick_select=select && select->quick;
record=0;
- flag= ((!indexfile && file->ha_table_flags() & HA_REC_NOT_IN_SEQ)
+ flag= ((!indexfile && (file->ha_table_flags() & HA_REC_NOT_IN_SEQ))
|| quick_select);
if (indexfile || flag)
ref_pos= &file->ref[0];
@@ -610,8 +610,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
}
if (error == 0)
param->examined_rows++;
- if (!error && (!select ||
- (!select->skip_record(thd, &skip_record) && !skip_record)))
+
+ if (error == 0 && (!select || select->skip_record(thd) > 0))
{
if (idx == param->keys)
{
@@ -624,6 +624,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
}
else
file->unlock_row();
+
/* It does not make sense to read more keys in case of a fatal error */
if (thd->is_error())
break;
@@ -960,10 +961,21 @@ static void make_sortkey(register SORTPARAM *param,
if (addonf->null_bit && field->is_null())
{
nulls[addonf->null_offset]|= addonf->null_bit;
+#ifdef HAVE_valgrind
+ bzero(to, addonf->length);
+#endif
}
else
{
+#ifdef HAVE_valgrind
+ uchar *end= field->pack(to, field->ptr);
+ uint length= (uint) ((to + addonf->length) - end);
+ DBUG_ASSERT((int) length >= 0);
+ if (length)
+ bzero(end, length);
+#else
(void) field->pack(to, field->ptr);
+#endif
}
to+= addonf->length;
}
@@ -1195,6 +1207,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
DBUG_ENTER("merge_buffers");
status_var_increment(current_thd->status_var.filesort_merge_passes);
+ current_thd->query_plan_fsort_passes++;
if (param->not_killable)
{
killed= &not_killable;
@@ -1208,7 +1221,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
offset= rec_length-res_length;
maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1));
to_start_filepos= my_b_tell(to_file);
- strpos= (uchar*) sort_buffer;
+ strpos= sort_buffer;
org_max_rows=max_rows= param->max_rows;
/* The following will fire if there is not enough space in sort_buffer */
@@ -1232,7 +1245,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
buffpek->base= strpos;
buffpek->max_keys= maxcount;
strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
- rec_length));
+ rec_length));
if (error == -1)
goto err; /* purecov: inspected */
buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected
@@ -1321,7 +1334,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
}
}
buffpek= (BUFFPEK*) queue_top(&queue);
- buffpek->base= sort_buffer;
+ buffpek->base= (uchar*) sort_buffer;
buffpek->max_keys= param->keys;
/*
@@ -1361,7 +1374,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
strpos != end ;
strpos+= rec_length)
{
- if (my_b_write(to_file, (uchar *) strpos, res_length))
+ if (my_b_write(to_file, strpos, res_length))
{
error=1; goto err;
}
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index 9814814e8db..773345b36fe 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -89,8 +89,6 @@ So, we can read full search-structure as 32-bit word
#include "mysql_version.h"
#include "lex.h"
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
-
const char *default_dbug_option="d:t:o,/tmp/gen_lex_hash.trace";
struct my_option my_long_options[] =
@@ -350,7 +348,10 @@ static void usage(int version)
my_progname, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
if (version)
return;
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
+ puts("Copyright (C) 2001 MySQL AB, by VVA and Monty");
+ puts("Copyright (C) 2011 Oracle");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license\n");
puts("This program generates a perfect hashing function for the sql_lex.cc");
printf("Usage: %s [OPTIONS]\n\n", my_progname);
my_print_help(my_long_options);
@@ -452,9 +453,25 @@ int main(int argc,char **argv)
/* Broken up to indicate that it's not advice to you, gentle reader. */
printf("/*\n\n Do " "not " "edit " "this " "file " "directly!\n\n*/\n");
- puts("/*");
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
- puts("*/");
+ printf("\
+/* Copyright (C) 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.\n\
+ Copyright (C) 2008-2011 Oracle\n\
+\n\
+ This program is free software; you can redistribute it and/or modify\n\
+ it under the terms of the GNU General Public License as published by\n\
+ the Free Software Foundation; version 2 of the License.\n\
+\n\
+ This program is distributed in the hope that it will be useful,\n\
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
+ GNU General Public License for more details.\n\
+\n\
+ You should have received a copy of the GNU General Public License\n\
+ along with this program; see the file COPYING. If not, write to the\n\
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston\n\
+ MA 02110-1301 USA. */\n\
+\n\
+");
/* Broken up to indicate that it's not advice to you, gentle reader. */
printf("/* Do " "not " "edit " "this " "file! This is generated by "
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 44015f3e2b4..8e2cd207962 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates.
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
@@ -4234,8 +4234,8 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows)
int ha_ndbcluster::end_bulk_insert()
{
int error= 0;
-
DBUG_ENTER("end_bulk_insert");
+
// Check if last inserts need to be flushed
if (m_bulk_insert_not_flushed)
{
@@ -4587,7 +4587,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
Thd_ndb *thd_ndb= get_thd_ndb(thd);
Ndb *ndb= thd_ndb->ndb;
- DBUG_PRINT("enter", ("this: 0x%lx thd: 0x%lx thd_ndb: %lx "
+ DBUG_PRINT("enter", ("this: 0x%lx thd: 0x%lx thd_ndb: 0x%lx "
"thd_ndb->lock_count: %d",
(long) this, (long) thd, (long) thd_ndb,
thd_ndb->lock_count));
@@ -6267,7 +6267,7 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
{
Ndb_tuple_id_range_guard g(m_share);
if ((m_skip_auto_increment &&
- ndb->readAutoIncrementValue(m_table, g.range, auto_value)) ||
+ ndb->readAutoIncrementValue(m_table, g.range, auto_value)) ||
ndb->getAutoIncrementValue(m_table, g.range, auto_value, cache_size, increment, offset))
{
if (--retries &&
@@ -10550,4 +10550,6 @@ mysql_declare_plugin(ndbcluster)
}
mysql_declare_plugin_end;
+#else
+int Sun_ar_require_a_symbol_here= 0;
#endif
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index fe802ce0e2d..31bede644d9 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2011, Oracle and/or its affiliates.
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
@@ -1548,7 +1548,9 @@ end:
dict->forceGCPWait();
int max_timeout= opt_ndb_sync_timeout;
- (void) pthread_mutex_lock(&ndb_schema_object->mutex);
+ /* Inconsistent usage of ndb_schema_object->mutex and LOCK_open */
+ (void) my_pthread_mutex_lock(&ndb_schema_object->mutex,
+ MYF_NO_DEADLOCK_DETECTION);
if (have_lock_open)
{
safe_mutex_assert_owner(&LOCK_open);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index cd5d7f201a7..10892ca6e0c 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
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
@@ -168,6 +168,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share)
:handler(hton, share)
{
DBUG_ENTER("ha_partition::ha_partition(table)");
+ init_alloc_root(&m_mem_root, 512, 512);
init_handler_variables();
DBUG_VOID_RETURN;
}
@@ -189,6 +190,7 @@ ha_partition::ha_partition(handlerton *hton, partition_info *part_info)
{
DBUG_ENTER("ha_partition::ha_partition(part_info)");
DBUG_ASSERT(part_info);
+ init_alloc_root(&m_mem_root, 512, 512);
init_handler_variables();
m_part_info= part_info;
m_create_handler= TRUE;
@@ -215,6 +217,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share,
:handler(hton, share)
{
DBUG_ENTER("ha_partition::ha_partition(clone)");
+ init_alloc_root(&m_mem_root, 512, 512);
init_handler_variables();
m_part_info= part_info_arg;
m_create_handler= TRUE;
@@ -242,6 +245,7 @@ void ha_partition::init_handler_variables()
m_file_buffer= NULL;
m_name_buffer_ptr= NULL;
m_engine_array= NULL;
+ m_connect_string= NULL;
m_file= NULL;
m_file_tot_parts= 0;
m_reorged_file= NULL;
@@ -320,9 +324,14 @@ ha_partition::~ha_partition()
for (i= 0; i < m_tot_parts; i++)
delete m_file[i];
}
- my_free((char*) m_ordered_rec_buffer, MYF(MY_ALLOW_ZERO_PTR));
+
+ my_free(m_ordered_rec_buffer, MYF(MY_ALLOW_ZERO_PTR));
+ m_ordered_rec_buffer= NULL;
clear_handler_file();
+
+ free_root(&m_mem_root, MYF(0));
+
DBUG_VOID_RETURN;
}
@@ -590,6 +599,13 @@ int ha_partition::create(const char *name, TABLE *table_arg,
char t_name[FN_REFLEN];
DBUG_ENTER("ha_partition::create");
+ if (create_info->used_fields & HA_CREATE_USED_CONNECTION)
+ {
+ my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
+ "CONNECTION not valid for partition");
+ DBUG_RETURN(1);
+ }
+
strmov(t_name, name);
DBUG_ASSERT(*fn_rext((char*)name) == '\0');
if (del_ren_cre_table(t_name, NULL, table_arg, create_info))
@@ -1036,8 +1052,8 @@ static bool print_admin_msg(THD* thd, const char* msg_type,
va_list args;
Protocol *protocol= thd->protocol;
uint length, msg_length;
- char msgbuf[MI_MAX_MSG_BUF];
- char name[NAME_LEN*2+2];
+ char msgbuf[HA_MAX_MSG_BUF];
+ char name[SAFE_NAME_LEN*2+2];
va_start(args, fmt);
msg_length= my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
@@ -1047,7 +1063,7 @@ static bool print_admin_msg(THD* thd, const char* msg_type,
if (!thd->vio_ok())
{
- sql_print_error("%s", msgbuf);
+ sql_print_error(fmt, args);
return TRUE;
}
@@ -1266,6 +1282,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
if ((error= set_up_table_before_create(tbl, part_name, create_info,
0, p_elem)))
goto error_create;
+ tbl->s->connect_string = p_elem->connect_string;
if ((error= file->ha_create(part_name, tbl, create_info)))
{
/*
@@ -1786,6 +1803,8 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
create_info->auto_increment_value= stats.auto_increment_value;
create_info->data_file_name= create_info->index_file_name = NULL;
+ create_info->connect_string.str= NULL;
+ create_info->connect_string.length= 0;
return;
}
@@ -2073,6 +2092,10 @@ int ha_partition::set_up_table_before_create(TABLE *tbl,
}
info->index_file_name= part_elem->index_file_name;
info->data_file_name= part_elem->data_file_name;
+ info->connect_string= part_elem->connect_string;
+ if (info->connect_string.length)
+ info->used_fields|= HA_CREATE_USED_CONNECTION;
+ tbl->s->connect_string= part_elem->connect_string;
DBUG_RETURN(0);
}
@@ -2187,8 +2210,10 @@ bool ha_partition::create_handler_file(const char *name)
/* 4 static words (tot words, checksum, tot partitions, name length) */
tot_len_words= 4 + tot_partition_words + tot_name_words;
tot_len_byte= PAR_WORD_SIZE * tot_len_words;
- if (!(file_buffer= (uchar *) my_malloc(tot_len_byte, MYF(MY_ZEROFILL))))
+ file_buffer= (uchar *) my_alloca(tot_len_byte);
+ if (!file_buffer)
DBUG_RETURN(TRUE);
+ bzero(file_buffer, tot_len_byte);
engine_array= (file_buffer + PAR_ENGINES_OFFSET);
name_buffer_ptr= (char*) (engine_array + tot_partition_words * PAR_WORD_SIZE
+ PAR_WORD_SIZE);
@@ -2247,11 +2272,28 @@ bool ha_partition::create_handler_file(const char *name)
{
result= my_write(file, (uchar *) file_buffer, tot_len_byte,
MYF(MY_WME | MY_NABP)) != 0;
+
+ /* Write connection information (for federatedx engine) */
+ part_it.rewind();
+ for (i= 0; i < no_parts && !result; i++)
+ {
+ uchar buffer[4];
+ part_elem= part_it++;
+ uint length = part_elem->connect_string.length;
+ int4store(buffer, length);
+ if (my_write(file, buffer, 4, MYF(MY_WME | MY_NABP)) ||
+ my_write(file, (uchar *) part_elem->connect_string.str, length,
+ MYF(MY_WME | MY_NABP)))
+ {
+ result= TRUE;
+ break;
+ }
+ }
VOID(my_close(file, MYF(0)));
}
else
result= TRUE;
- my_free((char*) file_buffer, MYF(0));
+ my_afree((char*) file_buffer);
DBUG_RETURN(result);
}
@@ -2264,10 +2306,10 @@ void ha_partition::clear_handler_file()
{
if (m_engine_array)
plugin_unlock_list(NULL, m_engine_array, m_tot_parts);
- my_free((char*) m_file_buffer, MYF(MY_ALLOW_ZERO_PTR));
- my_free((char*) m_engine_array, MYF(MY_ALLOW_ZERO_PTR));
+ free_root(&m_mem_root, MYF(MY_KEEP_PREALLOC));
m_file_buffer= NULL;
m_engine_array= NULL;
+ m_connect_string= NULL;
}
@@ -2423,7 +2465,7 @@ bool ha_partition::read_par_file(const char *name)
len_bytes= PAR_WORD_SIZE * len_words;
if (my_seek(file, 0, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
goto err1;
- if (!(file_buffer= (char*) my_malloc(len_bytes, MYF(0))))
+ if (!(file_buffer= (char*) alloc_root(&m_mem_root, len_bytes)))
goto err1;
if (my_read(file, (uchar *) file_buffer, len_bytes, MYF(MY_NABP)))
goto err2;
@@ -2447,14 +2489,37 @@ bool ha_partition::read_par_file(const char *name)
*/
if (len_words != (tot_partition_words + tot_name_words + 4))
goto err2;
- VOID(my_close(file, MYF(0)));
m_file_buffer= file_buffer; // Will be freed in clear_handler_file()
m_name_buffer_ptr= tot_name_len_offset + PAR_WORD_SIZE;
+ if (!(m_connect_string= (LEX_STRING*)
+ alloc_root(&m_mem_root, m_tot_parts * sizeof(LEX_STRING))))
+ goto err2;
+ bzero(m_connect_string, m_tot_parts * sizeof(LEX_STRING));
+
+ /* Read connection arguments (for federated X engine) */
+ for (i= 0; i < m_tot_parts; i++)
+ {
+ LEX_STRING connect_string;
+ uchar buffer[4];
+ if (my_read(file, buffer, 4, MYF(MY_NABP)))
+ {
+ /* No extra options; Probably not a federatedx engine */
+ break;
+ }
+ connect_string.length= uint4korr(buffer);
+ connect_string.str= (char*) alloc_root(&m_mem_root, connect_string.length+1);
+ if (my_read(file, (uchar*) connect_string.str, connect_string.length,
+ MYF(MY_NABP)))
+ break;
+ connect_string.str[connect_string.length]= 0;
+ m_connect_string[i]= connect_string;
+ }
+
+ VOID(my_close(file, MYF(0)));
DBUG_RETURN(false);
err2:
- my_free(file_buffer, MYF(0));
err1:
VOID(my_close(file, MYF(0)));
DBUG_RETURN(true);
@@ -2493,7 +2558,7 @@ bool ha_partition::setup_engine_array(MEM_ROOT *mem_root)
goto err;
}
if (!(m_engine_array= (plugin_ref*)
- my_malloc(m_tot_parts * sizeof(plugin_ref), MYF(MY_WME))))
+ alloc_root(&m_mem_root, m_tot_parts * sizeof(plugin_ref))))
goto err;
for (i= 0; i < m_tot_parts; i++)
@@ -2689,8 +2754,10 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
{
create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
FALSE);
+ table->s->connect_string = m_connect_string[(uint)(file-m_file)];
if ((error= (*file)->ha_open(table, name_buff, mode, test_if_locked)))
goto err_handler;
+ bzero(&table->s->connect_string, sizeof(LEX_STRING));
m_no_locks+= (*file)->lock_count();
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
} while (*(++file));
@@ -3661,7 +3728,7 @@ ha_rows ha_partition::guess_bulk_insert_rows()
0 Success
Note: end_bulk_insert can be called without start_bulk_insert
- being called, see bug¤44108.
+ being called, see bug#44108.
*/
@@ -3977,6 +4044,12 @@ void ha_partition::position(const uchar *record)
if (pad_length)
memset((ref + PARTITION_BYTES_IN_POS + file->ref_length), 0, pad_length);
+#ifdef SUPPORTING_PARTITION_OVER_DIFFERENT_ENGINES
+#ifdef HAVE_valgrind
+ bzero(ref + PARTITION_BYTES_IN_POS + ref_length,
+ max_ref_length-ref_length);
+#endif /* HAVE_valgrind */
+#endif
DBUG_VOID_RETURN;
}
@@ -5448,7 +5521,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
stat_info->update_time= file->stats.update_time;
stat_info->check_time= file->stats.check_time;
stat_info->check_sum= 0;
- if (file->ha_table_flags() & HA_HAS_CHECKSUM)
+ if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
stat_info->check_sum= file->checksum();
return;
}
@@ -5766,6 +5839,7 @@ int ha_partition::extra(enum ha_extra_function operation)
case HA_EXTRA_KEYREAD:
case HA_EXTRA_NO_KEYREAD:
case HA_EXTRA_FLUSH:
+ case HA_EXTRA_PREPARE_FOR_FORCED_CLOSE:
DBUG_RETURN(loop_extra(operation));
/* Category 2), used by non-MyISAM handlers */
@@ -5802,9 +5876,7 @@ int ha_partition::extra(enum ha_extra_function operation)
case HA_EXTRA_PREPARE_FOR_DROP:
case HA_EXTRA_FLUSH_CACHE:
{
- if (m_myisam)
- DBUG_RETURN(loop_extra(operation));
- break;
+ DBUG_RETURN(loop_extra(operation));
}
case HA_EXTRA_NO_READCHECK:
{
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 46e2f447a47..adb8214aae4 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
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
@@ -85,12 +85,14 @@ private:
uint m_open_test_lock; // Open test_if_locked
char *m_file_buffer; // Content of the .par file
char *m_name_buffer_ptr; // Pointer to first partition name
+ MEM_ROOT m_mem_root;
plugin_ref *m_engine_array; // Array of types of the handlers
handler **m_file; // Array of references to handler inst.
uint m_file_tot_parts; // Debug
handler **m_new_file; // Array of references to new handlers
handler **m_reorged_file; // Reorganised partitions
handler **m_added_file; // Added parts kept for errors
+ LEX_STRING *m_connect_string;
partition_info *m_part_info; // local reference to partition
Field **m_part_field_array; // Part field array locally to save acc
uchar *m_ordered_rec_buffer; // Row and key buffer for ord. idx scan
diff --git a/sql/handler.cc b/sql/handler.cc
index 82f5f2ee841..ab8da981c80 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,7 +27,7 @@
#include "mysql_priv.h"
#include "rpl_filter.h"
#include <myisampack.h>
-#include <errno.h>
+#include "myisam.h"
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
@@ -58,12 +59,13 @@ static const LEX_STRING sys_table_aliases[]=
{ C_STRING_WITH_LEN("NDB") }, { C_STRING_WITH_LEN("NDBCLUSTER") },
{ C_STRING_WITH_LEN("HEAP") }, { C_STRING_WITH_LEN("MEMORY") },
{ C_STRING_WITH_LEN("MERGE") }, { C_STRING_WITH_LEN("MRG_MYISAM") },
+ { C_STRING_WITH_LEN("Aria") }, { C_STRING_WITH_LEN("Maria") },
{NullS, 0}
};
const char *ha_row_type[] = {
"", "FIXED", "DYNAMIC", "COMPRESSED", "REDUNDANT", "COMPACT",
- /* Reserved to be "PAGE" in future versions */ "?",
+ "PAGE",
"?","?","?"
};
@@ -82,7 +84,7 @@ static plugin_ref ha_default_plugin(THD *thd)
{
if (thd->variables.table_plugin)
return thd->variables.table_plugin;
- return my_plugin_lock(thd, &global_system_variables.table_plugin);
+ return my_plugin_lock(thd, global_system_variables.table_plugin);
}
@@ -163,13 +165,8 @@ plugin_ref ha_lock_engine(THD *thd, const handlerton *hton)
{
if (hton)
{
- st_plugin_int **plugin= hton2plugin + hton->slot;
-
-#ifdef DBUG_OFF
- return my_plugin_lock(thd, plugin);
-#else
- return my_plugin_lock(thd, &plugin);
-#endif
+ st_plugin_int *plugin= hton2plugin[hton->slot];
+ return my_plugin_lock(thd, plugin_int_to_ref(plugin));
}
return NULL;
}
@@ -380,8 +377,7 @@ int ha_finalize_handlerton(st_plugin_int *plugin)
if (!hton)
goto end;
- switch (hton->state)
- {
+ switch (hton->state) {
case SHOW_OPTION_NO:
case SHOW_OPTION_DISABLED:
break;
@@ -435,8 +431,8 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
if (plugin->plugin->init && plugin->plugin->init(hton))
{
sql_print_error("Plugin '%s' init function returned error.",
- plugin->name.str);
- goto err;
+ plugin->name.str);
+ goto err;
}
/*
@@ -463,13 +459,19 @@ int ha_initialize_handlerton(st_plugin_int *plugin)
if (idx == (int) DB_TYPE_DEFAULT)
{
sql_print_warning("Too many storage engines!");
- goto err_deinit;
+ my_free(hton, MYF(0));
+ plugin->data= 0;
+ goto err_deinit;
}
if (hton->db_type != DB_TYPE_UNKNOWN)
sql_print_warning("Storage engine '%s' has conflicting typecode. "
"Assigning value %d.", plugin->plugin->name, idx);
hton->db_type= (enum legacy_db_type) idx;
}
+ installed_htons[hton->db_type]= hton;
+ tmp= hton->savepoint_offset;
+ hton->savepoint_offset= savepoint_alloc_size;
+ savepoint_alloc_size+= tmp;
/*
In case a plugin is uninstalled and re-installed later, it should
@@ -1092,6 +1094,12 @@ int ha_commit_trans(THD *thd, bool all)
my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
DBUG_ENTER("ha_commit_trans");
+ /* Just a random warning to test warnings pushed during autocommit. */
+ DBUG_EXECUTE_IF("warn_during_ha_commit_trans",
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARNING_NOT_COMPLETE_ROLLBACK,
+ ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)););
+
/*
We must not commit the normal transaction if a statement
transaction is pending. Otherwise statement transaction
@@ -1520,7 +1528,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
while ((got= hton->recover(hton, info->list, info->len)) > 0 )
{
sql_print_information("Found %d prepared transaction(s) in %s",
- got, ha_resolve_storage_engine_name(hton));
+ got, hton_name(hton)->str);
for (int i=0; i < got; i ++)
{
my_xid x=info->list[i].get_my_xid();
@@ -1587,16 +1595,6 @@ int ha_recover(HASH *commit_list)
if (info.commit_list)
sql_print_information("Starting crash recovery...");
-#ifndef WILL_BE_DELETED_LATER
- /*
- for now, only InnoDB supports 2pc. It means we can always safely
- rollback all pending transactions, without risking inconsistent data
- */
- DBUG_ASSERT(total_ha_2pc == (ulong) opt_bin_log+1); // only InnoDB and binlog
- tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK
- info.dry_run=FALSE;
-#endif
-
for (info.len= MAX_XID_LIST_SIZE ;
info.list==0 && info.len > MIN_XID_LIST_SIZE; info.len/=2)
{
@@ -2041,29 +2039,50 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
handler *handler::clone(const char *name, MEM_ROOT *mem_root)
{
handler *new_handler= get_new_handler(table->s, mem_root, ht);
+ if (! new_handler)
+ return NULL;
+
/*
Allocate handler->ref here because otherwise ha_open will allocate it
on this->table->mem_root and we will not be able to reclaim that memory
when the clone handler object is destroyed.
*/
- if (new_handler &&
- !(new_handler->ref= (uchar*) alloc_root(mem_root,
- ALIGN_SIZE(ref_length)*2)))
- new_handler= NULL;
+
+ if (!(new_handler->ref= (uchar*) alloc_root(mem_root,
+ ALIGN_SIZE(ref_length)*2)))
+ return NULL;
+
/*
TODO: Implement a more efficient way to have more than one index open for
the same table instance. The ha_open call is not cachable for clone.
+
+ This is not critical as the engines already have the table open
+ and should be able to use the original instance of the table.
*/
- if (new_handler && new_handler->ha_open(table,
- name,
- table->db_stat,
- HA_OPEN_IGNORE_IF_LOCKED))
- new_handler= NULL;
+ if (new_handler->ha_open(table, name, table->db_stat,
+ HA_OPEN_IGNORE_IF_LOCKED))
+ return NULL;
+ new_handler->cloned= 1; // Marker for debugging
return new_handler;
}
+double handler::keyread_time(uint index, uint ranges, ha_rows rows)
+{
+ /*
+ It is assumed that we will read trough the whole key range and that all
+ key blocks are half full (normally things are much better). It is also
+ assumed that each time we read the next key from the index, the handler
+ performs a random seek, thus the cost is proportional to the number of
+ blocks read. This model does not take into account clustered indexes -
+ engines that support that (e.g. InnoDB) may want to overwrite this method.
+ */
+ double keys_per_block= (stats.block_size/2.0/
+ (table->key_info[index].key_length +
+ ref_length) + 1);
+ return (rows + keys_per_block - 1)/ keys_per_block;
+}
void handler::ha_statistic_increment(ulong SSV::*offset) const
{
@@ -2166,8 +2185,8 @@ int handler::read_first_row(uchar * buf, uint primary_key)
else
{
/* Find the first row through the primary key */
- (void) ha_index_init(primary_key, 0);
- error=index_first(buf);
+ if (!(error = ha_index_init(primary_key, 0)))
+ error= index_first(buf);
(void) ha_index_end();
}
DBUG_RETURN(error);
@@ -2354,7 +2373,7 @@ int handler::update_auto_increment()
if ((nr= table->next_number_field->val_int()) != 0 ||
(table->auto_increment_field_not_null &&
- thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO))
+ thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO))
{
/*
Update next_insert_id if we had already generated a value in this
@@ -2552,7 +2571,7 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
table->mark_columns_used_by_index_no_reset(table->s->next_number_index,
table->read_set);
column_bitmaps_signal();
- index_init(table->s->next_number_index, 1);
+ ha_index_init(table->s->next_number_index, 1);
if (table->s->next_number_keypart == 0)
{ // Autoincrement at key-start
error=index_last(table->record[1]);
@@ -2586,7 +2605,7 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
else
nr= ((ulonglong) table->next_number_field->
val_int_offset(table->s->rec_buff_length)+1);
- index_end();
+ ha_index_end();
(void) extra(HA_EXTRA_NO_KEYREAD);
*first_value= nr;
}
@@ -2647,8 +2666,12 @@ void handler::print_keydup_error(uint key_nr, const char *msg)
- table->s->path
- table->alias
*/
+
+#define SET_FATAL_ERROR fatal_error=1
+
void handler::print_error(int error, myf errflag)
{
+ bool fatal_error= 0;
DBUG_ENTER("handler::print_error");
DBUG_PRINT("enter",("error: %d",error));
@@ -2666,6 +2689,13 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_KEY_NOT_FOUND:
case HA_ERR_NO_ACTIVE_RECORD:
case HA_ERR_END_OF_FILE:
+ /*
+ This errors is not not normally fatal (for example for reads). However
+ if you get it during an update or delete, then its fatal.
+ As the user is calling print_error() (which is not done on read), we
+ assume something when wrong with the update or delete.
+ */
+ SET_FATAL_ERROR;
textno=ER_KEY_NOT_FOUND;
break;
case HA_ERR_WRONG_MRG_TABLE_DEF:
@@ -2673,11 +2703,14 @@ void handler::print_error(int error, myf errflag)
break;
case HA_ERR_FOUND_DUPP_KEY:
{
- uint key_nr=get_dup_key(error);
- if ((int) key_nr >= 0)
+ if (table)
{
- print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME));
- DBUG_VOID_RETURN;
+ uint key_nr=get_dup_key(error);
+ if ((int) key_nr >= 0)
+ {
+ print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME));
+ DBUG_VOID_RETURN;
+ }
}
textno=ER_DUP_KEY;
break;
@@ -2714,21 +2747,29 @@ void handler::print_error(int error, myf errflag)
textno=ER_DUP_UNIQUE;
break;
case HA_ERR_RECORD_CHANGED:
+ /*
+ This is not fatal error when using HANDLER interface
+ SET_FATAL_ERROR;
+ */
textno=ER_CHECKREAD;
break;
case HA_ERR_CRASHED:
+ SET_FATAL_ERROR;
textno=ER_NOT_KEYFILE;
break;
case HA_ERR_WRONG_IN_RECORD:
+ SET_FATAL_ERROR;
textno= ER_CRASHED_ON_USAGE;
break;
case HA_ERR_CRASHED_ON_USAGE:
+ SET_FATAL_ERROR;
textno=ER_CRASHED_ON_USAGE;
break;
case HA_ERR_NOT_A_TABLE:
textno= error;
break;
case HA_ERR_CRASHED_ON_REPAIR:
+ SET_FATAL_ERROR;
textno=ER_CRASHED_ON_REPAIR;
break;
case HA_ERR_OUT_OF_MEM:
@@ -2827,14 +2868,27 @@ void handler::print_error(int error, myf errflag)
if (temporary)
my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine);
else
+ {
+ SET_FATAL_ERROR;
my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine);
+ }
}
else
my_error(ER_GET_ERRNO,errflag,error);
DBUG_VOID_RETURN;
}
}
+ if (fatal_error && (debug_assert_if_crashed_table ||
+ global_system_variables.log_warnings > 1))
+ {
+ /*
+ Log error to log before we crash or if extended warnings are requested
+ */
+ errflag|= ME_NOREFRESH;
+ }
+
my_error(textno, errflag, table_share->table_name.str, error);
+ DBUG_ASSERT(!fatal_error || !debug_assert_if_crashed_table);
DBUG_VOID_RETURN;
}
@@ -3592,7 +3646,7 @@ void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info,
stat_info->update_time= stats.update_time;
stat_info->check_time= stats.check_time;
stat_info->check_sum= 0;
- if (table_flags() & (ulong) HA_HAS_CHECKSUM)
+ if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_OLD_CHECKSUM))
stat_info->check_sum= checksum();
return;
}
@@ -3713,7 +3767,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
void st_ha_check_opt::init()
{
flags= sql_flags= 0;
- sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
+ start_time= my_time(0);
}
@@ -3899,7 +3953,8 @@ ha_find_files(THD *thd,const char *db,const char *path,
int error= 0;
DBUG_ENTER("ha_find_files");
DBUG_PRINT("enter", ("db: '%s' path: '%s' wild: '%s' dir: %d",
- db, path, wild ? wild : "NULL", dir));
+ val_or_null(db), val_or_null(path),
+ val_or_null(wild), dir));
st_find_files_args args= {db, path, wild, dir, files};
plugin_foreach(thd, find_files_handlerton,
@@ -4167,7 +4222,7 @@ int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
*/
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
{
- int UNINIT_VAR(result);
+ int result= 0;
DBUG_ENTER("handler::read_multi_range_next");
/* We should not be called after the last call returned EOF. */
@@ -4336,11 +4391,13 @@ int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
enum ha_rkey_function find_flag)
{
int error, error1;
- error= index_init(index, 0);
+ LINT_INIT(error1);
+
+ error= ha_index_init(index, 0);
if (!error)
{
error= index_read_map(buf, key, keypart_map, find_flag);
- error1= index_end();
+ error1= ha_index_end();
}
return error ? error : error1;
}
@@ -4465,7 +4522,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
{
if (db_type->state != SHOW_OPTION_YES)
{
- const LEX_STRING *name=&hton2plugin[db_type->slot]->name;
+ const LEX_STRING *name= hton_name(db_type);
result= stat_print(thd, name->str, name->length,
"", 0, "DISABLED", 8) ? 1 : 0;
}
diff --git a/sql/handler.h b/sql/handler.h
index c9943fdf1ff..e8f6abdca65 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -111,7 +111,8 @@
#define HA_CAN_FULLTEXT (1 << 21)
#define HA_CAN_SQL_HANDLER (1 << 22)
#define HA_NO_AUTO_INCREMENT (1 << 23)
-#define HA_HAS_CHECKSUM (1 << 24)
+/* Has automatic checksums and uses the old checksum format */
+#define HA_HAS_OLD_CHECKSUM (1 << 24)
/* Table data are stored in separate files (for lower_case_table_names) */
#define HA_FILE_BASED (1 << 26)
#define HA_NO_VARCHAR (1 << 27)
@@ -128,6 +129,8 @@
*/
#define HA_BINLOG_ROW_CAPABLE (LL(1) << 34)
#define HA_BINLOG_STMT_CAPABLE (LL(1) << 35)
+/* Has automatic checksums and uses the new checksum format */
+#define HA_HAS_NEW_CHECKSUM (LL(1) << 36)
/*
Set of all binlog flags. Currently only contain the capabilities
@@ -241,8 +244,6 @@
#define HA_LEX_CREATE_TMP_TABLE 1
#define HA_LEX_CREATE_IF_NOT_EXISTS 2
#define HA_LEX_CREATE_TABLE_LIKE 4
-#define HA_OPTION_NO_CHECKSUM (1L << 17)
-#define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
#define HA_MAX_REC_LENGTH 65535
/* Table caching type */
@@ -281,6 +282,11 @@ enum legacy_db_type
DB_TYPE_FIRST_DYNAMIC=42,
DB_TYPE_DEFAULT=127 // Must be last
};
+/*
+ Better name for DB_TYPE_UNKNOWN. Should be used for engines that do not have
+ a hard-coded type value here.
+ */
+#define DB_TYPE_AUTOASSIGN DB_TYPE_UNKNOWN
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
@@ -329,9 +335,8 @@ enum enum_binlog_command {
#define HA_CREATE_USED_PASSWORD (1L << 17)
#define HA_CREATE_USED_CONNECTION (1L << 18)
#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
-/** Unused. Reserved for future versions. */
+/* The following two are used by Maria engine: */
#define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
-/** Unused. Reserved for future versions. */
#define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
typedef ulonglong my_xid; // this line is the same as in log_event.h
@@ -719,6 +724,12 @@ struct handlerton
};
+inline LEX_STRING *hton_name(const handlerton *hton)
+{
+ return &(hton2plugin[hton->slot]->name);
+}
+
+
/* Possible flags of a handlerton (there can be 32 of them) */
#define HTON_NO_FLAGS 0
#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
@@ -770,6 +781,7 @@ struct THD_TRANS
bool modified_non_trans_table;
void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
+ THD_TRANS() {} /* Remove gcc warning */
};
@@ -883,9 +895,9 @@ typedef struct {
ulonglong delete_length;
ha_rows records;
ulong mean_rec_length;
- ulong create_time;
- ulong check_time;
- ulong update_time;
+ time_t create_time;
+ time_t check_time;
+ time_t update_time;
ulonglong check_sum;
} PARTITION_INFO;
@@ -898,7 +910,7 @@ class partition_info;
struct st_partition_iter;
#define NOT_A_PARTITION_ID ((uint32)-1)
-enum enum_ha_unused { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
+enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
typedef struct st_ha_create_information
{
@@ -930,12 +942,13 @@ typedef struct st_ha_create_information
uint options; /* OR of HA_CREATE_ options */
uint merge_insert_method;
uint extra_size; /* length of extra data segment */
- enum enum_ha_unused unused1;
+ /** Transactional or not. Unused; reserved for future versions. */
+ enum ha_choice transactional;
bool table_existed; /* 1 in create if table existed */
bool frm_only; /* 1 if no ha_create_table() */
bool varchar; /* 1 if table has a VARCHAR */
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
- enum enum_ha_unused unused2;
+ enum ha_choice page_checksum; /* If we have page_checksums */
} HA_CREATE_INFO;
@@ -1007,10 +1020,10 @@ typedef class Item COND;
typedef struct st_ha_check_opt
{
st_ha_check_opt() {} /* Remove gcc warning */
- ulong sort_buffer_size;
uint flags; /* isam layer flags (e.g. for myisamchk) */
uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
- KEY_CACHE *key_cache; /* new key cache when changing key cache */
+ time_t start_time; /* When check/repair starts */
+ KEY_CACHE *key_cache; /* new key cache when changing key cache */
void init();
} HA_CHECK_OPT;
@@ -1052,9 +1065,9 @@ public:
ha_rows records;
ha_rows deleted; /* Deleted records */
ulong mean_rec_length; /* physical reclength */
- ulong create_time; /* When table was created */
- ulong check_time;
- ulong update_time;
+ time_t create_time; /* When table was created */
+ time_t check_time;
+ time_t update_time;
uint block_size; /* index block size */
ha_statistics():
@@ -1121,6 +1134,7 @@ public:
enum {NONE=0, INDEX, RND} inited;
bool locked;
bool implicit_emptied; /* Can be !=0 only if HEAP */
+ bool cloned; /* 1 if this was created with clone */
const COND *pushed_cond;
/**
next_insert_id is the next value which should be inserted into the
@@ -1158,7 +1172,7 @@ public:
ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE),
- locked(FALSE), implicit_emptied(0),
+ locked(FALSE), implicit_emptied(0), cloned(0),
pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
auto_inc_intervals_count(0)
{}
@@ -1182,16 +1196,22 @@ public:
DBUG_ENTER("ha_index_init");
DBUG_ASSERT(inited==NONE);
if (!(result= index_init(idx, sorted)))
- inited=INDEX;
+ {
+ inited= INDEX;
+ active_index= idx;
+ }
DBUG_RETURN(result);
}
int ha_index_end()
{
DBUG_ENTER("ha_index_end");
DBUG_ASSERT(inited==INDEX);
- inited=NONE;
+ inited= NONE;
+ active_index= MAX_KEY;
DBUG_RETURN(index_end());
}
+ /* This is called after index_init() if we need to do a index scan */
+ virtual int prepare_index_scan() { return 0; }
int ha_rnd_init(bool scan)
{
int result;
@@ -1290,6 +1310,16 @@ public:
{ return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
virtual double read_time(uint index, uint ranges, ha_rows rows)
{ return rows2double(ranges+rows); }
+
+ /**
+ Calculate cost of 'keyread' scan for given index and number of records.
+
+ @param index index to read
+ @param ranges #of ranges to read
+ @param rows #of records to read
+ */
+ virtual double keyread_time(uint index, uint ranges, ha_rows rows);
+
virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
bool has_transactions()
{ return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
@@ -1346,7 +1376,12 @@ public:
as there may be several calls to this routine.
*/
virtual void column_bitmaps_signal();
- uint get_index(void) const { return active_index; }
+ /*
+ We have to check for inited as some engines, like innodb, sets
+ active_index during table scan.
+ */
+ uint get_index(void) const
+ { return inited == INDEX ? active_index : MAX_KEY; }
virtual int close(void)=0;
/**
@@ -1461,14 +1496,18 @@ public:
}
virtual int read_first_row(uchar *buf, uint primary_key);
/**
- The following function is only needed for tables that may be temporary
- tables during joins.
+ The following 3 function is only needed for tables that may be
+ internal temporary tables during joins.
*/
- virtual int restart_rnd_next(uchar *buf, uchar *pos)
+ virtual int remember_rnd_pos()
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int restart_rnd_next(uchar *buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int rnd_same(uchar *buf, uint inx)
{ return HA_ERR_WRONG_COMMAND; }
- virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
+
+ virtual ha_rows records_in_range(uint inx, key_range *min_key,
+ key_range *max_key)
{ return (ha_rows) 10; }
/*
If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
@@ -1564,6 +1603,7 @@ public:
{ return(NULL);} /* gets tablespace name from handler */
/** used in ALTER TABLE; 1 if changing storage engine is allowed */
virtual bool can_switch_engines() { return 1; }
+ virtual int can_continue_handler_scan() { return 0; }
/** used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
virtual int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
{ return 0; }
@@ -1586,7 +1626,8 @@ public:
*/
virtual const char **bas_ext() const =0;
- virtual int get_default_no_partitions(HA_CREATE_INFO *info) { return 1;}
+ virtual int get_default_no_partitions(HA_CREATE_INFO *create_info)
+ { return 1;}
virtual void set_auto_partitions(partition_info *part_info) { return; }
virtual bool get_no_parts(const char *name,
uint *no_parts)
@@ -1629,13 +1670,11 @@ public:
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
-
#define CHF_CREATE_FLAG 0
#define CHF_DELETE_FLAG 1
#define CHF_RENAME_FLAG 2
#define CHF_INDEX_FLAG 3
-
/**
@note lock_count() can return > 1 if the table is MERGE or partitioned.
*/
@@ -1763,6 +1802,8 @@ public:
return 0;
}
+ LEX_STRING *engine_name() { return hton_name(ht); }
+
protected:
/* Service methods for use by storage engines. */
void ha_statistic_increment(ulong SSV::*offset) const;
@@ -1782,10 +1823,10 @@ protected:
tables.
*/
virtual int delete_table(const char *name);
+
private:
/* Private helpers */
inline void mark_trx_read_write();
-private:
/*
Low-level primitives for storage engines. These should be
overridden by the storage engine class. To call these methods, use
@@ -1793,8 +1834,8 @@ private:
*/
virtual int open(const char *name, int mode, uint test_if_locked)=0;
- virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; }
- virtual int index_end() { active_index= MAX_KEY; return 0; }
+ virtual int index_init(uint idx, bool sorted) { return 0; }
+ virtual int index_end() { return 0; }
/**
rnd_init() can be called two times without rnd_end() in between
(it only makes sense if scan=1).
@@ -1980,7 +2021,7 @@ static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
{
- return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
+ return db_type == NULL ? "UNKNOWN" : hton_name(db_type)->str;
}
static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
diff --git a/sql/hash_filo.cc b/sql/hash_filo.cc
index 9303120e18a..fcc610fe776 100644
--- a/sql/hash_filo.cc
+++ b/sql/hash_filo.cc
@@ -25,3 +25,8 @@
#include "mysql_priv.h"
#include "hash_filo.h"
+
+#ifdef __WIN__
+// Remove linker warning 4221 about empty file
+namespace { char dummy; };
+#endif // __WIN__
diff --git a/sql/hostname.cc b/sql/hostname.cc
index 9796755e9fb..dfcdd3edd90 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -175,7 +176,7 @@ char * ip_to_hostname(struct in_addr *in, uint *errors)
char buff[GETHOSTBYADDR_BUFF_SIZE],buff2[GETHOSTBYNAME_BUFF_SIZE];
int tmp_errno;
struct hostent tmp_hostent, tmp_hostent2;
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
bzero(buff,sizeof(buff)); // Bug in purify
#endif
if (!(hp=gethostbyaddr_r((char*) in,sizeof(*in),
diff --git a/sql/item.cc b/sql/item.cc
index 930c5d7426e..23294a6dbeb 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -259,7 +259,7 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
String *res;
if (!(res= val_str(&str_value)))
- return NULL;
+ return 0;
if (str2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_BAD_NUM,
res->ptr(), res->length(), res->charset(),
@@ -382,9 +382,10 @@ Item::Item():
{
marker= 0;
maybe_null=null_value=with_sum_func=unsigned_flag=0;
+ in_rollup= 0;
decimals= 0; max_length= 0;
with_subselect= 0;
- cmp_context= (Item_result)-1;
+ cmp_context= IMPOSSIBLE_RESULT;
/* Put item in free list so that we can free all items at end */
THD *thd= current_thd;
@@ -422,6 +423,7 @@ Item::Item(THD *thd, Item *item):
marker(item->marker),
decimals(item->decimals),
maybe_null(item->maybe_null),
+ in_rollup(item->in_rollup),
null_value(item->null_value),
unsigned_flag(item->unsigned_flag),
with_sum_func(item->with_sum_func),
@@ -912,7 +914,7 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const
/**
Get the value of the function as a MYSQL_TIME structure.
- As a extra convenience the time structure is reset on error!
+ As a extra convenience the time structure is reset on error or NULL values!
*/
bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate)
@@ -1513,7 +1515,9 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
if (collation == &my_charset_bin)
{
if (derivation <= dt.derivation)
- ; // Do nothing
+ {
+ /* Do nothing */
+ }
else
{
set(dt);
@@ -1529,7 +1533,7 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
left_is_superset(this, &dt))
{
- // Do nothing
+ /* Do nothing */
}
else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) &&
left_is_superset(&dt, this))
@@ -1540,7 +1544,7 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
derivation < dt.derivation &&
dt.derivation >= DERIVATION_SYSCONST)
{
- // Do nothing;
+ /* Do nothing */
}
else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) &&
dt.derivation < derivation &&
@@ -1558,7 +1562,7 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
}
else if (derivation < dt.derivation)
{
- // Do nothing
+ /* Do nothing */
}
else if (dt.derivation < derivation)
{
@@ -1568,7 +1572,7 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
{
if (collation == dt.collation)
{
- // Do nothing
+ /* Do nothing */
}
else
{
@@ -1937,6 +1941,15 @@ void Item_field::reset_field(Field *f)
name= (char*) f->field_name;
}
+
+bool Item_field::enumerate_field_refs_processor(uchar *arg)
+{
+ Field_enumerator *fe= (Field_enumerator*)arg;
+ fe->visit_field(field);
+ return FALSE;
+}
+
+
const char *Item_ident::full_name() const
{
char *tmp;
@@ -3623,7 +3636,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
/* store pointer on SELECT_LEX from which item is dependent */
if (mark_item)
mark_item->depended_from= last;
- current->mark_as_dependent(last);
+ current->mark_as_dependent(last, resolved_item);
if (thd->lex->describe & DESCRIBE_EXTENDED)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
@@ -3724,7 +3737,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
int found_match_degree= 0;
Item_ident *cur_field;
int cur_match_degree= 0;
- char name_buff[NAME_LEN+1];
+ char name_buff[SAFE_NAME_LEN+1];
if (find_item->type() == Item::FIELD_ITEM ||
find_item->type() == Item::REF_ITEM)
@@ -4326,31 +4339,18 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
It's not an Item_field in the select list so we must make a new
Item_ref to point to the Item in the select list and replace the
Item_field created by the parser with the new Item_ref.
-
- NOTE: If we are fixing an alias reference inside ORDER/GROUP BY
- item tree, then we use new Item_ref as an intermediate value
- to resolve referenced item only.
- In this case the new Item_ref item is unused.
*/
Item_ref *rf= new Item_ref(context, db_name,table_name,field_name);
if (!rf)
return 1;
-
- bool save_group_fix_field= thd->lex->current_select->group_fix_field;
- /*
- No need for recursive resolving of aliases.
- */
- thd->lex->current_select->group_fix_field= 0;
-
bool ret= rf->fix_fields(thd, (Item **) &rf) || rf->check_cols(1);
- thd->lex->current_select->group_fix_field= save_group_fix_field;
if (ret)
return TRUE;
-
- if (save_group_fix_field && alias_name_used)
- thd->change_item_tree(reference, *rf->ref);
- else
- thd->change_item_tree(reference, rf);
+
+ SELECT_LEX *select= thd->lex->current_select;
+ thd->change_item_tree(reference,
+ select->parsing_place == IN_GROUP_BY &&
+ alias_name_used ? *rf->ref : rf);
return FALSE;
}
@@ -4654,7 +4654,7 @@ Item *Item_field::equal_fields_propagator(uchar *arg)
DATE/TIME represented as an int and as a string.
*/
if (!item ||
- (cmp_context != (Item_result)-1 && item->cmp_context != cmp_context))
+ (cmp_context != IMPOSSIBLE_RESULT && item->cmp_context != cmp_context))
item= this;
else if (field && (field->flags & ZEROFILL_FLAG) && IS_NUM(field->type()))
{
@@ -4718,7 +4718,7 @@ Item *Item_field::replace_equal_field(uchar *arg)
Item *const_item= item_equal->get_const();
if (const_item)
{
- if (cmp_context != (Item_result)-1 &&
+ if (cmp_context != IMPOSSIBLE_RESULT &&
const_item->cmp_context != cmp_context)
return this;
return const_item;
@@ -6466,6 +6466,42 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
/**
+ Mark references from inner selects used in group by clause
+
+ The method is used by the walk method when called for the expressions
+ from the group by clause. The callsare occurred in the function
+ fix_inner_refs invoked by JOIN::prepare.
+ The parameter passed to Item_outer_ref::check_inner_refs_processor
+ is the iterator over the list of inner references from the subselects
+ of the select to be prepared. The function marks those references
+ from this list whose occurrences are encountered in the group by
+ expressions passed to the walk method.
+
+ @param arg pointer to the iterator over a list of inner references
+
+ @return
+ FALSE always
+*/
+
+bool Item_outer_ref::check_inner_refs_processor(uchar *arg)
+{
+ List_iterator_fast<Item_outer_ref> *it=
+ ((List_iterator_fast<Item_outer_ref> *) arg);
+ Item_outer_ref *ref;
+ while ((ref= (*it)++))
+ {
+ if (ref == this)
+ {
+ ref->found_in_group_by= 1;
+ break;
+ }
+ }
+ (*it).rewind();
+ return FALSE;
+}
+
+
+/**
Compare two view column references for equality.
A view column reference is considered equal to another column
@@ -6994,9 +7030,7 @@ int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
if (field_type == MYSQL_TYPE_DATE)
type= MYSQL_TIMESTAMP_DATE;
-
- if (field_type == MYSQL_TYPE_DATETIME ||
- field_type == MYSQL_TYPE_TIMESTAMP)
+ else
type= MYSQL_TIMESTAMP_DATETIME;
const char *field_name= field->field_name;
@@ -7096,7 +7130,7 @@ bool Item_cache_int::cache_value()
}
-void Item_cache_int::store(Item *item, longlong val_arg)
+void Item_cache_int::store_longlong(Item *item, longlong val_arg)
{
/* An explicit values is given, save it. */
value_cached= TRUE;
diff --git a/sql/item.h b/sql/item.h
index 8d7ad3c41d3..be2d340a4d3 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -488,8 +488,7 @@ public:
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
- XPATH_NODESET, XPATH_NODESET_CMP,
- VIEW_FIXER_ITEM};
+ XPATH_NODESET, XPATH_NODESET_CMP};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@@ -516,13 +515,16 @@ public:
Item *next;
uint32 max_length;
/*
- TODO: convert name and name_length fields into String to keep them in sync
- (see bug #11829681/60295 etc).
+ TODO: convert name and name_length fields into LEX_STRING to keep them in
+ sync (see bug #11829681/60295 etc). Then also remove some strlen(name)
+ calls.
*/
uint name_length; /* Length of name */
int8 marker;
uint8 decimals;
my_bool maybe_null; /* If item may be null */
+ my_bool in_rollup; /* If used in GROUP BY list
+ of a query with ROLLUP */
my_bool null_value; /* if item is null */
my_bool unsigned_flag;
my_bool with_sum_func;
@@ -559,10 +561,17 @@ public:
Field *make_string_field(TABLE *table);
virtual bool fix_fields(THD *, Item **);
/*
- should be used in case where we are sure that we do not need
+ This method should be used in case where we are sure that we do not need
complete fix_fields() procedure.
- */
- inline void quick_fix_field() { fixed= 1; }
+ Usually this method is used by the optimizer when it has to create a new
+ item out of other already fixed items. For example, if the optimizer has
+ to create a new Item_func for an inferred equality whose left and right
+ parts are already fixed items. In some cases the optimizer cannot use
+ directly fixed items as the arguments of the created functional item,
+ but rather uses intermediate type conversion items. Then the method is
+ supposed to be applied recursively.
+ */
+ virtual inline void quick_fix_field() { fixed= 1; }
/* Function returns 1 on overflow and -1 on fatal errors */
int save_in_field_no_warnings(Field *field, bool no_conversions);
virtual int save_in_field(Field *field, bool no_conversions);
@@ -749,7 +758,11 @@ public:
virtual bool val_bool_result() { return val_bool(); }
virtual bool is_null_result() { return is_null(); }
- /* bit map of tables used by item */
+ /*
+ Bitmap of tables used by item
+ (note: if you need to check dependencies on individual columns, check out
+ class Field_enumerator)
+ */
virtual table_map used_tables() const { return (table_map) 0L; }
/*
Return table map of tables that can't be NULL tables (tables that are
@@ -852,6 +865,7 @@ public:
set value of aggregate function in case of no rows for grouping were found
*/
virtual void no_rows_in_result() {}
+ virtual void restore_to_before_no_rows_in_result() {}
virtual Item *copy_or_same(THD *thd) { return this; }
virtual Item *copy_andor_structure(THD *thd) { return this; }
virtual Item *real_item() { return this; }
@@ -905,8 +919,24 @@ public:
virtual bool change_context_processor(uchar *context) { return 0; }
virtual bool reset_query_id_processor(uchar *query_id_arg) { return 0; }
virtual bool is_expensive_processor(uchar *arg) { return 0; }
- virtual bool find_item_processor(uchar *arg) { return this == (void *) arg; }
virtual bool register_field_in_read_map(uchar *arg) { return 0; }
+ virtual bool enumerate_field_refs_processor(uchar *arg) { return 0; }
+ virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; }
+
+ /* To call bool function for all arguments */
+ struct bool_func_call_args
+ {
+ Item *original_func_item;
+ void (Item::*bool_function)();
+ };
+ bool call_bool_func_processor(uchar *org_item)
+ {
+ bool_func_call_args *info= (bool_func_call_args*) org_item;
+ /* Avoid recursion, as walk also calls for original item */
+ if (info->original_func_item != this)
+ (this->*(info->bool_function))();
+ return FALSE;
+ }
/*
Check if a partition function is allowed
SYNOPSIS
@@ -996,6 +1026,8 @@ public:
return FALSE;
}
+ virtual bool check_inner_refs_processor(uchar *arg) { return FALSE; }
+
/*
For SP local variable returns pointer to Item representing its
current value and pointer to current Item otherwise.
@@ -1057,6 +1089,30 @@ public:
};
+/*
+ Class to be used to enumerate all field references in an item tree.
+ Suggested usage:
+
+ class My_enumerator : public Field_enumerator
+ {
+ virtual void visit_field() { ... your actions ...}
+ }
+
+ My_enumerator enumerator;
+ item->walk(Item::enumerate_field_refs_processor, ...,(uchar*)&enumerator);
+
+ This is similar to Visitor pattern.
+*/
+
+class Field_enumerator
+{
+public:
+ virtual void visit_field(Field *field)= 0;
+ virtual ~Field_enumerator() {}; /* purecov: inspected */
+ Field_enumerator() {} /* Remove gcc warning */
+};
+
+
class sp_head;
@@ -1526,6 +1582,7 @@ public:
bool find_item_in_field_list_processor(uchar *arg);
bool register_field_in_read_map(uchar *arg);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+ bool enumerate_field_refs_processor(uchar *arg);
void cleanup();
bool result_as_longlong()
{
@@ -2064,9 +2121,9 @@ public:
class Item_partition_func_safe_string: public Item_string
{
public:
- Item_partition_func_safe_string(const char *name, uint length,
+ Item_partition_func_safe_string(const char *name_arg, uint length,
CHARSET_INFO *cs= NULL):
- Item_string(name, length, cs)
+ Item_string(name_arg, length, cs)
{}
};
@@ -2086,8 +2143,8 @@ public:
class Item_blob :public Item_partition_func_safe_string
{
public:
- Item_blob(const char *name, uint length) :
- Item_partition_func_safe_string(name, length, &my_charset_bin)
+ Item_blob(const char *name_arg, uint length) :
+ Item_partition_func_safe_string(name_arg, length, &my_charset_bin)
{ max_length= length; }
enum Type type() const { return TYPE_HOLDER; }
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
@@ -2115,8 +2172,8 @@ class Item_return_int :public Item_int
enum_field_types int_field_type;
public:
Item_return_int(const char *name_arg, uint length,
- enum_field_types field_type_arg, longlong value= 0)
- :Item_int(name_arg, value, length), int_field_type(field_type_arg)
+ enum_field_types field_type_arg, longlong value_arg= 0)
+ :Item_int(name_arg, value_arg, length), int_field_type(field_type_arg)
{
unsigned_flag=1;
}
@@ -2273,6 +2330,10 @@ public:
if (!depended_from)
(*ref)->update_used_tables();
}
+ bool const_item() const
+ {
+ return (*ref)->const_item();
+ }
table_map not_null_tables() const { return (*ref)->not_null_tables(); }
void set_result_field(Field *field) { result_field= field; }
bool is_result_field() { return 1; }
@@ -2289,6 +2350,14 @@ public:
return (*ref)->walk(processor, walk_subquery, arg) ||
(this->*processor)(arg);
}
+ void no_rows_in_result()
+ {
+ (*ref)->no_rows_in_result();
+ }
+ void restore_to_before_no_rows_in_result()
+ {
+ (*ref)->restore_to_before_no_rows_in_result();
+ }
virtual void print(String *str, enum_query_type query_type);
bool result_as_longlong()
{
@@ -2421,12 +2490,13 @@ public:
of the outer select.
*/
bool found_in_select_list;
+ bool found_in_group_by;
Item_outer_ref(Name_resolution_context *context_arg,
Item_field *outer_field_arg)
:Item_direct_ref(context_arg, 0, outer_field_arg->table_name,
outer_field_arg->field_name),
outer_ref(outer_field_arg), in_sum_func(0),
- found_in_select_list(0)
+ found_in_select_list(0), found_in_group_by(0)
{
ref= &outer_ref;
set_properties();
@@ -2437,7 +2507,7 @@ public:
bool alias_name_used_arg)
:Item_direct_ref(context_arg, item, table_name_arg, field_name_arg,
alias_name_used_arg),
- outer_ref(0), in_sum_func(0), found_in_select_list(1)
+ outer_ref(0), in_sum_func(0), found_in_select_list(1), found_in_group_by(0)
{}
void save_in_result_field(bool no_conversions)
{
@@ -2448,7 +2518,9 @@ public:
{
return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT;
}
+ table_map not_null_tables() const { return 0; }
virtual Ref_Type ref_type() { return OUTER_REF; }
+ bool check_inner_refs_processor(uchar * arg);
};
@@ -2849,7 +2921,8 @@ public:
{
return Item_field::save_in_field(field_arg, no_conversions);
}
- /*
+ enum Type type() const { return INSERT_VALUE_ITEM; }
+ /*
We use RAND_TABLE_BIT to prevent Item_insert_value from
being treated as a constant and precalculated before execution
*/
@@ -3048,7 +3121,7 @@ public:
Item_cache(field_type_arg), value(0) {}
virtual void store(Item *item){ Item_cache::store(item); }
- void store(Item *item, longlong val_arg);
+ void store_longlong(Item *item, longlong val_arg);
double val_real();
longlong val_int();
String* val_str(String *str);
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index d20bc66961d..798756ed9ef 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 23f081e1cc0..c6c09bf0cb5 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -879,7 +879,7 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item_cache_int *cache= new Item_cache_int();
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
@@ -891,7 +891,6 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
Item **a1, Item **a2,
Item_result type)
{
- enum enum_date_cmp_type cmp_type;
ulonglong const_value= (ulonglong)-1;
thd= current_thd;
owner= owner_arg;
@@ -900,7 +899,7 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
b= a2;
thd= current_thd;
- if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
+ if (can_compare_as_dates(*a, *b, &const_value))
{
a_type= (*a)->field_type();
b_type= (*b)->field_type();
@@ -918,13 +917,13 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
cache->set_used_tables(1);
if (!(*a)->is_datetime())
{
- cache->store((*a), const_value);
+ cache->store_longlong((*a), const_value);
a_cache= cache;
a= (Item **)&a_cache;
}
else
{
- cache->store((*b), const_value);
+ cache->store_longlong((*b), const_value);
b_cache= cache;
b= (Item **)&b_cache;
}
@@ -1146,7 +1145,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
Item_cache_int *cache= new Item_cache_int(MYSQL_TYPE_DATETIME);
/* Mark the cache as non-const to prevent re-caching. */
cache->set_used_tables(1);
- cache->store(item, value);
+ cache->store_longlong(item, value);
*cache_arg= cache;
*item_arg= cache_arg;
}
@@ -3030,6 +3029,16 @@ void Item_func_case::fix_length_and_dec()
nagg++;
if (!(found_types= collect_cmp_types(agg, nagg)))
return;
+ if (with_sum_func || current_thd->lex->current_select->group_list.elements)
+ {
+ /*
+ See TODO commentary in the setup_copy_fields function:
+ item in a group may be wrapped with an Item_copy_string item.
+ That item has a STRING_RESULT result type, so we need
+ to take this type into account.
+ */
+ found_types |= (1 << item_cmp_type(left_result_type, STRING_RESULT));
+ }
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
{
@@ -3066,9 +3075,8 @@ void Item_func_case::fix_length_and_dec()
agg_num_lengths(args[i + 1]);
if (else_expr_num != -1)
agg_num_lengths(args[else_expr_num]);
- max_length= my_decimal_precision_to_length_no_truncation(max_length +
- decimals, decimals,
- unsigned_flag);
+ max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
+ unsigned_flag);
}
}
@@ -3303,19 +3311,19 @@ int cmp_longlong(void *cmp_arg,
One of the args is unsigned and is too big to fit into the
positive signed range. Report no match.
*/
- if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX) ||
+ if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX)
+ ||
(b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX))
return a->unsigned_flag ? 1 : -1;
/*
Although the signedness differs both args can fit into the signed
positive range. Make them signed and compare as usual.
*/
- return cmp_longs (a->val, b->val);
+ return cmp_longs(a->val, b->val);
}
if (a->unsigned_flag)
- return cmp_ulongs ((ulonglong) a->val, (ulonglong) b->val);
- else
- return cmp_longs (a->val, b->val);
+ return cmp_ulongs((ulonglong) a->val, (ulonglong) b->val);
+ return cmp_longs(a->val, b->val);
}
static int cmp_double(void *cmp_arg, double *a,double *b)
@@ -5510,33 +5518,7 @@ void Item_equal::merge(Item_equal *item)
void Item_equal::sort(Item_field_cmpfunc compare, void *arg)
{
- bool swap;
- List_iterator<Item_field> it(fields);
- do
- {
- Item_field *item1= it++;
- Item_field **ref1= it.ref();
- Item_field *item2;
-
- swap= FALSE;
- while ((item2= it++))
- {
- Item_field **ref2= it.ref();
- if (compare(item1, item2, arg) < 0)
- {
- Item_field *item= *ref1;
- *ref1= *ref2;
- *ref2= item;
- swap= TRUE;
- }
- else
- {
- item1= item2;
- ref1= ref2;
- }
- }
- it.rewind();
- } while (swap);
+ exchange_sort<Item_field>(&fields, compare, arg);
}
@@ -5591,6 +5573,7 @@ void Item_equal::update_used_tables()
not_null_tables_cache= used_tables_cache= 0;
if ((const_item_cache= cond_false))
return;
+ const_item_cache= 1;
while ((item=li++))
{
item->update_used_tables();
@@ -5606,7 +5589,7 @@ longlong Item_equal::val_int()
return 0;
List_iterator_fast<Item_field> it(fields);
Item *item= const_item ? const_item : it++;
- if ((null_value= item->null_value))
+ if ((null_value= item->is_null()))
return 0;
eval_item->store_value(item);
while ((item_field= it++))
@@ -5614,7 +5597,7 @@ longlong Item_equal::val_int()
/* Skip fields of non-const tables. They haven't been read yet */
if (item_field->field->table->const_table)
{
- if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
+ if ((null_value= item_field->is_null()) || eval_item->cmp(item_field))
return 0;
}
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 4d8cadfcce9..f612f944877 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -1620,6 +1620,7 @@ public:
uint members();
bool contains(Field *field);
Item_field* get_first() { return fields.head(); }
+ uint n_fields() { return fields.elements; }
void merge(Item_equal *item);
void update_const();
enum Functype functype() const { return MULT_EQUAL_FUNC; }
diff --git a/sql/item_create.cc b/sql/item_create.cc
index e664d7861fb..a5dc3eeb5ad 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -78,7 +79,7 @@ public:
@param thd The current thread
@return An item representing the function call
*/
- virtual Item *create(THD *thd) = 0;
+ virtual Item *create_builder(THD *thd) = 0;
protected:
/** Constructor. */
@@ -103,7 +104,7 @@ public:
@param arg1 The first argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1) = 0;
+ virtual Item *create_1_arg(THD *thd, Item *arg1) = 0;
protected:
/** Constructor. */
@@ -129,7 +130,7 @@ public:
@param arg2 The second argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2) = 0;
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) = 0;
protected:
/** Constructor. */
@@ -156,7 +157,7 @@ public:
@param arg3 The third argument of the function
@return An item representing the function call
*/
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) = 0;
protected:
/** Constructor. */
@@ -173,8 +174,8 @@ protected:
class Create_sp_func : public Create_qfunc
{
public:
- virtual Item *create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list);
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list);
static Create_sp_func s_singleton;
@@ -219,7 +220,7 @@ protected:
class Create_func_abs : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_abs s_singleton;
@@ -232,7 +233,7 @@ protected:
class Create_func_acos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_acos s_singleton;
@@ -245,7 +246,7 @@ protected:
class Create_func_addtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_addtime s_singleton;
@@ -258,7 +259,7 @@ protected:
class Create_func_aes_encrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_encrypt s_singleton;
@@ -271,7 +272,7 @@ protected:
class Create_func_aes_decrypt : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_aes_decrypt s_singleton;
@@ -285,7 +286,7 @@ protected:
class Create_func_area : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_area s_singleton;
@@ -300,7 +301,7 @@ protected:
class Create_func_as_wkb : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkb s_singleton;
@@ -315,7 +316,7 @@ protected:
class Create_func_as_wkt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_as_wkt s_singleton;
@@ -329,7 +330,7 @@ protected:
class Create_func_asin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_asin s_singleton;
@@ -355,7 +356,7 @@ protected:
class Create_func_benchmark : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_benchmark s_singleton;
@@ -368,7 +369,7 @@ protected:
class Create_func_bin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bin s_singleton;
@@ -381,7 +382,7 @@ protected:
class Create_func_bit_count : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_count s_singleton;
@@ -394,7 +395,7 @@ protected:
class Create_func_bit_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_bit_length s_singleton;
@@ -407,7 +408,7 @@ protected:
class Create_func_ceiling : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ceiling s_singleton;
@@ -421,7 +422,7 @@ protected:
class Create_func_centroid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_centroid s_singleton;
@@ -435,7 +436,7 @@ protected:
class Create_func_char_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_char_length s_singleton;
@@ -448,7 +449,7 @@ protected:
class Create_func_coercibility : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_coercibility s_singleton;
@@ -461,7 +462,7 @@ protected:
class Create_func_compress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_compress s_singleton;
@@ -500,7 +501,7 @@ protected:
class Create_func_connection_id : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_connection_id s_singleton;
@@ -514,7 +515,7 @@ protected:
class Create_func_contains : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_contains s_singleton;
@@ -528,7 +529,7 @@ protected:
class Create_func_conv : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_conv s_singleton;
@@ -541,7 +542,7 @@ protected:
class Create_func_convert_tz : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_convert_tz s_singleton;
@@ -554,7 +555,7 @@ protected:
class Create_func_cos : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cos s_singleton;
@@ -567,7 +568,7 @@ protected:
class Create_func_cot : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_cot s_singleton;
@@ -580,7 +581,7 @@ protected:
class Create_func_crc32 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_crc32 s_singleton;
@@ -594,7 +595,7 @@ protected:
class Create_func_crosses : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_crosses s_singleton;
@@ -608,7 +609,7 @@ protected:
class Create_func_date_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_date_format s_singleton;
@@ -621,7 +622,7 @@ protected:
class Create_func_datediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_datediff s_singleton;
@@ -634,7 +635,7 @@ protected:
class Create_func_dayname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayname s_singleton;
@@ -647,7 +648,7 @@ protected:
class Create_func_dayofmonth : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofmonth s_singleton;
@@ -660,7 +661,7 @@ protected:
class Create_func_dayofweek : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofweek s_singleton;
@@ -673,7 +674,7 @@ protected:
class Create_func_dayofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dayofyear s_singleton;
@@ -686,7 +687,7 @@ protected:
class Create_func_decode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_decode s_singleton;
@@ -699,7 +700,7 @@ protected:
class Create_func_degrees : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_degrees s_singleton;
@@ -739,7 +740,7 @@ protected:
class Create_func_dimension : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dimension s_singleton;
@@ -754,7 +755,7 @@ protected:
class Create_func_disjoint : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_disjoint s_singleton;
@@ -781,7 +782,7 @@ protected:
class Create_func_encode : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_encode s_singleton;
@@ -808,7 +809,7 @@ protected:
class Create_func_endpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_endpoint s_singleton;
@@ -823,7 +824,7 @@ protected:
class Create_func_envelope : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_envelope s_singleton;
@@ -838,7 +839,7 @@ protected:
class Create_func_equals : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_equals s_singleton;
@@ -852,7 +853,7 @@ protected:
class Create_func_exp : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exp s_singleton;
@@ -879,7 +880,7 @@ protected:
class Create_func_exteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_exteriorring s_singleton;
@@ -906,7 +907,7 @@ protected:
class Create_func_find_in_set : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_find_in_set s_singleton;
@@ -919,7 +920,7 @@ protected:
class Create_func_floor : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_floor s_singleton;
@@ -932,7 +933,7 @@ protected:
class Create_func_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_format s_singleton;
@@ -945,7 +946,7 @@ protected:
class Create_func_found_rows : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_found_rows s_singleton;
@@ -958,7 +959,7 @@ protected:
class Create_func_from_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_from_days s_singleton;
@@ -1015,7 +1016,7 @@ protected:
class Create_func_geometry_type : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_geometry_type s_singleton;
@@ -1030,7 +1031,7 @@ protected:
class Create_func_geometryn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_geometryn s_singleton;
@@ -1044,7 +1045,7 @@ protected:
class Create_func_get_lock : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_get_lock s_singleton;
@@ -1058,7 +1059,7 @@ protected:
class Create_func_glength : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_glength s_singleton;
@@ -1085,7 +1086,7 @@ protected:
class Create_func_hex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_hex s_singleton;
@@ -1098,7 +1099,7 @@ protected:
class Create_func_ifnull : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_ifnull s_singleton;
@@ -1111,7 +1112,7 @@ protected:
class Create_func_inet_ntoa : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_ntoa s_singleton;
@@ -1124,7 +1125,7 @@ protected:
class Create_func_inet_aton : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_inet_aton s_singleton;
@@ -1137,7 +1138,7 @@ protected:
class Create_func_instr : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_instr s_singleton;
@@ -1151,7 +1152,7 @@ protected:
class Create_func_interiorringn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_interiorringn s_singleton;
@@ -1166,7 +1167,7 @@ protected:
class Create_func_intersects : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_intersects s_singleton;
@@ -1180,7 +1181,7 @@ protected:
class Create_func_is_free_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_free_lock s_singleton;
@@ -1193,7 +1194,7 @@ protected:
class Create_func_is_used_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_is_used_lock s_singleton;
@@ -1207,7 +1208,7 @@ protected:
class Create_func_isclosed : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isclosed s_singleton;
@@ -1222,7 +1223,7 @@ protected:
class Create_func_isempty : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isempty s_singleton;
@@ -1236,7 +1237,7 @@ protected:
class Create_func_isnull : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_isnull s_singleton;
@@ -1250,7 +1251,7 @@ protected:
class Create_func_issimple : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_issimple s_singleton;
@@ -1264,7 +1265,7 @@ protected:
class Create_func_last_day : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_last_day s_singleton;
@@ -1290,7 +1291,7 @@ protected:
class Create_func_lcase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_lcase s_singleton;
@@ -1316,7 +1317,7 @@ protected:
class Create_func_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_length s_singleton;
@@ -1329,7 +1330,7 @@ protected:
class Create_func_ln : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ln s_singleton;
@@ -1342,7 +1343,7 @@ protected:
class Create_func_load_file : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_load_file s_singleton;
@@ -1381,7 +1382,7 @@ protected:
class Create_func_log10 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log10 s_singleton;
@@ -1394,7 +1395,7 @@ protected:
class Create_func_log2 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_log2 s_singleton;
@@ -1407,7 +1408,7 @@ protected:
class Create_func_lpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_lpad s_singleton;
@@ -1420,7 +1421,7 @@ protected:
class Create_func_ltrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ltrim s_singleton;
@@ -1433,7 +1434,7 @@ protected:
class Create_func_makedate : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_makedate s_singleton;
@@ -1446,7 +1447,7 @@ protected:
class Create_func_maketime : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_maketime s_singleton;
@@ -1485,7 +1486,7 @@ protected:
class Create_func_md5 : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_md5 s_singleton;
@@ -1498,7 +1499,7 @@ protected:
class Create_func_monthname : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_monthname s_singleton;
@@ -1511,7 +1512,7 @@ protected:
class Create_func_name_const : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_name_const s_singleton;
@@ -1524,7 +1525,7 @@ protected:
class Create_func_nullif : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_nullif s_singleton;
@@ -1538,7 +1539,7 @@ protected:
class Create_func_numgeometries : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numgeometries s_singleton;
@@ -1553,7 +1554,7 @@ protected:
class Create_func_numinteriorring : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numinteriorring s_singleton;
@@ -1568,7 +1569,7 @@ protected:
class Create_func_numpoints : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_numpoints s_singleton;
@@ -1582,7 +1583,7 @@ protected:
class Create_func_oct : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_oct s_singleton;
@@ -1595,7 +1596,7 @@ protected:
class Create_func_ord : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ord s_singleton;
@@ -1609,7 +1610,7 @@ protected:
class Create_func_overlaps : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_overlaps s_singleton;
@@ -1623,7 +1624,7 @@ protected:
class Create_func_period_add : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_add s_singleton;
@@ -1636,7 +1637,7 @@ protected:
class Create_func_period_diff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_period_diff s_singleton;
@@ -1649,7 +1650,7 @@ protected:
class Create_func_pi : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_pi s_singleton;
@@ -1663,7 +1664,7 @@ protected:
class Create_func_pointn : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pointn s_singleton;
@@ -1677,7 +1678,7 @@ protected:
class Create_func_pow : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_pow s_singleton;
@@ -1690,7 +1691,7 @@ protected:
class Create_func_quote : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_quote s_singleton;
@@ -1703,7 +1704,7 @@ protected:
class Create_func_radians : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_radians s_singleton;
@@ -1729,7 +1730,7 @@ protected:
class Create_func_release_lock : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_release_lock s_singleton;
@@ -1742,7 +1743,7 @@ protected:
class Create_func_reverse : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_reverse s_singleton;
@@ -1768,7 +1769,7 @@ protected:
class Create_func_row_count : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_row_count s_singleton;
@@ -1781,7 +1782,7 @@ protected:
class Create_func_rpad : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_rpad s_singleton;
@@ -1794,7 +1795,7 @@ protected:
class Create_func_rtrim : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_rtrim s_singleton;
@@ -1807,7 +1808,7 @@ protected:
class Create_func_sec_to_time : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sec_to_time s_singleton;
@@ -1820,7 +1821,7 @@ protected:
class Create_func_sha : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sha s_singleton;
@@ -1833,7 +1834,7 @@ protected:
class Create_func_sign : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sign s_singleton;
@@ -1846,7 +1847,7 @@ protected:
class Create_func_sin : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sin s_singleton;
@@ -1859,7 +1860,7 @@ protected:
class Create_func_sleep : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sleep s_singleton;
@@ -1872,7 +1873,7 @@ protected:
class Create_func_soundex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_soundex s_singleton;
@@ -1885,7 +1886,7 @@ protected:
class Create_func_space : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_space s_singleton;
@@ -1898,7 +1899,7 @@ protected:
class Create_func_sqrt : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_sqrt s_singleton;
@@ -1912,7 +1913,7 @@ protected:
class Create_func_srid : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_srid s_singleton;
@@ -1927,7 +1928,7 @@ protected:
class Create_func_startpoint : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_startpoint s_singleton;
@@ -1941,7 +1942,7 @@ protected:
class Create_func_str_to_date : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_str_to_date s_singleton;
@@ -1954,7 +1955,7 @@ protected:
class Create_func_strcmp : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_strcmp s_singleton;
@@ -1967,7 +1968,7 @@ protected:
class Create_func_substr_index : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_substr_index s_singleton;
@@ -1980,7 +1981,7 @@ protected:
class Create_func_subtime : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_subtime s_singleton;
@@ -1993,7 +1994,7 @@ protected:
class Create_func_tan : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_tan s_singleton;
@@ -2006,7 +2007,7 @@ protected:
class Create_func_time_format : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_time_format s_singleton;
@@ -2019,7 +2020,7 @@ protected:
class Create_func_time_to_sec : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_time_to_sec s_singleton;
@@ -2032,7 +2033,7 @@ protected:
class Create_func_timediff : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_timediff s_singleton;
@@ -2045,7 +2046,7 @@ protected:
class Create_func_to_days : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_to_days s_singleton;
@@ -2059,7 +2060,7 @@ protected:
class Create_func_touches : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_touches s_singleton;
@@ -2073,7 +2074,7 @@ protected:
class Create_func_ucase : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_ucase s_singleton;
@@ -2086,7 +2087,7 @@ protected:
class Create_func_uncompress : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompress s_singleton;
@@ -2099,7 +2100,7 @@ protected:
class Create_func_uncompressed_length : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_uncompressed_length s_singleton;
@@ -2112,7 +2113,7 @@ protected:
class Create_func_unhex : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_unhex s_singleton;
@@ -2138,7 +2139,7 @@ protected:
class Create_func_uuid : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid s_singleton;
@@ -2151,7 +2152,7 @@ protected:
class Create_func_uuid_short : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_uuid_short s_singleton;
@@ -2164,7 +2165,7 @@ protected:
class Create_func_version : public Create_func_arg0
{
public:
- virtual Item *create(THD *thd);
+ virtual Item *create_builder(THD *thd);
static Create_func_version s_singleton;
@@ -2177,7 +2178,7 @@ protected:
class Create_func_weekday : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekday s_singleton;
@@ -2190,7 +2191,7 @@ protected:
class Create_func_weekofyear : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_weekofyear s_singleton;
@@ -2204,7 +2205,7 @@ protected:
class Create_func_within : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_within s_singleton;
@@ -2219,7 +2220,7 @@ protected:
class Create_func_x : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_x s_singleton;
@@ -2233,7 +2234,7 @@ protected:
class Create_func_xml_extractvalue : public Create_func_arg2
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_xml_extractvalue s_singleton;
@@ -2246,7 +2247,7 @@ protected:
class Create_func_xml_update : public Create_func_arg3
{
public:
- virtual Item *create(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+ virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
static Create_func_xml_update s_singleton;
@@ -2260,7 +2261,7 @@ protected:
class Create_func_y : public Create_func_arg1
{
public:
- virtual Item *create(THD *thd, Item *arg1);
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_y s_singleton;
@@ -2355,7 +2356,7 @@ Create_qfunc::create_func(THD *thd, LEX_STRING name, List<Item> *item_list)
if (thd->lex->copy_db_to(&db.str, &db.length))
return NULL;
- return create(thd, db, name, false, item_list);
+ return create_with_db(thd, db, name, false, item_list);
}
@@ -2472,8 +2473,8 @@ Create_udf_func::create(THD *thd, udf_func *udf, List<Item> *item_list)
Create_sp_func Create_sp_func::s_singleton;
Item*
-Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list)
+Create_sp_func::create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name, List<Item> *item_list)
{
int arg_count= 0;
Item *func= NULL;
@@ -2540,7 +2541,7 @@ Create_func_arg0::create_func(THD *thd, LEX_STRING name, List<Item> *item_list)
return NULL;
}
- return create(thd);
+ return create_builder(thd);
}
@@ -2566,7 +2567,7 @@ Create_func_arg1::create_func(THD *thd, LEX_STRING name, List<Item> *item_list)
return NULL;
}
- return create(thd, param_1);
+ return create_1_arg(thd, param_1);
}
@@ -2594,7 +2595,7 @@ Create_func_arg2::create_func(THD *thd, LEX_STRING name, List<Item> *item_list)
return NULL;
}
- return create(thd, param_1, param_2);
+ return create_2_arg(thd, param_1, param_2);
}
@@ -2624,14 +2625,14 @@ Create_func_arg3::create_func(THD *thd, LEX_STRING name, List<Item> *item_list)
return NULL;
}
- return create(thd, param_1, param_2, param_3);
+ return create_3_arg(thd, param_1, param_2, param_3);
}
Create_func_abs Create_func_abs::s_singleton;
Item*
-Create_func_abs::create(THD *thd, Item *arg1)
+Create_func_abs::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_abs(arg1);
}
@@ -2640,7 +2641,7 @@ Create_func_abs::create(THD *thd, Item *arg1)
Create_func_acos Create_func_acos::s_singleton;
Item*
-Create_func_acos::create(THD *thd, Item *arg1)
+Create_func_acos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_acos(arg1);
}
@@ -2649,7 +2650,7 @@ Create_func_acos::create(THD *thd, Item *arg1)
Create_func_addtime Create_func_addtime::s_singleton;
Item*
-Create_func_addtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_addtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 0);
}
@@ -2658,7 +2659,7 @@ Create_func_addtime::create(THD *thd, Item *arg1, Item *arg2)
Create_func_aes_encrypt Create_func_aes_encrypt::s_singleton;
Item*
-Create_func_aes_encrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_encrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_encrypt(arg1, arg2);
}
@@ -2667,7 +2668,7 @@ Create_func_aes_encrypt::create(THD *thd, Item *arg1, Item *arg2)
Create_func_aes_decrypt Create_func_aes_decrypt::s_singleton;
Item*
-Create_func_aes_decrypt::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_aes_decrypt::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_aes_decrypt(arg1, arg2);
}
@@ -2677,7 +2678,7 @@ Create_func_aes_decrypt::create(THD *thd, Item *arg1, Item *arg2)
Create_func_area Create_func_area::s_singleton;
Item*
-Create_func_area::create(THD *thd, Item *arg1)
+Create_func_area::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_area(arg1);
}
@@ -2688,7 +2689,7 @@ Create_func_area::create(THD *thd, Item *arg1)
Create_func_as_wkb Create_func_as_wkb::s_singleton;
Item*
-Create_func_as_wkb::create(THD *thd, Item *arg1)
+Create_func_as_wkb::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkb(arg1);
}
@@ -2699,7 +2700,7 @@ Create_func_as_wkb::create(THD *thd, Item *arg1)
Create_func_as_wkt Create_func_as_wkt::s_singleton;
Item*
-Create_func_as_wkt::create(THD *thd, Item *arg1)
+Create_func_as_wkt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_as_wkt(arg1);
}
@@ -2709,7 +2710,7 @@ Create_func_as_wkt::create(THD *thd, Item *arg1)
Create_func_asin Create_func_asin::s_singleton;
Item*
-Create_func_asin::create(THD *thd, Item *arg1)
+Create_func_asin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_asin(arg1);
}
@@ -2755,7 +2756,7 @@ Create_func_atan::create_native(THD *thd, LEX_STRING name,
Create_func_benchmark Create_func_benchmark::s_singleton;
Item*
-Create_func_benchmark::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_benchmark::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
return new (thd->mem_root) Item_func_benchmark(arg1, arg2);
@@ -2765,7 +2766,7 @@ Create_func_benchmark::create(THD *thd, Item *arg1, Item *arg2)
Create_func_bin Create_func_bin::s_singleton;
Item*
-Create_func_bin::create(THD *thd, Item *arg1)
+Create_func_bin::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i2= new (thd->mem_root) Item_int((int32) 2,1);
@@ -2776,7 +2777,7 @@ Create_func_bin::create(THD *thd, Item *arg1)
Create_func_bit_count Create_func_bit_count::s_singleton;
Item*
-Create_func_bit_count::create(THD *thd, Item *arg1)
+Create_func_bit_count::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_count(arg1);
}
@@ -2785,7 +2786,7 @@ Create_func_bit_count::create(THD *thd, Item *arg1)
Create_func_bit_length Create_func_bit_length::s_singleton;
Item*
-Create_func_bit_length::create(THD *thd, Item *arg1)
+Create_func_bit_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_bit_length(arg1);
}
@@ -2794,7 +2795,7 @@ Create_func_bit_length::create(THD *thd, Item *arg1)
Create_func_ceiling Create_func_ceiling::s_singleton;
Item*
-Create_func_ceiling::create(THD *thd, Item *arg1)
+Create_func_ceiling::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ceiling(arg1);
}
@@ -2804,7 +2805,7 @@ Create_func_ceiling::create(THD *thd, Item *arg1)
Create_func_centroid Create_func_centroid::s_singleton;
Item*
-Create_func_centroid::create(THD *thd, Item *arg1)
+Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_centroid(arg1);
}
@@ -2814,7 +2815,7 @@ Create_func_centroid::create(THD *thd, Item *arg1)
Create_func_char_length Create_func_char_length::s_singleton;
Item*
-Create_func_char_length::create(THD *thd, Item *arg1)
+Create_func_char_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_char_length(arg1);
}
@@ -2823,7 +2824,7 @@ Create_func_char_length::create(THD *thd, Item *arg1)
Create_func_coercibility Create_func_coercibility::s_singleton;
Item*
-Create_func_coercibility::create(THD *thd, Item *arg1)
+Create_func_coercibility::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_coercibility(arg1);
}
@@ -2875,7 +2876,7 @@ Create_func_concat_ws::create_native(THD *thd, LEX_STRING name,
Create_func_compress Create_func_compress::s_singleton;
Item*
-Create_func_compress::create(THD *thd, Item *arg1)
+Create_func_compress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_compress(arg1);
}
@@ -2884,7 +2885,7 @@ Create_func_compress::create(THD *thd, Item *arg1)
Create_func_connection_id Create_func_connection_id::s_singleton;
Item*
-Create_func_connection_id::create(THD *thd)
+Create_func_connection_id::create_builder(THD *thd)
{
thd->lex->safe_to_cache_query= 0;
return new (thd->mem_root) Item_func_connection_id();
@@ -2895,7 +2896,7 @@ Create_func_connection_id::create(THD *thd)
Create_func_contains Create_func_contains::s_singleton;
Item*
-Create_func_contains::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CONTAINS_FUNC);
@@ -2906,7 +2907,7 @@ Create_func_contains::create(THD *thd, Item *arg1, Item *arg2)
Create_func_conv Create_func_conv::s_singleton;
Item*
-Create_func_conv::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_conv::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_conv(arg1, arg2, arg3);
}
@@ -2915,7 +2916,7 @@ Create_func_conv::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
Create_func_convert_tz Create_func_convert_tz::s_singleton;
Item*
-Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_convert_tz::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_convert_tz(arg1, arg2, arg3);
}
@@ -2924,7 +2925,7 @@ Create_func_convert_tz::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
Create_func_cos Create_func_cos::s_singleton;
Item*
-Create_func_cos::create(THD *thd, Item *arg1)
+Create_func_cos::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_cos(arg1);
}
@@ -2933,7 +2934,7 @@ Create_func_cos::create(THD *thd, Item *arg1)
Create_func_cot Create_func_cot::s_singleton;
Item*
-Create_func_cot::create(THD *thd, Item *arg1)
+Create_func_cot::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "1", 1, 1);
Item *i2= new (thd->mem_root) Item_func_tan(arg1);
@@ -2944,7 +2945,7 @@ Create_func_cot::create(THD *thd, Item *arg1)
Create_func_crc32 Create_func_crc32::s_singleton;
Item*
-Create_func_crc32::create(THD *thd, Item *arg1)
+Create_func_crc32::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_crc32(arg1);
}
@@ -2954,7 +2955,7 @@ Create_func_crc32::create(THD *thd, Item *arg1)
Create_func_crosses Create_func_crosses::s_singleton;
Item*
-Create_func_crosses::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_crosses::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_CROSSES_FUNC);
@@ -2965,7 +2966,7 @@ Create_func_crosses::create(THD *thd, Item *arg1, Item *arg2)
Create_func_date_format Create_func_date_format::s_singleton;
Item*
-Create_func_date_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_date_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 0);
}
@@ -2974,7 +2975,7 @@ Create_func_date_format::create(THD *thd, Item *arg1, Item *arg2)
Create_func_datediff Create_func_datediff::s_singleton;
Item*
-Create_func_datediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_datediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
Item *i1= new (thd->mem_root) Item_func_to_days(arg1);
Item *i2= new (thd->mem_root) Item_func_to_days(arg2);
@@ -2986,7 +2987,7 @@ Create_func_datediff::create(THD *thd, Item *arg1, Item *arg2)
Create_func_dayname Create_func_dayname::s_singleton;
Item*
-Create_func_dayname::create(THD *thd, Item *arg1)
+Create_func_dayname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayname(arg1);
}
@@ -2995,7 +2996,7 @@ Create_func_dayname::create(THD *thd, Item *arg1)
Create_func_dayofmonth Create_func_dayofmonth::s_singleton;
Item*
-Create_func_dayofmonth::create(THD *thd, Item *arg1)
+Create_func_dayofmonth::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofmonth(arg1);
}
@@ -3004,7 +3005,7 @@ Create_func_dayofmonth::create(THD *thd, Item *arg1)
Create_func_dayofweek Create_func_dayofweek::s_singleton;
Item*
-Create_func_dayofweek::create(THD *thd, Item *arg1)
+Create_func_dayofweek::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 1);
}
@@ -3013,7 +3014,7 @@ Create_func_dayofweek::create(THD *thd, Item *arg1)
Create_func_dayofyear Create_func_dayofyear::s_singleton;
Item*
-Create_func_dayofyear::create(THD *thd, Item *arg1)
+Create_func_dayofyear::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dayofyear(arg1);
}
@@ -3022,7 +3023,7 @@ Create_func_dayofyear::create(THD *thd, Item *arg1)
Create_func_decode Create_func_decode::s_singleton;
Item*
-Create_func_decode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_decode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_decode(arg1, arg2);
}
@@ -3031,7 +3032,7 @@ Create_func_decode::create(THD *thd, Item *arg1, Item *arg2)
Create_func_degrees Create_func_degrees::s_singleton;
Item*
-Create_func_degrees::create(THD *thd, Item *arg1)
+Create_func_degrees::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "degrees", arg1,
180/M_PI, 0.0);
@@ -3116,7 +3117,7 @@ Create_func_des_encrypt::create_native(THD *thd, LEX_STRING name,
Create_func_dimension Create_func_dimension::s_singleton;
Item*
-Create_func_dimension::create(THD *thd, Item *arg1)
+Create_func_dimension::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dimension(arg1);
}
@@ -3127,7 +3128,7 @@ Create_func_dimension::create(THD *thd, Item *arg1)
Create_func_disjoint Create_func_disjoint::s_singleton;
Item*
-Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_disjoint::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_DISJOINT_FUNC);
@@ -3159,7 +3160,7 @@ Create_func_elt::create_native(THD *thd, LEX_STRING name,
Create_func_encode Create_func_encode::s_singleton;
Item*
-Create_func_encode::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_encode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_encode(arg1, arg2);
}
@@ -3207,7 +3208,7 @@ Create_func_encrypt::create_native(THD *thd, LEX_STRING name,
Create_func_endpoint Create_func_endpoint::s_singleton;
Item*
-Create_func_endpoint::create(THD *thd, Item *arg1)
+Create_func_endpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_ENDPOINT);
@@ -3219,7 +3220,7 @@ Create_func_endpoint::create(THD *thd, Item *arg1)
Create_func_envelope Create_func_envelope::s_singleton;
Item*
-Create_func_envelope::create(THD *thd, Item *arg1)
+Create_func_envelope::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_envelope(arg1);
}
@@ -3230,7 +3231,7 @@ Create_func_envelope::create(THD *thd, Item *arg1)
Create_func_equals Create_func_equals::s_singleton;
Item*
-Create_func_equals::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_equals::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_EQUALS_FUNC);
@@ -3241,7 +3242,7 @@ Create_func_equals::create(THD *thd, Item *arg1, Item *arg2)
Create_func_exp Create_func_exp::s_singleton;
Item*
-Create_func_exp::create(THD *thd, Item *arg1)
+Create_func_exp::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_exp(arg1);
}
@@ -3304,7 +3305,7 @@ Create_func_export_set::create_native(THD *thd, LEX_STRING name,
Create_func_exteriorring Create_func_exteriorring::s_singleton;
Item*
-Create_func_exteriorring::create(THD *thd, Item *arg1)
+Create_func_exteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_EXTERIORRING);
@@ -3336,7 +3337,7 @@ Create_func_field::create_native(THD *thd, LEX_STRING name,
Create_func_find_in_set Create_func_find_in_set::s_singleton;
Item*
-Create_func_find_in_set::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_find_in_set::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_find_in_set(arg1, arg2);
}
@@ -3345,7 +3346,7 @@ Create_func_find_in_set::create(THD *thd, Item *arg1, Item *arg2)
Create_func_floor Create_func_floor::s_singleton;
Item*
-Create_func_floor::create(THD *thd, Item *arg1)
+Create_func_floor::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_floor(arg1);
}
@@ -3354,7 +3355,7 @@ Create_func_floor::create(THD *thd, Item *arg1)
Create_func_format Create_func_format::s_singleton;
Item*
-Create_func_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_format(arg1, arg2);
}
@@ -3363,7 +3364,7 @@ Create_func_format::create(THD *thd, Item *arg1, Item *arg2)
Create_func_found_rows Create_func_found_rows::s_singleton;
Item*
-Create_func_found_rows::create(THD *thd)
+Create_func_found_rows::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -3374,7 +3375,7 @@ Create_func_found_rows::create(THD *thd)
Create_func_from_days Create_func_from_days::s_singleton;
Item*
-Create_func_from_days::create(THD *thd, Item *arg1)
+Create_func_from_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_from_days(arg1);
}
@@ -3502,7 +3503,7 @@ Create_func_geometry_from_wkb::create_native(THD *thd, LEX_STRING name,
Create_func_geometry_type Create_func_geometry_type::s_singleton;
Item*
-Create_func_geometry_type::create(THD *thd, Item *arg1)
+Create_func_geometry_type::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_geometry_type(arg1);
}
@@ -3513,7 +3514,7 @@ Create_func_geometry_type::create(THD *thd, Item *arg1)
Create_func_geometryn Create_func_geometryn::s_singleton;
Item*
-Create_func_geometryn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_geometryn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_GEOMETRYN);
@@ -3524,7 +3525,7 @@ Create_func_geometryn::create(THD *thd, Item *arg1, Item *arg2)
Create_func_get_lock Create_func_get_lock::s_singleton;
Item*
-Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_get_lock::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3536,7 +3537,7 @@ Create_func_get_lock::create(THD *thd, Item *arg1, Item *arg2)
Create_func_glength Create_func_glength::s_singleton;
Item*
-Create_func_glength::create(THD *thd, Item *arg1)
+Create_func_glength::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_glength(arg1);
}
@@ -3567,7 +3568,7 @@ Create_func_greatest::create_native(THD *thd, LEX_STRING name,
Create_func_hex Create_func_hex::s_singleton;
Item*
-Create_func_hex::create(THD *thd, Item *arg1)
+Create_func_hex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_hex(arg1);
}
@@ -3576,7 +3577,7 @@ Create_func_hex::create(THD *thd, Item *arg1)
Create_func_ifnull Create_func_ifnull::s_singleton;
Item*
-Create_func_ifnull::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_ifnull::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_ifnull(arg1, arg2);
}
@@ -3585,7 +3586,7 @@ Create_func_ifnull::create(THD *thd, Item *arg1, Item *arg2)
Create_func_inet_ntoa Create_func_inet_ntoa::s_singleton;
Item*
-Create_func_inet_ntoa::create(THD *thd, Item *arg1)
+Create_func_inet_ntoa::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_ntoa(arg1);
}
@@ -3594,7 +3595,7 @@ Create_func_inet_ntoa::create(THD *thd, Item *arg1)
Create_func_inet_aton Create_func_inet_aton::s_singleton;
Item*
-Create_func_inet_aton::create(THD *thd, Item *arg1)
+Create_func_inet_aton::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_inet_aton(arg1);
}
@@ -3603,7 +3604,7 @@ Create_func_inet_aton::create(THD *thd, Item *arg1)
Create_func_instr Create_func_instr::s_singleton;
Item*
-Create_func_instr::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_instr::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_locate(arg1, arg2);
}
@@ -3613,7 +3614,7 @@ Create_func_instr::create(THD *thd, Item *arg1, Item *arg2)
Create_func_interiorringn Create_func_interiorringn::s_singleton;
Item*
-Create_func_interiorringn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_interiorringn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_INTERIORRINGN);
@@ -3625,7 +3626,7 @@ Create_func_interiorringn::create(THD *thd, Item *arg1, Item *arg2)
Create_func_intersects Create_func_intersects::s_singleton;
Item*
-Create_func_intersects::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_intersects::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_INTERSECTS_FUNC);
@@ -3636,7 +3637,7 @@ Create_func_intersects::create(THD *thd, Item *arg1, Item *arg2)
Create_func_is_free_lock Create_func_is_free_lock::s_singleton;
Item*
-Create_func_is_free_lock::create(THD *thd, Item *arg1)
+Create_func_is_free_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3647,7 +3648,7 @@ Create_func_is_free_lock::create(THD *thd, Item *arg1)
Create_func_is_used_lock Create_func_is_used_lock::s_singleton;
Item*
-Create_func_is_used_lock::create(THD *thd, Item *arg1)
+Create_func_is_used_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3659,7 +3660,7 @@ Create_func_is_used_lock::create(THD *thd, Item *arg1)
Create_func_isclosed Create_func_isclosed::s_singleton;
Item*
-Create_func_isclosed::create(THD *thd, Item *arg1)
+Create_func_isclosed::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isclosed(arg1);
}
@@ -3670,7 +3671,7 @@ Create_func_isclosed::create(THD *thd, Item *arg1)
Create_func_isempty Create_func_isempty::s_singleton;
Item*
-Create_func_isempty::create(THD *thd, Item *arg1)
+Create_func_isempty::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isempty(arg1);
}
@@ -3680,7 +3681,7 @@ Create_func_isempty::create(THD *thd, Item *arg1)
Create_func_isnull Create_func_isnull::s_singleton;
Item*
-Create_func_isnull::create(THD *thd, Item *arg1)
+Create_func_isnull::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_isnull(arg1);
}
@@ -3690,7 +3691,7 @@ Create_func_isnull::create(THD *thd, Item *arg1)
Create_func_issimple Create_func_issimple::s_singleton;
Item*
-Create_func_issimple::create(THD *thd, Item *arg1)
+Create_func_issimple::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_issimple(arg1);
}
@@ -3700,7 +3701,7 @@ Create_func_issimple::create(THD *thd, Item *arg1)
Create_func_last_day Create_func_last_day::s_singleton;
Item*
-Create_func_last_day::create(THD *thd, Item *arg1)
+Create_func_last_day::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_last_day(arg1);
}
@@ -3746,7 +3747,7 @@ Create_func_last_insert_id::create_native(THD *thd, LEX_STRING name,
Create_func_lcase Create_func_lcase::s_singleton;
Item*
-Create_func_lcase::create(THD *thd, Item *arg1)
+Create_func_lcase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_lcase(arg1);
}
@@ -3776,7 +3777,7 @@ Create_func_least::create_native(THD *thd, LEX_STRING name,
Create_func_length Create_func_length::s_singleton;
Item*
-Create_func_length::create(THD *thd, Item *arg1)
+Create_func_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_length(arg1);
}
@@ -3785,7 +3786,7 @@ Create_func_length::create(THD *thd, Item *arg1)
Create_func_ln Create_func_ln::s_singleton;
Item*
-Create_func_ln::create(THD *thd, Item *arg1)
+Create_func_ln::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ln(arg1);
}
@@ -3794,7 +3795,7 @@ Create_func_ln::create(THD *thd, Item *arg1)
Create_func_load_file Create_func_load_file::s_singleton;
Item*
-Create_func_load_file::create(THD *thd, Item *arg1)
+Create_func_load_file::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -3883,7 +3884,7 @@ Create_func_log::create_native(THD *thd, LEX_STRING name,
Create_func_log10 Create_func_log10::s_singleton;
Item*
-Create_func_log10::create(THD *thd, Item *arg1)
+Create_func_log10::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log10(arg1);
}
@@ -3892,7 +3893,7 @@ Create_func_log10::create(THD *thd, Item *arg1)
Create_func_log2 Create_func_log2::s_singleton;
Item*
-Create_func_log2::create(THD *thd, Item *arg1)
+Create_func_log2::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_log2(arg1);
}
@@ -3901,7 +3902,7 @@ Create_func_log2::create(THD *thd, Item *arg1)
Create_func_lpad Create_func_lpad::s_singleton;
Item*
-Create_func_lpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_lpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_lpad(arg1, arg2, arg3);
}
@@ -3910,7 +3911,7 @@ Create_func_lpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
Create_func_ltrim Create_func_ltrim::s_singleton;
Item*
-Create_func_ltrim::create(THD *thd, Item *arg1)
+Create_func_ltrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ltrim(arg1);
}
@@ -3919,7 +3920,7 @@ Create_func_ltrim::create(THD *thd, Item *arg1)
Create_func_makedate Create_func_makedate::s_singleton;
Item*
-Create_func_makedate::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_makedate::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_makedate(arg1, arg2);
}
@@ -3928,7 +3929,7 @@ Create_func_makedate::create(THD *thd, Item *arg1, Item *arg2)
Create_func_maketime Create_func_maketime::s_singleton;
Item*
-Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_maketime::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_maketime(arg1, arg2, arg3);
}
@@ -4003,7 +4004,7 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name,
Create_func_md5 Create_func_md5::s_singleton;
Item*
-Create_func_md5::create(THD *thd, Item *arg1)
+Create_func_md5::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_md5(arg1);
}
@@ -4012,7 +4013,7 @@ Create_func_md5::create(THD *thd, Item *arg1)
Create_func_monthname Create_func_monthname::s_singleton;
Item*
-Create_func_monthname::create(THD *thd, Item *arg1)
+Create_func_monthname::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_monthname(arg1);
}
@@ -4021,7 +4022,7 @@ Create_func_monthname::create(THD *thd, Item *arg1)
Create_func_name_const Create_func_name_const::s_singleton;
Item*
-Create_func_name_const::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_name_const::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_name_const(arg1, arg2);
}
@@ -4030,7 +4031,7 @@ Create_func_name_const::create(THD *thd, Item *arg1, Item *arg2)
Create_func_nullif Create_func_nullif::s_singleton;
Item*
-Create_func_nullif::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_nullif::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_nullif(arg1, arg2);
}
@@ -4040,7 +4041,7 @@ Create_func_nullif::create(THD *thd, Item *arg1, Item *arg2)
Create_func_numgeometries Create_func_numgeometries::s_singleton;
Item*
-Create_func_numgeometries::create(THD *thd, Item *arg1)
+Create_func_numgeometries::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numgeometries(arg1);
}
@@ -4051,7 +4052,7 @@ Create_func_numgeometries::create(THD *thd, Item *arg1)
Create_func_numinteriorring Create_func_numinteriorring::s_singleton;
Item*
-Create_func_numinteriorring::create(THD *thd, Item *arg1)
+Create_func_numinteriorring::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numinteriorring(arg1);
}
@@ -4062,7 +4063,7 @@ Create_func_numinteriorring::create(THD *thd, Item *arg1)
Create_func_numpoints Create_func_numpoints::s_singleton;
Item*
-Create_func_numpoints::create(THD *thd, Item *arg1)
+Create_func_numpoints::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_numpoints(arg1);
}
@@ -4072,7 +4073,7 @@ Create_func_numpoints::create(THD *thd, Item *arg1)
Create_func_oct Create_func_oct::s_singleton;
Item*
-Create_func_oct::create(THD *thd, Item *arg1)
+Create_func_oct::create_1_arg(THD *thd, Item *arg1)
{
Item *i10= new (thd->mem_root) Item_int((int32) 10,2);
Item *i8= new (thd->mem_root) Item_int((int32) 8,1);
@@ -4083,7 +4084,7 @@ Create_func_oct::create(THD *thd, Item *arg1)
Create_func_ord Create_func_ord::s_singleton;
Item*
-Create_func_ord::create(THD *thd, Item *arg1)
+Create_func_ord::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ord(arg1);
}
@@ -4093,7 +4094,7 @@ Create_func_ord::create(THD *thd, Item *arg1)
Create_func_overlaps Create_func_overlaps::s_singleton;
Item*
-Create_func_overlaps::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_overlaps::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_OVERLAPS_FUNC);
@@ -4104,7 +4105,7 @@ Create_func_overlaps::create(THD *thd, Item *arg1, Item *arg2)
Create_func_period_add Create_func_period_add::s_singleton;
Item*
-Create_func_period_add::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_add::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_add(arg1, arg2);
}
@@ -4113,7 +4114,7 @@ Create_func_period_add::create(THD *thd, Item *arg1, Item *arg2)
Create_func_period_diff Create_func_period_diff::s_singleton;
Item*
-Create_func_period_diff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_period_diff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_period_diff(arg1, arg2);
}
@@ -4122,7 +4123,7 @@ Create_func_period_diff::create(THD *thd, Item *arg1, Item *arg2)
Create_func_pi Create_func_pi::s_singleton;
Item*
-Create_func_pi::create(THD *thd)
+Create_func_pi::create_builder(THD *thd)
{
return new (thd->mem_root) Item_static_float_func("pi()", M_PI, 6, 8);
}
@@ -4132,7 +4133,7 @@ Create_func_pi::create(THD *thd)
Create_func_pointn Create_func_pointn::s_singleton;
Item*
-Create_func_pointn::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pointn::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_decomp_n(arg1, arg2,
Item_func::SP_POINTN);
@@ -4143,7 +4144,7 @@ Create_func_pointn::create(THD *thd, Item *arg1, Item *arg2)
Create_func_pow Create_func_pow::s_singleton;
Item*
-Create_func_pow::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_pow::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_pow(arg1, arg2);
}
@@ -4152,7 +4153,7 @@ Create_func_pow::create(THD *thd, Item *arg1, Item *arg2)
Create_func_quote Create_func_quote::s_singleton;
Item*
-Create_func_quote::create(THD *thd, Item *arg1)
+Create_func_quote::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_quote(arg1);
}
@@ -4161,7 +4162,7 @@ Create_func_quote::create(THD *thd, Item *arg1)
Create_func_radians Create_func_radians::s_singleton;
Item*
-Create_func_radians::create(THD *thd, Item *arg1)
+Create_func_radians::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_units((char*) "radians", arg1,
M_PI/180, 0.0);
@@ -4187,8 +4188,11 @@ Create_func_rand::create_native(THD *thd, LEX_STRING name,
into a table, the order in which the rows are modified may differ
between master and slave, because the order is undefined. Hence,
the statement is unsafe to log in statement format.
+
+ For normal INSERT's this is howevever safe
*/
- thd->lex->set_stmt_unsafe();
+ if (thd->lex->sql_command != SQLCOM_INSERT)
+ thd->lex->set_stmt_unsafe();
switch (arg_count) {
case 0:
@@ -4218,7 +4222,7 @@ Create_func_rand::create_native(THD *thd, LEX_STRING name,
Create_func_release_lock Create_func_release_lock::s_singleton;
Item*
-Create_func_release_lock::create(THD *thd, Item *arg1)
+Create_func_release_lock::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4229,7 +4233,7 @@ Create_func_release_lock::create(THD *thd, Item *arg1)
Create_func_reverse Create_func_reverse::s_singleton;
Item*
-Create_func_reverse::create(THD *thd, Item *arg1)
+Create_func_reverse::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_reverse(arg1);
}
@@ -4276,7 +4280,7 @@ Create_func_round::create_native(THD *thd, LEX_STRING name,
Create_func_row_count Create_func_row_count::s_singleton;
Item*
-Create_func_row_count::create(THD *thd)
+Create_func_row_count::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4287,7 +4291,7 @@ Create_func_row_count::create(THD *thd)
Create_func_rpad Create_func_rpad::s_singleton;
Item*
-Create_func_rpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_rpad::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_rpad(arg1, arg2, arg3);
}
@@ -4296,7 +4300,7 @@ Create_func_rpad::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
Create_func_rtrim Create_func_rtrim::s_singleton;
Item*
-Create_func_rtrim::create(THD *thd, Item *arg1)
+Create_func_rtrim::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_rtrim(arg1);
}
@@ -4305,7 +4309,7 @@ Create_func_rtrim::create(THD *thd, Item *arg1)
Create_func_sec_to_time Create_func_sec_to_time::s_singleton;
Item*
-Create_func_sec_to_time::create(THD *thd, Item *arg1)
+Create_func_sec_to_time::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sec_to_time(arg1);
}
@@ -4314,7 +4318,7 @@ Create_func_sec_to_time::create(THD *thd, Item *arg1)
Create_func_sha Create_func_sha::s_singleton;
Item*
-Create_func_sha::create(THD *thd, Item *arg1)
+Create_func_sha::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sha(arg1);
}
@@ -4323,7 +4327,7 @@ Create_func_sha::create(THD *thd, Item *arg1)
Create_func_sign Create_func_sign::s_singleton;
Item*
-Create_func_sign::create(THD *thd, Item *arg1)
+Create_func_sign::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sign(arg1);
}
@@ -4332,7 +4336,7 @@ Create_func_sign::create(THD *thd, Item *arg1)
Create_func_sin Create_func_sin::s_singleton;
Item*
-Create_func_sin::create(THD *thd, Item *arg1)
+Create_func_sin::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sin(arg1);
}
@@ -4341,7 +4345,7 @@ Create_func_sin::create(THD *thd, Item *arg1)
Create_func_sleep Create_func_sleep::s_singleton;
Item*
-Create_func_sleep::create(THD *thd, Item *arg1)
+Create_func_sleep::create_1_arg(THD *thd, Item *arg1)
{
thd->lex->set_stmt_unsafe();
thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
@@ -4352,7 +4356,7 @@ Create_func_sleep::create(THD *thd, Item *arg1)
Create_func_soundex Create_func_soundex::s_singleton;
Item*
-Create_func_soundex::create(THD *thd, Item *arg1)
+Create_func_soundex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_soundex(arg1);
}
@@ -4361,7 +4365,7 @@ Create_func_soundex::create(THD *thd, Item *arg1)
Create_func_space Create_func_space::s_singleton;
Item*
-Create_func_space::create(THD *thd, Item *arg1)
+Create_func_space::create_1_arg(THD *thd, Item *arg1)
{
/**
TODO: Fix Bug#23637
@@ -4389,7 +4393,7 @@ Create_func_space::create(THD *thd, Item *arg1)
Create_func_sqrt Create_func_sqrt::s_singleton;
Item*
-Create_func_sqrt::create(THD *thd, Item *arg1)
+Create_func_sqrt::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_sqrt(arg1);
}
@@ -4399,7 +4403,7 @@ Create_func_sqrt::create(THD *thd, Item *arg1)
Create_func_srid Create_func_srid::s_singleton;
Item*
-Create_func_srid::create(THD *thd, Item *arg1)
+Create_func_srid::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_srid(arg1);
}
@@ -4410,7 +4414,7 @@ Create_func_srid::create(THD *thd, Item *arg1)
Create_func_startpoint Create_func_startpoint::s_singleton;
Item*
-Create_func_startpoint::create(THD *thd, Item *arg1)
+Create_func_startpoint::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_spatial_decomp(arg1,
Item_func::SP_STARTPOINT);
@@ -4421,7 +4425,7 @@ Create_func_startpoint::create(THD *thd, Item *arg1)
Create_func_str_to_date Create_func_str_to_date::s_singleton;
Item*
-Create_func_str_to_date::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_str_to_date::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_str_to_date(arg1, arg2);
}
@@ -4430,7 +4434,7 @@ Create_func_str_to_date::create(THD *thd, Item *arg1, Item *arg2)
Create_func_strcmp Create_func_strcmp::s_singleton;
Item*
-Create_func_strcmp::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_strcmp::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_strcmp(arg1, arg2);
}
@@ -4439,7 +4443,7 @@ Create_func_strcmp::create(THD *thd, Item *arg1, Item *arg2)
Create_func_substr_index Create_func_substr_index::s_singleton;
Item*
-Create_func_substr_index::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_substr_index::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_substr_index(arg1, arg2, arg3);
}
@@ -4448,7 +4452,7 @@ Create_func_substr_index::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
Create_func_subtime Create_func_subtime::s_singleton;
Item*
-Create_func_subtime::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_subtime::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_add_time(arg1, arg2, 0, 1);
}
@@ -4457,7 +4461,7 @@ Create_func_subtime::create(THD *thd, Item *arg1, Item *arg2)
Create_func_tan Create_func_tan::s_singleton;
Item*
-Create_func_tan::create(THD *thd, Item *arg1)
+Create_func_tan::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_tan(arg1);
}
@@ -4466,7 +4470,7 @@ Create_func_tan::create(THD *thd, Item *arg1)
Create_func_time_format Create_func_time_format::s_singleton;
Item*
-Create_func_time_format::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_time_format::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_date_format(arg1, arg2, 1);
}
@@ -4475,7 +4479,7 @@ Create_func_time_format::create(THD *thd, Item *arg1, Item *arg2)
Create_func_time_to_sec Create_func_time_to_sec::s_singleton;
Item*
-Create_func_time_to_sec::create(THD *thd, Item *arg1)
+Create_func_time_to_sec::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_time_to_sec(arg1);
}
@@ -4484,7 +4488,7 @@ Create_func_time_to_sec::create(THD *thd, Item *arg1)
Create_func_timediff Create_func_timediff::s_singleton;
Item*
-Create_func_timediff::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_timediff::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_timediff(arg1, arg2);
}
@@ -4493,7 +4497,7 @@ Create_func_timediff::create(THD *thd, Item *arg1, Item *arg2)
Create_func_to_days Create_func_to_days::s_singleton;
Item*
-Create_func_to_days::create(THD *thd, Item *arg1)
+Create_func_to_days::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_to_days(arg1);
}
@@ -4503,7 +4507,7 @@ Create_func_to_days::create(THD *thd, Item *arg1)
Create_func_touches Create_func_touches::s_singleton;
Item*
-Create_func_touches::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_touches::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_TOUCHES_FUNC);
@@ -4514,7 +4518,7 @@ Create_func_touches::create(THD *thd, Item *arg1, Item *arg2)
Create_func_ucase Create_func_ucase::s_singleton;
Item*
-Create_func_ucase::create(THD *thd, Item *arg1)
+Create_func_ucase::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_ucase(arg1);
}
@@ -4523,7 +4527,7 @@ Create_func_ucase::create(THD *thd, Item *arg1)
Create_func_uncompress Create_func_uncompress::s_singleton;
Item*
-Create_func_uncompress::create(THD *thd, Item *arg1)
+Create_func_uncompress::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompress(arg1);
}
@@ -4532,7 +4536,7 @@ Create_func_uncompress::create(THD *thd, Item *arg1)
Create_func_uncompressed_length Create_func_uncompressed_length::s_singleton;
Item*
-Create_func_uncompressed_length::create(THD *thd, Item *arg1)
+Create_func_uncompressed_length::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_uncompressed_length(arg1);
}
@@ -4541,7 +4545,7 @@ Create_func_uncompressed_length::create(THD *thd, Item *arg1)
Create_func_unhex Create_func_unhex::s_singleton;
Item*
-Create_func_unhex::create(THD *thd, Item *arg1)
+Create_func_unhex::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_unhex(arg1);
}
@@ -4586,7 +4590,7 @@ Create_func_unix_timestamp::create_native(THD *thd, LEX_STRING name,
Create_func_uuid Create_func_uuid::s_singleton;
Item*
-Create_func_uuid::create(THD *thd)
+Create_func_uuid::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4597,7 +4601,7 @@ Create_func_uuid::create(THD *thd)
Create_func_uuid_short Create_func_uuid_short::s_singleton;
Item*
-Create_func_uuid_short::create(THD *thd)
+Create_func_uuid_short::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
thd->lex->safe_to_cache_query= 0;
@@ -4608,7 +4612,7 @@ Create_func_uuid_short::create(THD *thd)
Create_func_version Create_func_version::s_singleton;
Item*
-Create_func_version::create(THD *thd)
+Create_func_version::create_builder(THD *thd)
{
thd->lex->set_stmt_unsafe();
return new (thd->mem_root) Item_static_string_func("version()",
@@ -4622,7 +4626,7 @@ Create_func_version::create(THD *thd)
Create_func_weekday Create_func_weekday::s_singleton;
Item*
-Create_func_weekday::create(THD *thd, Item *arg1)
+Create_func_weekday::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_weekday(arg1, 0);
}
@@ -4631,7 +4635,7 @@ Create_func_weekday::create(THD *thd, Item *arg1)
Create_func_weekofyear Create_func_weekofyear::s_singleton;
Item*
-Create_func_weekofyear::create(THD *thd, Item *arg1)
+Create_func_weekofyear::create_1_arg(THD *thd, Item *arg1)
{
Item *i1= new (thd->mem_root) Item_int((char*) "0", 3, 1);
return new (thd->mem_root) Item_func_week(arg1, i1);
@@ -4642,7 +4646,7 @@ Create_func_weekofyear::create(THD *thd, Item *arg1)
Create_func_within Create_func_within::s_singleton;
Item*
-Create_func_within::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_within::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_spatial_rel(arg1, arg2,
Item_func::SP_WITHIN_FUNC);
@@ -4654,7 +4658,7 @@ Create_func_within::create(THD *thd, Item *arg1, Item *arg2)
Create_func_x Create_func_x::s_singleton;
Item*
-Create_func_x::create(THD *thd, Item *arg1)
+Create_func_x::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_x(arg1);
}
@@ -4664,7 +4668,7 @@ Create_func_x::create(THD *thd, Item *arg1)
Create_func_xml_extractvalue Create_func_xml_extractvalue::s_singleton;
Item*
-Create_func_xml_extractvalue::create(THD *thd, Item *arg1, Item *arg2)
+Create_func_xml_extractvalue::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_xml_extractvalue(arg1, arg2);
}
@@ -4673,7 +4677,7 @@ Create_func_xml_extractvalue::create(THD *thd, Item *arg1, Item *arg2)
Create_func_xml_update Create_func_xml_update::s_singleton;
Item*
-Create_func_xml_update::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
+Create_func_xml_update::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
{
return new (thd->mem_root) Item_func_xml_update(arg1, arg2, arg3);
}
@@ -4683,7 +4687,7 @@ Create_func_xml_update::create(THD *thd, Item *arg1, Item *arg2, Item *arg3)
Create_func_y Create_func_y::s_singleton;
Item*
-Create_func_y::create(THD *thd, Item *arg1)
+Create_func_y::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_y(arg1);
}
diff --git a/sql/item_create.h b/sql/item_create.h
index 708e768eda6..ebe6c4942ff 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -92,8 +93,9 @@ public:
@param item_list The list of arguments to the function, can be NULL
@return An item representing the parsed function call
*/
- virtual Item* create(THD *thd, LEX_STRING db, LEX_STRING name,
- bool use_explicit_name, List<Item> *item_list) = 0;
+ virtual Item *create_with_db(THD *thd, LEX_STRING db, LEX_STRING name,
+ bool use_explicit_name,
+ List<Item> *item_list) = 0;
protected:
/** Constructor. */
diff --git a/sql/item_func.cc b/sql/item_func.cc
index feb87fe5fd7..2d1278e7ac3 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -208,6 +209,21 @@ Item_func::fix_fields(THD *thd, Item **ref)
return FALSE;
}
+void
+Item_func::quick_fix_field()
+{
+ Item **arg,**arg_end;
+ if (arg_count)
+ {
+ for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
+ {
+ if (!(*arg)->fixed)
+ (*arg)->quick_fix_field();
+ }
+ }
+ fixed= 1;
+}
+
bool Item_func::walk(Item_processor processor, bool walk_subquery,
uchar *argument)
@@ -455,7 +471,6 @@ Field *Item_func::tmp_table_field(TABLE *table)
break;
case STRING_RESULT:
return make_string_field(table);
- break;
case DECIMAL_RESULT:
field= Field_new_decimal::create_from_item(this);
break;
@@ -2136,7 +2151,7 @@ void Item_func_rand::seed_random(Item *arg)
args[0] is a constant.
*/
uint32 tmp= (uint32) arg->val_int();
- randominit(rand, (uint32) (tmp*0x10001L+55555555L),
+ my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L),
(uint32) (tmp*0x10000001L));
}
@@ -2156,7 +2171,7 @@ bool Item_func_rand::fix_fields(THD *thd,Item **ref)
No need to send a Rand log event if seed was given eg: RAND(seed),
as it will be replicated in the query as such.
*/
- if (!rand && !(rand= (struct rand_struct*)
+ if (!rand && !(rand= (struct my_rnd_struct*)
thd->stmt_arena->alloc(sizeof(*rand))))
return TRUE;
}
@@ -2753,8 +2768,7 @@ longlong Item_func_find_in_set::val_int()
}
null_value=0;
- int diff;
- if ((diff=buffer->length() - find->length()) >= 0)
+ if ((int) (buffer->length() - find->length()) >= 0)
{
my_wc_t wc= 0;
CHARSET_INFO *cs= cmp_collation.collation;
@@ -3989,7 +4003,8 @@ double user_var_entry::val_real(my_bool *null_value)
case STRING_RESULT:
return my_atof(value); // This is null terminated
case ROW_RESULT:
- DBUG_ASSERT(1); // Impossible
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // Impossible
break;
}
return 0.0; // Impossible
@@ -4020,7 +4035,8 @@ longlong user_var_entry::val_int(my_bool *null_value) const
return my_strtoll10(value, (char**) 0, &error);// String is null terminated
}
case ROW_RESULT:
- DBUG_ASSERT(1); // Impossible
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // Impossible
break;
}
return LL(0); // Impossible
@@ -4051,8 +4067,10 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
case STRING_RESULT:
if (str->copy(value, length, collation.collation))
str= 0; // EOM error
+ break;
case ROW_RESULT:
- DBUG_ASSERT(1); // Impossible
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // Impossible
break;
}
return(str);
@@ -4079,7 +4097,8 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);
break;
case ROW_RESULT:
- DBUG_ASSERT(1); // Impossible
+ case IMPOSSIBLE_RESULT:
+ DBUG_ASSERT(0); // Impossible
break;
}
return(val);
@@ -4428,7 +4447,7 @@ int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
if (result_type() == STRING_RESULT ||
(result_type() == REAL_RESULT &&
- field->result_type() == STRING_RESULT))
+ field->result_type() == STRING_RESULT))
{
String *result;
CHARSET_INFO *cs= collation.collation;
@@ -6152,8 +6171,8 @@ void uuid_short_init()
longlong Item_func_uuid_short::val_int()
{
ulonglong val;
- pthread_mutex_lock(&LOCK_uuid_generator);
+ pthread_mutex_lock(&LOCK_short_uuid_generator);
val= uuid_value++;
- pthread_mutex_unlock(&LOCK_uuid_generator);
+ pthread_mutex_unlock(&LOCK_short_uuid_generator);
return (longlong) val;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index de1338b4081..ea9ed39159a 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -118,6 +119,7 @@ public:
// Constructor used for Item_cond_and/or (see Item comment)
Item_func(THD *thd, Item_func *item);
bool fix_fields(THD *, Item **ref);
+ void quick_fix_field();
table_map used_tables() const;
table_map not_null_tables() const;
void update_used_tables();
@@ -258,6 +260,21 @@ public:
{
return functype() == *(Functype *) arg;
}
+
+ void no_rows_in_result()
+ {
+ bool_func_call_args info;
+ info.original_func_item= this;
+ info.bool_function= &Item::no_rows_in_result;
+ walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info);
+ }
+ void restore_to_before_no_rows_in_result()
+ {
+ bool_func_call_args info;
+ info.original_func_item= this;
+ info.bool_function= &Item::restore_to_before_no_rows_in_result;
+ walk(&Item::call_bool_func_processor, FALSE, (uchar*) &info);
+ }
};
@@ -754,7 +771,7 @@ public:
class Item_func_rand :public Item_real_func
{
- struct rand_struct *rand;
+ struct my_rnd_struct *rand;
bool first_eval; // TRUE if val_real() is called 1st time
public:
Item_func_rand(Item *a) :Item_real_func(a), rand(0), first_eval(TRUE) {}
@@ -1553,7 +1570,6 @@ public:
/* for fulltext search */
-#include <ft_global.h>
class Item_func_match :public Item_real_func
{
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 0a6e8d03a46..0bcd933e52b 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2003, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 9bf9d78a3c2..4040dbff7c6 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_row.h b/sql/item_row.h
index ebf2c2151a9..9838e360e5b 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index ed14f7f01e9..60d5d2f1341 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -120,7 +120,6 @@ String *Item_func_md5::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String * sptr= args[0]->val_str(str);
- str->set_charset(&my_charset_bin);
if (sptr)
{
uchar digest[16];
@@ -133,6 +132,7 @@ String *Item_func_md5::val_str(String *str)
return 0;
}
array_to_hex((char *) str->ptr(), (const char*) digest, 16);
+ str->set_charset(&my_charset_bin);
str->length((uint) 32);
return str;
}
@@ -159,7 +159,6 @@ String *Item_func_sha::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String * sptr= args[0]->val_str(str);
- str->set_charset(&my_charset_bin);
if (sptr) /* If we got value different from NULL */
{
SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
@@ -169,11 +168,13 @@ String *Item_func_sha::val_str(String *str)
/* No need to check error as the only case would be too long message */
mysql_sha1_input(&context,
(const uchar *) sptr->ptr(), sptr->length());
+
/* Ensure that memory is free and we got result */
if (!( str->alloc(SHA1_HASH_SIZE*2) ||
(mysql_sha1_result(&context,digest))))
{
array_to_hex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE);
+ str->set_charset(&my_charset_bin);
str->length((uint) SHA1_HASH_SIZE*2);
null_value=0;
return str;
@@ -511,7 +512,8 @@ String *Item_func_des_encrypt::val_str(String *str)
tail= 8 - (res_length % 8); // 1..8 marking extra length
res_length+=tail;
- tmp_arg.realloc(res_length);
+ if (tmp_arg.realloc(res_length))
+ goto error;
tmp_arg.length(0);
tmp_arg.append(res->ptr(), res->length());
code= ER_OUT_OF_RESOURCES;
@@ -646,7 +648,7 @@ String *Item_func_concat_ws::val_str(String *str)
use_as_buff= &tmp_value;
str->length(0); // QQ; Should be removed
- res=str;
+ res=str; // If 0 arg_count
// Skip until non-null argument is found.
// If not, return the empty string
@@ -3375,7 +3377,7 @@ longlong Item_func_crc32::val_int()
String *Item_func_compress::val_str(String *str)
{
int err= Z_OK, code;
- ulong new_size;
+ size_t new_size;
String *res;
Byte *body;
char *tmp, *last_char;
@@ -3411,8 +3413,8 @@ String *Item_func_compress::val_str(String *str)
body= ((Byte*)buffer.ptr()) + 4;
// As far as we have checked res->is_empty() we can use ptr()
- if ((err= compress(body, &new_size,
- (const Bytef*)res->ptr(), res->length())) != Z_OK)
+ if ((err= my_compress_buffer(body, &new_size, (const uchar *)res->ptr(),
+ res->length())) != Z_OK)
{
code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR;
push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code));
@@ -3490,156 +3492,17 @@ err:
}
#endif
-/*
- UUID, as in
- DCE 1.1: Remote Procedure Call,
- Open Group Technical Standard Document Number C706, October 1997,
- (supersedes C309 DCE: Remote Procedure Call 8/1994,
- which was basis for ISO/IEC 11578:1996 specification)
-*/
-
-static struct rand_struct uuid_rand;
-static uint nanoseq;
-static ulonglong uuid_time=0;
-static char clock_seq_and_node_str[]="-0000-000000000000";
-
-/**
- number of 100-nanosecond intervals between
- 1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
-*/
-#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * \
- 1000 * 1000 * 10)
-
-#define UUID_VERSION 0x1000
-#define UUID_VARIANT 0x8000
-
-static void tohex(char *to, uint from, uint len)
-{
- to+= len;
- while (len--)
- {
- *--to= _dig_vec_lower[from & 15];
- from >>= 4;
- }
-}
-
-static void set_clock_seq_str()
-{
- uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
- tohex(clock_seq_and_node_str+1, clock_seq, 4);
- nanoseq= 0;
-}
String *Item_func_uuid::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
- char *s;
- THD *thd= current_thd;
+ uchar guid[MY_UUID_SIZE];
- pthread_mutex_lock(&LOCK_uuid_generator);
- if (! uuid_time) /* first UUID() call. initializing data */
- {
- ulong tmp=sql_rnd_with_mutex();
- uchar mac[6];
- int i;
- if (my_gethwaddr(mac))
- {
- /* purecov: begin inspected */
- /*
- generating random "hardware addr"
- and because specs explicitly specify that it should NOT correlate
- with a clock_seq value (initialized random below), we use a separate
- randominit() here
- */
- randominit(&uuid_rand, tmp + (ulong) thd, tmp + (ulong)global_query_id);
- for (i=0; i < (int)sizeof(mac); i++)
- mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
- /* purecov: end */
- }
- s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
- for (i=sizeof(mac)-1 ; i>=0 ; i--)
- {
- *--s=_dig_vec_lower[mac[i] & 15];
- *--s=_dig_vec_lower[mac[i] >> 4];
- }
- randominit(&uuid_rand, tmp + (ulong) server_start_time,
- tmp + (ulong) thd->status_var.bytes_sent);
- set_clock_seq_str();
- }
-
- ulonglong tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq;
-
- if (likely(tv > uuid_time))
- {
- /*
- Current time is ahead of last timestamp, as it should be.
- If we "borrowed time", give it back, just as long as we
- stay ahead of the previous timestamp.
- */
- if (nanoseq)
- {
- DBUG_ASSERT((tv > uuid_time) && (nanoseq > 0));
- /*
- -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
- */
- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
- tv-= delta;
- nanoseq-= delta;
- }
- }
- else
- {
- if (unlikely(tv == uuid_time))
- {
- /*
- For low-res system clocks. If several requests for UUIDs
- end up on the same tick, we add a nano-second to make them
- different.
- ( current_timestamp + nanoseq * calls_in_this_period )
- may end up > next_timestamp; this is OK. Nonetheless, we'll
- try to unwind nanoseq when we get a chance to.
- If nanoseq overflows, we'll start over with a new numberspace
- (so the if() below is needed so we can avoid the ++tv and thus
- match the follow-up if() if nanoseq overflows!).
- */
- if (likely(++nanoseq))
- ++tv;
- }
-
- if (unlikely(tv <= uuid_time))
- {
- /*
- If the admin changes the system clock (or due to Daylight
- Saving Time), the system clock may be turned *back* so we
- go through a period once more for which we already gave out
- UUIDs. To avoid duplicate UUIDs despite potentially identical
- times, we make a new random component.
- We also come here if the nanoseq "borrowing" overflows.
- In either case, we throw away any nanoseq borrowing since it's
- irrelevant in the new numberspace.
- */
- set_clock_seq_str();
- tv= my_getsystime() + UUID_TIME_OFFSET;
- nanoseq= 0;
- DBUG_PRINT("uuid",("making new numberspace"));
- }
- }
-
- uuid_time=tv;
- pthread_mutex_unlock(&LOCK_uuid_generator);
-
- uint32 time_low= (uint32) (tv & 0xFFFFFFFF);
- uint16 time_mid= (uint16) ((tv >> 32) & 0xFFFF);
- uint16 time_hi_and_version= (uint16) ((tv >> 48) | UUID_VERSION);
-
- str->realloc(UUID_LENGTH+1);
- str->length(UUID_LENGTH);
+ str->realloc(MY_UUID_STRING_LENGTH+1);
+ str->length(MY_UUID_STRING_LENGTH);
str->set_charset(system_charset_info);
- s=(char *) str->ptr();
- s[8]=s[13]='-';
- tohex(s, time_low, 8);
- tohex(s+9, time_mid, 4);
- tohex(s+14, time_hi_and_version, 4);
- strmov(s+18, clock_seq_and_node_str);
+ my_uuid(guid);
+ my_uuid2str(guid, (char *)str->ptr());
+
return str;
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index b5aa804e17b..e8fa041af4f 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -30,8 +30,15 @@ protected:
character set. No memory is allocated.
@retval A pointer to the str_value member.
*/
- String *make_empty_result() {
- str_value.set("", 0, collation.collation);
+ String *make_empty_result()
+ {
+ /*
+ Reset string length to an empty string. We don't use str_value.set() as
+ we don't want to free and potentially have to reallocate the buffer
+ for each call.
+ */
+ str_value.length(0);
+ str_value.set_charset(collation.collation);
return &str_value;
}
public:
@@ -850,7 +857,7 @@ public:
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
};
-#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
+
class Item_func_uuid: public Item_str_func
{
public:
@@ -862,7 +869,7 @@ public:
charset when hex(), format(), md5(), etc, and implicit
number-to-string conversion will use 'ascii'
*/
- max_length= UUID_LENGTH * system_charset_info->mbmaxlen;
+ max_length= MY_UUID_STRING_LENGTH * system_charset_info->mbmaxlen;
}
const char *func_name() const{ return "uuid"; }
String *val_str(String *);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 10dd6c93717..985313226eb 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2010, Oracle and/or its affiliates.
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
@@ -39,7 +39,8 @@ inline Item * and_items(Item* cond, Item *item)
Item_subselect::Item_subselect():
Item_result_field(), value_assigned(0), thd(0), substitution(0),
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
- const_item_cache(1), engine_changed(0), changed(0), is_correlated(FALSE)
+ const_item_cache(1), in_fix_fields(0), eliminated(FALSE),
+ engine_changed(0), changed(0), is_correlated(FALSE)
{
with_subselect= 1;
reset();
@@ -152,9 +153,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
DBUG_ASSERT(fixed == 0);
engine->set_thd((thd= thd_param));
+ if (!in_fix_fields)
+ refers_to.empty();
+ eliminated= FALSE;
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
return TRUE;
+
+ in_fix_fields++;
if (!(res= engine->prepare()))
{
@@ -163,8 +169,6 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
if (substitution)
{
- int ret= 0;
-
// did we changed top item of WHERE condition
if (unit->outer_select()->where == (*ref))
unit->outer_select()->where= substitution; // correct WHERE for PS
@@ -178,20 +182,20 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
substitution= 0;
thd->where= "checking transformed subquery";
if (!(*ref)->fixed)
- ret= (*ref)->fix_fields(thd, ref);
- thd->where= save_where;
- return ret;
+ res= (*ref)->fix_fields(thd, ref);
+ goto end;
}
// Is it one field subselect?
if (engine->cols() > max_columns)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
- return TRUE;
+ res= 1;
+ goto end;
}
fix_length_and_dec();
}
else
- goto err;
+ goto end;
if ((uncacheable= engine->uncacheable()))
{
@@ -201,12 +205,31 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
}
fixed= 1;
-err:
+end:
+ in_fix_fields--;
thd->where= save_where;
return res;
}
+bool Item_subselect::enumerate_field_refs_processor(uchar *arg)
+{
+ List_iterator<Item> it(refers_to);
+ Item *item;
+ while ((item= it++))
+ {
+ if (item->walk(&Item::enumerate_field_refs_processor, FALSE, arg))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool Item_subselect::mark_as_eliminated_processor(uchar *arg)
+{
+ eliminated= TRUE;
+ return FALSE;
+}
+
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
uchar *argument)
{
@@ -224,6 +247,7 @@ bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
if (lex->having && (lex->having)->walk(processor, walk_subquery,
argument))
return 1;
+ /* TODO: why does this walk WHERE/HAVING but not ON expressions of outer joins? */
while ((item=li++))
{
@@ -414,6 +438,7 @@ void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
void Item_singlerow_subselect::reset()
{
+ eliminated= FALSE;
null_value= TRUE;
if (value)
value->null_value= TRUE;
@@ -1058,9 +1083,9 @@ Item_in_subselect::single_value_transformer(JOIN *join,
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
substitution= optimizer;
- SELECT_LEX *current= thd->lex->current_select, *up;
+ SELECT_LEX *current= thd->lex->current_select;
- thd->lex->current_select= up= current->return_after_parsing();
+ thd->lex->current_select= current->return_after_parsing();
//optimizer never use Item **ref => we can pass 0 as parameter
if (!optimizer || optimizer->fix_left(thd, 0))
{
@@ -1285,8 +1310,8 @@ Item_in_subselect::row_value_transformer(JOIN *join)
SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
substitution= optimizer;
- SELECT_LEX *current= thd->lex->current_select, *up;
- thd->lex->current_select= up= current->return_after_parsing();
+ SELECT_LEX *current= thd->lex->current_select;
+ thd->lex->current_select= current->return_after_parsing();
//optimizer never use Item **ref => we can pass 0 as parameter
if (!optimizer || optimizer->fix_left(thd, 0))
{
@@ -1330,7 +1355,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
for (uint i= 0; i < cols_num; i++)
{
DBUG_ASSERT((left_expr->fixed &&
- select_lex->ref_pointer_array[i]->fixed) ||
+ select_lex->ref_pointer_array[i]->fixed) ||
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
Item_ref::OUTER_REF));
@@ -1408,7 +1433,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
{
Item *item, *item_isnull;
DBUG_ASSERT((left_expr->fixed &&
- select_lex->ref_pointer_array[i]->fixed) ||
+ select_lex->ref_pointer_array[i]->fixed) ||
(select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
Item_ref::OUTER_REF));
@@ -1532,7 +1557,7 @@ Item_subselect::trans_res
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
{
Query_arena *arena, backup;
- SELECT_LEX *current= thd->lex->current_select, *up;
+ SELECT_LEX *current= thd->lex->current_select;
const char *save_where= thd->where;
Item_subselect::trans_res res= RES_ERROR;
bool result;
@@ -1574,7 +1599,7 @@ Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
goto err;
}
- thd->lex->current_select= up= current->return_after_parsing();
+ thd->lex->current_select= current->return_after_parsing();
result= (!left_expr->fixed &&
left_expr->fix_fields(thd, optimizer->arguments()));
/* fix_fields can change reference to left_expr, we need reassign it */
@@ -1759,6 +1784,10 @@ int subselect_single_select_engine::prepare()
{
if (prepared)
return 0;
+ if (select_lex->join)
+ {
+ select_lex->cleanup();
+ }
join= new JOIN(thd, select_lex->item_list,
select_lex->options | SELECT_NO_UNLOCK, result);
if (!join || !result)
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 74bbec626c1..6822dace6bb 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
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
@@ -54,8 +54,16 @@ protected:
bool have_to_be_excluded;
/* cache of constant state */
bool const_item_cache;
-
+
public:
+ /*
+ References from inside the subquery to the select that this predicate is
+ in. References to parent selects not included.
+ */
+ List<Item> refers_to;
+ int in_fix_fields;
+ bool eliminated;
+
/* changed engine indicator */
bool engine_changed;
/* subquery is transformed */
@@ -84,6 +92,7 @@ public:
void cleanup();
virtual void reset()
{
+ eliminated= FALSE;
null_value= 1;
}
virtual trans_res select_transformer(JOIN *join);
@@ -128,6 +137,8 @@ public:
virtual void reset_value_registration() {}
enum_parsing_place place() { return parsing_place; }
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
+ bool mark_as_eliminated_processor(uchar *arg);
+ bool enumerate_field_refs_processor(uchar *arg);
/**
Get the SELECT_LEX structure associated with this Item.
@@ -227,6 +238,7 @@ public:
subs_type substype() { return EXISTS_SUBS; }
void reset()
{
+ eliminated= FALSE;
value= 0;
}
@@ -298,6 +310,7 @@ public:
subs_type substype() { return IN_SUBS; }
void reset()
{
+ eliminated= FALSE;
value= 0;
null_value= 0;
was_null= 0;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 40ac31918be..92c2ba83f23 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -350,7 +351,7 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
sl= sl->master_unit()->outer_select() )
sl->master_unit()->item->with_sum_func= 1;
}
- thd->lex->current_select->mark_as_dependent(aggr_sel);
+ thd->lex->current_select->mark_as_dependent(aggr_sel, NULL);
return FALSE;
}
@@ -521,11 +522,6 @@ void Item_sum::update_used_tables ()
args[i]->update_used_tables();
used_tables_cache|= args[i]->used_tables();
}
-
- used_tables_cache&= PSEUDO_TABLE_BITS;
-
- /* the aggregate function is aggregated into its local context */
- used_tables_cache |= (1 << aggr_sel->join->tables) - 1;
}
}
@@ -1621,8 +1617,22 @@ void Item_sum_hybrid::cleanup()
void Item_sum_hybrid::no_rows_in_result()
{
- was_values= FALSE;
- clear();
+ /* We may be called here twice in case of ref field in function */
+ if (was_values)
+ {
+ was_values= FALSE;
+ was_null_value= value->null_value;
+ clear();
+ }
+}
+
+void Item_sum_hybrid::restore_to_before_no_rows_in_result()
+{
+ if (!was_values)
+ {
+ was_values= TRUE;
+ null_value= value->null_value= was_null_value;
+ }
}
@@ -2450,7 +2460,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
tree_key_length+= f->pack_length();
if ((f_type == MYSQL_TYPE_VARCHAR) ||
(!f->binary() && (f_type == MYSQL_TYPE_STRING ||
- f_type == MYSQL_TYPE_VAR_STRING)))
+ f_type == MYSQL_TYPE_VAR_STRING)))
{
all_binary= FALSE;
break;
@@ -3035,10 +3045,10 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
object being copied.
*/
ORDER *tmp;
- if (!(order= (ORDER **) thd->alloc(sizeof(ORDER *) * arg_count_order +
+ if (!(tmp= (ORDER *) thd->alloc(sizeof(ORDER *) * arg_count_order +
sizeof(ORDER) * arg_count_order)))
return;
- tmp= (ORDER *)(order + arg_count_order);
+ order= (ORDER **)(tmp + arg_count_order);
for (uint i= 0; i < arg_count_order; i++, tmp++)
{
memcpy(tmp, item->order[i], sizeof(ORDER));
@@ -3047,7 +3057,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
}
-
void Item_func_group_concat::cleanup()
{
DBUG_ENTER("Item_func_group_concat::cleanup");
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 418899e61aa..27dfb90ecf4 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -256,6 +257,12 @@ protected:
*/
Item **orig_args, *tmp_orig_args[2];
table_map used_tables_cache;
+
+ /*
+ TRUE <=> We've managed to calculate the value of this Item in
+ opt_sum_query(), hence it can be considered constant at all subsequent
+ steps.
+ */
bool forced_const;
public:
@@ -326,6 +333,15 @@ public:
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
virtual Item *result_item(Field *field)
{ return new Item_field(field); }
+ /*
+ Return bitmap of tables that are needed to evaluate the item.
+
+ The implementation takes into account the used strategy: items resolved
+ at optimization phase will report 0.
+ Items that depend on the number of join output records, but not columns
+ of any particular table (like COUNT(*)) will report 0 from used_tables(),
+ but will still return false from const_item().
+ */
table_map used_tables() const { return used_tables_cache; }
void update_used_tables ();
void cleanup()
@@ -482,7 +498,7 @@ public:
enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
void reset_field() {} // not used
void update_field() {} // not used
- virtual void no_rows_in_result() {}
+ void no_rows_in_result() {}
void fix_length_and_dec();
enum Item_result result_type () const { return val.traits->type(); }
virtual void calculate_val_and_count();
@@ -831,6 +847,7 @@ protected:
enum_field_types hybrid_field_type;
int cmp_sign;
bool was_values; // Set if we have found at least one row (for max/min only)
+ bool was_null_value;
public:
Item_sum_hybrid(Item *item_par,int sign)
@@ -862,6 +879,7 @@ protected:
void cleanup();
bool any_value() { return was_values; }
void no_rows_in_result();
+ void restore_to_before_no_rows_in_result();
Field *create_tmp_field(bool group, TABLE *table,
uint convert_blob_length);
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 31474f1d6ca..0b5392cb0e5 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -540,8 +540,9 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
%U,%u should be used with %Y and not %X or %x
*/
if ((strict_week_number &&
- (strict_week_number_year < 0 ||
- strict_week_number_year_type != sunday_first_n_first_week_non_iso)) ||
+ (strict_week_number_year < 0 ||
+ strict_week_number_year_type !=
+ sunday_first_n_first_week_non_iso)) ||
(!strict_week_number && strict_week_number_year >= 0))
goto err;
@@ -756,11 +757,13 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
str->append(hours_i < 12 ? "AM" : "PM",2);
break;
case 'r':
- length= sprintf(intbuff, ((l_time->hour % 24) < 12) ?
- "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM",
- (l_time->hour+11)%12+1,
- l_time->minute,
- l_time->second);
+ length= my_sprintf(intbuff,
+ (intbuff,
+ ((l_time->hour % 24) < 12) ?
+ "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM",
+ (l_time->hour+11)%12+1,
+ l_time->minute,
+ l_time->second));
str->append(intbuff, length);
break;
case 'S':
@@ -769,8 +772,12 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'T':
- length= sprintf(intbuff, "%02d:%02d:%02d",
- l_time->hour, l_time->minute, l_time->second);
+ length= my_sprintf(intbuff,
+ (intbuff,
+ "%02d:%02d:%02d",
+ l_time->hour,
+ l_time->minute,
+ l_time->second));
str->append(intbuff, length);
break;
case 'U':
@@ -2999,7 +3006,7 @@ String *Item_func_maketime::val_str(String *str)
char buf[28];
char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
int len = (int)(ptr - buf) +
- sprintf(ptr, ":%02u:%02u", (uint) minute, (uint) second);
+ my_sprintf(ptr, (ptr, ":%02u:%02u", (uint)minute, (uint)second));
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
buf, len, MYSQL_TIMESTAMP_TIME,
NullS);
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 0852629b1ae..4daef708fa3 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2009-2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 751c975b48e..7464fbb440e 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
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
@@ -2034,8 +2034,8 @@ static int my_xpath_parse_OrExpr(MY_XPATH *xpath)
Item *prev= xpath->item;
if (!my_xpath_parse_AndExpr(xpath))
{
- return 0;
xpath->error= 1;
+ return 0;
}
xpath->item= new Item_cond_or(nodeset2bool(xpath, prev),
nodeset2bool(xpath, xpath->item));
diff --git a/sql/lex.h b/sql/lex.h
index 87264a35565..a22b491b739 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -390,6 +390,7 @@ static SYMBOL symbols[] = {
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
{ "PARSER", SYM(PARSER_SYM)},
{ "PAGE", SYM(PAGE_SYM)},
+ { "PAGE_CHECKSUM", SYM(PAGE_CHECKSUM_SYM)},
{ "PARTIAL", SYM(PARTIAL)},
{ "PARTITION", SYM(PARTITION_SYM)},
{ "PARTITIONING", SYM(PARTITIONING_SYM)},
@@ -545,6 +546,7 @@ static SYMBOL symbols[] = {
{ "TO", SYM(TO_SYM)},
{ "TRAILING", SYM(TRAILING)},
{ "TRANSACTION", SYM(TRANSACTION_SYM)},
+ { "TRANSACTIONAL", SYM(TRANSACTIONAL_SYM)},
{ "TRIGGER", SYM(TRIGGER_SYM)},
{ "TRIGGERS", SYM(TRIGGERS_SYM)},
{ "TRUE", SYM(TRUE_SYM)},
diff --git a/sql/lock.cc b/sql/lock.cc
index feaba4267c1..7fb725c9861 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -36,8 +36,8 @@
This is followed by a call to thr_multi_lock() for all tables.
- When statement is done, we call mysql_unlock_tables().
- This will call thr_multi_unlock() followed by
- table_handler->external_lock(thd, F_UNLCK) for each table.
+ table_handler->external_lock(thd, F_UNLCK) followed by
+ thr_multi_unlock() for each table.
- Note that mysql_unlock_tables() may be called several times as
MySQL in some cases can free some tables earlier than others.
@@ -213,7 +213,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
for (;;)
{
if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS,
- &write_lock_used)))
+ &write_lock_used)) ||
+ ! sql_lock->table_count)
break;
if (global_read_lock && write_lock_used &&
@@ -259,8 +260,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
thd_proc_info(thd, "System lock");
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
- if (sql_lock->table_count && lock_external(thd, sql_lock->table,
- sql_lock->table_count))
+ if (lock_external(thd, sql_lock->table, sql_lock->table_count))
{
/* Clear the lock type of all lock data to avoid reusage. */
reset_lock_data(sql_lock);
@@ -281,8 +281,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
thd->lock_id)];
if (rc > 1) /* a timeout or a deadlock */
{
- if (sql_lock->table_count)
- VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
+ VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
my_error(rc, MYF(0));
my_free((uchar*) sql_lock,MYF(0));
sql_lock= 0;
@@ -387,10 +386,10 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
{
DBUG_ENTER("mysql_unlock_tables");
- if (sql_lock->lock_count)
- thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
if (sql_lock->table_count)
VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
+ if (sql_lock->lock_count)
+ thr_multi_unlock(sql_lock->locks,sql_lock->lock_count, 0);
my_free((uchar*) sql_lock,MYF(0));
DBUG_VOID_RETURN;
}
@@ -420,25 +419,8 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
uint i,found;
DBUG_ENTER("mysql_unlock_read_tables");
- /* Move all write locks first */
- THR_LOCK_DATA **lock=sql_lock->locks;
- for (i=found=0 ; i < sql_lock->lock_count ; i++)
- {
- if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ)
- {
- swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]);
- lock++;
- found++;
- }
- }
- /* unlock the read locked tables */
- if (i != found)
- {
- thr_multi_unlock(lock,i-found);
- sql_lock->lock_count= found;
- }
+ /* Call external lock for all tables to be unlocked */
- /* Then do the same for the external locks */
/* Move all write locked tables first */
TABLE **table=sql_lock->table;
for (i=found=0 ; i < sql_lock->table_count ; i++)
@@ -457,6 +439,27 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
VOID(unlock_external(thd,table,i-found));
sql_lock->table_count=found;
}
+
+ /* Call thr_unlock() for all tables to be unlocked */
+
+ /* Move all write locks first */
+ THR_LOCK_DATA **lock=sql_lock->locks;
+ for (i=found=0 ; i < sql_lock->lock_count ; i++)
+ {
+ if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ)
+ {
+ swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]);
+ lock++;
+ found++;
+ }
+ }
+ /* unlock the read locked tables */
+ if (i != found)
+ {
+ thr_multi_unlock(lock, i-found, 0);
+ sql_lock->lock_count= found;
+ }
+
/* Fix the lock positions in TABLE */
table= sql_lock->table;
found= 0;
@@ -584,8 +587,21 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
&write_lock_used)))
{
- for (uint i=0; i < locked->lock_count; i++)
- thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
+ if (table->children_attached)
+ {
+ /*
+ Don't abort locks for underlying tables just because merge table
+ is deleted. Doing would cause anyone accessing these tables to
+ spin in open_table/close_table forever until lock is released.
+ */
+ thr_multi_unlock(locked->locks, locked->lock_count,
+ THR_UNLOCK_UPDATE_STATUS);
+ }
+ else
+ {
+ for (uint i=0; i < locked->lock_count; i++)
+ thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
+ }
my_free((uchar*) locked,MYF(0));
}
DBUG_VOID_RETURN;
@@ -626,21 +642,36 @@ bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
}
+/**
+ Merge two thr_lock:s
+ mysql_lock_merge()
+
+ @param a Original locks
+ @param b New locks
+
+ @retval New lock structure that contains a and b
+
+ @note
+ a and b are freed with my_free()
+*/
+
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
{
MYSQL_LOCK *sql_lock;
TABLE **table, **end_table;
DBUG_ENTER("mysql_lock_merge");
+ DBUG_PRINT("enter", ("a->lock_count: %u b->lock_count: %u",
+ a->lock_count, b->lock_count));
if (!(sql_lock= (MYSQL_LOCK*)
my_malloc(sizeof(*sql_lock)+
- sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
+ sizeof(THR_LOCK_DATA*)*((a->lock_count+b->lock_count)*2) +
sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME))))
DBUG_RETURN(0); // Fatal error
sql_lock->lock_count=a->lock_count+b->lock_count;
sql_lock->table_count=a->table_count+b->table_count;
sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
- sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count);
+ sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count*2);
memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
memcpy(sql_lock->locks+a->lock_count,b->locks,
b->lock_count*sizeof(*b->locks));
@@ -661,6 +692,18 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
(*table)->lock_data_start+= a->lock_count;
}
+ /*
+ Ensure that locks of the same tables share same data structures if we
+ reopen a table that is already open. This can happen for example with
+ MERGE tables.
+ */
+
+ /* Copy the lock data array. thr_merge_lock() reorders its content */
+ memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
+ sql_lock->lock_count * sizeof(*sql_lock->locks));
+ thr_merge_locks(sql_lock->locks + sql_lock->lock_count,
+ a->lock_count, b->lock_count);
+
/* Delete old, not needed locks */
my_free((uchar*) a,MYF(0));
my_free((uchar*) b,MYF(0));
@@ -832,7 +875,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
/*
Allocating twice the number of pointers for lock data for use in
- thr_mulit_lock(). This function reorders the lock data, but cannot
+ thr_multi_lock(). This function reorders the lock data, but cannot
update the table values. So the second part of the array is copied
from the first part immediately before calling thr_multi_lock().
*/
@@ -882,7 +925,10 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
*to++= table;
if (locks)
for ( ; org_locks != locks ; org_locks++)
+ {
(*org_locks)->debug_print_param= (void *) table;
+ (*org_locks)->lock->name= table->alias;
+ }
}
/*
We do not use 'tables', because there are cases where store_lock()
@@ -1049,20 +1095,26 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
DBUG_RETURN(-1);
table_list->table=table;
+ table->s->deleting= table_list->deleting;
/* Return 1 if table is in use */
DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
- check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
+ (check_in_use ?
+ RTFC_NO_FLAG :
+ RTFC_WAIT_OTHER_THREAD_FLAG),
+ table_list->deleting)));
}
void unlock_table_name(THD *thd, TABLE_LIST *table_list)
{
+ DBUG_ENTER("unlock_table_name");
if (table_list->table)
{
hash_delete(&open_cache, (uchar*) table_list->table);
broadcast_refresh();
}
+ DBUG_VOID_RETURN;
}
diff --git a/sql/log.cc b/sql/log.cc
index 77d12641442..95f8e9e82ee 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -372,6 +372,7 @@ bool Log_to_csv_event_handler::
Open_tables_state open_tables_backup;
ulonglong save_thd_options;
bool save_time_zone_used;
+ DBUG_ENTER("log_general");
/*
CSV uses TIME_to_timestamp() internally if table needs to be repaired
@@ -490,7 +491,7 @@ err:
thd->options= save_thd_options;
thd->time_zone_used= save_time_zone_used;
- return result;
+ DBUG_RETURN(result);
}
@@ -987,7 +988,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
/* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
sctx->priv_user ? sctx->priv_user : "", "[",
- sctx->user ? sctx->user : "", "] @ ",
+ sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""), "] @ ",
sctx->host ? sctx->host : "", " [",
sctx->ip ? sctx->ip : "", "]", NullS) -
user_host_buff);
@@ -1010,6 +1011,17 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
query_length= command_name[thd->command].length;
}
+ if (!query_length)
+ {
+ /*
+ Not a real query; Reset counts for slow query logging
+ (QQ: Wonder if this is really needed)
+ */
+ thd->sent_row_count= thd->examined_row_count= 0;
+ thd->query_plan_flags= QPLAN_INIT;
+ thd->query_plan_fsort_passes= 0;
+ }
+
for (current_handler= slow_log_handler_list; *current_handler ;)
error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
user_host_buff, user_host_len,
@@ -1206,6 +1218,7 @@ void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
{
my_bool *tmp_opt= 0;
MYSQL_LOG *file_log;
+ LINT_INIT(file_log);
switch (log_type) {
case QUERY_LOG_SLOW:
@@ -1598,7 +1611,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
else
{
/*
- We flush the cache with a rollback, wrapped in a beging/rollback if:
+ We flush the cache with a rollback, wrapped in a begin/rollback if:
. aborting a transaction that modified a non-transactional table or
the OPTION_KEEP_LOG is activate.
. aborting a statement that modified both transactional and
@@ -1679,6 +1692,7 @@ bool MYSQL_BIN_LOG::check_write_error(THD *thd)
DBUG_RETURN(checked);
}
+
/**
@note
How do we handle this (unlikely but legal) case:
@@ -1752,17 +1766,17 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
int check_binlog_magic(IO_CACHE* log, const char** errmsg)
{
- char magic[4];
+ uchar magic[4];
DBUG_ASSERT(my_b_tell(log) == 0);
- if (my_b_read(log, (uchar*) magic, sizeof(magic)))
+ if (my_b_read(log, magic, sizeof(magic)))
{
*errmsg = "I/O error reading the header from the binary log";
sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
log->error);
return 1;
}
- if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
+ if (bcmp(magic, BINLOG_MAGIC, sizeof(magic)))
{
*errmsg = "Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL";
return 1;
@@ -1863,6 +1877,7 @@ static int find_uniq_filename(char *name)
size_t buf_length, length;
char *start, *end;
DBUG_ENTER("find_uniq_filename");
+ LINT_INIT(number);
length= dirname_part(buff, name, &buf_length);
start= name + length;
@@ -2333,19 +2348,39 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
if (my_b_write(&log_file, (uchar*) "\n", 1))
tmp_errno= errno;
}
+
/* For slow query log */
sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
sprintf(lock_time_buff, "%.6f", ulonglong2double(lock_utime)/1000000.0);
if (my_b_printf(&log_file,
- "# Query_time: %s Lock_time: %s"
- " Rows_sent: %lu Rows_examined: %lu\n",
+ "# Thread_id: %lu Schema: %s QC_hit: %s\n" \
+ "# Query_time: %s Lock_time: %s Rows_sent: %lu Rows_examined: %lu\n",
+ (ulong) thd->thread_id, (thd->db ? thd->db : ""),
+ ((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"),
query_time_buff, lock_time_buff,
(ulong) thd->sent_row_count,
- (ulong) thd->examined_row_count) == (uint) -1)
+ (ulong) thd->examined_row_count) == (size_t) -1)
tmp_errno= errno;
+ if ((thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_QUERY_PLAN) &&
+ (thd->query_plan_flags &
+ (QPLAN_FULL_SCAN | QPLAN_FULL_JOIN | QPLAN_TMP_TABLE |
+ QPLAN_TMP_DISK | QPLAN_FILESORT | QPLAN_FILESORT_DISK)) &&
+ my_b_printf(&log_file,
+ "# Full_scan: %s Full_join: %s "
+ "Tmp_table: %s Tmp_table_on_disk: %s\n"
+ "# Filesort: %s Filesort_on_disk: %s Merge_passes: %lu\n",
+ ((thd->query_plan_flags & QPLAN_FULL_SCAN) ? "Yes" : "No"),
+ ((thd->query_plan_flags & QPLAN_FULL_JOIN) ? "Yes" : "No"),
+ ((thd->query_plan_flags & QPLAN_TMP_TABLE) ? "Yes" : "No"),
+ ((thd->query_plan_flags & QPLAN_TMP_DISK) ? "Yes" : "No"),
+ ((thd->query_plan_flags & QPLAN_FILESORT) ? "Yes" : "No"),
+ ((thd->query_plan_flags & QPLAN_FILESORT_DISK) ?
+ "Yes" : "No"),
+ thd->query_plan_fsort_passes) == (size_t) -1)
+ tmp_errno= errno;
if (thd->db && strcmp(thd->db, db))
{ // Database changed
- if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
+ if (my_b_printf(&log_file,"use %s;\n",thd->db) == (size_t) -1)
tmp_errno= errno;
strmov(db,thd->db);
}
@@ -2489,7 +2524,12 @@ void MYSQL_BIN_LOG::init_pthread_objects()
DBUG_ASSERT(inited == 0);
inited= 1;
(void) pthread_mutex_init(&LOCK_log, MY_MUTEX_INIT_SLOW);
- (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
+ /*
+ LOCK_index and LOCK_log are taken in wrong order
+ Can be seen with 'mysql-test-run ndb.ndb_binlog_basic'
+ */
+ (void) my_pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW, "LOCK_index",
+ MYF_NO_DEADLOCK_DETECTION);
(void) pthread_cond_init(&update_cond, 0);
}
@@ -2651,7 +2691,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
an extension for the binary log files.
In this case we write a standard header to it.
*/
- if (my_b_safe_write(&log_file, (uchar*) BINLOG_MAGIC,
+ if (my_b_safe_write(&log_file, BINLOG_MAGIC,
BIN_LOG_HEADER_SIZE))
goto err;
bytes_written+= BIN_LOG_HEADER_SIZE;
@@ -2989,6 +3029,12 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
DBUG_ENTER("reset_logs");
ha_reset_logs(thd);
+ /*
+ We need to get both locks to be sure that no one is trying to
+ write to the index log file.
+ */
+ pthread_mutex_lock(&LOCK_log);
+ pthread_mutex_lock(&LOCK_index);
/*
The following mutex is needed to ensure that no threads call
@@ -2998,13 +3044,6 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
*/
pthread_mutex_lock(&LOCK_thread_count);
- /*
- We need to get both locks to be sure that no one is trying to
- write to the index log file.
- */
- pthread_mutex_lock(&LOCK_log);
- pthread_mutex_lock(&LOCK_index);
-
/* Save variables so that we can reopen the log */
save_name=name;
name=0; // Protect against free
@@ -4392,7 +4431,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
binlog_[wild_]{do|ignore}_table?" (WL#1049)"
*/
const char *local_db= event_info->get_db();
- if ((thd && !(thd->options & OPTION_BIN_LOG)) ||
+ if ((!(thd->options & OPTION_BIN_LOG)) ||
(thd->lex->sql_command != SQLCOM_ROLLBACK_TO_SAVEPOINT &&
thd->lex->sql_command != SQLCOM_SAVEPOINT &&
!binlog_filter->db_ok(local_db)))
@@ -5373,39 +5412,39 @@ void sql_print_information(const char *format, ...)
/********* transaction coordinator log for 2pc - mmap() based solution *******/
/*
- the log consists of a file, mmapped to a memory.
- file is divided on pages of tc_log_page_size size.
- (usable size of the first page is smaller because of log header)
- there's PAGE control structure for each page
- each page (or rather PAGE control structure) can be in one of three
- states - active, syncing, pool.
- there could be only one page in active or syncing states,
- but many in pool - pool is fifo queue.
- usual lifecycle of a page is pool->active->syncing->pool
- "active" page - is a page where new xid's are logged.
- the page stays active as long as syncing slot is taken.
- "syncing" page is being synced to disk. no new xid can be added to it.
- when the sync is done the page is moved to a pool and an active page
+ the log consists of a file, mapped to memory.
+ file is divided into pages of tc_log_page_size size.
+ (usable size of the first page is smaller because of the log header)
+ there is a PAGE control structure for each page
+ each page (or rather its PAGE control structure) can be in one of
+ the three states - active, syncing, pool.
+ there could be only one page in the active or syncing state,
+ but many in pool - pool is a fifo queue.
+ the usual lifecycle of a page is pool->active->syncing->pool.
+ the "active" page is a page where new xid's are logged.
+ the page stays active as long as the syncing slot is taken.
+ the "syncing" page is being synced to disk. no new xid can be added to it.
+ when the syncing is done the page is moved to a pool and an active page
becomes "syncing".
the result of such an architecture is a natural "commit grouping" -
If commits are coming faster than the system can sync, they do not
- stall. Instead, all commit that came since the last sync are
- logged to the same page, and they all are synced with the next -
+ stall. Instead, all commits that came since the last sync are
+ logged to the same "active" page, and they all are synced with the next -
one - sync. Thus, thought individual commits are delayed, throughput
is not decreasing.
- when a xid is added to an active page, the thread of this xid waits
+ when an xid is added to an active page, the thread of this xid waits
for a page's condition until the page is synced. when syncing slot
becomes vacant one of these waiters is awaken to take care of syncing.
it syncs the page and signals all waiters that the page is synced.
PAGE::waiters is used to count these waiters, and a page may never
become active again until waiters==0 (that is all waiters from the
- previous sync have noticed the sync was completed)
+ previous sync have noticed that the sync was completed)
note, that the page becomes "dirty" and has to be synced only when a
new xid is added into it. Removing a xid from a page does not make it
- dirty - we don't sync removals to disk.
+ dirty - we don't sync xid removals to disk.
*/
ulong tc_log_page_waits= 0;
@@ -5414,7 +5453,7 @@ ulong tc_log_page_waits= 0;
#define TC_LOG_HEADER_SIZE (sizeof(tc_log_magic)+1)
-static const char tc_log_magic[]={(char) 254, 0x23, 0x05, 0x74};
+static const uchar tc_log_magic[]={(uchar) 254, 0x23, 0x05, 0x74};
ulong opt_tc_log_size= TC_LOG_MIN_SIZE;
ulong tc_log_max_pages_used=0, tc_log_page_size=0, tc_log_cur_pages_used=0;
@@ -5471,7 +5510,8 @@ int TC_LOG_MMAP::open(const char *opt_name)
inited=2;
npages=(uint)file_length/tc_log_page_size;
- DBUG_ASSERT(npages >= 3); // to guarantee non-empty pool
+ if (npages < 3) // to guarantee non-empty pool
+ goto err;
if (!(pages=(PAGE *)my_malloc(npages*sizeof(PAGE), MYF(MY_WME|MY_ZEROFILL))))
goto err;
inited=3;
@@ -5482,9 +5522,9 @@ int TC_LOG_MMAP::open(const char *opt_name)
pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0);
- pg->start=(my_xid *)(data + i*tc_log_page_size);
- pg->end=(my_xid *)(pg->start + tc_log_page_size);
+ pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
+ pg->end=pg->start + pg->size;
}
pages[0].size=pages[0].free=
(tc_log_page_size-TC_LOG_HEADER_SIZE)/sizeof(my_xid);
@@ -5528,7 +5568,7 @@ err:
-# if there're waiters - take the one with the most free space.
@todo
- TODO page merging. try to allocate adjacent page first,
+ page merging. try to allocate adjacent page first,
so that they can be flushed both in one sync
*/
@@ -5537,8 +5577,7 @@ void TC_LOG_MMAP::get_active_from_pool()
PAGE **p, **best_p=0;
int best_free;
- if (syncing)
- pthread_mutex_lock(&LOCK_pool);
+ pthread_mutex_lock(&LOCK_pool);
do
{
@@ -5558,20 +5597,21 @@ void TC_LOG_MMAP::get_active_from_pool()
}
while ((*best_p == 0 || best_free == 0) && overflow());
+ safe_mutex_assert_owner(&LOCK_active);
active=*best_p;
- if (active->free == active->size) // we've chosen an empty page
- {
- tc_log_cur_pages_used++;
- set_if_bigger(tc_log_max_pages_used, tc_log_cur_pages_used);
- }
if ((*best_p)->next) // unlink the page from the pool
*best_p=(*best_p)->next;
else
pool_last=*best_p;
+ pthread_mutex_unlock(&LOCK_pool);
- if (syncing)
- pthread_mutex_unlock(&LOCK_pool);
+ pthread_mutex_lock(&active->lock);
+ if (active->free == active->size) // we've chosen an empty page
+ {
+ tc_log_cur_pages_used++;
+ set_if_bigger(tc_log_max_pages_used, tc_log_cur_pages_used);
+ }
}
/**
@@ -5626,7 +5666,7 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
pthread_mutex_lock(&LOCK_active);
/*
- if active page is full - just wait...
+ if the active page is full - just wait...
frankly speaking, active->free here accessed outside of mutex
protection, but it's safe, because it only means we may miss an
unlog() for the active page, and we're not waiting for it here -
@@ -5638,9 +5678,17 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
/* no active page ? take one from the pool */
if (active == 0)
get_active_from_pool();
+ else
+ pthread_mutex_lock(&active->lock);
p=active;
- pthread_mutex_lock(&p->lock);
+
+ /*
+ p->free is always > 0 here because to decrease it one needs
+ to take p->lock and before it one needs to take LOCK_active.
+ But checked that active->free > 0 under LOCK_active and
+ haven't release it ever since
+ */
/* searching for an empty slot */
while (*p->ptr)
@@ -5654,38 +5702,51 @@ int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
*p->ptr++= xid;
p->free--;
p->state= DIRTY;
-
- /* to sync or not to sync - this is the question */
- pthread_mutex_unlock(&LOCK_active);
- pthread_mutex_lock(&LOCK_sync);
pthread_mutex_unlock(&p->lock);
+ pthread_mutex_lock(&LOCK_sync);
if (syncing)
{ // somebody's syncing. let's wait
+ pthread_mutex_unlock(&LOCK_active);
+ pthread_mutex_lock(&p->lock);
p->waiters++;
- /*
- note - it must be while (), not do ... while () here
- as p->state may be not DIRTY when we come here
- */
- while (p->state == DIRTY && syncing)
+ for (;;)
+ {
+ int not_dirty = p->state != DIRTY;
+ pthread_mutex_unlock(&p->lock);
+ if (not_dirty || !syncing)
+ break;
pthread_cond_wait(&p->cond, &LOCK_sync);
+ pthread_mutex_lock(&p->lock);
+ }
p->waiters--;
err= p->state == ERROR;
if (p->state != DIRTY) // page was synced
{
+ pthread_mutex_unlock(&LOCK_sync);
if (p->waiters == 0)
pthread_cond_signal(&COND_pool); // in case somebody's waiting
- pthread_mutex_unlock(&LOCK_sync);
+ pthread_mutex_unlock(&p->lock);
goto done; // we're done
}
- } // page was not synced! do it now
- DBUG_ASSERT(active == p && syncing == 0);
- pthread_mutex_lock(&LOCK_active);
- syncing=p; // place is vacant - take it
- active=0; // page is not active anymore
- pthread_cond_broadcast(&COND_active); // in case somebody's waiting
- pthread_mutex_unlock(&LOCK_active);
- pthread_mutex_unlock(&LOCK_sync);
+ DBUG_ASSERT(!syncing);
+ pthread_mutex_unlock(&p->lock);
+ syncing = p;
+ pthread_mutex_unlock(&LOCK_sync);
+
+ pthread_mutex_lock(&LOCK_active);
+ active=0; // page is not active anymore
+ pthread_cond_broadcast(&COND_active);
+ pthread_mutex_unlock(&LOCK_active);
+ }
+ else
+ {
+ syncing = p; // place is vacant - take it
+ pthread_mutex_unlock(&LOCK_sync);
+ active = 0; // page is not active anymore
+ pthread_cond_broadcast(&COND_active);
+ pthread_mutex_unlock(&LOCK_active);
+ }
err= sync();
done:
@@ -5702,7 +5763,7 @@ int TC_LOG_MMAP::sync()
sit down and relax - this can take a while...
note - no locks are held at this point
*/
- err= my_msync(fd, syncing->start, 1, MS_SYNC);
+ err= my_msync(fd, syncing->start, syncing->size * sizeof(my_xid), MS_SYNC);
/* page is synced. let's move it to the pool */
pthread_mutex_lock(&LOCK_pool);
@@ -5710,14 +5771,23 @@ int TC_LOG_MMAP::sync()
pool_last=syncing;
syncing->next=0;
syncing->state= err ? ERROR : POOL;
- pthread_cond_broadcast(&syncing->cond); // signal "sync done"
pthread_cond_signal(&COND_pool); // in case somebody's waiting
pthread_mutex_unlock(&LOCK_pool);
/* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync);
+ pthread_cond_broadcast(&syncing->cond); // signal "sync done"
syncing=0;
- pthread_cond_signal(&active->cond); // wake up a new syncer
+ /*
+ we check the "active" pointer without LOCK_active. Still, it's safe -
+ "active" can change from NULL to not NULL any time, but it
+ will take LOCK_sync before waiting on active->cond. That is, it can never
+ miss a signal.
+ And "active" can change to NULL only by the syncing thread
+ (the thread that will send a signal below)
+ */
+ if (active)
+ pthread_cond_signal(&active->cond); // wake up a new syncer
pthread_mutex_unlock(&LOCK_sync);
return err;
}
@@ -5734,13 +5804,13 @@ int TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
DBUG_ASSERT(*x == xid);
DBUG_ASSERT(x >= p->start && x < p->end);
- *x=0;
pthread_mutex_lock(&p->lock);
+ *x=0;
p->free++;
DBUG_ASSERT(p->free <= p->size);
set_if_smaller(p->ptr, x);
- if (p->free == p->size) // the page is completely empty
+ if (p->free == p->size) // the page is completely empty
statistic_decrement(tc_log_cur_pages_used, &LOCK_status);
if (p->waiters == 0) // the page is in pool and ready to rock
pthread_cond_signal(&COND_pool); // ping ... for overflow()
@@ -5784,7 +5854,7 @@ int TC_LOG_MMAP::recover()
HASH xids;
PAGE *p=pages, *end_p=pages+npages;
- if (memcmp(data, tc_log_magic, sizeof(tc_log_magic)))
+ if (bcmp(data, tc_log_magic, sizeof(tc_log_magic)))
{
sql_print_error("Bad magic header in tc log");
goto err1;
diff --git a/sql/log.h b/sql/log.h
index 81342f6e696..361ad0f2a91 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/log_event.cc b/sql/log_event.cc
index fac3e3f264b..f56fa3c698a 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -834,10 +834,9 @@ Log_event::do_shall_skip(Relay_log_info *rli)
if ((server_id == ::server_id && !rli->replicate_same_server_id) ||
(rli->slave_skip_counter == 1 && rli->is_in_group()))
return EVENT_SKIP_IGNORE;
- else if (rli->slave_skip_counter > 0)
+ if (rli->slave_skip_counter > 0)
return EVENT_SKIP_COUNT;
- else
- return EVENT_SKIP_NOT;
+ return EVENT_SKIP_NOT;
}
@@ -1678,11 +1677,11 @@ beg:
int i, end;
char buff[512], *pos;
pos= buff;
- pos+= sprintf(buff, "%s", dec.sign() ? "-" : "");
+ pos+= my_sprintf(buff, (buff, "%s", dec.sign() ? "-" : ""));
end= ROUND_UP(dec.frac) + ROUND_UP(dec.intg)-1;
for (i=0; i < end; i++)
- pos+= sprintf(pos, "%09d.", dec.buf[i]);
- pos+= sprintf(pos, "%09d", dec.buf[i]);
+ pos+= my_sprintf(pos, (pos, "%09d.", dec.buf[i]));
+ pos+= my_sprintf(pos, (pos, "%09d", dec.buf[i]));
my_b_printf(file, "%s", buff);
my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
precision, decimals);
@@ -1731,13 +1730,13 @@ beg:
case MYSQL_TYPE_DATETIME:
{
- size_t d, t;
+ ulong d, t;
uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
- d= i64 / 1000000;
- t= i64 % 1000000;
+ d= (ulong) (i64 / 1000000);
+ t= (ulong) (i64 % 1000000);
my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
- d / 10000, (d % 10000) / 100, d % 100,
- t / 10000, (t % 10000) / 100, t % 100);
+ (int) (d / 10000), (int) (d % 10000) / 100, (int) (d % 100),
+ (int) (t / 10000), (int) (t % 10000) / 100, (int) t % 100);
my_snprintf(typestr, typestr_length, "DATETIME");
return 8;
}
@@ -2161,7 +2160,7 @@ static void write_str_with_code_and_len(uchar **dst, const char *src,
*/
DBUG_ASSERT(len <= 255);
DBUG_ASSERT(src);
- *((*dst)++)= code;
+ *((*dst)++)= (uchar) code;
*((*dst)++)= (uchar) len;
bmove(*dst, src, len);
(*dst)+= len;
@@ -3320,6 +3319,19 @@ START SLAVE; . Query: '%s'", expected_error, thd->query());
/* If the query was not ignored, it is printed to the general log */
if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
+ else
+ {
+ /*
+ Bug#54201: If we skip an INSERT query that uses auto_increment, then we
+ should reset any @@INSERT_ID set by an Intvar_log_event associated with
+ the query; otherwise the @@INSERT_ID will linger until the next INSERT
+ that uses auto_increment and may affect extra triggers on the slave etc.
+
+ We reset INSERT_ID unconditionally; it is probably cheaper than
+ checking if it is necessary.
+ */
+ thd->auto_inc_intervals_forced.empty();
+ }
compare_errors:
@@ -5501,7 +5513,8 @@ void User_var_log_event::pack_info(Protocol* protocol)
if (!(buf= (char*) my_malloc(val_offset + FLOATING_POINT_BUFFER,
MYF(MY_WME))))
return;
- event_len+= sprintf(buf + val_offset, "%.14g", real_val);
+ event_len+= my_sprintf(buf + val_offset,
+ (buf + val_offset, "%.14g", real_val));
break;
case INT_RESULT:
if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
@@ -5542,8 +5555,9 @@ void User_var_log_event::pack_info(Protocol* protocol)
}
break;
case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
default:
- DBUG_ASSERT(1);
+ DBUG_ASSERT(0);
return;
}
}
@@ -5632,8 +5646,9 @@ bool User_var_log_event::write(IO_CACHE* file)
pos= (uchar*) val;
break;
case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
default:
- DBUG_ASSERT(1);
+ DBUG_ASSERT(0);
return 0;
}
int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
@@ -5751,7 +5766,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
break;
case ROW_RESULT:
default:
- DBUG_ASSERT(1);
+ DBUG_ASSERT(0);
return;
}
}
@@ -5813,8 +5828,9 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
it= new Item_string(val, val_len, charset);
break;
case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
default:
- DBUG_ASSERT(1);
+ DBUG_ASSERT(0);
return 0;
}
}
@@ -6255,7 +6271,7 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
void Create_file_log_event::pack_info(Protocol *protocol)
{
- char buf[NAME_LEN*2 + 30 + 21*2], *pos;
+ char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos;
pos= strmov(buf, "db=");
memcpy(pos, db, db_len);
pos= strmov(pos + db_len, ";table=");
@@ -6437,9 +6453,10 @@ void Append_block_log_event::print(FILE* file,
void Append_block_log_event::pack_info(Protocol *protocol)
{
char buf[256];
- size_t length;
- length= my_snprintf(buf, sizeof(buf), ";file_id=%u;block_len=%u",
- file_id, block_len);
+ uint length;
+ length= (uint) my_sprintf(buf,
+ (buf, ";file_id=%u;block_len=%u", file_id,
+ block_len));
protocol->store(buf, length, &my_charset_bin);
}
@@ -6588,9 +6605,9 @@ void Delete_file_log_event::print(FILE* file,
void Delete_file_log_event::pack_info(Protocol *protocol)
{
char buf[64];
- size_t length;
- length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
- protocol->store(buf, length, &my_charset_bin);
+ uint length;
+ length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
+ protocol->store(buf, (int32) length, &my_charset_bin);
}
#endif
@@ -6686,9 +6703,9 @@ void Execute_load_log_event::print(FILE* file,
void Execute_load_log_event::pack_info(Protocol *protocol)
{
char buf[64];
- size_t length;
- length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
- protocol->store(buf, length, &my_charset_bin);
+ uint length;
+ length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
+ protocol->store(buf, (int32) length, &my_charset_bin);
}
@@ -7321,7 +7338,7 @@ int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_DUMP("row_data", row_data, min(length, 32));
#endif
@@ -8128,7 +8145,7 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_DUMP("event buffer", (uchar*) buf, event_len);
#endif
@@ -9207,7 +9224,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_DUMP("key data", m_key, table->key_info->key_length);
#endif
@@ -9237,7 +9254,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_PRINT("info",("found first matching record"));
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
#endif
@@ -9630,7 +9647,7 @@ Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
Now we have the right row to update. The old row (the one we're
looking for) is in record[1] and the new row is in record[0].
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
/*
Don't print debug messages when running valgrind since they can
trigger false warnings.
@@ -9708,7 +9725,6 @@ Incident_log_event::description() const
};
DBUG_PRINT("info", ("m_incident: %d", m_incident));
-
return description[m_incident];
}
@@ -9803,3 +9819,29 @@ st_print_event_info::st_print_event_info()
open_cached_file(&body_cache, NULL, NULL, 0, flags);
}
#endif
+
+#if defined(MYSQL_SERVER)
+/*
+ Access to the current replication position.
+
+ There is a dummy replacement for this in the embedded library that returns
+ FALSE; this is used by XtraDB to allow it to access replication stuff while
+ still being able to use the same plugin in both stand-alone and embedded.
+*/
+bool rpl_get_position_info(const char **log_file_name, ulonglong *log_pos,
+ const char **group_relay_log_name,
+ ulonglong *relay_log_pos)
+{
+#if defined(EMBEDDED_LIBRARY) || !defined(HAVE_REPLICATION)
+ return FALSE;
+#else
+ const Relay_log_info *rli= &(active_mi->rli);
+ *log_file_name= rli->group_master_log_name;
+ *log_pos= rli->group_master_log_pos +
+ (rli->future_event_relay_log_pos - rli->group_relay_log_pos);
+ *group_relay_log_name= rli->group_relay_log_name;
+ *relay_log_pos= rli->future_event_relay_log_pos;
+ return TRUE;
+#endif
+}
+#endif
diff --git a/sql/log_event.h b/sql/log_event.h
index 7c707c29278..645585c8ccb 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -400,7 +400,7 @@ struct sql_ex_info
#define ELQ_DUP_HANDLING_OFFSET ELQ_FILE_ID_OFFSET + 12
/* 4 bytes which all binlogs should begin with */
-#define BINLOG_MAGIC "\xfe\x62\x69\x6e"
+#define BINLOG_MAGIC (const uchar*) "\xfe\x62\x69\x6e"
/*
The 2 flags below were useless :
@@ -3961,6 +3961,10 @@ static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache,
reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
}
+bool rpl_get_position_info(const char **log_file_name, ulonglong *log_pos,
+ const char **group_relay_log_name,
+ ulonglong *relay_log_pos);
+
/**
@} (end of group Replication)
*/
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index ceeda41a603..cc9d712a834 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2007, 2010, Oracle and/or its affiliates.
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
@@ -753,7 +753,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_DUMP("table->record[0]", table->record[0], table->s->reclength);
DBUG_DUMP("table->record[1]", table->record[1], table->s->reclength);
#endif
@@ -779,7 +779,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_DUMP("table->record[0]", table->record[0], table->s->reclength);
DBUG_DUMP("table->record[1]", table->record[1], table->s->reclength);
#endif
@@ -1433,7 +1433,7 @@ int Old_rows_log_event::do_add_row_data(uchar *row_data, size_t length)
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_DUMP("row_data", row_data, min(length, 32));
#endif
@@ -2382,7 +2382,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_DUMP("key data", m_key, table->key_info->key_length);
#endif
@@ -2412,7 +2412,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_PRINT("info",("found first matching record"));
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
#endif
@@ -2934,7 +2934,7 @@ Update_rows_log_event_old::do_exec_row(const Relay_log_info *const rli)
Now we have the right row to update. The old row (the one we're
looking for) is in record[1] and the new row is in record[0].
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
/*
Don't print debug messages when running valgrind since they can
trigger false warnings.
diff --git a/sql/log_event_old.h b/sql/log_event_old.h
index 719802a80fb..da5cf403fdb 100644
--- a/sql/log_event_old.h
+++ b/sql/log_event_old.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 MySQL AB. All rights reserved.
+/* Copyright 2007 MySQL AB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/log_slow.h b/sql/log_slow.h
new file mode 100644
index 00000000000..5559c002fde
--- /dev/null
+++ b/sql/log_slow.h
@@ -0,0 +1,107 @@
+/* Copyright (C) 2009 Monty Program Ab
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 or later 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* Defining what to log to slow log */
+
+#define LOG_SLOW_VERBOSITY_INIT 0
+#define LOG_SLOW_VERBOSITY_INNODB 1 << 0
+#define LOG_SLOW_VERBOSITY_QUERY_PLAN 1 << 1
+
+#ifdef DEFINE_VARIABLES_LOG_SLOW
+
+/* Names here must be in same order as the bit's above */
+static const char *log_slow_verbosity_names[]=
+{
+ "innodb","query_plan",
+ NullS
+};
+
+static const unsigned int log_slow_verbosity_names_len[]=
+{
+ sizeof("innodb") -1,
+ sizeof("query_plan")-1
+};
+
+TYPELIB log_slow_verbosity_typelib=
+{ array_elements(log_slow_verbosity_names)-1,"", log_slow_verbosity_names,
+ (unsigned int *) log_slow_verbosity_names_len };
+
+#else
+extern TYPELIB log_slow_verbosity_typelib;
+#endif /* DEFINE_VARIABLES_LOG_SLOW */
+
+/* Defines for what kind of query plan was used and what to log */
+
+/*
+ We init the used query plan with a bit that is alwyas set and all 'no' bits
+ to enable easy testing of what to log in sql_log.cc
+*/
+#define QPLAN_INIT (QPLAN_ALWAYS_SET | QPLAN_QC_NO)
+
+#define QPLAN_ADMIN 1 << 0
+#define QPLAN_FILESORT 1 << 1
+#define QPLAN_FILESORT_DISK 1 << 2
+#define QPLAN_FULL_JOIN 1 << 3
+#define QPLAN_FULL_SCAN 1 << 4
+#define QPLAN_QC 1 << 5
+#define QPLAN_QC_NO 1 << 6
+#define QPLAN_TMP_DISK 1 << 7
+#define QPLAN_TMP_TABLE 1 << 8
+/* ... */
+#define QPLAN_MAX ((ulong) 1) << 31 /* reserved as placeholder */
+#define QPLAN_ALWAYS_SET QPLAN_MAX
+#define QPLAN_VISIBLE_MASK (~(QPLAN_ALWAYS_SET))
+
+#ifdef DEFINE_VARIABLES_LOG_SLOW
+/* Names here must be in same order as the bit's above */
+static const char *log_slow_filter_names[]=
+{
+ "admin",
+ "filesort",
+ "filesort_on_disk",
+ "full_join",
+ "full_scan",
+ "query_cache",
+ "query_cache_miss",
+ "tmp_table",
+ "tmp_table_on_disk",
+ NullS
+};
+
+static const unsigned int log_slow_filter_names_len[]=
+{
+ sizeof("admin")-1,
+ sizeof("filesort")-1,
+ sizeof("filesort_on_disk")-1,
+ sizeof("full_join")-1,
+ sizeof("full_scan")-1,
+ sizeof("query_cache")-1,
+ sizeof("query_cache_miss")-1,
+ sizeof("tmp_table")-1,
+ sizeof("tmp_table_on_disk")-1
+};
+
+TYPELIB log_slow_filter_typelib=
+{ array_elements(log_slow_filter_names)-1,"", log_slow_filter_names,
+ (unsigned int *) log_slow_filter_names_len };
+
+#else
+extern TYPELIB log_slow_filter_typelib;
+#endif /* DEFINE_VARIABLES_LOG_SLOW */
+
+static inline ulong fix_log_slow_filter(ulong org_filter)
+{
+ return org_filter ? org_filter : QPLAN_ALWAYS_SET;
+}
diff --git a/sql/message.h b/sql/message.h
index beb66b7ab5d..f0acc03b9bb 100644
--- a/sql/message.h
+++ b/sql/message.h
@@ -64,8 +64,8 @@
// MessageText:
//
// %1For more information, see Help and Support Center at http://www.mysql.com.
-//
-//
+//
+//
//
#define MSG_DEFAULT 0xC0000064L
diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc
index 8c2d16c40b0..ce1d5973d5d 100644
--- a/sql/mf_iocache.cc
+++ b/sql/mf_iocache.cc
@@ -85,6 +85,12 @@ int _my_b_net_read(register IO_CACHE *info, uchar *Buffer,
}
} /* extern "C" */
+
+#elif defined(__WIN__)
+
+// Remove linker warning 4221 about empty file
+namespace { char dummy; };
+
#endif /* HAVE_REPLICATION */
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index dfb2a5fc9ef..960ccbf3439 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
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
@@ -40,7 +40,7 @@ int decimal_operation_results(int result)
case E_DEC_TRUNCATED:
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED),
- "", (long)-1);
+ "", (ulong) 0);
break;
case E_DEC_OVERFLOW:
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
@@ -56,7 +56,7 @@ int decimal_operation_results(int result)
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
- "decimal", "", "", (long)-1);
+ "decimal", "", "", (ulong) 0);
break;
case E_DEC_OOM:
my_error(ER_OUT_OF_RESOURCES, MYF(0));
@@ -253,12 +253,12 @@ print_decimal(const my_decimal *dec)
int i, end;
char buff[512], *pos;
pos= buff;
- pos+= sprintf(buff, "Decimal: sign: %d intg: %d frac: %d { ",
- dec->sign(), dec->intg, dec->frac);
+ pos+= my_sprintf(buff, (buff, "Decimal: sign: %d intg: %d frac: %d { ",
+ dec->sign(), dec->intg, dec->frac));
end= ROUND_UP(dec->frac)+ROUND_UP(dec->intg)-1;
for (i=0; i < end; i++)
- pos+= sprintf(pos, "%09d, ", dec->buf[i]);
- pos+= sprintf(pos, "%09d }\n", dec->buf[i]);
+ pos+= my_sprintf(pos, (pos, "%09d, ", dec->buf[i]));
+ pos+= my_sprintf(pos, (pos, "%09d }\n", dec->buf[i]));
fputs(buff, DBUG_FILE);
}
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index 21f485560da..a8f2a460abf 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
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
@@ -101,6 +101,11 @@ public:
{
len= DECIMAL_BUFF_LENGTH;
buf= buffer;
+#if !defined (HAVE_valgrind) && !defined(DBUG_OFF)
+ /* Set buffer to 'random' value to find wrong buffer usage */
+ for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
+ buffer[i]= i;
+#endif
}
my_decimal()
diff --git a/sql/my_lock.c b/sql/my_lock.c
index f66d7282f72..276259b106a 100644
--- a/sql/my_lock.c
+++ b/sql/my_lock.c
@@ -25,7 +25,15 @@
#include <thr_alarm.h>
#include <errno.h>
- /* Lock a part of a file */
+/**
+ @breif Lock a part of a file
+
+ @note
+ This works like mysys/my_lock.c, with the exception that this function
+ uses the thr_alarm() to break long lock statements.
+ (mysys can't use thr_alarm() as by default the alarm handling doesn't
+ exists)
+*/
int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
{
@@ -36,29 +44,34 @@ int my_lock(File fd,int locktype,my_off_t start,my_off_t length,myf MyFlags)
DBUG_ENTER("my_lock");
DBUG_PRINT("my",("Fd: %d Op: %d start: %ld Length: %ld MyFlags: %d",
fd,locktype,(ulong) start,(ulong) length,MyFlags));
- if (my_disable_locking)
+ if (my_disable_locking && ! (MyFlags & MY_FORCE_LOCK))
DBUG_RETURN(0); /* purecov: inspected */
+
m_lock.l_type=(short) locktype;
m_lock.l_whence=0L;
m_lock.l_start=(long) start;
m_lock.l_len=(long) length;
- wait_for_alarm=(MyFlags & MY_DONT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
- (uint) 12*60*60);
if (fcntl(fd,F_SETLK,&m_lock) != -1) /* Check if we can lock */
DBUG_RETURN(0); /* Ok, file locked */
- DBUG_PRINT("info",("Was locked, trying with alarm"));
- if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
- {
- int value;
- while ((value=fcntl(fd,F_SETLKW,&m_lock)) && !thr_got_alarm(&alarmed) &&
- errno == EINTR) ;
- thr_end_alarm(&alarmed);
- if (value != -1)
- DBUG_RETURN(0);
- }
- else
+
+ if (!(MyFlags & MY_NO_WAIT))
{
- errno=EINTR;
+ wait_for_alarm= (MyFlags & MY_SHORT_WAIT ? MY_HOW_OFTEN_TO_ALARM :
+ (uint) 12*60*60);
+ DBUG_PRINT("info",("Was locked, trying with alarm"));
+ if (!thr_alarm(&alarmed,wait_for_alarm,&alarm_buff))
+ {
+ int value;
+ while ((value=fcntl(fd,F_SETLKW,&m_lock)) && !thr_got_alarm(&alarmed) &&
+ errno == EINTR) ;
+ thr_end_alarm(&alarmed);
+ if (value != -1)
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ errno=EINTR;
+ }
}
if (errno == EINTR || errno == EACCES)
my_errno=EAGAIN; /* Easier to check for this */
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 4b89a7a7961..7b3c264c896 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -45,6 +45,7 @@
#include "sql_array.h"
#include "sql_plugin.h"
#include "scheduler.h"
+#include "log_slow.h"
class Parser_state;
@@ -543,14 +544,27 @@ protected:
#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4
#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8
-#define OPTIMIZER_SWITCH_LAST 16
-/* The following must be kept in sync with optimizer_switch_str in mysqld.cc */
-#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
- OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
- OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
- OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
+#ifdef DBUG_OFF
+# define OPTIMIZER_SWITCH_LAST 16
+#else
+# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 16
+# define OPTIMIZER_SWITCH_LAST 32
+#endif
+#ifdef DBUG_OFF
+/* The following must be kept in sync with optimizer_switch_str in mysqld.cc */
+# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
+#else
+# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
+ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
+ OPTIMIZER_SWITCH_TABLE_ELIMINATION)
+#endif
/*
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
@@ -653,7 +667,8 @@ enum enum_parsing_place
IN_HAVING,
SELECT_LIST,
IN_WHERE,
- IN_ON
+ IN_ON,
+ IN_GROUP_BY
};
struct st_table;
@@ -900,20 +915,19 @@ struct Query_cache_query_flags
(((L)->sql_command == SQLCOM_SELECT) && (L)->safe_to_cache_query)
#else
#define QUERY_CACHE_FLAGS_SIZE 0
-#define query_cache_store_query(A, B)
-#define query_cache_destroy()
-#define query_cache_result_size_limit(A)
-#define query_cache_init()
-#define query_cache_resize(A)
-#define query_cache_set_min_res_unit(A)
-#define query_cache_invalidate3(A, B, C)
-#define query_cache_invalidate1(A)
+#define query_cache_store_query(A, B) do { } while(0)
+#define query_cache_destroy() do { } while(0)
+#define query_cache_result_size_limit(A) do { } while(0)
+#define query_cache_init() do { } while(0)
+#define query_cache_resize(A) do { } while(0)
+#define query_cache_set_min_res_unit(A) do { } while(0)
+#define query_cache_invalidate3(A, B, C) do { } while(0)
+#define query_cache_invalidate1(A) do { } while(0)
#define query_cache_send_result_to_client(A, B, C) 0
#define query_cache_invalidate_by_MyISAM_filename_ref NULL
#define query_cache_abort(A)
#define query_cache_end_of_result(A)
-#define query_cache_invalidate_by_MyISAM_filename_ref NULL
#define query_cache_maybe_disabled(T) 1
#define query_cache_is_cacheable_query(L) 0
#endif /*HAVE_QUERY_CACHE*/
@@ -938,7 +952,7 @@ inline bool check_and_unset_keyword(const char *dbug_str)
{
const char *extra_str= "-d,";
char total_str[200];
- if (_db_strict_keyword_ (dbug_str))
+ if (_db_keyword_ (0, dbug_str, 1))
{
strxmov(total_str, extra_str, dbug_str, NullS);
DBUG_SET(total_str);
@@ -998,7 +1012,7 @@ check_and_unset_inject_value(int value)
#define SET_ERROR_INJECT_VALUE(x) \
current_thd->error_inject_value= (x)
#define ERROR_INJECT_CRASH(code) \
- DBUG_EVALUATE_IF(code, (abort(), 0), 0)
+ DBUG_EVALUATE_IF(code, (DBUG_ABORT(), 0), 0)
#define ERROR_INJECT_ACTION(code, action) \
(check_and_unset_keyword(code) ? ((action), 0) : 0)
#define ERROR_INJECT(code) \
@@ -1008,7 +1022,7 @@ check_and_unset_inject_value(int value)
#define ERROR_INJECT_VALUE_ACTION(value,action) \
(check_and_unset_inject_value(value) ? (action) : 0)
#define ERROR_INJECT_VALUE_CRASH(value) \
- ERROR_INJECT_VALUE_ACTION(value, (abort(), 0))
+ ERROR_INJECT_VALUE_ACTION(value, (DBUG_ABORT(), 0))
#endif
@@ -1031,6 +1045,9 @@ inline bool is_supported_parser_charset(CHARSET_INFO *cs)
return test(cs->mbminlen == 1);
}
bool setup_connection_thread_globals(THD *thd);
+bool login_connection(THD *thd);
+void end_connection(THD *thd);
+void prepare_new_connection_state(THD* thd);
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
@@ -1083,7 +1100,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
void log_slow_statement(THD *thd);
bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
bool records_are_comparable(const TABLE *table);
-bool compare_records(const TABLE *table);
+bool compare_record(const TABLE *table);
bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
void wait_while_table_is_used(THD *thd, TABLE *table,
@@ -1173,7 +1190,7 @@ int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
List<Item> &fields, List<Item> &all_fields, ORDER *order,
bool *hidden_group_fields);
bool fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
- Item **ref_pointer_array, ORDER *group_list= NULL);
+ Item **ref_pointer_array);
bool handle_select(THD *thd, LEX *lex, select_result *result,
ulong setup_tables_done_option);
@@ -1195,6 +1212,11 @@ bool mysql_handle_derived(LEX *lex, bool (*processor)(THD *thd,
TABLE_LIST *table));
bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t);
bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
+bool check_table_file_presence(char *old_path, char *path,
+ const char *db,
+ const char *table_name,
+ const char *alias,
+ bool issue_error);
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item ***copy_func, Field **from_field,
Field **def_field,
@@ -1250,6 +1272,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag,
bool ignore);
+void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type,
+ enum_duplicates duplic,
+ bool is_multi_insert);
int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
TABLE_LIST *table_list);
void prepare_triggers_for_insert_stmt(TABLE *table);
@@ -1459,6 +1484,7 @@ bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *group,bool asc);
bool push_new_name_resolution_context(THD *thd,
TABLE_LIST *left_op,
TABLE_LIST *right_op);
+Item *normalize_cond(Item *cond);
void add_join_on(TABLE_LIST *b,Item *expr);
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields,
SELECT_LEX *lex);
@@ -1606,7 +1632,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
#define RTFC_WAIT_OTHER_THREAD_FLAG 0x0002
#define RTFC_CHECK_KILLED_FLAG 0x0004
bool remove_table_from_cache(THD *thd, const char *db, const char *table,
- uint flags);
+ uint flags, my_bool deleting);
#define NORMAL_PART_NAME 0
#define TEMP_PART_NAME 1
@@ -1940,6 +1966,7 @@ extern ulong slow_launch_threads, slow_launch_time;
extern ulong table_cache_size, table_def_size;
extern MYSQL_PLUGIN_IMPORT ulong max_connections;
extern ulong max_connect_errors, connect_timeout;
+extern ulong extra_max_connections;
extern ulong slave_net_timeout, slave_trans_retries;
extern uint max_user_connections;
extern ulong what_to_log,flush_time;
@@ -1962,7 +1989,7 @@ extern ulong opt_tc_log_size, tc_log_max_pages_used, tc_log_page_size;
extern ulong tc_log_page_waits;
extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb;
extern uint test_flags,select_errors,ha_open_options;
-extern uint protocol_version, mysqld_port, dropping_tables;
+extern uint protocol_version, mysqld_port, mysqld_extra_port, dropping_tables;
extern uint delay_key_write_options;
extern ulong max_long_data_size;
#endif /* MYSQL_SERVER */
@@ -1990,14 +2017,15 @@ extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop, shutdown_in_progress;
extern bool in_bootstrap;
extern uint volatile thread_count, thread_running, global_read_lock;
-extern uint connection_count;
+extern ulong thread_created;
+extern uint connection_count, extra_connection_count;
extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
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 my_bool opt_readonly, lower_case_file_system;
extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
-extern my_bool opt_secure_auth;
+extern my_bool opt_secure_auth, debug_assert_if_crashed_table;
extern char* opt_secure_file_priv;
extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
extern my_bool sp_automatic_privileges, opt_noacl;
@@ -2028,7 +2056,7 @@ extern FILE *stderror_file;
extern pthread_key(MEM_ROOT**,THR_MALLOC);
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db,
LOCK_mapped_file,LOCK_user_locks, LOCK_status,
- LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
+ LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock,
LOCK_global_system_variables, LOCK_user_conn,
@@ -2059,7 +2087,7 @@ extern MYSQL_PLUGIN_IMPORT struct system_variables global_system_variables;
#ifdef MYSQL_SERVER
extern struct system_variables max_system_variables;
extern struct system_status_var global_status_var;
-extern struct rand_struct sql_rand;
+extern struct my_rnd_struct sql_rand;
extern const char *opt_date_time_formats[];
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
@@ -2081,6 +2109,11 @@ extern SHOW_COMP_OPTION have_community_features;
extern handlerton *partition_hton;
extern handlerton *myisam_hton;
+/*
+ @todo remove, make it static in ha_maria.cc
+ currently it's needed for sql_select.cc
+*/
+extern handlerton *maria_hton;
extern handlerton *heap_hton;
extern SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen;
@@ -2295,6 +2328,7 @@ const char *get_canonical_filename(handler *file, const char *path,
#define MYSQL50_TABLE_NAME_PREFIX "#mysql50#"
#define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9
+#define SAFE_NAME_LEN (NAME_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH)
uint build_table_shadow_filename(char *buff, size_t bufflen,
ALTER_PARTITION_PARAM_TYPE *lpt);
diff --git a/sql/mysql_priv.h.pp b/sql/mysql_priv.h.pp
deleted file mode 100644
index d874a2591d1..00000000000
--- a/sql/mysql_priv.h.pp
+++ /dev/null
@@ -1,10977 +0,0 @@
-#include <my_global.h>
-#include <my_config.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <math.h>
-#include <limits.h>
-#include <float.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/timeb.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-#include <alloca.h>
-#include <errno.h>
-#include <crypt.h>
-#include <assert.h>
-#include <my_attribute.h>
-int __cxa_pure_virtual () __attribute__ ((weak));
-#include <my_dbug.h>
-struct _db_code_state_;
-extern int _db_keyword_(struct _db_code_state_ *cs, const char *keyword);
-extern int _db_strict_keyword_(const char *keyword);
-extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
-extern int _db_explain_init_(char *buf, size_t len);
-extern void _db_setjmp_(void);
-extern void _db_longjmp_(void);
-extern void _db_process_(const char *name);
-extern void _db_push_(const char *control);
-extern void _db_pop_(void);
-extern void _db_set_(struct _db_code_state_ *cs, const char *control);
-extern void _db_set_init_(const char *control);
-extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
- const char **_sfunc_,const char **_sfile_,
- uint *_slevel_, char ***);
-extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
- uint *_slevel_);
-extern void _db_pargs_(uint _line_,const char *keyword);
-extern void _db_doprnt_ (const char *format,...)
- __attribute__((format(printf, 1, 2)));
-extern void _db_dump_(uint _line_,const char *keyword,
- const unsigned char *memory, size_t length);
-extern void _db_end_(void);
-extern void _db_lock_file_(void);
-extern void _db_unlock_file_(void);
-extern FILE *_db_fp_(void);
-typedef int File;
-typedef int my_socket;
-typedef void (*sig_return)();
-typedef char pchar;
-typedef char puchar;
-typedef char pbool;
-typedef short pshort;
-typedef float pfloat;
-typedef int (*qsort_cmp)(const void *,const void *);
-typedef int (*qsort_cmp2)(void*, const void *,const void *);
-#include <sys/socket.h>
-typedef socklen_t size_socket;
-typedef long my_ptrdiff_t;
-typedef unsigned char uchar;
-typedef signed char int8;
-typedef unsigned char uint8;
-typedef short int16;
-typedef unsigned short uint16;
-typedef int int32;
-typedef unsigned int uint32;
-typedef unsigned long long int ulonglong;
-typedef long long int longlong;
-typedef longlong int64;
-typedef ulonglong uint64;
-typedef unsigned long long my_ulonglong;
-typedef int intptr;
-typedef ulonglong my_off_t;
-typedef off_t os_off_t;
-typedef uint8 int7;
-typedef short int15;
-typedef int myf;
-typedef char my_bool;
-typedef char bool;
-typedef union {
- double v;
- long m[2];
-} doubleget_union;
-#include <dlfcn.h>
-#include <mysql_version.h>
-#include <mysql_embed.h>
-#include <my_sys.h>
-#include <my_pthread.h>
-#include <pthread.h>
-#include <sched.h>
-extern int my_pthread_getprio(pthread_t thread_id);
-typedef void *(* pthread_handler)(void *);
-extern void my_pthread_setprio(pthread_t thread_id,int prior);
-extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
-typedef struct st_safe_mutex_t
-{
- pthread_mutex_t global,mutex;
- const char *file;
- uint line,count;
- pthread_t thread;
-} safe_mutex_t;
-int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
- const char *file, uint line);
-int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line);
-int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
-int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
-int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
- uint line);
-int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
- struct timespec *abstime, const char *file, uint line);
-void safe_mutex_global_init(void);
-void safe_mutex_end(FILE *file);
-typedef ulong my_thread_id;
-extern my_bool my_thread_global_init(void);
-extern void my_thread_global_end(void);
-extern my_bool my_thread_init(void);
-extern void my_thread_end(void);
-extern const char *my_thread_name(void);
-extern my_thread_id my_thread_dbug_id(void);
-extern int pthread_no_free(void *);
-extern int pthread_dummy(int);
-struct st_my_thread_var
-{
- int thr_errno;
- pthread_cond_t suspend;
- pthread_mutex_t mutex;
- pthread_mutex_t * volatile current_mutex;
- pthread_cond_t * volatile current_cond;
- pthread_t pthread_self;
- my_thread_id id;
- int cmp_length;
- int volatile abort;
- my_bool init;
- struct st_my_thread_var *next,**prev;
- void *opt_info;
- void *dbug;
- char name[10 +1];
-};
-extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
-extern uint my_thread_end_wait_time;
-extern uint thd_lib_detected;
-#include <m_ctype.h>
-#include <my_attribute.h>
-typedef struct unicase_info_st
-{
- uint16 toupper;
- uint16 tolower;
- uint16 sort;
-} MY_UNICASE_INFO;
-extern MY_UNICASE_INFO *my_unicase_default[256];
-extern MY_UNICASE_INFO *my_unicase_turkish[256];
-typedef struct uni_ctype_st
-{
- uchar pctype;
- uchar *ctype;
-} MY_UNI_CTYPE;
-extern MY_UNI_CTYPE my_uni_ctype[256];
-typedef struct my_uni_idx_st
-{
- uint16 from;
- uint16 to;
- uchar *tab;
-} MY_UNI_IDX;
-typedef struct
-{
- uint beg;
- uint end;
- uint mb_len;
-} my_match_t;
-enum my_lex_states
-{
- MY_LEX_START, MY_LEX_CHAR, MY_LEX_IDENT,
- MY_LEX_IDENT_SEP, MY_LEX_IDENT_START,
- MY_LEX_REAL, MY_LEX_HEX_NUMBER, MY_LEX_BIN_NUMBER,
- MY_LEX_CMP_OP, MY_LEX_LONG_CMP_OP, MY_LEX_STRING, MY_LEX_COMMENT, MY_LEX_END,
- MY_LEX_OPERATOR_OR_IDENT, MY_LEX_NUMBER_IDENT, MY_LEX_INT_OR_REAL,
- MY_LEX_REAL_OR_POINT, MY_LEX_BOOL, MY_LEX_EOL, MY_LEX_ESCAPE,
- MY_LEX_LONG_COMMENT, MY_LEX_END_LONG_COMMENT, MY_LEX_SEMICOLON,
- MY_LEX_SET_VAR, MY_LEX_USER_END, MY_LEX_HOSTNAME, MY_LEX_SKIP,
- MY_LEX_USER_VARIABLE_DELIMITER, MY_LEX_SYSTEM_VAR,
- MY_LEX_IDENT_OR_KEYWORD,
- MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN, MY_LEX_IDENT_OR_NCHAR,
- MY_LEX_STRING_OR_DELIMITER
-};
-struct charset_info_st;
-typedef struct my_collation_handler_st
-{
- my_bool (*init)(struct charset_info_st *, void *(*alloc)(size_t));
- int (*strnncoll)(struct charset_info_st *,
- const uchar *, size_t, const uchar *, size_t, my_bool);
- int (*strnncollsp)(struct charset_info_st *,
- const uchar *, size_t, const uchar *, size_t,
- my_bool diff_if_only_endspace_difference);
- size_t (*strnxfrm)(struct charset_info_st *,
- uchar *, size_t, const uchar *, size_t);
- size_t (*strnxfrmlen)(struct charset_info_st *, size_t);
- my_bool (*like_range)(struct charset_info_st *,
- const char *s, size_t s_length,
- pchar w_prefix, pchar w_one, pchar w_many,
- size_t res_length,
- char *min_str, char *max_str,
- size_t *min_len, size_t *max_len);
- int (*wildcmp)(struct charset_info_st *,
- const char *str,const char *str_end,
- const char *wildstr,const char *wildend,
- int escape,int w_one, int w_many);
- int (*strcasecmp)(struct charset_info_st *, const char *, const char *);
- uint (*instr)(struct charset_info_st *,
- const char *b, size_t b_length,
- const char *s, size_t s_length,
- my_match_t *match, uint nmatch);
- void (*hash_sort)(struct charset_info_st *cs, const uchar *key, size_t len,
- ulong *nr1, ulong *nr2);
- my_bool (*propagate)(struct charset_info_st *cs, const uchar *str, size_t len);
-} MY_COLLATION_HANDLER;
-extern MY_COLLATION_HANDLER my_collation_mb_bin_handler;
-extern MY_COLLATION_HANDLER my_collation_8bit_bin_handler;
-extern MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler;
-extern MY_COLLATION_HANDLER my_collation_ucs2_uca_handler;
-typedef int (*my_charset_conv_mb_wc)(struct charset_info_st *, ulong *,
- const uchar *, const uchar *);
-typedef int (*my_charset_conv_wc_mb)(struct charset_info_st *, ulong,
- uchar *, uchar *);
-typedef size_t (*my_charset_conv_case)(struct charset_info_st *,
- char *, size_t, char *, size_t);
-typedef struct my_charset_handler_st
-{
- my_bool (*init)(struct charset_info_st *, void *(*alloc)(size_t));
- uint (*ismbchar)(struct charset_info_st *, const char *, const char *);
- uint (*mbcharlen)(struct charset_info_st *, uint c);
- size_t (*numchars)(struct charset_info_st *, const char *b, const char *e);
- size_t (*charpos)(struct charset_info_st *, const char *b, const char *e,
- size_t pos);
- size_t (*well_formed_len)(struct charset_info_st *,
- const char *b,const char *e,
- size_t nchars, int *error);
- size_t (*lengthsp)(struct charset_info_st *, const char *ptr, size_t length);
- size_t (*numcells)(struct charset_info_st *, const char *b, const char *e);
- my_charset_conv_mb_wc mb_wc;
- my_charset_conv_wc_mb wc_mb;
- int (*ctype)(struct charset_info_st *cs, int *ctype,
- const uchar *s, const uchar *e);
- size_t (*caseup_str)(struct charset_info_st *, char *);
- size_t (*casedn_str)(struct charset_info_st *, char *);
- my_charset_conv_case caseup;
- my_charset_conv_case casedn;
- size_t (*snprintf)(struct charset_info_st *, char *to, size_t n,
- const char *fmt,
- ...) __attribute__((format(printf, 4, 5)));
- size_t (*long10_to_str)(struct charset_info_st *, char *to, size_t n,
- int radix, long int val);
- size_t (*longlong10_to_str)(struct charset_info_st *, char *to, size_t n,
- int radix, longlong val);
- void (*fill)(struct charset_info_st *, char *to, size_t len, int fill);
- long (*strntol)(struct charset_info_st *, const char *s, size_t l,
- int base, char **e, int *err);
- ulong (*strntoul)(struct charset_info_st *, const char *s, size_t l,
- int base, char **e, int *err);
- longlong (*strntoll)(struct charset_info_st *, const char *s, size_t l,
- int base, char **e, int *err);
- ulonglong (*strntoull)(struct charset_info_st *, const char *s, size_t l,
- int base, char **e, int *err);
- double (*strntod)(struct charset_info_st *, char *s, size_t l, char **e,
- int *err);
- longlong (*strtoll10)(struct charset_info_st *cs,
- const char *nptr, char **endptr, int *error);
- ulonglong (*strntoull10rnd)(struct charset_info_st *cs,
- const char *str, size_t length,
- int unsigned_fl,
- char **endptr, int *error);
- size_t (*scan)(struct charset_info_st *, const char *b, const char *e,
- int sq);
-} MY_CHARSET_HANDLER;
-extern MY_CHARSET_HANDLER my_charset_8bit_handler;
-extern MY_CHARSET_HANDLER my_charset_ucs2_handler;
-typedef struct charset_info_st
-{
- uint number;
- uint primary_number;
- uint binary_number;
- uint state;
- const char *csname;
- const char *name;
- const char *comment;
- const char *tailoring;
- uchar *ctype;
- uchar *to_lower;
- uchar *to_upper;
- uchar *sort_order;
- uint16 *contractions;
- uint16 **sort_order_big;
- uint16 *tab_to_uni;
- MY_UNI_IDX *tab_from_uni;
- MY_UNICASE_INFO **caseinfo;
- uchar *state_map;
- uchar *ident_map;
- uint strxfrm_multiply;
- uchar caseup_multiply;
- uchar casedn_multiply;
- uint mbminlen;
- uint mbmaxlen;
- uint16 min_sort_char;
- uint16 max_sort_char;
- uchar pad_char;
- my_bool escape_with_backslash_is_dangerous;
- MY_CHARSET_HANDLER *cset;
- MY_COLLATION_HANDLER *coll;
-} CHARSET_INFO;
-extern CHARSET_INFO my_charset_bin;
-extern CHARSET_INFO my_charset_big5_chinese_ci;
-extern CHARSET_INFO my_charset_big5_bin;
-extern CHARSET_INFO my_charset_cp932_japanese_ci;
-extern CHARSET_INFO my_charset_cp932_bin;
-extern CHARSET_INFO my_charset_eucjpms_japanese_ci;
-extern CHARSET_INFO my_charset_eucjpms_bin;
-extern CHARSET_INFO my_charset_euckr_korean_ci;
-extern CHARSET_INFO my_charset_euckr_bin;
-extern CHARSET_INFO my_charset_gb2312_chinese_ci;
-extern CHARSET_INFO my_charset_gb2312_bin;
-extern CHARSET_INFO my_charset_gbk_chinese_ci;
-extern CHARSET_INFO my_charset_gbk_bin;
-extern CHARSET_INFO my_charset_latin1;
-extern CHARSET_INFO my_charset_latin1_german2_ci;
-extern CHARSET_INFO my_charset_latin1_bin;
-extern CHARSET_INFO my_charset_latin2_czech_ci;
-extern CHARSET_INFO my_charset_sjis_japanese_ci;
-extern CHARSET_INFO my_charset_sjis_bin;
-extern CHARSET_INFO my_charset_tis620_thai_ci;
-extern CHARSET_INFO my_charset_tis620_bin;
-extern CHARSET_INFO my_charset_ucs2_general_ci;
-extern CHARSET_INFO my_charset_ucs2_bin;
-extern CHARSET_INFO my_charset_ucs2_unicode_ci;
-extern CHARSET_INFO my_charset_ujis_japanese_ci;
-extern CHARSET_INFO my_charset_ujis_bin;
-extern CHARSET_INFO my_charset_utf8_general_ci;
-extern CHARSET_INFO my_charset_utf8_unicode_ci;
-extern CHARSET_INFO my_charset_utf8_bin;
-extern CHARSET_INFO my_charset_cp1250_czech_ci;
-extern CHARSET_INFO my_charset_filename;
-extern size_t my_strnxfrm_simple(CHARSET_INFO *, uchar *, size_t,
- const uchar *, size_t);
-size_t my_strnxfrmlen_simple(CHARSET_INFO *, size_t);
-extern int my_strnncoll_simple(CHARSET_INFO *, const uchar *, size_t,
- const uchar *, size_t, my_bool);
-extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, size_t,
- const uchar *, size_t,
- my_bool diff_if_only_endspace_difference);
-extern void my_hash_sort_simple(CHARSET_INFO *cs,
- const uchar *key, size_t len,
- ulong *nr1, ulong *nr2);
-extern size_t my_lengthsp_8bit(CHARSET_INFO *cs, const char *ptr, size_t length);
-extern uint my_instr_simple(struct charset_info_st *,
- const char *b, size_t b_length,
- const char *s, size_t s_length,
- my_match_t *match, uint nmatch);
-extern size_t my_caseup_str_8bit(CHARSET_INFO *, char *);
-extern size_t my_casedn_str_8bit(CHARSET_INFO *, char *);
-extern size_t my_caseup_8bit(CHARSET_INFO *, char *src, size_t srclen,
- char *dst, size_t dstlen);
-extern size_t my_casedn_8bit(CHARSET_INFO *, char *src, size_t srclen,
- char *dst, size_t dstlen);
-extern int my_strcasecmp_8bit(CHARSET_INFO * cs, const char *, const char *);
-int my_mb_wc_8bit(CHARSET_INFO *cs,ulong *wc, const uchar *s,const uchar *e);
-int my_wc_mb_8bit(CHARSET_INFO *cs,ulong wc, uchar *s, uchar *e);
-int my_mb_ctype_8bit(CHARSET_INFO *,int *, const uchar *,const uchar *);
-int my_mb_ctype_mb(CHARSET_INFO *,int *, const uchar *,const uchar *);
-size_t my_scan_8bit(CHARSET_INFO *cs, const char *b, const char *e, int sq);
-size_t my_snprintf_8bit(struct charset_info_st *, char *to, size_t n,
- const char *fmt, ...)
- __attribute__((format(printf, 4, 5)));
-long my_strntol_8bit(CHARSET_INFO *, const char *s, size_t l, int base,
- char **e, int *err);
-ulong my_strntoul_8bit(CHARSET_INFO *, const char *s, size_t l, int base,
- char **e, int *err);
-longlong my_strntoll_8bit(CHARSET_INFO *, const char *s, size_t l, int base,
- char **e, int *err);
-ulonglong my_strntoull_8bit(CHARSET_INFO *, const char *s, size_t l, int base,
- char **e, int *err);
-double my_strntod_8bit(CHARSET_INFO *, char *s, size_t l,char **e,
- int *err);
-size_t my_long10_to_str_8bit(CHARSET_INFO *, char *to, size_t l, int radix,
- long int val);
-size_t my_longlong10_to_str_8bit(CHARSET_INFO *, char *to, size_t l, int radix,
- longlong val);
-longlong my_strtoll10_8bit(CHARSET_INFO *cs,
- const char *nptr, char **endptr, int *error);
-longlong my_strtoll10_ucs2(CHARSET_INFO *cs,
- const char *nptr, char **endptr, int *error);
-ulonglong my_strntoull10rnd_8bit(CHARSET_INFO *cs,
- const char *str, size_t length, int
- unsigned_fl, char **endptr, int *error);
-ulonglong my_strntoull10rnd_ucs2(CHARSET_INFO *cs,
- const char *str, size_t length,
- int unsigned_fl, char **endptr, int *error);
-void my_fill_8bit(CHARSET_INFO *cs, char* to, size_t l, int fill);
-my_bool my_like_range_simple(CHARSET_INFO *cs,
- const char *ptr, size_t ptr_length,
- pbool escape, pbool w_one, pbool w_many,
- size_t res_length,
- char *min_str, char *max_str,
- size_t *min_length, size_t *max_length);
-my_bool my_like_range_mb(CHARSET_INFO *cs,
- const char *ptr, size_t ptr_length,
- pbool escape, pbool w_one, pbool w_many,
- size_t res_length,
- char *min_str, char *max_str,
- size_t *min_length, size_t *max_length);
-my_bool my_like_range_ucs2(CHARSET_INFO *cs,
- const char *ptr, size_t ptr_length,
- pbool escape, pbool w_one, pbool w_many,
- size_t res_length,
- char *min_str, char *max_str,
- size_t *min_length, size_t *max_length);
-int my_wildcmp_8bit(CHARSET_INFO *,
- const char *str,const char *str_end,
- const char *wildstr,const char *wildend,
- int escape, int w_one, int w_many);
-int my_wildcmp_bin(CHARSET_INFO *,
- const char *str,const char *str_end,
- const char *wildstr,const char *wildend,
- int escape, int w_one, int w_many);
-size_t my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e);
-size_t my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e);
-size_t my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, size_t pos);
-size_t my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e,
- size_t pos, int *error);
-uint my_mbcharlen_8bit(CHARSET_INFO *, uint c);
-extern size_t my_caseup_str_mb(CHARSET_INFO *, char *);
-extern size_t my_casedn_str_mb(CHARSET_INFO *, char *);
-extern size_t my_caseup_mb(CHARSET_INFO *, char *src, size_t srclen,
- char *dst, size_t dstlen);
-extern size_t my_casedn_mb(CHARSET_INFO *, char *src, size_t srclen,
- char *dst, size_t dstlen);
-extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *);
-int my_wildcmp_mb(CHARSET_INFO *,
- const char *str,const char *str_end,
- const char *wildstr,const char *wildend,
- int escape, int w_one, int w_many);
-size_t my_numchars_mb(CHARSET_INFO *, const char *b, const char *e);
-size_t my_numcells_mb(CHARSET_INFO *, const char *b, const char *e);
-size_t my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, size_t pos);
-size_t my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e,
- size_t pos, int *error);
-uint my_instr_mb(struct charset_info_st *,
- const char *b, size_t b_length,
- const char *s, size_t s_length,
- my_match_t *match, uint nmatch);
-int my_wildcmp_unicode(CHARSET_INFO *cs,
- const char *str, const char *str_end,
- const char *wildstr, const char *wildend,
- int escape, int w_one, int w_many,
- MY_UNICASE_INFO **weights);
-extern my_bool my_parse_charset_xml(const char *bug, size_t len,
- int (*add)(CHARSET_INFO *cs));
-extern char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end,
- pchar c);
-my_bool my_propagate_simple(CHARSET_INFO *cs, const uchar *str, size_t len);
-my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, size_t len);
-uint my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong len);
-my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
-my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs);
-#include <stdarg.h>
-#include <typelib.h>
-#include "my_alloc.h"
-typedef struct st_used_mem
-{
- struct st_used_mem *next;
- unsigned int left;
- unsigned int size;
-} USED_MEM;
-typedef struct st_mem_root
-{
- USED_MEM *free;
- USED_MEM *used;
- USED_MEM *pre_alloc;
- size_t min_malloc;
- size_t block_size;
- unsigned int block_num;
- unsigned int first_block_usage;
- void (*error_handler)(void);
-} MEM_ROOT;
-typedef struct st_typelib {
- unsigned int count;
- const char *name;
- const char **type_names;
- unsigned int *type_lengths;
-} TYPELIB;
-extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
-extern int find_type_or_exit(const char *x, TYPELIB *typelib,
- const char *option);
-extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name);
-extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
-extern const char *get_type(TYPELIB *typelib,unsigned int nr);
-extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
-extern TYPELIB sql_protocol_typelib;
-extern void *my_malloc(size_t Size,myf MyFlags);
-extern void *my_realloc(void *oldpoint, size_t Size, myf MyFlags);
-extern void my_no_flags_free(void *ptr);
-extern void *my_memdup(const void *from,size_t length,myf MyFlags);
-extern char *my_strdup(const char *from,myf MyFlags);
-extern char *my_strndup(const char *from, size_t length,
- myf MyFlags);
-extern uint my_get_large_page_size(void);
-extern uchar * my_large_malloc(size_t size, myf my_flags);
-extern void my_large_free(uchar * ptr, myf my_flags);
-extern int errno;
-extern char errbuff[(2)][(256)];
-extern char *home_dir;
-extern const char *my_progname;
-extern char curr_dir[];
-extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
-extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
- myf MyFlags);
-extern uint my_file_limit;
-extern ulong my_thread_stack_size;
-extern my_bool my_use_large_pages;
-extern uint my_large_page_size;
-extern CHARSET_INFO *default_charset_info;
-extern CHARSET_INFO *all_charsets[256];
-extern CHARSET_INFO compiled_charsets[];
-extern ulong my_file_opened,my_stream_opened, my_tmp_file_created;
-extern ulong my_file_total_opened;
-extern uint mysys_usage_id;
-extern my_bool my_init_done;
-extern void (*my_sigtstp_cleanup)(void),
- (*my_sigtstp_restart)(void),
- (*my_abort_hook)(int);
-extern int my_umask,
- my_umask_dir,
- my_recived_signals,
- my_safe_to_handle_signal,
- my_dont_interrupt;
-extern my_bool mysys_uses_curses, my_use_symdir;
-extern ulong sf_malloc_cur_memory, sf_malloc_max_memory;
-extern ulong my_default_record_cache_size;
-extern my_bool my_disable_locking, my_disable_async_io,
- my_disable_flush_key_blocks, my_disable_symlinks;
-extern char wild_many,wild_one,wild_prefix;
-extern const char *charsets_dir;
-extern char *my_defaults_extra_file;
-extern const char *my_defaults_group_suffix;
-extern const char *my_defaults_file;
-extern my_bool timed_mutexes;
-typedef struct wild_file_pack
-{
- uint wilds;
- uint not_pos;
- char * *wild;
-} WF_PACK;
-enum loglevel {
- ERROR_LEVEL,
- WARNING_LEVEL,
- INFORMATION_LEVEL
-};
-enum cache_type
-{
- TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE,
- SEQ_READ_APPEND ,
- READ_FIFO, READ_NET,WRITE_NET};
-enum flush_type
-{
- FLUSH_KEEP,
- FLUSH_RELEASE,
- FLUSH_IGNORE_CHANGED,
- FLUSH_FORCE_WRITE
-};
-typedef struct st_record_cache
-{
- File file;
- int rc_seek,error,inited;
- uint rc_length,read_length,reclength;
- my_off_t rc_record_pos,end_of_file;
- uchar *rc_buff,*rc_buff2,*rc_pos,*rc_end,*rc_request_pos;
- enum cache_type type;
-} RECORD_CACHE;
-enum file_type
-{
- UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE, STREAM_BY_FOPEN, STREAM_BY_FDOPEN,
- FILE_BY_MKSTEMP, FILE_BY_DUP
-};
-struct st_my_file_info
-{
- char * name;
- enum file_type type;
-};
-extern struct st_my_file_info *my_file_info;
-typedef struct st_dynamic_array
-{
- uchar *buffer;
- uint elements,max_element;
- uint alloc_increment;
- uint size_of_element;
-} DYNAMIC_ARRAY;
-typedef struct st_my_tmpdir
-{
- DYNAMIC_ARRAY full_list;
- char **list;
- uint cur, max;
- pthread_mutex_t mutex;
-} MY_TMPDIR;
-typedef struct st_dynamic_string
-{
- char *str;
- size_t length,max_length,alloc_increment;
-} DYNAMIC_STRING;
-struct st_io_cache;
-typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
-typedef struct st_io_cache_share
-{
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- pthread_cond_t cond_writer;
- my_off_t pos_in_file;
- struct st_io_cache *source_cache;
- uchar *buffer;
- uchar *read_end;
- int running_threads;
- int total_threads;
- int error;
-} IO_CACHE_SHARE;
-typedef struct st_io_cache
-{
- my_off_t pos_in_file;
- my_off_t end_of_file;
- uchar *read_pos;
- uchar *read_end;
- uchar *buffer;
- uchar *request_pos;
- uchar *write_buffer;
- uchar *append_read_pos;
- uchar *write_pos;
- uchar *write_end;
- uchar **current_pos, **current_end;
- pthread_mutex_t append_buffer_lock;
- IO_CACHE_SHARE *share;
- int (*read_function)(struct st_io_cache *,uchar *,size_t);
- int (*write_function)(struct st_io_cache *,const uchar *,size_t);
- enum cache_type type;
- IO_CACHE_CALLBACK pre_read;
- IO_CACHE_CALLBACK post_read;
- IO_CACHE_CALLBACK pre_close;
- ulong disk_writes;
- void* arg;
- char *file_name;
- char *dir,*prefix;
- File file;
- int seek_not_done,error;
- size_t buffer_length;
- size_t read_length;
- myf myflags;
- my_bool alloced_buffer;
-} IO_CACHE;
-typedef int (*qsort2_cmp)(const void *, const void *, const void *);
-int my_b_copy_to_file(IO_CACHE *cache, FILE *file);
-my_off_t my_b_append_tell(IO_CACHE* info);
-my_off_t my_b_safe_tell(IO_CACHE* info);
-typedef uint32 ha_checksum;
-typedef int (*Process_option_func)(void *ctx, const char *group_name,
- const char *option);
-#include <my_alloc.h>
-extern int my_copy(const char *from,const char *to,myf MyFlags);
-extern int my_append(const char *from,const char *to,myf MyFlags);
-extern int my_delete(const char *name,myf MyFlags);
-extern int my_getwd(char * buf,size_t size,myf MyFlags);
-extern int my_setwd(const char *dir,myf MyFlags);
-extern int my_lock(File fd,int op,my_off_t start, my_off_t length,myf MyFlags);
-extern void *my_once_alloc(size_t Size,myf MyFlags);
-extern void my_once_free(void);
-extern char *my_once_strdup(const char *src,myf myflags);
-extern void *my_once_memdup(const void *src, size_t len, myf myflags);
-extern File my_open(const char *FileName,int Flags,myf MyFlags);
-extern File my_register_filename(File fd, const char *FileName,
- enum file_type type_of_file,
- uint error_message_number, myf MyFlags);
-extern File my_create(const char *FileName,int CreateFlags,
- int AccessFlags, myf MyFlags);
-extern int my_close(File Filedes,myf MyFlags);
-extern File my_dup(File file, myf MyFlags);
-extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
-extern int my_readlink(char *to, const char *filename, myf MyFlags);
-extern int my_realpath(char *to, const char *filename, myf MyFlags);
-extern File my_create_with_symlink(const char *linkname, const char *filename,
- int createflags, int access_flags,
- myf MyFlags);
-extern int my_delete_with_symlink(const char *name, myf MyFlags);
-extern int my_rename_with_symlink(const char *from,const char *to,myf MyFlags);
-extern int my_symlink(const char *content, const char *linkname, myf MyFlags);
-extern size_t my_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags);
-extern size_t my_pread(File Filedes,uchar *Buffer,size_t Count,my_off_t offset,
- myf MyFlags);
-extern int my_rename(const char *from,const char *to,myf MyFlags);
-extern my_off_t my_seek(File fd,my_off_t pos,int whence,myf MyFlags);
-extern my_off_t my_tell(File fd,myf MyFlags);
-extern size_t my_write(File Filedes,const uchar *Buffer,size_t Count,
- myf MyFlags);
-extern size_t my_pwrite(File Filedes,const uchar *Buffer,size_t Count,
- my_off_t offset,myf MyFlags);
-extern size_t my_fread(FILE *stream,uchar *Buffer,size_t Count,myf MyFlags);
-extern size_t my_fwrite(FILE *stream,const uchar *Buffer,size_t Count,
- myf MyFlags);
-extern my_off_t my_fseek(FILE *stream,my_off_t pos,int whence,myf MyFlags);
-extern my_off_t my_ftell(FILE *stream,myf MyFlags);
-extern void *_mymalloc(size_t uSize,const char *sFile,
- uint uLine, myf MyFlag);
-extern void *_myrealloc(void *pPtr,size_t uSize,const char *sFile,
- uint uLine, myf MyFlag);
-extern void * my_multi_malloc (myf MyFlags, ...);
-extern void _myfree(void *pPtr,const char *sFile,uint uLine, myf MyFlag);
-extern int _sanity(const char *sFile, uint uLine);
-extern void *_my_memdup(const void *from, size_t length,
- const char *sFile, uint uLine,myf MyFlag);
-extern char * _my_strdup(const char *from, const char *sFile, uint uLine,
- myf MyFlag);
-extern char *_my_strndup(const char *from, size_t length,
- const char *sFile, uint uLine,
- myf MyFlag);
-extern void *my_memmem(const void *haystack, size_t haystacklen,
- const void *needle, size_t needlelen);
-extern int check_if_legal_filename(const char *path);
-extern int check_if_legal_tablename(const char *path);
-extern void init_glob_errs(void);
-extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
-extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
-extern int my_fclose(FILE *fd,myf MyFlags);
-extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
-extern int my_sync(File fd, myf my_flags);
-extern int my_sync_dir(const char *dir_name, myf my_flags);
-extern int my_sync_dir_by_file(const char *file_name, myf my_flags);
-extern int my_error (int nr,myf MyFlags, ...);
-extern int my_printf_error (uint my_err, const char *format, myf MyFlags, ...)
- __attribute__((format(printf, 2, 4)));
-extern int my_error_register(const char **errmsgs, int first, int last);
-extern const char **my_error_unregister(int first, int last);
-extern int my_message(uint my_err, const char *str,myf MyFlags);
-extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
-extern int my_message_curses(uint my_err, const char *str,myf MyFlags);
-extern my_bool my_init(void);
-extern void my_end(int infoflag);
-extern int my_redel(const char *from, const char *to, int MyFlags);
-extern int my_copystat(const char *from, const char *to, int MyFlags);
-extern char * my_filename(File fd);
-extern my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist);
-extern char *my_tmpdir(MY_TMPDIR *tmpdir);
-extern void free_tmpdir(MY_TMPDIR *tmpdir);
-extern void my_remember_signal(int signal_number,void (*func)(int));
-extern size_t dirname_part(char * to,const char *name, size_t *to_res_length);
-extern size_t dirname_length(const char *name);
-extern int test_if_hard_path(const char *dir_name);
-extern my_bool has_path(const char *name);
-extern char *convert_dirname(char *to, const char *from, const char *from_end);
-extern void to_unix_path(char * name);
-extern char * fn_ext(const char *name);
-extern char * fn_same(char * toname,const char *name,int flag);
-extern char * fn_format(char * to,const char *name,const char *dir,
- const char *form, uint flag);
-extern size_t strlength(const char *str);
-extern void pack_dirname(char * to,const char *from);
-extern size_t unpack_dirname(char * to,const char *from);
-extern size_t cleanup_dirname(char * to,const char *from);
-extern size_t system_filename(char * to,const char *from);
-extern size_t unpack_filename(char * to,const char *from);
-extern char * intern_filename(char * to,const char *from);
-extern char * directory_file_name(char * dst, const char *src);
-extern int pack_filename(char * to, const char *name, size_t max_length);
-extern char * my_path(char * to,const char *progname,
- const char *own_pathname_part);
-extern char * my_load_path(char * to, const char *path,
- const char *own_path_prefix);
-extern int wild_compare(const char *str,const char *wildstr,
- pbool str_is_pattern);
-extern WF_PACK *wf_comp(char * str);
-extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
-extern void wf_end(struct wild_file_pack *buffer);
-extern my_bool array_append_string_unique(const char *str,
- const char **array, size_t size);
-extern void get_date(char * to,int timeflag,time_t use_time);
-extern void soundex(CHARSET_INFO *, char * out_pntr, char * in_pntr,
- pbool remove_garbage);
-extern int init_record_cache(RECORD_CACHE *info,size_t cachesize,File file,
- size_t reclength,enum cache_type type,
- pbool use_async_io);
-extern int read_cache_record(RECORD_CACHE *info,uchar *to);
-extern int end_record_cache(RECORD_CACHE *info);
-extern int write_cache_record(RECORD_CACHE *info,my_off_t filepos,
- const uchar *record,size_t length);
-extern int flush_write_cache(RECORD_CACHE *info);
-extern long my_clock(void);
-extern void sigtstp_handler(int signal_number);
-extern void handle_recived_signals(void);
-extern void my_set_alarm_variable(int signo);
-extern void my_string_ptr_sort(uchar *base,uint items,size_t size);
-extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements,
- size_t size_of_element,uchar *buffer[]);
-extern void my_qsort(void *base_ptr, size_t total_elems, size_t size,
- qsort_cmp cmp);
-extern void my_qsort2(void *base_ptr, size_t total_elems, size_t size,
- qsort2_cmp cmp, void *cmp_argument);
-extern qsort2_cmp get_ptr_compare(size_t);
-void my_store_ptr(uchar *buff, size_t pack_length, my_off_t pos);
-my_off_t my_get_ptr(uchar *ptr, size_t pack_length);
-extern int init_io_cache(IO_CACHE *info,File file,size_t cachesize,
- enum cache_type type,my_off_t seek_offset,
- pbool use_async_io, myf cache_myflags);
-extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type,
- my_off_t seek_offset,pbool use_async_io,
- pbool clear_cache);
-extern void setup_io_cache(IO_CACHE* info);
-extern int _my_b_read(IO_CACHE *info,uchar *Buffer,size_t Count);
-extern int _my_b_read_r(IO_CACHE *info,uchar *Buffer,size_t Count);
-extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
- IO_CACHE *write_cache, uint num_threads);
-extern void remove_io_thread(IO_CACHE *info);
-extern int _my_b_seq_read(IO_CACHE *info,uchar *Buffer,size_t Count);
-extern int _my_b_net_read(IO_CACHE *info,uchar *Buffer,size_t Count);
-extern int _my_b_get(IO_CACHE *info);
-extern int _my_b_async_read(IO_CACHE *info,uchar *Buffer,size_t Count);
-extern int _my_b_write(IO_CACHE *info,const uchar *Buffer,size_t Count);
-extern int my_b_append(IO_CACHE *info,const uchar *Buffer,size_t Count);
-extern int my_b_safe_write(IO_CACHE *info,const uchar *Buffer,size_t Count);
-extern int my_block_write(IO_CACHE *info, const uchar *Buffer,
- size_t Count, my_off_t pos);
-extern int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock);
-extern int end_io_cache(IO_CACHE *info);
-extern size_t my_b_fill(IO_CACHE *info);
-extern void my_b_seek(IO_CACHE *info,my_off_t pos);
-extern size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length);
-extern my_off_t my_b_filelength(IO_CACHE *info);
-extern size_t my_b_printf(IO_CACHE *info, const char* fmt, ...);
-extern size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
-extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
- const char *prefix, size_t cache_size,
- myf cache_myflags);
-extern my_bool real_open_cached_file(IO_CACHE *cache);
-extern void close_cached_file(IO_CACHE *cache);
-File create_temp_file(char *to, const char *dir, const char *pfx,
- int mode, myf MyFlags);
-extern my_bool init_dynamic_array2(DYNAMIC_ARRAY *array,uint element_size,
- void *init_buffer, uint init_alloc,
- uint alloc_increment
- );
-extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array,uint element_size,
- uint init_alloc,uint alloc_increment
- );
-extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,uchar * element);
-extern uchar *alloc_dynamic(DYNAMIC_ARRAY *array);
-extern uchar *pop_dynamic(DYNAMIC_ARRAY*);
-extern my_bool set_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index);
-extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements);
-extern void get_dynamic(DYNAMIC_ARRAY *array,uchar * element,uint array_index);
-extern void delete_dynamic(DYNAMIC_ARRAY *array);
-extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index);
-extern void freeze_size(DYNAMIC_ARRAY *array);
-extern int get_index_dynamic(DYNAMIC_ARRAY *array, uchar * element);
-extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
- size_t init_alloc,size_t alloc_increment);
-extern my_bool dynstr_append(DYNAMIC_STRING *str, const char *append);
-my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
- size_t length);
-extern my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append,
- ...);
-extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
-extern my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size);
-extern my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n);
-extern void dynstr_free(DYNAMIC_STRING *str);
-extern void init_alloc_root(MEM_ROOT *mem_root, size_t block_size,
- size_t pre_alloc_size);
-extern void *alloc_root(MEM_ROOT *mem_root, size_t Size);
-extern void *multi_alloc_root(MEM_ROOT *mem_root, ...);
-extern void free_root(MEM_ROOT *root, myf MyFLAGS);
-extern void set_prealloc_root(MEM_ROOT *root, char *ptr);
-extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
- size_t prealloc_size);
-extern char *strdup_root(MEM_ROOT *root,const char *str);
-extern char *strmake_root(MEM_ROOT *root,const char *str,size_t len);
-extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len);
-extern int get_defaults_options(int argc, char **argv,
- char **defaults, char **extra_defaults,
- char **group_suffix);
-extern int load_defaults(const char *conf_file, const char **groups,
- int *argc, char ***argv);
-extern int modify_defaults_file(const char *file_location, const char *option,
- const char *option_value,
- const char *section_name, int remove_option);
-extern int my_search_option_files(const char *conf_file, int *argc,
- char ***argv, uint *args_used,
- Process_option_func func, void *func_ctx);
-extern void free_defaults(char **argv);
-extern void my_print_default_files(const char *conf_file);
-extern void print_defaults(const char *conf_file, const char **groups);
-extern my_bool my_compress(uchar *, size_t *, size_t *);
-extern my_bool my_uncompress(uchar *, size_t , size_t *);
-extern uchar *my_compress_alloc(const uchar *packet, size_t *len,
- size_t *complen);
-extern int packfrm(uchar *, size_t, uchar **, size_t *);
-extern int unpackfrm(uchar **, size_t *, const uchar *);
-extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem,
- size_t count);
-extern void my_sleep(ulong m_seconds);
-extern ulong crc32(ulong crc, const uchar *buf, uint len);
-extern uint my_set_max_open_files(uint files);
-void my_free_open_file_info(void);
-extern time_t my_time(myf flags);
-extern ulonglong my_getsystime(void);
-extern ulonglong my_micro_time();
-extern ulonglong my_micro_time_and_time(time_t *time_arg);
-time_t my_time_possible_from_micro(ulonglong microtime);
-extern my_bool my_gethwaddr(uchar *to);
-extern int my_getncpus();
-#include <sys/mman.h>
-int my_msync(int, void *, size_t, int);
-extern uint get_charset_number(const char *cs_name, uint cs_flags);
-extern uint get_collation_number(const char *name);
-extern const char *get_charset_name(uint cs_number);
-extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
-extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
-extern CHARSET_INFO *get_charset_by_csname(const char *cs_name,
- uint cs_flags, myf my_flags);
-extern my_bool resolve_charset(const char *cs_name,
- CHARSET_INFO *default_cs,
- CHARSET_INFO **cs);
-extern my_bool resolve_collation(const char *cl_name,
- CHARSET_INFO *default_cl,
- CHARSET_INFO **cl);
-extern void free_charsets(void);
-extern char *get_charsets_dir(char *buf);
-extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
-extern my_bool init_compiled_charsets(myf flags);
-extern void add_compiled_collation(CHARSET_INFO *cs);
-extern size_t escape_string_for_mysql(CHARSET_INFO *charset_info,
- char *to, size_t to_length,
- const char *from, size_t length);
-extern size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info,
- char *to, size_t to_length,
- const char *from, size_t length);
-extern void thd_increment_bytes_sent(ulong length);
-extern void thd_increment_bytes_received(ulong length);
-extern void thd_increment_net_big_packet_count(ulong length);
-#include <my_time.h>
-#include "my_global.h"
-#include "mysql_time.h"
-enum enum_mysql_timestamp_type
-{
- MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
- MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
-};
-typedef struct st_mysql_time
-{
- unsigned int year, month, day, hour, minute, second;
- unsigned long second_part;
- my_bool neg;
- enum enum_mysql_timestamp_type time_type;
-} MYSQL_TIME;
-extern ulonglong log_10_int[20];
-extern uchar days_in_month[];
-typedef long my_time_t;
-my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
- ulong flags, int *was_cut);
-enum enum_mysql_timestamp_type
-str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
- uint flags, int *was_cut);
-longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
- uint flags, int *was_cut);
-ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
-ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
-ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
-ulonglong TIME_to_ulonglong(const MYSQL_TIME *);
-my_bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time,
- int *warning);
-int check_time_range(struct st_mysql_time *, int *warning);
-long calc_daynr(uint year,uint month,uint day);
-uint calc_days_in_year(uint year);
-uint year_2000_handling(uint year);
-void my_init_time(void);
-static inline my_bool validate_timestamp_range(const MYSQL_TIME *t)
-{
- if ((t->year > 2038 || t->year < (1900 + 70 - 1)) ||
- (t->year == 2038 && (t->month > 1 || t->day > 19)) ||
- (t->year == (1900 + 70 - 1) && (t->month < 12 || t->day < 31)))
- return (0);
- return (1);
-}
-my_time_t
-my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone,
- my_bool *in_dst_time_gap);
-void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
-int my_time_to_str(const MYSQL_TIME *l_time, char *to);
-int my_date_to_str(const MYSQL_TIME *l_time, char *to);
-int my_datetime_to_str(const MYSQL_TIME *l_time, char *to);
-int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);
-enum interval_type
-{
- INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, INTERVAL_DAY,
- INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, INTERVAL_MICROSECOND,
- INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE,
- INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND,
- INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND,
- INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND, INTERVAL_LAST
-};
-#include <m_string.h>
-#include <strings.h>
-#include <string.h>
-#include <stdarg.h>
-#include <strings.h>
-#include <memory.h>
-extern void *(*my_str_malloc)(size_t);
-extern void (*my_str_free)(void *);
-extern char *stpcpy(char *, const char *);
-extern char _dig_vec_upper[];
-extern char _dig_vec_lower[];
-extern const double log_10[309];
-extern void bmove512(uchar *dst,const uchar *src,size_t len);
-extern void bmove_upp(uchar *dst,const uchar *src,size_t len);
-extern void bchange(uchar *dst,size_t old_len,const uchar *src,
- size_t new_len,size_t tot_len);
-extern void strappend(char *s,size_t len,pchar fill);
-extern char *strend(const char *s);
-extern char *strcend(const char *, pchar);
-extern char *strfield(char *src,int fields,int chars,int blanks,
- int tabch);
-extern char *strfill(char * s,size_t len,pchar fill);
-extern size_t strinstr(const char *str,const char *search);
-extern size_t r_strinstr(const char *str, size_t from, const char *search);
-extern char *strkey(char *dst,char *head,char *tail,char *flags);
-extern char *strmake(char *dst,const char *src,size_t length);
-extern char *strnmov(char *dst,const char *src,size_t n);
-extern char *strsuff(const char *src,const char *suffix);
-extern char *strcont(const char *src,const char *set);
-extern char *strxcat (char *dst,const char *src, ...);
-extern char *strxmov (char *dst,const char *src, ...);
-extern char *strxcpy (char *dst,const char *src, ...);
-extern char *strxncat (char *dst,size_t len, const char *src, ...);
-extern char *strxnmov (char *dst,size_t len, const char *src, ...);
-extern char *strxncpy (char *dst,size_t len, const char *src, ...);
-extern int is_prefix(const char *, const char *);
-double my_strtod(const char *str, char **end, int *error);
-double my_atof(const char *nptr);
-extern char *llstr(longlong value,char *buff);
-extern char *ullstr(longlong value,char *buff);
-extern char *int2str(long val, char *dst, int radix, int upcase);
-extern char *int10_to_str(long val,char *dst,int radix);
-extern char *str2int(const char *src,int radix,long lower,long upper,
- long *val);
-longlong my_strtoll10(const char *nptr, char **endptr, int *error);
-extern char *longlong2str(longlong val,char *dst,int radix);
-extern char *longlong10_to_str(longlong val,char *dst,int radix);
-extern size_t my_vsnprintf(char *str, size_t n,
- const char *format, va_list ap);
-extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...)
- __attribute__((format(printf, 3, 4)));
-struct st_mysql_lex_string
-{
- char *str;
- size_t length;
-};
-typedef struct st_mysql_lex_string LEX_STRING;
-#include <hash.h>
-typedef uchar *(*hash_get_key)(const uchar *,size_t*,my_bool);
-typedef void (*hash_free_key)(void *);
-typedef struct st_hash {
- size_t key_offset,key_length;
- size_t blength;
- ulong records;
- uint flags;
- DYNAMIC_ARRAY array;
- hash_get_key get_key;
- void (*free)(void *);
- CHARSET_INFO *charset;
-} HASH;
-typedef uint HASH_SEARCH_STATE;
-my_bool _hash_init(HASH *hash, uint growth_size,CHARSET_INFO *charset,
- ulong default_array_elements, size_t key_offset,
- size_t key_length, hash_get_key get_key,
- void (*free_element)(void*), uint flags );
-void hash_free(HASH *tree);
-void my_hash_reset(HASH *hash);
-uchar *hash_element(HASH *hash,ulong idx);
-uchar *hash_search(const HASH *info, const uchar *key, size_t length);
-uchar *hash_first(const HASH *info, const uchar *key, size_t length,
- HASH_SEARCH_STATE *state);
-uchar *hash_next(const HASH *info, const uchar *key, size_t length,
- HASH_SEARCH_STATE *state);
-my_bool my_hash_insert(HASH *info,const uchar *data);
-my_bool hash_delete(HASH *hash,uchar *record);
-my_bool hash_update(HASH *hash,uchar *record,uchar *old_key,size_t old_key_length);
-void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, uchar *new_row);
-my_bool hash_check(HASH *hash);
-#include <signal.h>
-#include <thr_lock.h>
-#include <my_pthread.h>
-#include <my_list.h>
-typedef struct st_list {
- struct st_list *prev,*next;
- void *data;
-} LIST;
-typedef int (*list_walk_action)(void *,void *);
-extern LIST *list_add(LIST *root,LIST *element);
-extern LIST *list_delete(LIST *root,LIST *element);
-extern LIST *list_cons(void *data,LIST *root);
-extern LIST *list_reverse(LIST *root);
-extern void list_free(LIST *root,unsigned int free_data);
-extern unsigned int list_length(LIST *);
-extern int list_walk(LIST *,list_walk_action action,unsigned char * argument);
-struct st_thr_lock;
-extern ulong locks_immediate,locks_waited ;
-enum thr_lock_type { TL_IGNORE=-1,
- TL_UNLOCK,
- TL_READ,
- TL_READ_WITH_SHARED_LOCKS,
- TL_READ_HIGH_PRIORITY,
- TL_READ_NO_INSERT,
- TL_WRITE_ALLOW_WRITE,
- TL_WRITE_ALLOW_READ,
- TL_WRITE_CONCURRENT_INSERT,
- TL_WRITE_DELAYED,
- TL_WRITE_DEFAULT,
- TL_WRITE_LOW_PRIORITY,
- TL_WRITE,
- TL_WRITE_ONLY};
-enum enum_thr_lock_result { THR_LOCK_SUCCESS= 0, THR_LOCK_ABORTED= 1,
- THR_LOCK_WAIT_TIMEOUT= 2, THR_LOCK_DEADLOCK= 3 };
-extern ulong max_write_lock_count;
-extern ulong table_lock_wait_timeout;
-extern my_bool thr_lock_inited;
-extern enum thr_lock_type thr_upgraded_concurrent_insert_lock;
-typedef struct st_thr_lock_info
-{
- pthread_t thread;
- my_thread_id thread_id;
- ulong n_cursors;
-} THR_LOCK_INFO;
-typedef struct st_thr_lock_owner
-{
- THR_LOCK_INFO *info;
-} THR_LOCK_OWNER;
-typedef struct st_thr_lock_data {
- THR_LOCK_OWNER *owner;
- struct st_thr_lock_data *next,**prev;
- struct st_thr_lock *lock;
- pthread_cond_t *cond;
- enum thr_lock_type type;
- void *status_param;
- void *debug_print_param;
-} THR_LOCK_DATA;
-struct st_lock_list {
- THR_LOCK_DATA *data,**last;
-};
-typedef struct st_thr_lock {
- LIST list;
- pthread_mutex_t mutex;
- struct st_lock_list read_wait;
- struct st_lock_list read;
- struct st_lock_list write_wait;
- struct st_lock_list write;
- ulong write_lock_count;
- uint read_no_write_count;
- void (*get_status)(void*, int);
- void (*copy_status)(void*,void*);
- void (*update_status)(void*);
- void (*restore_status)(void*);
- my_bool (*check_status)(void *);
-} THR_LOCK;
-extern LIST *thr_lock_thread_list;
-extern pthread_mutex_t THR_LOCK_lock;
-my_bool init_thr_lock(void);
-void thr_lock_info_init(THR_LOCK_INFO *info);
-void thr_lock_init(THR_LOCK *lock);
-void thr_lock_delete(THR_LOCK *lock);
-void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data,
- void *status_param);
-enum enum_thr_lock_result thr_lock(THR_LOCK_DATA *data,
- THR_LOCK_OWNER *owner,
- enum thr_lock_type lock_type);
-void thr_unlock(THR_LOCK_DATA *data);
-enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data,
- uint count, THR_LOCK_OWNER *owner);
-void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
-void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock);
-my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread);
-void thr_print_locks(void);
-my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data);
-void thr_downgrade_write_lock(THR_LOCK_DATA *data,
- enum thr_lock_type new_lock_type);
-my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data);
-#include <my_base.h>
-#include <my_global.h>
-#include <my_dir.h>
-#include <sys/stat.h>
-typedef struct fileinfo
-{
- char *name;
- struct stat *mystat;
-} FILEINFO;
-typedef struct st_my_dir
-{
- struct fileinfo *dir_entry;
- uint number_off_files;
-} MY_DIR;
-extern MY_DIR *my_dir(const char *path,myf MyFlags);
-extern void my_dirend(MY_DIR *buffer);
-extern struct stat *my_stat(const char *path, struct stat *stat_area, myf my_flags);
-extern int my_fstat(int filenr, struct stat *stat_area, myf MyFlags);
-#include <my_sys.h>
-#include <m_string.h>
-#include <errno.h>
-#include <my_list.h>
-enum ha_rkey_function {
- HA_READ_KEY_EXACT,
- HA_READ_KEY_OR_NEXT,
- HA_READ_KEY_OR_PREV,
- HA_READ_AFTER_KEY,
- HA_READ_BEFORE_KEY,
- HA_READ_PREFIX,
- HA_READ_PREFIX_LAST,
- HA_READ_PREFIX_LAST_OR_PREV,
- HA_READ_MBR_CONTAIN,
- HA_READ_MBR_INTERSECT,
- HA_READ_MBR_WITHIN,
- HA_READ_MBR_DISJOINT,
- HA_READ_MBR_EQUAL
-};
-enum ha_key_alg {
- HA_KEY_ALG_UNDEF= 0,
- HA_KEY_ALG_BTREE= 1,
- HA_KEY_ALG_RTREE= 2,
- HA_KEY_ALG_HASH= 3,
- HA_KEY_ALG_FULLTEXT= 4
-};
-enum ha_storage_media {
- HA_SM_DEFAULT= 0,
- HA_SM_DISK= 1,
- HA_SM_MEMORY= 2
-};
-enum ha_extra_function {
- HA_EXTRA_NORMAL=0,
- HA_EXTRA_QUICK=1,
- HA_EXTRA_NOT_USED=2,
- HA_EXTRA_CACHE=3,
- HA_EXTRA_NO_CACHE=4,
- HA_EXTRA_NO_READCHECK=5,
- HA_EXTRA_READCHECK=6,
- HA_EXTRA_KEYREAD=7,
- HA_EXTRA_NO_KEYREAD=8,
- HA_EXTRA_NO_USER_CHANGE=9,
- HA_EXTRA_KEY_CACHE=10,
- HA_EXTRA_NO_KEY_CACHE=11,
- HA_EXTRA_WAIT_LOCK=12,
- HA_EXTRA_NO_WAIT_LOCK=13,
- HA_EXTRA_WRITE_CACHE=14,
- HA_EXTRA_FLUSH_CACHE=15,
- HA_EXTRA_NO_KEYS=16,
- HA_EXTRA_KEYREAD_CHANGE_POS=17,
- HA_EXTRA_REMEMBER_POS=18,
- HA_EXTRA_RESTORE_POS=19,
- HA_EXTRA_REINIT_CACHE=20,
- HA_EXTRA_FORCE_REOPEN=21,
- HA_EXTRA_FLUSH,
- HA_EXTRA_NO_ROWS,
- HA_EXTRA_RESET_STATE,
- HA_EXTRA_IGNORE_DUP_KEY,
- HA_EXTRA_NO_IGNORE_DUP_KEY,
- HA_EXTRA_PREPARE_FOR_DROP,
- HA_EXTRA_PREPARE_FOR_UPDATE,
- HA_EXTRA_PRELOAD_BUFFER_SIZE,
- HA_EXTRA_CHANGE_KEY_TO_UNIQUE,
- HA_EXTRA_CHANGE_KEY_TO_DUP,
- HA_EXTRA_KEYREAD_PRESERVE_FIELDS,
- HA_EXTRA_MMAP,
- HA_EXTRA_IGNORE_NO_KEY,
- HA_EXTRA_NO_IGNORE_NO_KEY,
- HA_EXTRA_MARK_AS_LOG_TABLE,
- HA_EXTRA_WRITE_CAN_REPLACE,
- HA_EXTRA_WRITE_CANNOT_REPLACE,
- HA_EXTRA_DELETE_CANNOT_BATCH,
- HA_EXTRA_UPDATE_CANNOT_BATCH,
- HA_EXTRA_INSERT_WITH_UPDATE,
- HA_EXTRA_PREPARE_FOR_RENAME,
- HA_EXTRA_ATTACH_CHILDREN,
- HA_EXTRA_DETACH_CHILDREN
-};
-enum ha_panic_function {
- HA_PANIC_CLOSE,
- HA_PANIC_WRITE,
- HA_PANIC_READ
-};
-enum ha_base_keytype {
- HA_KEYTYPE_END=0,
- HA_KEYTYPE_TEXT=1,
- HA_KEYTYPE_BINARY=2,
- HA_KEYTYPE_SHORT_INT=3,
- HA_KEYTYPE_LONG_INT=4,
- HA_KEYTYPE_FLOAT=5,
- HA_KEYTYPE_DOUBLE=6,
- HA_KEYTYPE_NUM=7,
- HA_KEYTYPE_USHORT_INT=8,
- HA_KEYTYPE_ULONG_INT=9,
- HA_KEYTYPE_LONGLONG=10,
- HA_KEYTYPE_ULONGLONG=11,
- HA_KEYTYPE_INT24=12,
- HA_KEYTYPE_UINT24=13,
- HA_KEYTYPE_INT8=14,
- HA_KEYTYPE_VARTEXT1=15,
- HA_KEYTYPE_VARBINARY1=16,
- HA_KEYTYPE_VARTEXT2=17,
- HA_KEYTYPE_VARBINARY2=18,
- HA_KEYTYPE_BIT=19
-};
-typedef ulong key_part_map;
-enum en_fieldtype {
- FIELD_LAST=-1,FIELD_NORMAL,FIELD_SKIP_ENDSPACE,FIELD_SKIP_PRESPACE,
- FIELD_SKIP_ZERO,FIELD_BLOB,FIELD_CONSTANT,FIELD_INTERVALL,FIELD_ZERO,
- FIELD_VARCHAR,FIELD_CHECK,
- FIELD_enum_val_count
-};
-enum data_file_type {
- STATIC_RECORD, DYNAMIC_RECORD, COMPRESSED_RECORD, BLOCK_RECORD
-};
-typedef struct st_key_range
-{
- const uchar *key;
- uint length;
- key_part_map keypart_map;
- enum ha_rkey_function flag;
-} key_range;
-typedef struct st_key_multi_range
-{
- key_range start_key;
- key_range end_key;
- char *ptr;
- uint range_flag;
-} KEY_MULTI_RANGE;
-typedef my_off_t ha_rows;
-typedef void (* invalidator_by_filename)(const char * filename);
-#include <queues.h>
-typedef struct st_queue {
- uchar **root;
- void *first_cmp_arg;
- uint elements;
- uint max_elements;
- uint offset_to_key;
- int max_at_top;
- int (*compare)(void *, uchar *,uchar *);
- uint auto_extent;
-} QUEUE;
-typedef int (*queue_compare)(void *,uchar *, uchar *);
-int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, queue_compare compare,
- void *first_cmp_arg);
-int init_queue_ex(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, queue_compare compare,
- void *first_cmp_arg, uint auto_extent);
-int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, queue_compare compare,
- void *first_cmp_arg);
-int resize_queue(QUEUE *queue, uint max_elements);
-void delete_queue(QUEUE *queue);
-void queue_insert(QUEUE *queue,uchar *element);
-int queue_insert_safe(QUEUE *queue, uchar *element);
-uchar *queue_remove(QUEUE *queue,uint idx);
-void _downheap(QUEUE *queue,uint idx);
-void queue_fix(QUEUE *queue);
-#include "sql_bitmap.h"
-#include <my_bitmap.h>
-#include <m_string.h>
-typedef uint32 my_bitmap_map;
-typedef struct st_bitmap
-{
- my_bitmap_map *bitmap;
- uint n_bits;
- my_bitmap_map last_word_mask;
- my_bitmap_map *last_word_ptr;
- pthread_mutex_t *mutex;
-} MY_BITMAP;
-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 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);
-extern my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2);
-extern my_bool bitmap_is_overlapping(const MY_BITMAP *map1,
- const MY_BITMAP *map2);
-extern my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit);
-extern my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit);
-extern my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit);
-extern uint bitmap_set_next(MY_BITMAP *map);
-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 void 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);
-extern void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2);
-extern void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2);
-extern void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2);
-extern void bitmap_invert(MY_BITMAP *map);
-extern void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2);
-extern uint bitmap_lock_set_next(MY_BITMAP *map);
-extern void bitmap_lock_clear_bit(MY_BITMAP *map, uint bitmap_bit);
-static inline void
-bitmap_set_bit(MY_BITMAP *map,uint bit)
-{
- assert(bit < (map)->n_bits);
- (((uchar*)(map)->bitmap)[(bit) / 8] |= (1 << ((bit) & 7)));
-}
-static inline void
-bitmap_flip_bit(MY_BITMAP *map,uint bit)
-{
- assert(bit < (map)->n_bits);
- (((uchar*)(map)->bitmap)[(bit) / 8] ^= (1 << ((bit) & 7)));
-}
-static inline void
-bitmap_clear_bit(MY_BITMAP *map,uint bit)
-{
- assert(bit < (map)->n_bits);
- (((uchar*)(map)->bitmap)[(bit) / 8] &= ~ (1 << ((bit) & 7)));
-}
-static inline uint
-bitmap_is_set(const MY_BITMAP *map,uint bit)
-{
- assert(bit < (map)->n_bits);
- return (uint) (((uchar*)(map)->bitmap)[(bit) / 8] & (1 << ((bit) & 7)));
-}
-static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
-{
- *(map1)->last_word_ptr|= (map1)->last_word_mask;
- *(map2)->last_word_ptr|= (map2)->last_word_mask;
- return memcmp((map1)->bitmap, (map2)->bitmap, 4*((((map1))->n_bits + 31)/32))==0;
-}
-template <uint default_width> class Bitmap
-{
- MY_BITMAP map;
- uint32 buffer[(default_width+31)/32];
-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(uint prefix_to_set) { init(); set_prefix(prefix_to_set); }
- uint length() const { return default_width; }
- Bitmap& operator=(const Bitmap& map2)
- {
- init();
- memcpy(buffer, map2.buffer, sizeof(buffer));
- return *this;
- }
- void set_bit(uint n) { bitmap_set_bit(&map, n); }
- void clear_bit(uint n) { bitmap_clear_bit(&map, n); }
- void set_prefix(uint n) { bitmap_set_prefix(&map, n); }
- void set_all() { (memset((&map)->bitmap, 0xFF, 4*((((&map))->n_bits + 31)/32))); }
- void clear_all() { { memset((&map)->bitmap, 0, 4*((((&map))->n_bits + 31)/32)); }; }
- void intersect(Bitmap& map2) { bitmap_intersect(&map, &map2.map); }
- void intersect(ulonglong map2buff)
- {
- MY_BITMAP map2;
- bitmap_init(&map2, (uint32 *)&map2buff, sizeof(ulonglong)*8, 0);
- bitmap_intersect(&map, &map2);
- }
- void intersect_extended(ulonglong map2buff)
- {
- intersect(map2buff);
- if (map.n_bits > sizeof(ulonglong) * 8)
- bitmap_set_above(&map, sizeof(ulonglong),
- ((map2buff & (1LL << (sizeof(ulonglong) * 8 - 1))) ? 1 : 0));
- }
- void subtract(Bitmap& map2) { bitmap_subtract(&map, &map2.map); }
- void merge(Bitmap& map2) { bitmap_union(&map, &map2.map); }
- my_bool is_set(uint n) const { return bitmap_is_set(&map, n); }
- my_bool is_prefix(uint n) const { return bitmap_is_prefix(&map, n); }
- my_bool is_clear_all() const { return bitmap_is_clear_all(&map); }
- my_bool is_set_all() const { return bitmap_is_set_all(&map); }
- my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); }
- my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); }
- my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
- char *print(char *buf) const
- {
- char *s=buf;
- const uchar *e=(uchar *)buffer, *b=e+sizeof(buffer)-1;
- while (!*b && b>e)
- b--;
- if ((*s=_dig_vec_upper[*b >> 4]) != '0')
- s++;
- *s++=_dig_vec_upper[*b & 15];
- while (--b>=e)
- {
- *s++=_dig_vec_upper[*b >> 4];
- *s++=_dig_vec_upper[*b & 15];
- }
- *s=0;
- return buf;
- }
- ulonglong to_ulonglong() const
- {
- if (sizeof(buffer) >= 8)
- return (*((ulonglong *) (buffer)));
- assert(sizeof(buffer) >= 4);
- return (ulonglong) (*((uint32 *) (buffer)));
- }
-};
-template <> class Bitmap<64>
-{
- ulonglong map;
-public:
- Bitmap<64>() { }
- explicit Bitmap<64>(uint prefix_to_set) { set_prefix(prefix_to_set); }
- void init() { }
- void init(uint prefix_to_set) { set_prefix(prefix_to_set); }
- uint length() const { return 64; }
- void set_bit(uint n) { map|= ((ulonglong)1) << n; }
- void clear_bit(uint n) { map&= ~(((ulonglong)1) << n); }
- void set_prefix(uint n)
- {
- if (n >= length())
- set_all();
- else
- map= (((ulonglong)1) << n)-1;
- }
- void set_all() { map=~(ulonglong)0; }
- void clear_all() { map=(ulonglong)0; }
- void intersect(Bitmap<64>& map2) { map&= map2.map; }
- void intersect(ulonglong map2) { map&= map2; }
- void intersect_extended(ulonglong map2) { map&= map2; }
- void subtract(Bitmap<64>& map2) { map&= ~map2.map; }
- void merge(Bitmap<64>& map2) { map|= map2.map; }
- my_bool is_set(uint n) const { return ((map & (((ulonglong)1) << n)) ? 1 : 0); }
- my_bool is_prefix(uint n) const { return map == (((ulonglong)1) << n)-1; }
- my_bool is_clear_all() const { return map == (ulonglong)0; }
- my_bool is_set_all() const { return map == ~(ulonglong)0; }
- my_bool is_subset(const Bitmap<64>& map2) const { return !(map & ~map2.map); }
- my_bool is_overlapping(const Bitmap<64>& map2) const { return (map & map2.map)!= 0; }
- my_bool operator==(const Bitmap<64>& map2) const { return map == map2.map; }
- char *print(char *buf) const { longlong2str(map,buf,16); return buf; }
- ulonglong to_ulonglong() const { return map; }
-};
-#include "sql_array.h"
-#include <my_sys.h>
-template <class Elem> class Dynamic_array
-{
- DYNAMIC_ARRAY array;
-public:
- Dynamic_array(uint prealloc=16, uint increment=16)
- {
- init_dynamic_array2(&array,sizeof(Elem),NULL,prealloc,increment );
- }
- Elem& at(int idx)
- {
- return *(((Elem*)array.buffer) + idx);
- }
- Elem *front()
- {
- return (Elem*)array.buffer;
- }
- Elem *back()
- {
- return ((Elem*)array.buffer) + array.elements;
- }
- In_C_you_should_use_my_bool_instead() append(Elem &el)
- {
- return (insert_dynamic(&array, (uchar*)&el));
- }
- int elements()
- {
- return array.elements;
- }
- ~Dynamic_array()
- {
- delete_dynamic(&array);
- }
- typedef int (*CMP_FUNC)(const Elem *el1, const Elem *el2);
- void sort(CMP_FUNC cmp_func)
- {
- my_qsort(array.buffer, array.elements, sizeof(Elem), (qsort_cmp)cmp_func);
- }
-};
-#include "sql_plugin.h"
-class sys_var;
-#include <mysql/plugin.h>
-typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
-struct st_mysql_xid {
- long formatID;
- long gtrid_length;
- long bqual_length;
- char data[128];
-};
-typedef struct st_mysql_xid MYSQL_XID;
-enum enum_mysql_show_type
-{
- SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
- SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
- SHOW_ARRAY, SHOW_FUNC, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_LONGLONG, SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_HAVE, SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, SHOW_LONG_NOFLUSH, SHOW_LONGLONG_STATUS, SHOW_DOUBLE
-};
-struct st_mysql_show_var {
- const char *name;
- char *value;
- enum enum_mysql_show_type type;
-};
-typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, char *);
-struct st_mysql_sys_var;
-struct st_mysql_value;
-typedef int (*mysql_var_check_func)(void* thd,
- struct st_mysql_sys_var *var,
- void *save, struct st_mysql_value *value);
-typedef void (*mysql_var_update_func)(void* thd,
- struct st_mysql_sys_var *var,
- void *var_ptr, const void *save);
-struct st_mysql_plugin
-{
- int type;
- void *info;
- const char *name;
- const char *author;
- const char *descr;
- int license;
- int (*init)(void *);
- int (*deinit)(void *);
- unsigned int version;
- struct st_mysql_show_var *status_vars;
- struct st_mysql_sys_var **system_vars;
- void * __reserved1;
-};
-enum enum_ftparser_mode
-{
- MYSQL_FTPARSER_SIMPLE_MODE= 0,
- MYSQL_FTPARSER_WITH_STOPWORDS= 1,
- MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
-};
-enum enum_ft_token_type
-{
- FT_TOKEN_EOF= 0,
- FT_TOKEN_WORD= 1,
- FT_TOKEN_LEFT_PAREN= 2,
- FT_TOKEN_RIGHT_PAREN= 3,
- FT_TOKEN_STOPWORD= 4
-};
-typedef struct st_mysql_ftparser_boolean_info
-{
- enum enum_ft_token_type type;
- int yesno;
- int weight_adjust;
- char wasign;
- char trunc;
- char prev;
- char *quot;
-} MYSQL_FTPARSER_BOOLEAN_INFO;
-typedef struct st_mysql_ftparser_param
-{
- int (*mysql_parse)(struct st_mysql_ftparser_param *,
- char *doc, int doc_len);
- int (*mysql_add_word)(struct st_mysql_ftparser_param *,
- char *word, int word_len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
- void *ftparser_state;
- void *mysql_ftparam;
- struct charset_info_st *cs;
- char *doc;
- int length;
- int flags;
- enum enum_ftparser_mode mode;
-} MYSQL_FTPARSER_PARAM;
-struct st_mysql_ftparser
-{
- int interface_version;
- int (*parse)(MYSQL_FTPARSER_PARAM *param);
- int (*init)(MYSQL_FTPARSER_PARAM *param);
- int (*deinit)(MYSQL_FTPARSER_PARAM *param);
-};
-struct st_mysql_storage_engine
-{
- int interface_version;
-};
-struct handlerton;
-struct st_mysql_daemon
-{
- int interface_version;
-};
-struct st_mysql_information_schema
-{
- int interface_version;
-};
-struct st_mysql_value
-{
- int (*value_type)(struct st_mysql_value *);
- const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
- int (*val_real)(struct st_mysql_value *, double *realbuf);
- int (*val_int)(struct st_mysql_value *, long long *intbuf);
-};
-int thd_in_lock_tables(const void* thd);
-int thd_tablespace_op(const void* thd);
-long long thd_test_options(const void* thd, long long test_options);
-int thd_sql_command(const void* thd);
-const char *thd_proc_info(void* thd, const char *info);
-void **thd_ha_data(const void* thd, const struct handlerton *hton);
-int thd_tx_isolation(const void* thd);
-char *thd_security_context(void* thd, char *buffer, unsigned int length,
- unsigned int max_query_len);
-void thd_inc_row_count(void* thd);
-int mysql_tmpfile(const char *prefix);
-int thd_killed(const void* thd);
-unsigned long thd_get_thread_id(const void* thd);
-void *thd_alloc(void* thd, unsigned int size);
-void *thd_calloc(void* thd, unsigned int size);
-char *thd_strdup(void* thd, const char *str);
-char *thd_strmake(void* thd, const char *str, unsigned int size);
-void *thd_memdup(void* thd, const void* str, unsigned int size);
-MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
- const char *str, unsigned int size,
- int allocate_lex_string);
-void thd_get_xid(const void* thd, MYSQL_XID *xid);
-void mysql_query_cache_invalidate4(void* thd,
- const char *key, unsigned int key_length,
- int using_trx);
-typedef enum enum_mysql_show_type SHOW_TYPE;
-typedef struct st_mysql_show_var SHOW_VAR;
-struct st_plugin_dl
-{
- LEX_STRING dl;
- void *handle;
- struct st_mysql_plugin *plugins;
- int version;
- uint ref_count;
-};
-struct st_plugin_int
-{
- LEX_STRING name;
- struct st_mysql_plugin *plugin;
- struct st_plugin_dl *plugin_dl;
- uint state;
- uint ref_count;
- void *data;
- MEM_ROOT mem_root;
- sys_var *system_vars;
-};
-typedef struct st_plugin_int **plugin_ref;
-typedef int (*plugin_type_init)(struct st_plugin_int *);
-extern char *opt_plugin_load;
-extern char *opt_plugin_dir_ptr;
-extern char opt_plugin_dir[512];
-extern const LEX_STRING plugin_type_names[];
-extern int plugin_init(int *argc, char **argv, int init_flags);
-extern void plugin_shutdown(void);
-extern void my_print_help_inc_plugins(struct my_option *options, uint size);
-extern In_C_you_should_use_my_bool_instead() plugin_is_ready(const LEX_STRING *name, int type);
-extern plugin_ref plugin_lock(THD *thd, plugin_ref *ptr );
-extern plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name,
- int type );
-extern void plugin_unlock(THD *thd, plugin_ref plugin);
-extern void plugin_unlock_list(THD *thd, plugin_ref *list, uint count);
-extern In_C_you_should_use_my_bool_instead() mysql_install_plugin(THD *thd, const LEX_STRING *name,
- const LEX_STRING *dl);
-extern In_C_you_should_use_my_bool_instead() mysql_uninstall_plugin(THD *thd, const LEX_STRING *name);
-extern In_C_you_should_use_my_bool_instead() plugin_register_builtin(struct st_mysql_plugin *plugin);
-extern void plugin_thdvar_init(THD *thd);
-extern void plugin_thdvar_cleanup(THD *thd);
-typedef my_bool (plugin_foreach_func)(THD *thd,
- plugin_ref plugin,
- void *arg);
-extern In_C_you_should_use_my_bool_instead() plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
- int type, uint state_mask, void *arg);
-#include "scheduler.h"
-class THD;
-class scheduler_functions
-{
-public:
- uint max_threads;
- In_C_you_should_use_my_bool_instead() (*init)(void);
- In_C_you_should_use_my_bool_instead() (*init_new_connection_thread)(void);
- void (*add_connection)(THD *thd);
- void (*post_kill_notification)(THD *thd);
- In_C_you_should_use_my_bool_instead() (*end_thread)(THD *thd, In_C_you_should_use_my_bool_instead() cache_thread);
- void (*end)(void);
- scheduler_functions();
-};
-enum scheduler_types
-{
- SCHEDULER_ONE_THREAD_PER_CONNECTION=0,
- SCHEDULER_NO_THREADS,
- SCHEDULER_POOL_OF_THREADS
-};
-void one_thread_per_connection_scheduler(scheduler_functions* func);
-void one_thread_scheduler(scheduler_functions* func);
-enum pool_command_op
-{
- NOT_IN_USE_OP= 0, NORMAL_OP= 1, CONNECT_OP, KILL_OP, DIE_OP
-};
-class thd_scheduler
-{};
-enum enum_query_type
-{
- QT_ORDINARY,
- QT_IS
-};
-typedef ulonglong table_map;
-typedef Bitmap<64> key_map;
-typedef ulong nesting_map;
-typedef ulonglong nested_join_map;
-typedef ulonglong query_id_t;
-extern query_id_t global_query_id;
-inline query_id_t next_query_id() { return global_query_id++; }
-extern const key_map key_map_empty;
-extern key_map key_map_full;
-extern const char *primary_key_name;
-#include "mysql_com.h"
-enum enum_server_command
-{
- COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST,
- COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS,
- COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING,
- COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP,
- COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
- COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE,
- COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON,
- COM_END
-};
-struct st_vio;
-typedef struct st_vio Vio;
-typedef struct st_net {
- Vio *vio;
- unsigned char *buff,*buff_end,*write_pos,*read_pos;
- my_socket fd;
- unsigned long remain_in_buf,length, buf_length, where_b;
- unsigned long max_packet,max_packet_size;
- unsigned int pkt_nr,compress_pkt_nr;
- unsigned int write_timeout, read_timeout, retry_count;
- int fcntl;
- unsigned int *return_status;
- unsigned char reading_or_writing;
- char save_char;
- my_bool unused0;
- my_bool unused;
- my_bool compress;
- my_bool unused1;
- unsigned char *query_cache_query;
- unsigned int last_errno;
- unsigned char error;
- my_bool unused2;
- my_bool return_errno;
- char last_error[512];
- char sqlstate[5 +1];
- void *extension;
-} NET;
-enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
- MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
- MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
- MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
- MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
- MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
- MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
- MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
- MYSQL_TYPE_BIT,
- MYSQL_TYPE_NEWDECIMAL=246,
- MYSQL_TYPE_ENUM=247,
- MYSQL_TYPE_SET=248,
- MYSQL_TYPE_TINY_BLOB=249,
- MYSQL_TYPE_MEDIUM_BLOB=250,
- MYSQL_TYPE_LONG_BLOB=251,
- MYSQL_TYPE_BLOB=252,
- MYSQL_TYPE_VAR_STRING=253,
- MYSQL_TYPE_STRING=254,
- MYSQL_TYPE_GEOMETRY=255
-};
-enum mysql_enum_shutdown_level {
- SHUTDOWN_DEFAULT = 0,
- SHUTDOWN_WAIT_CONNECTIONS= (unsigned char)(1 << 0),
- SHUTDOWN_WAIT_TRANSACTIONS= (unsigned char)(1 << 1),
- SHUTDOWN_WAIT_UPDATES= (unsigned char)(1 << 3),
- SHUTDOWN_WAIT_ALL_BUFFERS= ((unsigned char)(1 << 3) << 1),
- SHUTDOWN_WAIT_CRITICAL_BUFFERS= ((unsigned char)(1 << 3) << 1) + 1,
- KILL_QUERY= 254,
- KILL_CONNECTION= 255
-};
-enum enum_cursor_type
-{
- CURSOR_TYPE_NO_CURSOR= 0,
- CURSOR_TYPE_READ_ONLY= 1,
- CURSOR_TYPE_FOR_UPDATE= 2,
- CURSOR_TYPE_SCROLLABLE= 4
-};
-enum enum_mysql_set_option
-{
- MYSQL_OPTION_MULTI_STATEMENTS_ON,
- MYSQL_OPTION_MULTI_STATEMENTS_OFF
-};
-my_bool my_net_init(NET *net, Vio* vio);
-void my_net_local_init(NET *net);
-void net_end(NET *net);
- void net_clear(NET *net, my_bool clear_buffer);
-my_bool net_realloc(NET *net, size_t length);
-my_bool net_flush(NET *net);
-my_bool my_net_write(NET *net,const unsigned char *packet, size_t len);
-my_bool net_write_command(NET *net,unsigned char command,
- const unsigned char *header, size_t head_len,
- const unsigned char *packet, size_t len);
-int net_real_write(NET *net,const unsigned char *packet, size_t len);
-unsigned long my_net_read(NET *net);
-void my_net_set_write_timeout(NET *net, uint timeout);
-void my_net_set_read_timeout(NET *net, uint timeout);
-struct sockaddr;
-int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
- unsigned int timeout);
-struct rand_struct {
- unsigned long seed1,seed2,max_value;
- double max_value_dbl;
-};
-enum Item_result {STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT,
- DECIMAL_RESULT};
-typedef struct st_udf_args
-{
- unsigned int arg_count;
- enum Item_result *arg_type;
- char **args;
- unsigned long *lengths;
- char *maybe_null;
- char **attributes;
- unsigned long *attribute_lengths;
- void *extension;
-} UDF_ARGS;
-typedef struct st_udf_init
-{
- my_bool maybe_null;
- unsigned int decimals;
- unsigned long max_length;
- char *ptr;
- my_bool const_item;
- void *extension;
-} UDF_INIT;
-void randominit(struct rand_struct *, unsigned long seed1,
- unsigned long seed2);
-double my_rnd(struct rand_struct *);
-void create_random_string(char *to, unsigned int length, struct rand_struct *rand_st);
-void hash_password(unsigned long *to, const char *password, unsigned int password_len);
-void make_scrambled_password_323(char *to, const char *password);
-void scramble_323(char *to, const char *message, const char *password);
-my_bool check_scramble_323(const char *, const char *message,
- unsigned long *salt);
-void get_salt_from_password_323(unsigned long *res, const char *password);
-void make_password_from_salt_323(char *to, const unsigned long *salt);
-void make_scrambled_password(char *to, const char *password);
-void scramble(char *to, const char *message, const char *password);
-my_bool check_scramble(const char *reply, const char *message,
- const unsigned char *hash_stage2);
-void get_salt_from_password(unsigned char *res, const char *password);
-void make_password_from_salt(char *to, const unsigned char *hash_stage2);
-char *octet2hex(char *to, const char *str, unsigned int len);
-char *get_tty_password(const char *opt_message);
-const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
-my_bool my_thread_init(void);
-void my_thread_end(void);
-ulong net_field_length(uchar **packet);
-my_ulonglong net_field_length_ll(uchar **packet);
-uchar *net_store_length(uchar *pkg, ulonglong length);
-#include <violite.h>
-#include "my_net.h"
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-void my_inet_ntoa(struct in_addr in, char *buf);
-struct hostent;
-struct hostent *my_gethostbyname_r(const char *name,
- struct hostent *result, char *buffer,
- int buflen, int *h_errnop);
-enum enum_vio_type
-{
- VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, VIO_TYPE_NAMEDPIPE,
- VIO_TYPE_SSL, VIO_TYPE_SHARED_MEMORY
-};
-Vio* vio_new(my_socket sd, enum enum_vio_type type, uint flags);
-void vio_delete(Vio* vio);
-int vio_close(Vio* vio);
-void vio_reset(Vio* vio, enum enum_vio_type type,
- my_socket sd, void * hPipe, uint flags);
-size_t vio_read(Vio *vio, uchar * buf, size_t size);
-size_t vio_read_buff(Vio *vio, uchar * buf, size_t size);
-size_t vio_write(Vio *vio, const uchar * buf, size_t size);
-int vio_blocking(Vio *vio, my_bool onoff, my_bool *old_mode);
-my_bool vio_is_blocking(Vio *vio);
-int vio_fastsend(Vio *vio);
-int vio_keepalive(Vio *vio, my_bool onoff);
-my_bool vio_should_retry(Vio *vio);
-my_bool vio_was_interrupted(Vio *vio);
-const char* vio_description(Vio *vio);
-enum enum_vio_type vio_type(Vio* vio);
-int vio_errno(Vio*vio);
-my_socket vio_fd(Vio*vio);
-my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
-void vio_in_addr(Vio *vio, struct in_addr *in);
-my_bool vio_poll_read(Vio *vio,uint timeout);
-void vio_end(void);
-enum SSL_type
-{
- SSL_TYPE_NOT_SPECIFIED= -1,
- SSL_TYPE_NONE,
- SSL_TYPE_ANY,
- SSL_TYPE_X509,
- SSL_TYPE_SPECIFIED
-};
-struct st_vio
-{
- my_socket sd;
- void * hPipe;
- my_bool localhost;
- int fcntl_mode;
- struct sockaddr_in local;
- struct sockaddr_in remote;
- enum enum_vio_type type;
- char desc[30];
- char *read_buffer;
- char *read_pos;
- char *read_end;
- void (*viodelete)(Vio*);
- int (*vioerrno)(Vio*);
- size_t (*read)(Vio*, uchar *, size_t);
- size_t (*write)(Vio*, const uchar *, size_t);
- int (*vioblocking)(Vio*, my_bool, my_bool *);
- my_bool (*is_blocking)(Vio*);
- int (*viokeepalive)(Vio*, my_bool);
- int (*fastsend)(Vio*);
- my_bool (*peer_addr)(Vio*, char *, uint16*);
- void (*in_addr)(Vio*, struct in_addr*);
- my_bool (*should_retry)(Vio*);
- my_bool (*was_interrupted)(Vio*);
- int (*vioclose)(Vio*);
- void (*timeout)(Vio*, unsigned int which, unsigned int timeout);
-};
-#include "unireg.h"
-#include "mysqld_error.h"
-#include "structs.h"
-struct st_table;
-class Field;
-typedef struct st_date_time_format {
- uchar positions[8];
- char time_separator;
- uint flag;
- LEX_STRING format;
-} DATE_TIME_FORMAT;
-typedef struct st_keyfile_info {
- uchar ref[8];
- uchar dupp_ref[8];
- uint ref_length;
- uint block_size;
- File filenr;
- ha_rows records;
- ha_rows deleted;
- ulonglong data_file_length;
- ulonglong max_data_file_length;
- ulonglong index_file_length;
- ulonglong max_index_file_length;
- ulonglong delete_length;
- ulonglong auto_increment_value;
- int errkey,sortkey;
- time_t create_time;
- time_t check_time;
- time_t update_time;
- ulong mean_rec_length;
-} KEYFILE_INFO;
-typedef struct st_key_part_info {
- Field *field;
- uint offset;
- uint null_offset;
- uint16 length;
- uint16 store_length;
- uint16 key_type;
- uint16 fieldnr;
- uint16 key_part_flag;
- uint8 type;
- uint8 null_bit;
-} KEY_PART_INFO ;
-typedef struct st_key {
- uint key_length;
- ulong flags;
- uint key_parts;
- uint extra_length;
- uint usable_key_parts;
- uint block_size;
- enum ha_key_alg algorithm;
- union
- {
- plugin_ref parser;
- LEX_STRING *parser_name;
- };
- KEY_PART_INFO *key_part;
- char *name;
- ulong *rec_per_key;
- union {
- int bdb_return_if_eq;
- } handler;
- struct st_table *table;
-} KEY;
-struct st_join_table;
-typedef struct st_reginfo {
- struct st_join_table *join_tab;
- enum thr_lock_type lock_type;
- In_C_you_should_use_my_bool_instead() not_exists_optimize;
- In_C_you_should_use_my_bool_instead() impossible_range;
-} REGINFO;
-struct st_read_record;
-class SQL_SELECT;
-class THD;
-class handler;
-typedef struct st_read_record {
- struct st_table *table;
- handler *file;
- struct st_table **forms;
- int (*read_record)(struct st_read_record *);
- THD *thd;
- SQL_SELECT *select;
- uint cache_records;
- uint ref_length,struct_length,reclength,rec_cache_size,error_offset;
- uint index;
- uchar *ref_pos;
- uchar *record;
- uchar *rec_buf;
- uchar *cache,*cache_pos,*cache_end,*read_positions;
- IO_CACHE *io_cache;
- In_C_you_should_use_my_bool_instead() print_error, ignore_not_found_rows;
-} READ_RECORD;
-typedef enum enum_mysql_timestamp_type timestamp_type;
-typedef struct {
- ulong year,month,day,hour;
- ulonglong minute,second,second_part;
- In_C_you_should_use_my_bool_instead() neg;
-} INTERVAL;
-typedef struct st_known_date_time_format {
- const char *format_name;
- const char *date_format;
- const char *datetime_format;
- const char *time_format;
-} KNOWN_DATE_TIME_FORMAT;
-enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED};
-extern const char *show_comp_option_name[];
-typedef int *(*update_var)(THD *, struct st_mysql_show_var *);
-typedef struct st_lex_user {
- LEX_STRING user, host, password;
-} LEX_USER;
-typedef struct user_resources {
- uint questions;
- uint updates;
- uint conn_per_hour;
- uint user_conn;
- enum {QUERIES_PER_HOUR= 1, UPDATES_PER_HOUR= 2, CONNECTIONS_PER_HOUR= 4,
- USER_CONNECTIONS= 8};
- uint specified_limits;
-} USER_RESOURCES;
-typedef struct user_conn {
- char *user;
- char *host;
- ulonglong reset_utime;
- uint len;
- uint connections;
- uint conn_per_hour, updates, questions;
- USER_RESOURCES user_resources;
-} USER_CONN;
-class Discrete_interval {
-private:
- ulonglong interval_min;
- ulonglong interval_values;
- ulonglong interval_max;
-public:
- Discrete_interval *next;
- void replace(ulonglong start, ulonglong val, ulonglong incr)
- {
- interval_min= start;
- interval_values= val;
- interval_max= (val == ((unsigned long long)(~0ULL))) ? val : start + val * incr;
- }
- Discrete_interval(ulonglong start, ulonglong val, ulonglong incr) :
- next(NULL) { replace(start, val, incr); };
- Discrete_interval() : next(NULL) { replace(0, 0, 0); };
- ulonglong minimum() const { return interval_min; };
- ulonglong values() const { return interval_values; };
- ulonglong maximum() const { return interval_max; };
- In_C_you_should_use_my_bool_instead() merge_if_contiguous(ulonglong start, ulonglong val, ulonglong incr)
- {
- if (interval_max == start)
- {
- if (val == ((unsigned long long)(~0ULL)))
- {
- interval_values= interval_max= val;
- }
- else
- {
- interval_values+= val;
- interval_max= start + val * incr;
- }
- return 0;
- }
- return 1;
- };
-};
-class Discrete_intervals_list {
-private:
- Discrete_interval *head;
- Discrete_interval *tail;
- Discrete_interval *current;
- uint elements;
- void copy_(const Discrete_intervals_list& from)
- {
- for (Discrete_interval *i= from.head; i; i= i->next)
- {
- Discrete_interval j= *i;
- append(&j);
- }
- }
-public:
- Discrete_intervals_list() : head(NULL), current(NULL), elements(0) {};
- Discrete_intervals_list(const Discrete_intervals_list& from)
- {
- copy_(from);
- }
- void operator=(const Discrete_intervals_list& from)
- {
- empty();
- copy_(from);
- }
- void empty_no_free()
- {
- head= current= NULL;
- elements= 0;
- }
- void empty()
- {
- for (Discrete_interval *i= head; i;)
- {
- Discrete_interval *next= i->next;
- delete i;
- i= next;
- }
- empty_no_free();
- }
- const Discrete_interval* get_next()
- {
- Discrete_interval *tmp= current;
- if (current != NULL)
- current= current->next;
- return tmp;
- }
- ~Discrete_intervals_list() { empty(); };
- In_C_you_should_use_my_bool_instead() append(ulonglong start, ulonglong val, ulonglong incr);
- In_C_you_should_use_my_bool_instead() append(Discrete_interval *interval);
- ulonglong minimum() const { return (head ? head->minimum() : 0); };
- ulonglong maximum() const { return (head ? tail->maximum() : 0); };
- uint nb_elements() const { return elements; }
-};
-void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size);
-void *sql_alloc(size_t);
-void *sql_calloc(size_t);
-char *sql_strdup(const char *str);
-char *sql_strmake(const char *str, size_t len);
-void *sql_memdup(const void * ptr, size_t size);
-void sql_element_free(void *ptr);
-char *sql_strmake_with_convert(const char *str, size_t arg_length,
- CHARSET_INFO *from_cs,
- size_t max_res_length,
- CHARSET_INFO *to_cs, size_t *result_length);
-uint kill_one_thread(THD *thd, ulong id, In_C_you_should_use_my_bool_instead() only_kill_query);
-void sql_kill(THD *thd, ulong id, In_C_you_should_use_my_bool_instead() only_kill_query);
-In_C_you_should_use_my_bool_instead() net_request_file(NET* net, const char* fname);
-char* query_table_status(THD *thd,const char *db,const char *table_name);
-extern CHARSET_INFO *system_charset_info, *files_charset_info ;
-extern CHARSET_INFO *national_charset_info, *table_alias_charset;
-enum Derivation
-{
- DERIVATION_IGNORABLE= 5,
- DERIVATION_COERCIBLE= 4,
- DERIVATION_SYSCONST= 3,
- DERIVATION_IMPLICIT= 2,
- DERIVATION_NONE= 1,
- DERIVATION_EXPLICIT= 0
-};
-typedef struct my_locale_st
-{
- uint number;
- const char *name;
- const char *description;
- const In_C_you_should_use_my_bool_instead() is_ascii;
- TYPELIB *month_names;
- TYPELIB *ab_month_names;
- TYPELIB *day_names;
- TYPELIB *ab_day_names;
-} MY_LOCALE;
-extern MY_LOCALE my_locale_en_US;
-extern MY_LOCALE *my_locales[];
-extern MY_LOCALE *my_default_lc_time_names;
-MY_LOCALE *my_locale_by_name(const char *name);
-MY_LOCALE *my_locale_by_number(uint number);
-class Object_creation_ctx
-{
-public:
- Object_creation_ctx *set_n_backup(THD *thd);
- void restore_env(THD *thd, Object_creation_ctx *backup_ctx);
-protected:
- Object_creation_ctx() {}
- virtual Object_creation_ctx *create_backup_ctx(THD *thd) const = 0;
- virtual void change_env(THD *thd) const = 0;
-public:
- virtual ~Object_creation_ctx()
- { }
-};
-class Default_object_creation_ctx : public Object_creation_ctx
-{
-public:
- CHARSET_INFO *get_client_cs()
- {
- return m_client_cs;
- }
- CHARSET_INFO *get_connection_cl()
- {
- return m_connection_cl;
- }
-protected:
- Default_object_creation_ctx(THD *thd);
- Default_object_creation_ctx(CHARSET_INFO *client_cs,
- CHARSET_INFO *connection_cl);
-protected:
- virtual Object_creation_ctx *create_backup_ctx(THD *thd) const;
- virtual void change_env(THD *thd) const;
-protected:
- CHARSET_INFO *m_client_cs;
- CHARSET_INFO *m_connection_cl;
-};
-struct TABLE_LIST;
-class String;
-void view_store_options(THD *thd, TABLE_LIST *table, String *buff);
-enum enum_parsing_place
-{
- NO_MATTER,
- IN_HAVING,
- SELECT_LIST,
- IN_WHERE,
- IN_ON
-};
-struct st_table;
-class THD;
-enum enum_check_fields
-{
- CHECK_FIELD_IGNORE,
- CHECK_FIELD_WARN,
- CHECK_FIELD_ERROR_FOR_NULL
-};
-typedef struct st_sql_list {
- uint elements;
- uchar *first;
- uchar **next;
- st_sql_list() {}
- inline void empty()
- {
- elements=0;
- first=0;
- next= &first;
- }
- inline void link_in_list(uchar *element,uchar **next_ptr)
- {
- elements++;
- (*next)=element;
- next= next_ptr;
- *next=0;
- }
- inline void save_and_clear(struct st_sql_list *save)
- {
- *save= *this;
- empty();
- }
- inline void push_front(struct st_sql_list *save)
- {
- *save->next= first;
- first= save->first;
- elements+= save->elements;
- }
- inline void push_back(struct st_sql_list *save)
- {
- if (save->first)
- {
- *next= save->first;
- next= save->next;
- elements+= save->elements;
- }
- }
-} SQL_LIST;
-extern pthread_key_t THR_THD;
-inline THD *_current_thd(void)
-{
- return ((THD*) pthread_getspecific((THR_THD)));
-}
-extern "C"
-const char *set_thd_proc_info(THD *thd, const char *info,
- const char *calling_func,
- const char *calling_file,
- const unsigned int calling_line);
-enum enum_table_ref_type
-{
- TABLE_REF_NULL= 0,
- TABLE_REF_VIEW,
- TABLE_REF_BASE_TABLE,
- TABLE_REF_I_S_TABLE,
- TABLE_REF_TMP_TABLE
-};
-extern ulong server_id, concurrency;
-typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
- uint key_length,
- ulonglong *engine_data);
-#include "sql_string.h"
-class String;
-int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
-String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
-uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
- const char *from, uint32 from_length,
- CHARSET_INFO *from_cs, uint *errors);
-uint32 well_formed_copy_nchars(CHARSET_INFO *to_cs,
- char *to, uint to_length,
- CHARSET_INFO *from_cs,
- const char *from, uint from_length,
- uint nchars,
- const char **well_formed_error_pos,
- const char **cannot_convert_error_pos,
- const char **from_end_pos);
-size_t my_copy_with_hex_escaping(CHARSET_INFO *cs,
- char *dst, size_t dstlen,
- const char *src, size_t srclen);
-class String
-{
- char *Ptr;
- uint32 str_length,Alloced_length;
- In_C_you_should_use_my_bool_instead() alloced;
- CHARSET_INFO *str_charset;
-public:
- String()
- {
- Ptr=0; str_length=Alloced_length=0; alloced=0;
- str_charset= &my_charset_bin;
- }
- String(uint32 length_arg)
- {
- alloced=0; Alloced_length=0; (void) real_alloc(length_arg);
- str_charset= &my_charset_bin;
- }
- String(const char *str, CHARSET_INFO *cs)
- {
- Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
- str_charset=cs;
- }
- String(const char *str,uint32 len, CHARSET_INFO *cs)
- {
- Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
- str_charset=cs;
- }
- String(char *str,uint32 len, CHARSET_INFO *cs)
- {
- Ptr=(char*) str; Alloced_length=str_length=len; alloced=0;
- str_charset=cs;
- }
- String(const String &str)
- {
- Ptr=str.Ptr ; str_length=str.str_length ;
- Alloced_length=str.Alloced_length; alloced=0;
- str_charset=str.str_charset;
- }
- static void *operator new(size_t size, MEM_ROOT *mem_root)
- { return (void*) alloc_root(mem_root, (uint) size); }
- static void operator delete(void *ptr_arg,size_t size)
- { ; }
- static void operator delete(void *ptr_arg, MEM_ROOT *mem_root)
- { }
- ~String() { free(); }
- inline void set_charset(CHARSET_INFO *charset_arg)
- { str_charset= charset_arg; }
- inline CHARSET_INFO *charset() const { return str_charset; }
- inline uint32 length() const { return str_length;}
- inline uint32 alloced_length() const { return Alloced_length;}
- inline char& operator [] (uint32 i) const { return Ptr[i]; }
- inline void length(uint32 len) { str_length=len ; }
- inline In_C_you_should_use_my_bool_instead() is_empty() { return (str_length == 0); }
- inline void mark_as_const() { Alloced_length= 0;}
- inline const char *ptr() const { return Ptr; }
- inline char *c_ptr()
- {
- if (!Ptr || Ptr[str_length])
- (void) realloc(str_length);
- return Ptr;
- }
- inline char *c_ptr_quick()
- {
- if (Ptr && str_length < Alloced_length)
- Ptr[str_length]=0;
- return Ptr;
- }
- inline char *c_ptr_safe()
- {
- if (Ptr && str_length < Alloced_length)
- Ptr[str_length]=0;
- else
- (void) realloc(str_length);
- return Ptr;
- }
- void set(String &str,uint32 offset,uint32 arg_length)
- {
- assert(&str != this);
- free();
- Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0;
- if (str.Alloced_length)
- Alloced_length=str.Alloced_length-offset;
- else
- Alloced_length=0;
- str_charset=str.str_charset;
- }
- inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs)
- {
- free();
- Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0;
- str_charset=cs;
- }
- inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs)
- {
- free();
- Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
- str_charset=cs;
- }
- In_C_you_should_use_my_bool_instead() set_ascii(const char *str, uint32 arg_length);
- inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
- {
- if (!alloced)
- {
- Ptr=(char*) str; str_length=Alloced_length=arg_length;
- }
- str_charset=cs;
- }
- In_C_you_should_use_my_bool_instead() set_int(longlong num, In_C_you_should_use_my_bool_instead() unsigned_flag, CHARSET_INFO *cs);
- In_C_you_should_use_my_bool_instead() set(longlong num, CHARSET_INFO *cs)
- { return set_int(num, false, cs); }
- In_C_you_should_use_my_bool_instead() set(ulonglong num, CHARSET_INFO *cs)
- { return set_int((longlong)num, true, cs); }
- In_C_you_should_use_my_bool_instead() set_real(double num,uint decimals, CHARSET_INFO *cs);
- inline void chop()
- {
- Ptr[str_length--]= '\0';
- }
- inline void free()
- {
- if (alloced)
- {
- alloced=0;
- Alloced_length=0;
- ((void)(myf) (0),my_no_flags_free(Ptr));
- Ptr=0;
- str_length=0;
- }
- }
- inline In_C_you_should_use_my_bool_instead() alloc(uint32 arg_length)
- {
- if (arg_length < Alloced_length)
- return 0;
- return real_alloc(arg_length);
- }
- In_C_you_should_use_my_bool_instead() real_alloc(uint32 arg_length);
- In_C_you_should_use_my_bool_instead() realloc(uint32 arg_length);
- inline void shrink(uint32 arg_length)
- {
- if (arg_length < Alloced_length)
- {
- char *new_ptr;
- if (!(new_ptr=(char*) my_realloc(Ptr,arg_length,(myf) (0))))
- {
- Alloced_length = 0;
- real_alloc(arg_length);
- }
- else
- {
- Ptr=new_ptr;
- Alloced_length=arg_length;
- }
- }
- }
- In_C_you_should_use_my_bool_instead() is_alloced() { return alloced; }
- inline String& operator = (const String &s)
- {
- if (&s != this)
- {
- assert(!s.uses_buffer_owned_by(this));
- free();
- Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
- alloced=0;
- }
- return *this;
- }
- In_C_you_should_use_my_bool_instead() copy();
- In_C_you_should_use_my_bool_instead() copy(const String &s);
- In_C_you_should_use_my_bool_instead() copy(const char *s,uint32 arg_length, CHARSET_INFO *cs);
- static In_C_you_should_use_my_bool_instead() needs_conversion(uint32 arg_length,
- CHARSET_INFO *cs_from, CHARSET_INFO *cs_to,
- uint32 *offset);
- In_C_you_should_use_my_bool_instead() copy_aligned(const char *s, uint32 arg_length, uint32 offset,
- CHARSET_INFO *cs);
- In_C_you_should_use_my_bool_instead() set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
- In_C_you_should_use_my_bool_instead() copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
- CHARSET_INFO *csto, uint *errors);
- In_C_you_should_use_my_bool_instead() append(const String &s);
- In_C_you_should_use_my_bool_instead() append(const char *s);
- In_C_you_should_use_my_bool_instead() append(const char *s,uint32 arg_length);
- In_C_you_should_use_my_bool_instead() append(const char *s,uint32 arg_length, CHARSET_INFO *cs);
- In_C_you_should_use_my_bool_instead() append(IO_CACHE* file, uint32 arg_length);
- In_C_you_should_use_my_bool_instead() append_with_prefill(const char *s, uint32 arg_length,
- uint32 full_length, char fill_char);
- int strstr(const String &search,uint32 offset=0);
- int strrstr(const String &search,uint32 offset=0);
- In_C_you_should_use_my_bool_instead() replace(uint32 offset,uint32 arg_length,const char *to,uint32 length);
- In_C_you_should_use_my_bool_instead() replace(uint32 offset,uint32 arg_length,const String &to);
- inline In_C_you_should_use_my_bool_instead() append(char chr)
- {
- if (str_length < Alloced_length)
- {
- Ptr[str_length++]=chr;
- }
- else
- {
- if (realloc(str_length+1))
- return 1;
- Ptr[str_length++]=chr;
- }
- return 0;
- }
- In_C_you_should_use_my_bool_instead() fill(uint32 max_length,char fill);
- void strip_sp();
- friend int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
- friend int stringcmp(const String *a,const String *b);
- friend String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
- uint32 numchars();
- int charpos(int i,uint32 offset=0);
- int reserve(uint32 space_needed)
- {
- return realloc(str_length + space_needed);
- }
- int reserve(uint32 space_needed, uint32 grow_by);
- void q_append(const char c)
- {
- Ptr[str_length++] = c;
- }
- void q_append(const uint32 n)
- {
- *((long *) (Ptr + str_length))= (long) (n);
- str_length += 4;
- }
- void q_append(double d)
- {
- do { *((long *) (Ptr + str_length)) = ((doubleget_union *)&(d))->m[0]; *(((long *) (Ptr + str_length))+1) = ((doubleget_union *)&(d))->m[1]; } while (0);
- str_length += 8;
- }
- void q_append(double *d)
- {
- do { *((long *) (Ptr + str_length)) = ((doubleget_union *)&(*d))->m[0]; *(((long *) (Ptr + str_length))+1) = ((doubleget_union *)&(*d))->m[1]; } while (0);
- str_length += 8;
- }
- void q_append(const char *data, uint32 data_len)
- {
- memcpy(Ptr + str_length, data, data_len);
- str_length += data_len;
- }
- void write_at_position(int position, uint32 value)
- {
- *((long *) (Ptr + position))= (long) (value);
- }
- void qs_append(const char *str, uint32 len);
- void qs_append(double d);
- void qs_append(double *d);
- inline void qs_append(const char c)
- {
- Ptr[str_length]= c;
- str_length++;
- }
- void qs_append(int i);
- void qs_append(uint i);
- inline char *prep_append(uint32 arg_length, uint32 step_alloc)
- {
- uint32 new_length= arg_length + str_length;
- if (new_length > Alloced_length)
- {
- if (realloc(new_length + step_alloc))
- return 0;
- }
- uint32 old_length= str_length;
- str_length+= arg_length;
- return Ptr+ old_length;
- }
- inline In_C_you_should_use_my_bool_instead() append(const char *s, uint32 arg_length, uint32 step_alloc)
- {
- uint32 new_length= arg_length + str_length;
- if (new_length > Alloced_length && realloc(new_length + step_alloc))
- return (1);
- memcpy(Ptr+str_length, s, arg_length);
- str_length+= arg_length;
- return (0);
- }
- void print(String *print);
- void swap(String &s);
- inline In_C_you_should_use_my_bool_instead() uses_buffer_owned_by(const String *s) const
- {
- return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
- }
-};
-static inline In_C_you_should_use_my_bool_instead() check_if_only_end_space(CHARSET_INFO *cs, char *str,
- char *end)
-{
- return str+ cs->cset->scan(cs, str, end, 2) == end;
-}
-#include "sql_list.h"
-class Sql_alloc
-{
-public:
- static void *operator new(size_t size) throw ()
- {
- return sql_alloc(size);
- }
- static void *operator new[](size_t size)
- {
- return sql_alloc(size);
- }
- static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
- { return alloc_root(mem_root, size); }
- static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
- { return alloc_root(mem_root, size); }
- static void operator delete(void *ptr, size_t size) { ; }
- static void operator delete(void *ptr, MEM_ROOT *mem_root)
- { }
- static void operator delete[](void *ptr, MEM_ROOT *mem_root)
- { }
- static void operator delete[](void *ptr, size_t size) { ; }
- inline Sql_alloc() {}
- inline ~Sql_alloc() {}
-};
-struct list_node :public Sql_alloc
-{
- list_node *next;
- void *info;
- list_node(void *info_par,list_node *next_par)
- :next(next_par),info(info_par)
- {}
- list_node()
- {
- info= 0;
- next= this;
- }
-};
-extern list_node end_of_list;
-class base_list :public Sql_alloc
-{
-protected:
- list_node *first,**last;
-public:
- uint elements;
- inline void empty() { elements=0; first= &end_of_list; last=&first;}
- inline base_list() { empty(); }
- inline base_list(const base_list &tmp) :Sql_alloc()
- {
- elements= tmp.elements;
- first= tmp.first;
- last= elements ? tmp.last : &first;
- }
- base_list(const base_list &rhs, MEM_ROOT *mem_root);
- inline base_list(In_C_you_should_use_my_bool_instead() error) { }
- inline In_C_you_should_use_my_bool_instead() push_back(void *info)
- {
- if (((*last)=new list_node(info, &end_of_list)))
- {
- last= &(*last)->next;
- elements++;
- return 0;
- }
- return 1;
- }
- inline In_C_you_should_use_my_bool_instead() push_back(void *info, MEM_ROOT *mem_root)
- {
- if (((*last)=new (mem_root) list_node(info, &end_of_list)))
- {
- last= &(*last)->next;
- elements++;
- return 0;
- }
- return 1;
- }
- inline In_C_you_should_use_my_bool_instead() push_front(void *info)
- {
- list_node *node=new list_node(info,first);
- if (node)
- {
- if (last == &first)
- last= &node->next;
- first=node;
- elements++;
- return 0;
- }
- return 1;
- }
- void remove(list_node **prev)
- {
- list_node *node=(*prev)->next;
- if (!--elements)
- last= &first;
- else if (last == &(*prev)->next)
- last= prev;
- delete *prev;
- *prev=node;
- }
- inline void concat(base_list *list)
- {
- if (!list->is_empty())
- {
- *last= list->first;
- last= list->last;
- elements+= list->elements;
- }
- }
- inline void *pop(void)
- {
- if (first == &end_of_list) return 0;
- list_node *tmp=first;
- first=first->next;
- if (!--elements)
- last= &first;
- return tmp->info;
- }
- inline void disjoin(base_list *list)
- {
- list_node **prev= &first;
- list_node *node= first;
- list_node *list_first= list->first;
- elements=0;
- while (node && node != list_first)
- {
- prev= &node->next;
- node= node->next;
- elements++;
- }
- *prev= *last;
- last= prev;
- }
- inline void prepand(base_list *list)
- {
- if (!list->is_empty())
- {
- *list->last= first;
- first= list->first;
- elements+= list->elements;
- }
- }
- inline void swap(base_list &rhs)
- {
- { list_node * dummy; dummy= first; first= rhs.first; rhs.first= dummy; };
- { list_node ** dummy; dummy= last; last= rhs.last; rhs.last= dummy; };
- { uint dummy; dummy= elements; elements= rhs.elements; rhs.elements= dummy; };
- }
- inline list_node* last_node() { return *last; }
- inline list_node* first_node() { return first;}
- inline void *head() { return first->info; }
- inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
- inline In_C_you_should_use_my_bool_instead() is_empty() { return first == &end_of_list ; }
- inline list_node *last_ref() { return &end_of_list; }
- friend class base_list_iterator;
- friend class error_list;
- friend class error_list_iterator;
-protected:
- void after(void *info,list_node *node)
- {
- list_node *new_node=new list_node(info,node->next);
- node->next=new_node;
- elements++;
- if (last == &(node->next))
- last= &new_node->next;
- }
-};
-class base_list_iterator
-{
-protected:
- base_list *list;
- list_node **el,**prev,*current;
- void sublist(base_list &ls, uint elm)
- {
- ls.first= *el;
- ls.last= list->last;
- ls.elements= elm;
- }
-public:
- base_list_iterator()
- :list(0), el(0), prev(0), current(0)
- {}
- base_list_iterator(base_list &list_par)
- { init(list_par); }
- inline void init(base_list &list_par)
- {
- list= &list_par;
- el= &list_par.first;
- prev= 0;
- current= 0;
- }
- inline void *next(void)
- {
- prev=el;
- current= *el;
- el= &current->next;
- return current->info;
- }
- inline void *next_fast(void)
- {
- list_node *tmp;
- tmp= *el;
- el= &tmp->next;
- return tmp->info;
- }
- inline void rewind(void)
- {
- el= &list->first;
- }
- inline void *replace(void *element)
- {
- void *tmp=current->info;
- assert(current->info != 0);
- current->info=element;
- return tmp;
- }
- void *replace(base_list &new_list)
- {
- void *ret_value=current->info;
- if (!new_list.is_empty())
- {
- *new_list.last=current->next;
- current->info=new_list.first->info;
- current->next=new_list.first->next;
- if ((list->last == &current->next) && (new_list.elements > 1))
- list->last= new_list.last;
- list->elements+=new_list.elements-1;
- }
- return ret_value;
- }
- inline void remove(void)
- {
- list->remove(prev);
- el=prev;
- current=0;
- }
- void after(void *element)
- {
- list->after(element,current);
- current=current->next;
- el= &current->next;
- }
- inline void **ref(void)
- {
- return &current->info;
- }
- inline In_C_you_should_use_my_bool_instead() is_last(void)
- {
- return el == &list->last_ref()->next;
- }
- friend class error_list_iterator;
-};
-template <class T> class List :public base_list
-{
-public:
- inline List() :base_list() {}
- inline List(const List<T> &tmp) :base_list(tmp) {}
- inline List(const List<T> &tmp, MEM_ROOT *mem_root) :
- base_list(tmp, mem_root) {}
- inline In_C_you_should_use_my_bool_instead() push_back(T *a) { return base_list::push_back(a); }
- inline In_C_you_should_use_my_bool_instead() push_back(T *a, MEM_ROOT *mem_root)
- { return base_list::push_back(a, mem_root); }
- inline In_C_you_should_use_my_bool_instead() push_front(T *a) { return base_list::push_front(a); }
- inline T* head() {return (T*) base_list::head(); }
- inline T** head_ref() {return (T**) base_list::head_ref(); }
- inline T* pop() {return (T*) base_list::pop(); }
- inline void concat(List<T> *list) { base_list::concat(list); }
- inline void disjoin(List<T> *list) { base_list::disjoin(list); }
- inline void prepand(List<T> *list) { base_list::prepand(list); }
- void delete_elements(void)
- {
- list_node *element,*next;
- for (element=first; element != &end_of_list; element=next)
- {
- next=element->next;
- delete (T*) element->info;
- }
- empty();
- }
-};
-template <class T> class List_iterator :public base_list_iterator
-{
-public:
- List_iterator(List<T> &a) : base_list_iterator(a) {}
- List_iterator() : base_list_iterator() {}
- inline void init(List<T> &a) { base_list_iterator::init(a); }
- inline T* operator++(int) { return (T*) base_list_iterator::next(); }
- inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
- inline T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
- inline void rewind(void) { base_list_iterator::rewind(); }
- inline void remove() { base_list_iterator::remove(); }
- inline void after(T *a) { base_list_iterator::after(a); }
- inline T** ref(void) { return (T**) base_list_iterator::ref(); }
-};
-template <class T> class List_iterator_fast :public base_list_iterator
-{
-protected:
- inline T *replace(T *a) { return (T*) 0; }
- inline T *replace(List<T> &a) { return (T*) 0; }
- inline void remove(void) { }
- inline void after(T *a) { }
- inline T** ref(void) { return (T**) 0; }
-public:
- inline List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
- inline List_iterator_fast() : base_list_iterator() {}
- inline void init(List<T> &a) { base_list_iterator::init(a); }
- inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
- inline void rewind(void) { base_list_iterator::rewind(); }
- void sublist(List<T> &list_arg, uint el_arg)
- {
- base_list_iterator::sublist(list_arg, el_arg);
- }
-};
-struct ilink
-{
- struct ilink **prev,*next;
- static void *operator new(size_t size)
- {
- return (void*)my_malloc((uint)size, (myf) (16 | 8));
- }
- static void operator delete(void* ptr_arg, size_t size)
- {
- ((void)(myf) (16|64),my_no_flags_free((uchar*)ptr_arg));
- }
- inline ilink()
- {
- prev=0; next=0;
- }
- inline void unlink()
- {
- if (prev) *prev= next;
- if (next) next->prev=prev;
- prev=0 ; next=0;
- }
- virtual ~ilink() { unlink(); }
-};
-class i_string: public ilink
-{
-public:
- const char* ptr;
- i_string():ptr(0) { }
- i_string(const char* s) : ptr(s) {}
-};
-class i_string_pair: public ilink
-{
-public:
- const char* key;
- const char* val;
- i_string_pair():key(0),val(0) { }
- i_string_pair(const char* key_arg, const char* val_arg) :
- key(key_arg),val(val_arg) {}
-};
-template <class T> class I_List_iterator;
-class base_ilist
-{
-public:
- struct ilink *first,last;
- inline void empty() { first= &last; last.prev= &first; }
- base_ilist() { empty(); }
- inline In_C_you_should_use_my_bool_instead() is_empty() { return first == &last; }
- inline void append(ilink *a)
- {
- first->prev= &a->next;
- a->next=first; a->prev= &first; first=a;
- }
- inline void push_back(ilink *a)
- {
- *last.prev= a;
- a->next= &last;
- a->prev= last.prev;
- last.prev= &a->next;
- }
- inline struct ilink *get()
- {
- struct ilink *first_link=first;
- if (first_link == &last)
- return 0;
- first_link->unlink();
- return first_link;
- }
- inline struct ilink *head()
- {
- return (first != &last) ? first : 0;
- }
- friend class base_list_iterator;
-};
-class base_ilist_iterator
-{
- base_ilist *list;
- struct ilink **el,*current;
-public:
- base_ilist_iterator(base_ilist &list_par) :list(&list_par),
- el(&list_par.first),current(0) {}
- void *next(void)
- {
- current= *el;
- if (current == &list->last) return 0;
- el= &current->next;
- return current;
- }
-};
-template <class T>
-class I_List :private base_ilist
-{
-public:
- I_List() :base_ilist() {}
- inline void empty() { base_ilist::empty(); }
- inline In_C_you_should_use_my_bool_instead() is_empty() { return base_ilist::is_empty(); }
- inline void append(T* a) { base_ilist::append(a); }
- inline void push_back(T* a) { base_ilist::push_back(a); }
- inline T* get() { return (T*) base_ilist::get(); }
- inline T* head() { return (T*) base_ilist::head(); }
- friend class I_List_iterator<T>;
-};
-template <class T> class I_List_iterator :public base_ilist_iterator
-{
-public:
- I_List_iterator(I_List<T> &a) : base_ilist_iterator(a) {}
- inline T* operator++(int) { return (T*) base_ilist_iterator::next(); }
-};
-template <typename T>
-inline
-void
-list_copy_and_replace_each_value(List<T> &list, MEM_ROOT *mem_root)
-{
- List_iterator<T> it(list);
- T *el;
- while ((el= it++))
- it.replace(el->clone(mem_root));
-}
-#include "sql_map.h"
-class mapped_files;
-mapped_files *map_file(const char * name,uchar *magic,uint magic_length);
-void unmap_file(mapped_files *map);
-class mapped_files :public ilink {
- uchar *map;
- ha_rows size;
- char *name;
- File file;
- int error;
- uint use_count;
-public:
- mapped_files(const char * name,uchar *magic,uint magic_length);
- ~mapped_files();
- friend class mapped_file;
- friend mapped_files *map_file(const char * name,uchar *magic,
- uint magic_length);
- friend void unmap_file(mapped_files *map);
-};
-class mapped_file
-{
- mapped_files *file;
-public:
- mapped_file(const char * name,uchar *magic,uint magic_length)
- {
- file=map_file(name,magic,magic_length);
- }
- ~mapped_file()
- {
- unmap_file(file);
- }
- uchar *map()
- {
- return file->map;
- }
-};
-#include "my_decimal.h"
-#include <decimal.h>
-typedef enum
-{TRUNCATE=0, HALF_EVEN, HALF_UP, CEILING, FLOOR}
- decimal_round_mode;
-typedef int32 decimal_digit_t;
-typedef struct st_decimal_t {
- int intg, frac, len;
- my_bool sign;
- decimal_digit_t *buf;
-} decimal_t;
-int internal_str2dec(const char *from, decimal_t *to, char **end,
- my_bool fixed);
-int decimal2string(decimal_t *from, char *to, int *to_len,
- int fixed_precision, int fixed_decimals,
- char filler);
-int decimal2ulonglong(decimal_t *from, ulonglong *to);
-int ulonglong2decimal(ulonglong from, decimal_t *to);
-int decimal2longlong(decimal_t *from, longlong *to);
-int longlong2decimal(longlong from, decimal_t *to);
-int decimal2double(decimal_t *from, double *to);
-int double2decimal(double from, decimal_t *to);
-int decimal_actual_fraction(decimal_t *from);
-int decimal2bin(decimal_t *from, uchar *to, int precision, int scale);
-int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale);
-int decimal_size(int precision, int scale);
-int decimal_bin_size(int precision, int scale);
-int decimal_result_size(decimal_t *from1, decimal_t *from2, char op,
- int param);
-int decimal_intg(decimal_t *from);
-int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to);
-int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to);
-int decimal_cmp(decimal_t *from1, decimal_t *from2);
-int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to);
-int decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to,
- int scale_incr);
-int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to);
-int decimal_round(decimal_t *from, decimal_t *to, int new_scale,
- decimal_round_mode mode);
-int decimal_is_zero(decimal_t *from);
-void max_decimal(int precision, int frac, decimal_t *to);
-inline uint my_decimal_size(uint precision, uint scale)
-{
- return decimal_size(precision, scale) + 1;
-}
-inline int my_decimal_int_part(uint precision, uint decimals)
-{
- return precision - ((decimals == 31) ? 0 : decimals);
-}
-class my_decimal :public decimal_t
-{
- decimal_digit_t buffer[9];
-public:
- void init()
- {
- len= 9;
- buf= buffer;
- for (uint i= 0; i < 9; i++)
- buffer[i]= i;
- }
- my_decimal()
- {
- init();
- }
- void fix_buffer_pointer() { buf= buffer; }
- In_C_you_should_use_my_bool_instead() sign() const { return decimal_t::sign; }
- void sign(In_C_you_should_use_my_bool_instead() s) { decimal_t::sign= s; }
- uint precision() const { return intg + frac; }
- void swap(my_decimal &rhs)
- {
- { my_decimal dummy; dummy= *this; *this= rhs; rhs= dummy; };
- { decimal_digit_t * dummy; dummy= buf; buf= rhs.buf; rhs.buf= dummy; };
- }
-};
-void print_decimal(const my_decimal *dec);
-void print_decimal_buff(const my_decimal *dec, const uchar* ptr, int length);
-const char *dbug_decimal_as_string(char *buff, const my_decimal *val);
-int decimal_operation_results(int result);
-inline
-void max_my_decimal(my_decimal *to, int precision, int frac)
-{
- assert((precision <= ((9 * 9) - 8*2))&& (frac <= 30));
- max_decimal(precision, frac, (decimal_t*) to);
-}
-inline void max_internal_decimal(my_decimal *to)
-{
- max_my_decimal(to, ((9 * 9) - 8*2), 0);
-}
-inline int check_result(uint mask, int result)
-{
- if (result & mask)
- decimal_operation_results(result);
- return result;
-}
-inline int check_result_and_overflow(uint mask, int result, my_decimal *val)
-{
- if (check_result(mask, result) & 2)
- {
- In_C_you_should_use_my_bool_instead() sign= val->sign();
- val->fix_buffer_pointer();
- max_internal_decimal(val);
- val->sign(sign);
- }
- return result;
-}
-inline uint my_decimal_length_to_precision(uint length, uint scale,
- In_C_you_should_use_my_bool_instead() unsigned_flag)
-{
- assert(length || !scale);
- return (uint) (length - (scale>0 ? 1:0) -
- (unsigned_flag || !length ? 0:1));
-}
-inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
- In_C_you_should_use_my_bool_instead() unsigned_flag)
-{
- assert(precision || !scale);
- do { if ((precision) > (((9 * 9) - 8*2))) (precision)=(((9 * 9) - 8*2)); } while(0);
- return (uint32)(precision + (scale>0 ? 1:0) +
- (unsigned_flag || !precision ? 0:1));
-}
-inline
-int my_decimal_string_length(const my_decimal *d)
-{
- return (((d)->intg ? (d)->intg : 1) + (d)->frac + ((d)->frac > 0) + 2);
-}
-inline
-int my_decimal_max_length(const my_decimal *d)
-{
- return (((d)->intg ? (d)->intg : 1) + (d)->frac + ((d)->frac > 0) + 2) - 1;
-}
-inline
-int my_decimal_get_binary_size(uint precision, uint scale)
-{
- return decimal_bin_size((int)precision, (int)scale);
-}
-inline
-void my_decimal2decimal(const my_decimal *from, my_decimal *to)
-{
- *to= *from;
- to->fix_buffer_pointer();
-}
-int my_decimal2binary(uint mask, const my_decimal *d, uchar *bin, int prec,
- int scale);
-inline
-int binary2my_decimal(uint mask, const uchar *bin, my_decimal *d, int prec,
- int scale)
-{
- return check_result(mask, bin2decimal(bin, (decimal_t*) d, prec, scale));
-}
-inline
-int my_decimal_set_zero(my_decimal *d)
-{
- do { (((decimal_t*) d))->buf[0]=0; (((decimal_t*) d))->intg=1; (((decimal_t*) d))->frac=0; (((decimal_t*) d))->sign=0; } while(0);
- return 0;
-}
-inline
-In_C_you_should_use_my_bool_instead() my_decimal_is_zero(const my_decimal *decimal_value)
-{
- return decimal_is_zero((decimal_t*) decimal_value);
-}
-inline
-int my_decimal_round(uint mask, const my_decimal *from, int scale,
- In_C_you_should_use_my_bool_instead() truncate, my_decimal *to)
-{
- return check_result(mask, decimal_round((decimal_t*) from, to, scale,
- (truncate ? TRUNCATE : HALF_UP)));
-}
-inline
-int my_decimal_floor(uint mask, const my_decimal *from, my_decimal *to)
-{
- return check_result(mask, decimal_round((decimal_t*) from, to, 0, FLOOR));
-}
-inline
-int my_decimal_ceiling(uint mask, const my_decimal *from, my_decimal *to)
-{
- return check_result(mask, decimal_round((decimal_t*) from, to, 0, CEILING));
-}
-int my_decimal2string(uint mask, const my_decimal *d, uint fixed_prec,
- uint fixed_dec, char filler, String *str);
-inline
-int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag,
- longlong *l)
-{
- my_decimal rounded;
- decimal_round((decimal_t*)d, &rounded, 0, HALF_UP);
- return check_result(mask, (unsigned_flag ?
- decimal2ulonglong(&rounded, (ulonglong *)l) :
- decimal2longlong(&rounded, l)));
-}
-inline
-int my_decimal2double(uint mask, const my_decimal *d, double *result)
-{
- return decimal2double((decimal_t*) d, result);
-}
-inline
-int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end)
-{
- return check_result_and_overflow(mask, internal_str2dec((str), ((decimal_t*)d), (end), 0),
- d);
-}
-int str2my_decimal(uint mask, const char *from, uint length,
- CHARSET_INFO *charset, my_decimal *decimal_value);
-inline
-int double2my_decimal(uint mask, double val, my_decimal *d)
-{
- return check_result_and_overflow(mask, double2decimal(val, (decimal_t*)d), d);
-}
-inline
-int int2my_decimal(uint mask, longlong i, my_bool unsigned_flag, my_decimal *d)
-{
- return check_result(mask, (unsigned_flag ?
- ulonglong2decimal((ulonglong)i, d) :
- longlong2decimal(i, d)));
-}
-inline
-void my_decimal_neg(decimal_t *arg)
-{
- if (decimal_is_zero(arg))
- {
- arg->sign= 0;
- return;
- }
- do { (arg)->sign^=1; } while(0);
-}
-inline
-int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a,
- const my_decimal *b)
-{
- return check_result_and_overflow(mask,
- decimal_add((decimal_t*)a,(decimal_t*)b,res),
- res);
-}
-inline
-int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a,
- const my_decimal *b)
-{
- return check_result_and_overflow(mask,
- decimal_sub((decimal_t*)a,(decimal_t*)b,res),
- res);
-}
-inline
-int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a,
- const my_decimal *b)
-{
- return check_result_and_overflow(mask,
- decimal_mul((decimal_t*)a,(decimal_t*)b,res),
- res);
-}
-inline
-int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a,
- const my_decimal *b, int div_scale_inc)
-{
- return check_result_and_overflow(mask,
- decimal_div((decimal_t*)a,(decimal_t*)b,res,
- div_scale_inc),
- res);
-}
-inline
-int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
- const my_decimal *b)
-{
- return check_result_and_overflow(mask,
- decimal_mod((decimal_t*)a,(decimal_t*)b,res),
- res);
-}
-inline
-int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
-{
- return decimal_cmp((decimal_t*) a, (decimal_t*) b);
-}
-inline
-int my_decimal_intg(const my_decimal *a)
-{
- return decimal_intg((decimal_t*) a);
-}
-void my_decimal_trim(ulong *precision, uint *scale);
-#include "handler.h"
-#include <my_handler.h>
-#include "myisampack.h"
-typedef struct st_HA_KEYSEG
-{
- CHARSET_INFO *charset;
- uint32 start;
- uint32 null_pos;
- uint16 bit_pos;
- uint16 flag;
- uint16 length;
- uint8 type;
- uint8 language;
- uint8 null_bit;
- uint8 bit_start,bit_end;
- uint8 bit_length;
-} HA_KEYSEG;
-extern int ha_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint ,
- my_bool, my_bool);
-extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
- register uchar *b, uint key_length, uint nextflag,
- uint *diff_pos);
-extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a);
-extern void my_handler_error_register(void);
-extern void my_handler_error_unregister(void);
-#include <ft_global.h>
-typedef struct st_ft_info FT_INFO;
-struct _ft_vft
-{
- int (*read_next)(FT_INFO *, char *);
- float (*find_relevance)(FT_INFO *, uchar *, uint);
- void (*close_search)(FT_INFO *);
- float (*get_relevance)(FT_INFO *);
- void (*reinit_search)(FT_INFO *);
-};
-struct st_ft_info
-{
- struct _ft_vft *please;
-};
-extern const char *ft_stopword_file;
-extern const char *ft_precompiled_stopwords[];
-extern ulong ft_min_word_len;
-extern ulong ft_max_word_len;
-extern ulong ft_query_expansion_limit;
-extern char ft_boolean_syntax[15];
-extern struct st_mysql_ftparser ft_default_parser;
-int ft_init_stopwords(void);
-void ft_free_stopwords(void);
-FT_INFO *ft_init_search(uint,void *, uint, uchar *, uint,CHARSET_INFO *, uchar *);
-my_bool ft_boolean_check_syntax_string(const uchar *);
-#include <keycache.h>
-struct st_block_link;
-typedef struct st_block_link BLOCK_LINK;
-struct st_keycache_page;
-typedef struct st_keycache_page KEYCACHE_PAGE;
-struct st_hash_link;
-typedef struct st_hash_link HASH_LINK;
-typedef struct st_keycache_wqueue
-{
- struct st_my_thread_var *last_thread;
-} KEYCACHE_WQUEUE;
-typedef struct st_key_cache
-{
- my_bool key_cache_inited;
- my_bool in_resize;
- my_bool resize_in_flush;
- my_bool can_be_used;
- size_t key_cache_mem_size;
- uint key_cache_block_size;
- ulong min_warm_blocks;
- ulong age_threshold;
- ulonglong keycache_time;
- uint hash_entries;
- int hash_links;
- int hash_links_used;
- int disk_blocks;
- ulong blocks_used;
- ulong blocks_unused;
- ulong blocks_changed;
- ulong warm_blocks;
- ulong cnt_for_resize_op;
- long blocks_available;
- HASH_LINK **hash_root;
- HASH_LINK *hash_link_root;
- HASH_LINK *free_hash_list;
- BLOCK_LINK *free_block_list;
- BLOCK_LINK *block_root;
- uchar *block_mem;
- BLOCK_LINK *used_last;
- BLOCK_LINK *used_ins;
- pthread_mutex_t cache_lock;
- KEYCACHE_WQUEUE resize_queue;
- KEYCACHE_WQUEUE waiting_for_resize_cnt;
- KEYCACHE_WQUEUE waiting_for_hash_link;
- KEYCACHE_WQUEUE waiting_for_block;
- BLOCK_LINK *changed_blocks[128];
- BLOCK_LINK *file_blocks[128];
- ulonglong param_buff_size;
- ulong param_block_size;
- ulong param_division_limit;
- ulong param_age_threshold;
- ulong global_blocks_changed;
- ulonglong global_cache_w_requests;
- ulonglong global_cache_write;
- ulonglong global_cache_r_requests;
- ulonglong global_cache_read;
- int blocks;
- my_bool in_init;
-} KEY_CACHE;
-extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache;
-extern int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold);
-extern int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold);
-extern void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
- uint age_threshold);
-extern uchar *key_cache_read(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length,int return_buffer);
-extern int key_cache_insert(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length);
-extern int key_cache_write(KEY_CACHE *keycache,
- File file, my_off_t filepos, int level,
- uchar *buff, uint length,
- uint block_length,int force_write);
-extern int flush_key_blocks(KEY_CACHE *keycache,
- int file, enum flush_type type);
-extern void end_key_cache(KEY_CACHE *keycache, my_bool cleanup);
-extern my_bool multi_keycache_init(void);
-extern void multi_keycache_free(void);
-extern KEY_CACHE *multi_key_cache_search(uchar *key, uint length);
-extern my_bool multi_key_cache_set(const uchar *key, uint length,
- KEY_CACHE *key_cache);
-extern void multi_key_cache_change(KEY_CACHE *old_data,
- KEY_CACHE *new_data);
-extern int reset_key_cache_counters(const char *name,
- KEY_CACHE *key_cache);
-enum legacy_db_type
-{
- DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
- DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
- DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
- DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
- DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
- DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
- DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
- DB_TYPE_FEDERATED_DB,
- DB_TYPE_BLACKHOLE_DB,
- DB_TYPE_PARTITION_DB,
- DB_TYPE_BINLOG,
- DB_TYPE_SOLID,
- DB_TYPE_PBXT,
- DB_TYPE_TABLE_FUNCTION,
- DB_TYPE_MEMCACHE,
- DB_TYPE_FALCON,
- DB_TYPE_MARIA,
- DB_TYPE_FIRST_DYNAMIC=42,
- DB_TYPE_DEFAULT=127
-};
-enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
- ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
- ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT, ROW_TYPE_PAGE };
-enum enum_binlog_func {
- BFN_RESET_LOGS= 1,
- BFN_RESET_SLAVE= 2,
- BFN_BINLOG_WAIT= 3,
- BFN_BINLOG_END= 4,
- BFN_BINLOG_PURGE_FILE= 5
-};
-enum enum_binlog_command {
- LOGCOM_CREATE_TABLE,
- LOGCOM_ALTER_TABLE,
- LOGCOM_RENAME_TABLE,
- LOGCOM_DROP_TABLE,
- LOGCOM_CREATE_DB,
- LOGCOM_ALTER_DB,
- LOGCOM_DROP_DB
-};
-typedef ulonglong my_xid;
-struct xid_t {
- long formatID;
- long gtrid_length;
- long bqual_length;
- char data[128];
- xid_t() {}
- In_C_you_should_use_my_bool_instead() eq(struct xid_t *xid)
- { return eq(xid->gtrid_length, xid->bqual_length, xid->data); }
- In_C_you_should_use_my_bool_instead() eq(long g, long b, const char *d)
- { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
- void set(struct xid_t *xid)
- { memcpy(this, xid, xid->length()); }
- void set(long f, const char *g, long gl, const char *b, long bl)
- {
- formatID= f;
- memcpy(data, g, gtrid_length= gl);
- memcpy(data+gl, b, bqual_length= bl);
- }
- void set(ulonglong xid)
- {
- my_xid tmp;
- formatID= 1;
- set(8, 0, "MySQLXid");
- memcpy(data+8, &server_id, sizeof(server_id));
- tmp= xid;
- memcpy(data+(8 +sizeof(server_id)), &tmp, sizeof(tmp));
- gtrid_length=((8 +sizeof(server_id))+sizeof(my_xid));
- }
- void set(long g, long b, const char *d)
- {
- formatID= 1;
- gtrid_length= g;
- bqual_length= b;
- memcpy(data, d, g+b);
- }
- In_C_you_should_use_my_bool_instead() is_null() { return formatID == -1; }
- void null() { formatID= -1; }
- my_xid quick_get_my_xid()
- {
- my_xid tmp;
- memcpy(&tmp, data+(8 +sizeof(server_id)), sizeof(tmp));
- return tmp;
- }
- my_xid get_my_xid()
- {
- return gtrid_length == ((8 +sizeof(server_id))+sizeof(my_xid)) && bqual_length == 0 &&
- !memcmp(data+8, &server_id, sizeof(server_id)) &&
- !memcmp(data, "MySQLXid", 8) ?
- quick_get_my_xid() : 0;
- }
- uint length()
- {
- return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+
- gtrid_length+bqual_length;
- }
- uchar *key()
- {
- return (uchar *)&gtrid_length;
- }
- uint key_length()
- {
- return sizeof(gtrid_length)+sizeof(bqual_length)+gtrid_length+bqual_length;
- }
-};
-typedef struct xid_t XID;
-enum ts_command_type
-{
- TS_CMD_NOT_DEFINED = -1,
- CREATE_TABLESPACE = 0,
- ALTER_TABLESPACE = 1,
- CREATE_LOGFILE_GROUP = 2,
- ALTER_LOGFILE_GROUP = 3,
- DROP_TABLESPACE = 4,
- DROP_LOGFILE_GROUP = 5,
- CHANGE_FILE_TABLESPACE = 6,
- ALTER_ACCESS_MODE_TABLESPACE = 7
-};
-enum ts_alter_tablespace_type
-{
- TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
- ALTER_TABLESPACE_ADD_FILE = 1,
- ALTER_TABLESPACE_DROP_FILE = 2
-};
-enum tablespace_access_mode
-{
- TS_NOT_DEFINED= -1,
- TS_READ_ONLY = 0,
- TS_READ_WRITE = 1,
- TS_NOT_ACCESSIBLE = 2
-};
-struct handlerton;
-class st_alter_tablespace : public Sql_alloc
-{
- public:
- const char *tablespace_name;
- const char *logfile_group_name;
- enum ts_command_type ts_cmd_type;
- enum ts_alter_tablespace_type ts_alter_tablespace_type;
- const char *data_file_name;
- const char *undo_file_name;
- const char *redo_file_name;
- ulonglong extent_size;
- ulonglong undo_buffer_size;
- ulonglong redo_buffer_size;
- ulonglong initial_size;
- ulonglong autoextend_size;
- ulonglong max_size;
- uint nodegroup_id;
- handlerton *storage_engine;
- In_C_you_should_use_my_bool_instead() wait_until_completed;
- const char *ts_comment;
- enum tablespace_access_mode ts_access_mode;
- st_alter_tablespace()
- {
- tablespace_name= NULL;
- logfile_group_name= "DEFAULT_LG";
- ts_cmd_type= TS_CMD_NOT_DEFINED;
- data_file_name= NULL;
- undo_file_name= NULL;
- redo_file_name= NULL;
- extent_size= 1024*1024;
- undo_buffer_size= 8*1024*1024;
- redo_buffer_size= 8*1024*1024;
- initial_size= 128*1024*1024;
- autoextend_size= 0;
- max_size= 0;
- storage_engine= NULL;
- nodegroup_id= 65535;
- wait_until_completed= (1);
- ts_comment= NULL;
- ts_access_mode= TS_NOT_DEFINED;
- }
-};
-struct st_table;
-typedef struct st_table TABLE;
-typedef struct st_table_share TABLE_SHARE;
-struct st_foreign_key_info;
-typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
-typedef In_C_you_should_use_my_bool_instead() (stat_print_fn)(THD *thd, const char *type, uint type_len,
- const char *file, uint file_len,
- const char *status, uint status_len);
-enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
-extern st_plugin_int *hton2plugin[15];
-enum log_status
-{
- HA_LOG_STATUS_FREE= 0,
- HA_LOG_STATUS_INUSE= 1,
- HA_LOG_STATUS_NOSUCHLOG= 2
-};
-void signal_log_not_needed(struct handlerton, char *log_file);
-struct handler_log_file_data {
- LEX_STRING filename;
- enum log_status status;
-};
-enum handler_iterator_type
-{
- HA_TRANSACTLOG_ITERATOR= 1
-};
-enum handler_create_iterator_result
-{
- HA_ITERATOR_OK,
- HA_ITERATOR_UNSUPPORTED,
- HA_ITERATOR_ERROR
-};
-struct handler_iterator {
- int (*next)(struct handler_iterator *, void *iterator_object);
- void (*destroy)(struct handler_iterator *);
- void *buffer;
-};
-struct handlerton
-{
- SHOW_COMP_OPTION state;
- enum legacy_db_type db_type;
- uint slot;
- uint savepoint_offset;
- int (*close_connection)(handlerton *hton, THD *thd);
- int (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
- int (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
- int (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
- int (*commit)(handlerton *hton, THD *thd, In_C_you_should_use_my_bool_instead() all);
- int (*rollback)(handlerton *hton, THD *thd, In_C_you_should_use_my_bool_instead() all);
- int (*prepare)(handlerton *hton, THD *thd, In_C_you_should_use_my_bool_instead() all);
- int (*recover)(handlerton *hton, XID *xid_list, uint len);
- int (*commit_by_xid)(handlerton *hton, XID *xid);
- int (*rollback_by_xid)(handlerton *hton, XID *xid);
- void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
- void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
- void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
- handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
- void (*drop_database)(handlerton *hton, char* path);
- int (*panic)(handlerton *hton, enum ha_panic_function flag);
- int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
- In_C_you_should_use_my_bool_instead() (*flush_logs)(handlerton *hton);
- In_C_you_should_use_my_bool_instead() (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
- uint (*partition_flags)();
- uint (*alter_table_flags)(uint flags);
- int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
- int (*fill_files_table)(handlerton *hton, THD *thd,
- TABLE_LIST *tables,
- class Item *cond);
- uint32 flags;
- int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg);
- void (*binlog_log_query)(handlerton *hton, THD *thd,
- enum_binlog_command binlog_command,
- const char *query, uint query_length,
- const char *db, const char *table_name);
- int (*release_temporary_latches)(handlerton *hton, THD *thd);
- enum log_status (*get_log_status)(handlerton *hton, char *log);
- enum handler_create_iterator_result
- (*create_iterator)(handlerton *hton, enum handler_iterator_type type,
- struct handler_iterator *fill_this_in);
- int (*discover)(handlerton *hton, THD* thd, const char *db,
- const char *name,
- uchar **frmblob,
- size_t *frmlen);
- int (*find_files)(handlerton *hton, THD *thd,
- const char *db,
- const char *path,
- const char *wild, In_C_you_should_use_my_bool_instead() dir, List<LEX_STRING> *files);
- int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
- const char *name);
- uint32 license;
- void *data;
-};
-class Ha_trx_info;
-struct THD_TRANS
-{
- In_C_you_should_use_my_bool_instead() no_2pc;
- Ha_trx_info *ha_list;
- In_C_you_should_use_my_bool_instead() modified_non_trans_table;
- void reset() { no_2pc= (0); modified_non_trans_table= (0); }
-};
-class Ha_trx_info
-{
-public:
- void register_ha(THD_TRANS *trans, handlerton *ht_arg)
- {
- assert(m_flags == 0);
- assert(m_ht == NULL);
- assert(m_next == NULL);
- m_ht= ht_arg;
- m_flags= (int) TRX_READ_ONLY;
- m_next= trans->ha_list;
- trans->ha_list= this;
- }
- void reset()
- {
- m_next= NULL;
- m_ht= NULL;
- m_flags= 0;
- }
- Ha_trx_info() { reset(); }
- void set_trx_read_write()
- {
- assert(is_started());
- m_flags|= (int) TRX_READ_WRITE;
- }
- In_C_you_should_use_my_bool_instead() is_trx_read_write() const
- {
- assert(is_started());
- return m_flags & (int) TRX_READ_WRITE;
- }
- In_C_you_should_use_my_bool_instead() is_started() const { return m_ht != NULL; }
- void coalesce_trx_with(const Ha_trx_info *stmt_trx)
- {
- assert(is_started());
- if (stmt_trx->is_trx_read_write())
- set_trx_read_write();
- }
- Ha_trx_info *next() const
- {
- assert(is_started());
- return m_next;
- }
- handlerton *ht() const
- {
- assert(is_started());
- return m_ht;
- }
-private:
- enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 };
- Ha_trx_info *m_next;
- handlerton *m_ht;
- uchar m_flags;
-};
-enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
- ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
-enum ndb_distribution { ND_KEYHASH= 0, ND_LINHASH= 1 };
-typedef struct {
- ulonglong data_file_length;
- ulonglong max_data_file_length;
- ulonglong index_file_length;
- ulonglong delete_length;
- ha_rows records;
- ulong mean_rec_length;
- time_t create_time;
- time_t check_time;
- time_t update_time;
- ulonglong check_sum;
-} PARTITION_INFO;
-class Item;
-struct st_table_log_memory_entry;
-class partition_info;
-struct st_partition_iter;
-enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
-typedef struct st_ha_create_information
-{
- CHARSET_INFO *table_charset, *default_table_charset;
- LEX_STRING connect_string;
- const char *password, *tablespace;
- LEX_STRING comment;
- const char *data_file_name, *index_file_name;
- const char *alias;
- ulonglong max_rows,min_rows;
- ulonglong auto_increment_value;
- ulong table_options;
- ulong avg_row_length;
- ulong used_fields;
- ulong key_block_size;
- SQL_LIST merge_list;
- handlerton *db_type;
- enum row_type row_type;
- uint null_bits;
- uint options;
- uint merge_insert_method;
- uint extra_size;
- enum ha_choice transactional;
- In_C_you_should_use_my_bool_instead() table_existed;
- In_C_you_should_use_my_bool_instead() frm_only;
- In_C_you_should_use_my_bool_instead() varchar;
- enum ha_storage_media storage_media;
- enum ha_choice page_checksum;
-} HA_CREATE_INFO;
-typedef struct st_key_create_information
-{
- enum ha_key_alg algorithm;
- ulong block_size;
- LEX_STRING parser_name;
-} KEY_CREATE_INFO;
-class TABLEOP_HOOKS
-{
-public:
- TABLEOP_HOOKS() {}
- virtual ~TABLEOP_HOOKS() {}
- inline void prelock(TABLE **tables, uint count)
- {
- do_prelock(tables, count);
- }
- inline int postlock(TABLE **tables, uint count)
- {
- return do_postlock(tables, count);
- }
-private:
- virtual void do_prelock(TABLE **tables, uint count)
- {
- }
- virtual int do_postlock(TABLE **tables, uint count)
- {
- return 0;
- }
-};
-typedef struct st_savepoint SAVEPOINT;
-extern ulong savepoint_alloc_size;
-extern KEY_CREATE_INFO default_key_create_info;
-typedef class Item COND;
-typedef struct st_ha_check_opt
-{
- st_ha_check_opt() {}
- ulong sort_buffer_size;
- uint flags;
- uint sql_flags;
- KEY_CACHE *key_cache;
- void init();
-} HA_CHECK_OPT;
-typedef struct st_handler_buffer
-{
- const uchar *buffer;
- const uchar *buffer_end;
- uchar *end_of_used_area;
-} HANDLER_BUFFER;
-typedef struct system_status_var SSV;
-class ha_statistics
-{
-public:
- ulonglong data_file_length;
- ulonglong max_data_file_length;
- ulonglong index_file_length;
- ulonglong max_index_file_length;
- ulonglong delete_length;
- ulonglong auto_increment_value;
- ha_rows records;
- ha_rows deleted;
- ulong mean_rec_length;
- time_t create_time;
- time_t check_time;
- time_t update_time;
- uint block_size;
- ha_statistics():
- data_file_length(0), max_data_file_length(0),
- index_file_length(0), delete_length(0), auto_increment_value(0),
- records(0), deleted(0), mean_rec_length(0), create_time(0),
- check_time(0), update_time(0), block_size(0)
- {}
-};
-uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
-class handler :public Sql_alloc
-{
-public:
- typedef ulonglong Table_flags;
-protected:
- struct st_table_share *table_share;
- struct st_table *table;
- Table_flags cached_table_flags;
- ha_rows estimation_rows_to_insert;
-public:
- handlerton *ht;
- uchar *ref;
- uchar *dup_ref;
- ha_statistics stats;
- In_C_you_should_use_my_bool_instead() multi_range_sorted;
- KEY_MULTI_RANGE *multi_range_curr;
- KEY_MULTI_RANGE *multi_range_end;
- HANDLER_BUFFER *multi_range_buffer;
- key_range save_end_range, *end_range;
- KEY_PART_INFO *range_key_part;
- int key_compare_result_on_equal;
- In_C_you_should_use_my_bool_instead() eq_range;
- uint errkey;
- uint key_used_on_scan;
- uint active_index;
- uint ref_length;
- FT_INFO *ft_handler;
- enum {NONE=0, INDEX, RND} inited;
- In_C_you_should_use_my_bool_instead() locked;
- In_C_you_should_use_my_bool_instead() implicit_emptied;
- const COND *pushed_cond;
- ulonglong next_insert_id;
- ulonglong insert_id_for_cur_row;
- Discrete_interval auto_inc_interval_for_cur_row;
- handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
- :table_share(share_arg), table(0),
- estimation_rows_to_insert(0), ht(ht_arg),
- ref(0), key_used_on_scan(64), active_index(64),
- ref_length(sizeof(my_off_t)),
- ft_handler(0), inited(NONE),
- locked((0)), implicit_emptied(0),
- pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0)
- {}
- virtual ~handler(void)
- {
- assert(locked == (0));
- }
- virtual handler *clone(MEM_ROOT *mem_root);
- void init()
- {
- cached_table_flags= table_flags();
- }
- int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
- int ha_index_init(uint idx, In_C_you_should_use_my_bool_instead() sorted)
- {
- int result;
- const char *_db_func_, *_db_file_; uint _db_level_; char **_db_framep_; _db_enter_ ("ha_index_init","./sql/handler.h",1159,&_db_func_,&_db_file_,&_db_level_, &_db_framep_);
- assert(inited==NONE);
- if (!(result= index_init(idx, sorted)))
- inited=INDEX;
- do {_db_return_ (1163, &_db_func_, &_db_file_, &_db_level_); return(result);} while(0);
- }
- int ha_index_end()
- {
- const char *_db_func_, *_db_file_; uint _db_level_; char **_db_framep_; _db_enter_ ("ha_index_end","./sql/handler.h",1167,&_db_func_,&_db_file_,&_db_level_, &_db_framep_);
- assert(inited==INDEX);
- inited=NONE;
- do {_db_return_ (1170, &_db_func_, &_db_file_, &_db_level_); return(index_end());} while(0);
- }
- int ha_rnd_init(In_C_you_should_use_my_bool_instead() scan)
- {
- int result;
- const char *_db_func_, *_db_file_; uint _db_level_; char **_db_framep_; _db_enter_ ("ha_rnd_init","./sql/handler.h",1175,&_db_func_,&_db_file_,&_db_level_, &_db_framep_);
- assert(inited==NONE || (inited==RND && scan));
- inited= (result= rnd_init(scan)) ? NONE: RND;
- do {_db_return_ (1178, &_db_func_, &_db_file_, &_db_level_); return(result);} while(0);
- }
- int ha_rnd_end()
- {
- const char *_db_func_, *_db_file_; uint _db_level_; char **_db_framep_; _db_enter_ ("ha_rnd_end","./sql/handler.h",1182,&_db_func_,&_db_file_,&_db_level_, &_db_framep_);
- assert(inited==RND);
- inited=NONE;
- do {_db_return_ (1185, &_db_func_, &_db_file_, &_db_level_); return(rnd_end());} while(0);
- }
- int ha_reset();
- int ha_index_or_rnd_end()
- {
- return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
- }
- Table_flags ha_table_flags() const { return cached_table_flags; }
- int ha_external_lock(THD *thd, int lock_type);
- int ha_write_row(uchar * buf);
- int ha_update_row(const uchar * old_data, uchar * new_data);
- int ha_delete_row(const uchar * buf);
- void ha_release_auto_increment();
- int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
- int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
- int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
- void ha_start_bulk_insert(ha_rows rows)
- {
- estimation_rows_to_insert= rows;
- start_bulk_insert(rows);
- }
- int ha_end_bulk_insert()
- {
- estimation_rows_to_insert= 0;
- return end_bulk_insert();
- }
- int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
- uint *dup_key_found);
- int ha_delete_all_rows();
- int ha_reset_auto_increment(ulonglong value);
- int ha_backup(THD* thd, HA_CHECK_OPT* check_opt);
- int ha_restore(THD* thd, HA_CHECK_OPT* check_opt);
- int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
- int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
- In_C_you_should_use_my_bool_instead() ha_check_and_repair(THD *thd);
- int ha_disable_indexes(uint mode);
- int ha_enable_indexes(uint mode);
- int ha_discard_or_import_tablespace(my_bool discard);
- void ha_prepare_for_alter();
- int ha_rename_table(const char *from, const char *to);
- int ha_delete_table(const char *name);
- void ha_drop_table(const char *name);
- int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
- int ha_create_handler_files(const char *name, const char *old_name,
- int action_flag, HA_CREATE_INFO *info);
- int ha_change_partitions(HA_CREATE_INFO *create_info,
- const char *path,
- ulonglong *copied,
- ulonglong *deleted,
- const uchar *pack_frm_data,
- size_t pack_frm_len);
- int ha_drop_partitions(const char *path);
- int ha_rename_partitions(const char *path);
- int ha_optimize_partitions(THD *thd);
- int ha_analyze_partitions(THD *thd);
- int ha_check_partitions(THD *thd);
- int ha_repair_partitions(THD *thd);
- void adjust_next_insert_id_after_explicit_value(ulonglong nr);
- int update_auto_increment();
- void print_keydup_error(uint key_nr, const char *msg);
- virtual void print_error(int error, myf errflag);
- virtual In_C_you_should_use_my_bool_instead() get_error_message(int error, String *buf);
- uint get_dup_key(int error);
- virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
- {
- table= table_arg;
- table_share= share;
- }
- virtual double scan_time()
- { return ((double) (ulonglong) (stats.data_file_length)) / 4096 + 2; }
- virtual double read_time(uint index, uint ranges, ha_rows rows)
- { return ((double) (ulonglong) (ranges+rows)); }
- virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
- In_C_you_should_use_my_bool_instead() has_transactions()
- { return (ha_table_flags() & (1 << 0)) == 0; }
- virtual uint extra_rec_buf_length() const { return 0; }
- virtual In_C_you_should_use_my_bool_instead() is_fatal_error(int error, uint flags)
- {
- if (!error ||
- ((flags & 1) &&
- (error == 121 ||
- error == 141)))
- return (0);
- return (1);
- }
- virtual ha_rows records() { return stats.records; }
- virtual ha_rows estimate_rows_upper_bound()
- { return stats.records+10; }
- virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
- virtual const char *index_type(uint key_number) { assert(0); return "";}
- virtual void column_bitmaps_signal();
- uint get_index(void) const { return active_index; }
- virtual int close(void)=0;
- virtual In_C_you_should_use_my_bool_instead() start_bulk_update() { return 1; }
- virtual In_C_you_should_use_my_bool_instead() start_bulk_delete() { return 1; }
- virtual int exec_bulk_update(uint *dup_key_found)
- {
- assert((0));
- return 131;
- }
- virtual void end_bulk_update() { return; }
- virtual int end_bulk_delete()
- {
- assert((0));
- return 131;
- }
- virtual int index_read_map(uchar * buf, const uchar * key,
- key_part_map keypart_map,
- enum ha_rkey_function find_flag)
- {
- uint key_len= calculate_key_len(table, active_index, key, keypart_map);
- return index_read(buf, key, key_len, find_flag);
- }
- virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
- key_part_map keypart_map,
- enum ha_rkey_function find_flag);
- virtual int index_next(uchar * buf)
- { return 131; }
- virtual int index_prev(uchar * buf)
- { return 131; }
- virtual int index_first(uchar * buf)
- { return 131; }
- virtual int index_last(uchar * buf)
- { return 131; }
- virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
- virtual int index_read_last_map(uchar * buf, const uchar * key,
- key_part_map keypart_map)
- {
- uint key_len= calculate_key_len(table, active_index, key, keypart_map);
- return index_read_last(buf, key, key_len);
- }
- virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
- KEY_MULTI_RANGE *ranges, uint range_count,
- In_C_you_should_use_my_bool_instead() sorted, HANDLER_BUFFER *buffer);
- virtual int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
- virtual int read_range_first(const key_range *start_key,
- const key_range *end_key,
- In_C_you_should_use_my_bool_instead() eq_range, In_C_you_should_use_my_bool_instead() sorted);
- virtual int read_range_next();
- int compare_key(key_range *range);
- virtual int ft_init() { return 131; }
- void ft_end() { ft_handler=NULL; }
- virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
- { return NULL; }
- virtual int ft_read(uchar *buf) { return 131; }
- virtual int rnd_next(uchar *buf)=0;
- virtual int rnd_pos(uchar * buf, uchar *pos)=0;
- virtual int rnd_pos_by_record(uchar *record)
- {
- position(record);
- return rnd_pos(record, ref);
- }
- virtual int read_first_row(uchar *buf, uint primary_key);
- virtual int restart_rnd_next(uchar *buf, uchar *pos)
- { return 131; }
- virtual int rnd_same(uchar *buf, uint inx)
- { return 131; }
- virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
- { return (ha_rows) 10; }
- virtual void position(const uchar *record)=0;
- virtual int info(uint)=0;
- virtual void get_dynamic_partition_info(PARTITION_INFO *stat_info,
- uint part_id);
- virtual int extra(enum ha_extra_function operation)
- { return 0; }
- virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
- { return extra(operation); }
- virtual In_C_you_should_use_my_bool_instead() was_semi_consistent_read() { return 0; }
- virtual void try_semi_consistent_read(In_C_you_should_use_my_bool_instead()) {}
- virtual void unlock_row() {}
- virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
- virtual void get_auto_increment(ulonglong offset, ulonglong increment,
- ulonglong nb_desired_values,
- ulonglong *first_value,
- ulonglong *nb_reserved_values);
- void set_next_insert_id(ulonglong id)
- {
- do {_db_pargs_(1488,"info"); _db_doprnt_ ("auto_increment: next value %lu", (ulong)id);} while(0);
- next_insert_id= id;
- }
- void restore_auto_increment(ulonglong prev_insert_id)
- {
- next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
- insert_id_for_cur_row;
- }
- virtual void update_create_info(HA_CREATE_INFO *create_info) {}
- int check_old_types();
- virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
- { return -1; }
- virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
- { return -1; }
- virtual int dump(THD* thd, int fd = -1) { return 131; }
- virtual int indexes_are_disabled(void) {return 0;}
- virtual int net_read_dump(NET* net) { return 131; }
- virtual char *update_table_comment(const char * comment)
- { return (char*) comment;}
- virtual void append_create_info(String *packet) {}
- virtual In_C_you_should_use_my_bool_instead() is_fk_defined_on_table_or_index(uint index)
- { return (0); }
- virtual char* get_foreign_key_create_info()
- { return(NULL);}
- virtual char* get_tablespace_name(THD *thd, char *name, uint name_len)
- { return(NULL);}
- virtual In_C_you_should_use_my_bool_instead() can_switch_engines() { return 1; }
- virtual int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
- { return 0; }
- virtual uint referenced_by_foreign_key() { return 0;}
- virtual void init_table_handle_for_HANDLER()
- { return; }
- virtual void free_foreign_key_create_info(char* str) {}
- virtual const char *table_type() const =0;
- virtual const char **bas_ext() const =0;
- virtual int get_default_no_partitions(HA_CREATE_INFO *info) { return 1;}
- virtual void set_auto_partitions(partition_info *part_info) { return; }
- virtual In_C_you_should_use_my_bool_instead() get_no_parts(const char *name,
- uint *no_parts)
- {
- *no_parts= 0;
- return 0;
- }
- virtual void set_part_info(partition_info *part_info) {return;}
- virtual ulong index_flags(uint idx, uint part, In_C_you_should_use_my_bool_instead() all_parts) const =0;
- virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
- { return (131); }
- virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
- uint num_of_keys)
- { return (131); }
- virtual int final_drop_index(TABLE *table_arg)
- { return (131); }
- uint max_record_length() const
- { return ((65535) < (max_supported_record_length()) ? (65535) : (max_supported_record_length())); }
- uint max_keys() const
- { return ((64) < (max_supported_keys()) ? (64) : (max_supported_keys())); }
- uint max_key_parts() const
- { return ((16) < (max_supported_key_parts()) ? (16) : (max_supported_key_parts())); }
- uint max_key_length() const
- { return ((3072) < (max_supported_key_length()) ? (3072) : (max_supported_key_length())); }
- uint max_key_part_length() const
- { return ((3072) < (max_supported_key_part_length()) ? (3072) : (max_supported_key_part_length())); }
- virtual uint max_supported_record_length() const { return 65535; }
- virtual uint max_supported_keys() const { return 0; }
- virtual uint max_supported_key_parts() const { return 16; }
- virtual uint max_supported_key_length() const { return 3072; }
- virtual uint max_supported_key_part_length() const { return 255; }
- virtual uint min_record_length(uint options) const { return 1; }
- virtual In_C_you_should_use_my_bool_instead() low_byte_first() const { return 1; }
- virtual uint checksum() const { return 0; }
- virtual In_C_you_should_use_my_bool_instead() is_crashed() const { return 0; }
- virtual In_C_you_should_use_my_bool_instead() auto_repair() const { return 0; }
- virtual uint lock_count(void) const { return 1; }
- virtual THR_LOCK_DATA **store_lock(THD *thd,
- THR_LOCK_DATA **to,
- enum thr_lock_type lock_type)=0;
- virtual uint8 table_cache_type() { return 0; }
- virtual my_bool register_query_cache_table(THD *thd, char *table_key,
- uint key_length,
- qc_engine_callback
- *engine_callback,
- ulonglong *engine_data)
- {
- *engine_callback= 0;
- return (1);
- }
- virtual In_C_you_should_use_my_bool_instead() primary_key_is_clustered() { return (0); }
- virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
- {
- return memcmp(ref1, ref2, ref_length);
- }
- virtual const COND *cond_push(const COND *cond) { return cond; };
- virtual void cond_pop() { return; };
- virtual In_C_you_should_use_my_bool_instead() check_if_incompatible_data(HA_CREATE_INFO *create_info,
- uint table_changes)
- { return 1; }
- virtual void use_hidden_primary_key();
-protected:
- void ha_statistic_increment(ulong SSV::*offset) const;
- void **ha_data(THD *) const;
- THD *ha_thd(void) const;
- virtual int rename_table(const char *from, const char *to);
- virtual int delete_table(const char *name);
-private:
- inline void mark_trx_read_write();
-private:
- virtual int open(const char *name, int mode, uint test_if_locked)=0;
- virtual int index_init(uint idx, In_C_you_should_use_my_bool_instead() sorted) { active_index= idx; return 0; }
- virtual int index_end() { active_index= 64; return 0; }
- virtual int rnd_init(In_C_you_should_use_my_bool_instead() scan)= 0;
- virtual int rnd_end() { return 0; }
- virtual int write_row(uchar *buf __attribute__((unused)))
- {
- return 131;
- }
- virtual int update_row(const uchar *old_data __attribute__((unused)),
- uchar *new_data __attribute__((unused)))
- {
- return 131;
- }
- virtual int delete_row(const uchar *buf __attribute__((unused)))
- {
- return 131;
- }
- virtual int reset() { return 0; }
- virtual Table_flags table_flags(void) const= 0;
- virtual int external_lock(THD *thd __attribute__((unused)),
- int lock_type __attribute__((unused)))
- {
- return 0;
- }
- virtual void release_auto_increment() { return; };
- virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
- { return 0; }
- virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
- { return -1; }
- virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
- { return -1; }
- virtual void start_bulk_insert(ha_rows rows) {}
- virtual int end_bulk_insert() { return 0; }
- virtual int index_read(uchar * buf, const uchar * key, uint key_len,
- enum ha_rkey_function find_flag)
- { return 131; }
- virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
- { return ((_my_thread_var())->thr_errno= 131); }
- virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
- uint *dup_key_found)
- {
- assert((0));
- return 131;
- }
- virtual int delete_all_rows()
- { return ((_my_thread_var())->thr_errno=131); }
- virtual int reset_auto_increment(ulonglong value)
- { return 131; }
- virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
- { return -1; }
- virtual int restore(THD* thd, HA_CHECK_OPT* check_opt)
- { return -1; }
- virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
- { return -1; }
- virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
- { return -1; }
- virtual In_C_you_should_use_my_bool_instead() check_and_repair(THD *thd) { return (1); }
- virtual int disable_indexes(uint mode) { return 131; }
- virtual int enable_indexes(uint mode) { return 131; }
- virtual int discard_or_import_tablespace(my_bool discard)
- { return ((_my_thread_var())->thr_errno=131); }
- virtual void prepare_for_alter() { return; }
- virtual void drop_table(const char *name);
- virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
- virtual int create_handler_files(const char *name, const char *old_name,
- int action_flag, HA_CREATE_INFO *info)
- { return (0); }
- virtual int change_partitions(HA_CREATE_INFO *create_info,
- const char *path,
- ulonglong *copied,
- ulonglong *deleted,
- const uchar *pack_frm_data,
- size_t pack_frm_len)
- { return 131; }
- virtual int drop_partitions(const char *path)
- { return 131; }
- virtual int rename_partitions(const char *path)
- { return 131; }
- virtual int optimize_partitions(THD *thd)
- { return 131; }
- virtual int analyze_partitions(THD *thd)
- { return 131; }
- virtual int check_partitions(THD *thd)
- { return 131; }
- virtual int repair_partitions(THD *thd)
- { return 131; }
-};
-extern const char *ha_row_type[];
-extern const char *tx_isolation_names[];
-extern const char *binlog_format_names[];
-extern TYPELIB tx_isolation_typelib;
-extern TYPELIB myisam_stats_method_typelib;
-extern ulong total_ha, total_ha_2pc;
-handlerton *ha_default_handlerton(THD *thd);
-plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
-plugin_ref ha_lock_engine(THD *thd, handlerton *hton);
-handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
-handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
- handlerton *db_type);
-handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
- In_C_you_should_use_my_bool_instead() no_substitute, In_C_you_should_use_my_bool_instead() report_error);
-static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
-{
- return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
-}
-static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
-{
- return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
-}
-static inline In_C_you_should_use_my_bool_instead() ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
-{
- return db_type == NULL ? (0) : ((db_type->flags & flag) ? 1 : 0);
-}
-static inline In_C_you_should_use_my_bool_instead() ha_storage_engine_is_enabled(const handlerton *db_type)
-{
- return (db_type && db_type->create) ?
- (db_type->state == SHOW_OPTION_YES) : (0);
-}
-int ha_init_errors(void);
-int ha_init(void);
-int ha_end(void);
-int ha_initialize_handlerton(st_plugin_int *plugin);
-int ha_finalize_handlerton(st_plugin_int *plugin);
-TYPELIB *ha_known_exts(void);
-int ha_panic(enum ha_panic_function flag);
-void ha_close_connection(THD* thd);
-In_C_you_should_use_my_bool_instead() ha_flush_logs(handlerton *db_type);
-void ha_drop_database(char* path);
-int ha_create_table(THD *thd, const char *path,
- const char *db, const char *table_name,
- HA_CREATE_INFO *create_info,
- In_C_you_should_use_my_bool_instead() update_create_info);
-int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
- const char *db, const char *alias, In_C_you_should_use_my_bool_instead() generate_warning);
-In_C_you_should_use_my_bool_instead() ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
-int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
-int ha_discover(THD* thd, const char* dbname, const char* name,
- uchar** frmblob, size_t* frmlen);
-int ha_find_files(THD *thd,const char *db,const char *path,
- const char *wild, In_C_you_should_use_my_bool_instead() dir, List<LEX_STRING>* files);
-int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
-extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
-int ha_resize_key_cache(KEY_CACHE *key_cache);
-int ha_change_key_cache_param(KEY_CACHE *key_cache);
-int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
-int ha_end_key_cache(KEY_CACHE *key_cache);
-int ha_release_temporary_latches(THD *thd);
-int ha_start_consistent_snapshot(THD *thd);
-int ha_commit_or_rollback_by_xid(XID *xid, In_C_you_should_use_my_bool_instead() commit);
-int ha_commit_one_phase(THD *thd, In_C_you_should_use_my_bool_instead() all);
-int ha_rollback_trans(THD *thd, In_C_you_should_use_my_bool_instead() all);
-int ha_prepare(THD *thd);
-int ha_recover(HASH *commit_list);
-int ha_commit_trans(THD *thd, In_C_you_should_use_my_bool_instead() all);
-int ha_autocommit_or_rollback(THD *thd, int error);
-int ha_enable_transaction(THD *thd, In_C_you_should_use_my_bool_instead() on);
-int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
-int ha_savepoint(THD *thd, SAVEPOINT *sv);
-int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
-void trans_register_ha(THD *thd, In_C_you_should_use_my_bool_instead() all, handlerton *ht);
-#include "parse_file.h"
-enum file_opt_type {
- FILE_OPTIONS_STRING,
- FILE_OPTIONS_ESTRING,
- FILE_OPTIONS_ULONGLONG,
- FILE_OPTIONS_REV,
- FILE_OPTIONS_TIMESTAMP,
- FILE_OPTIONS_STRLIST,
- FILE_OPTIONS_ULLLIST
-};
-struct File_option
-{
- LEX_STRING name;
- int offset;
- file_opt_type type;
-};
-class Unknown_key_hook
-{
-public:
- Unknown_key_hook() {}
- virtual ~Unknown_key_hook() {}
- virtual In_C_you_should_use_my_bool_instead() process_unknown_string(char *&unknown_key, uchar* base,
- MEM_ROOT *mem_root, char *end)= 0;
-};
-class File_parser_dummy_hook: public Unknown_key_hook
-{
-public:
- File_parser_dummy_hook() {}
- virtual In_C_you_should_use_my_bool_instead() process_unknown_string(char *&unknown_key, uchar* base,
- MEM_ROOT *mem_root, char *end);
-};
-extern File_parser_dummy_hook file_parser_dummy_hook;
-In_C_you_should_use_my_bool_instead() get_file_options_ulllist(char *&ptr, char *end, char *line,
- uchar* base, File_option *parameter,
- MEM_ROOT *mem_root);
-char *
-parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str);
-class File_parser;
-File_parser *sql_parse_prepare(const LEX_STRING *file_name,
- MEM_ROOT *mem_root, In_C_you_should_use_my_bool_instead() bad_format_errors);
-my_bool
-sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
- const LEX_STRING *type,
- uchar* base, File_option *parameters, uint versions);
-my_bool rename_in_schema_file(const char *schema, const char *old_name,
- const char *new_name, ulonglong revision,
- uint num_view_backups);
-class File_parser: public Sql_alloc
-{
- char *buff, *start, *end;
- LEX_STRING file_type;
- my_bool content_ok;
-public:
- File_parser() :buff(0), start(0), end(0), content_ok(0)
- { file_type.str= 0; file_type.length= 0; }
- my_bool ok() { return content_ok; }
- LEX_STRING *type() { return &file_type; }
- my_bool parse(uchar* base, MEM_ROOT *mem_root,
- struct File_option *parameters, uint required,
- Unknown_key_hook *hook);
- friend File_parser *sql_parse_prepare(const LEX_STRING *file_name,
- MEM_ROOT *mem_root,
- In_C_you_should_use_my_bool_instead() bad_format_errors);
-};
-#include "table.h"
-class Item;
-class Item_subselect;
-class GRANT_TABLE;
-class st_select_lex_unit;
-class st_select_lex;
-class partition_info;
-class COND_EQUAL;
-class Security_context;
-class View_creation_ctx : public Default_object_creation_ctx,
- public Sql_alloc
-{
-public:
- static View_creation_ctx *create(THD *thd);
- static View_creation_ctx *create(THD *thd,
- TABLE_LIST *view);
-private:
- View_creation_ctx(THD *thd)
- : Default_object_creation_ctx(thd)
- { }
-};
-typedef struct st_order {
- struct st_order *next;
- Item **item;
- Item *item_ptr;
- Item **item_copy;
- int counter;
- In_C_you_should_use_my_bool_instead() asc;
- In_C_you_should_use_my_bool_instead() free_me;
- In_C_you_should_use_my_bool_instead() in_field_list;
- In_C_you_should_use_my_bool_instead() counter_used;
- Field *field;
- char *buff;
- table_map used, depend_map;
-} ORDER;
-typedef struct st_grant_info
-{
- GRANT_TABLE *grant_table;
- uint version;
- ulong privilege;
- ulong want_privilege;
- ulong orig_want_privilege;
-} GRANT_INFO;
-enum tmp_table_type
-{
- NO_TMP_TABLE, NON_TRANSACTIONAL_TMP_TABLE, TRANSACTIONAL_TMP_TABLE,
- INTERNAL_TMP_TABLE, SYSTEM_TMP_TABLE
-};
-enum trg_event_type
-{
- TRG_EVENT_INSERT= 0,
- TRG_EVENT_UPDATE= 1,
- TRG_EVENT_DELETE= 2,
- TRG_EVENT_MAX
-};
-enum frm_type_enum
-{
- FRMTYPE_ERROR= 0,
- FRMTYPE_TABLE,
- FRMTYPE_VIEW
-};
-enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP };
-typedef struct st_filesort_info
-{
- IO_CACHE *io_cache;
- uchar **sort_keys;
- uchar *buffpek;
- uint buffpek_len;
- uchar *addon_buf;
- size_t addon_length;
- struct st_sort_addon_field *addon_field;
- void (*unpack)(struct st_sort_addon_field *, uchar *);
- uchar *record_pointers;
- ha_rows found_records;
-} FILESORT_INFO;
-enum timestamp_auto_set_type
-{
- TIMESTAMP_NO_AUTO_SET= 0, TIMESTAMP_AUTO_SET_ON_INSERT= 1,
- TIMESTAMP_AUTO_SET_ON_UPDATE= 2, TIMESTAMP_AUTO_SET_ON_BOTH= 3
-};
-class Field_timestamp;
-class Field_blob;
-class Table_triggers_list;
-enum enum_table_category
-{
- TABLE_UNKNOWN_CATEGORY=0,
- TABLE_CATEGORY_TEMPORARY=1,
- TABLE_CATEGORY_USER=2,
- TABLE_CATEGORY_SYSTEM=3,
- TABLE_CATEGORY_INFORMATION=4,
- TABLE_CATEGORY_PERFORMANCE=5
-};
-typedef enum enum_table_category TABLE_CATEGORY;
-TABLE_CATEGORY get_table_category(const LEX_STRING *db,
- const LEX_STRING *name);
-typedef struct st_table_share
-{
- st_table_share() {}
- TABLE_CATEGORY table_category;
- HASH name_hash;
- MEM_ROOT mem_root;
- TYPELIB keynames;
- TYPELIB fieldnames;
- TYPELIB *intervals;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- struct st_table_share *next,
- **prev;
- Field **field;
- Field **found_next_number_field;
- Field *timestamp_field;
- KEY *key_info;
- uint *blob_field;
- uchar *default_values;
- LEX_STRING comment;
- CHARSET_INFO *table_charset;
- MY_BITMAP all_set;
- LEX_STRING table_cache_key;
- LEX_STRING db;
- LEX_STRING table_name;
- LEX_STRING path;
- LEX_STRING normalized_path;
- LEX_STRING connect_string;
- key_map keys_in_use;
- key_map keys_for_keyread;
- ha_rows min_rows, max_rows;
- ulong avg_row_length;
- ulong raid_chunksize;
- ulong version, mysql_version;
- ulong timestamp_offset;
- ulong reclength;
- plugin_ref db_plugin;
- inline handlerton *db_type() const
- {
- return db_plugin ? ((handlerton*)((db_plugin)[0]->data)) : NULL;
- }
- enum row_type row_type;
- enum tmp_table_type tmp_table;
- enum ha_choice transactional;
- enum ha_choice page_checksum;
- uint ref_count;
- uint open_count;
- uint blob_ptr_size;
- uint key_block_size;
- uint null_bytes, last_null_bit_pos;
- uint fields;
- uint rec_buff_length;
- uint keys, key_parts;
- uint max_key_length, max_unique_length, total_key_length;
- uint uniques;
- uint null_fields;
- uint blob_fields;
- uint timestamp_field_offset;
- uint varchar_fields;
- uint db_create_options;
- uint db_options_in_use;
- uint db_record_offset;
- uint raid_type, raid_chunks;
- uint rowid_field_offset;
- uint primary_key;
- uint next_number_index;
- uint next_number_key_offset;
- uint next_number_keypart;
- uint error, open_errno, errarg;
- uint column_bitmap_size;
- uchar frm_version;
- In_C_you_should_use_my_bool_instead() null_field_first;
- In_C_you_should_use_my_bool_instead() system;
- In_C_you_should_use_my_bool_instead() crypted;
- In_C_you_should_use_my_bool_instead() db_low_byte_first;
- In_C_you_should_use_my_bool_instead() crashed;
- In_C_you_should_use_my_bool_instead() is_view;
- In_C_you_should_use_my_bool_instead() name_lock, replace_with_name_lock;
- In_C_you_should_use_my_bool_instead() waiting_on_cond;
- ulong table_map_id;
- ulonglong table_map_version;
- int cached_row_logging_check;
- void set_table_cache_key(char *key_buff, uint key_length)
- {
- table_cache_key.str= key_buff;
- table_cache_key.length= key_length;
- db.str= table_cache_key.str;
- db.length= strlen(db.str);
- table_name.str= db.str + db.length + 1;
- table_name.length= strlen(table_name.str);
- }
- void set_table_cache_key(char *key_buff, const char *key, uint key_length)
- {
- memcpy(key_buff, key, key_length);
- set_table_cache_key(key_buff, key_length);
- }
- inline In_C_you_should_use_my_bool_instead() honor_global_locks()
- {
- return ((table_category == TABLE_CATEGORY_USER)
- || (table_category == TABLE_CATEGORY_SYSTEM));
- }
- inline In_C_you_should_use_my_bool_instead() require_write_privileges()
- {
- return (table_category == TABLE_CATEGORY_PERFORMANCE);
- }
- inline ulong get_table_def_version()
- {
- return table_map_id;
- }
- enum enum_table_ref_type get_table_ref_type() const
- {
- if (is_view)
- return TABLE_REF_VIEW;
- switch (tmp_table) {
- case NO_TMP_TABLE:
- return TABLE_REF_BASE_TABLE;
- case SYSTEM_TMP_TABLE:
- return TABLE_REF_I_S_TABLE;
- default:
- return TABLE_REF_TMP_TABLE;
- }
- }
- ulong get_table_ref_version() const
- {
- return (tmp_table == SYSTEM_TMP_TABLE || is_view) ? 0 : table_map_id;
- }
-} TABLE_SHARE;
-extern ulong refresh_version;
-enum index_hint_type
-{
- INDEX_HINT_IGNORE,
- INDEX_HINT_USE,
- INDEX_HINT_FORCE
-};
-struct st_table {
- st_table() {}
- TABLE_SHARE *s;
- handler *file;
- struct st_table *next, *prev;
- struct st_table *parent;
- TABLE_LIST *child_l;
- TABLE_LIST **child_last_l;
- THD *in_use;
- Field **field;
- uchar *record[2];
- uchar *write_row_record;
- uchar *insert_values;
- key_map covering_keys;
- key_map quick_keys, merge_keys;
- key_map keys_in_use_for_query;
- key_map keys_in_use_for_group_by;
- key_map keys_in_use_for_order_by;
- KEY *key_info;
- Field *next_number_field;
- Field *found_next_number_field;
- Field_timestamp *timestamp_field;
- Table_triggers_list *triggers;
- TABLE_LIST *pos_in_table_list;
- ORDER *group;
- const char *alias;
- uchar *null_flags;
- my_bitmap_map *bitmap_init_value;
- MY_BITMAP def_read_set, def_write_set, tmp_set;
- MY_BITMAP *read_set, *write_set;
- query_id_t query_id;
- ha_rows quick_rows[64];
- key_part_map const_key_parts[64];
- uint quick_key_parts[64];
- uint quick_n_ranges[64];
- ha_rows quick_condition_rows;
- timestamp_auto_set_type timestamp_field_type;
- table_map map;
- uint lock_position;
- uint lock_data_start;
- uint lock_count;
- uint tablenr,used_fields;
- uint temp_pool_slot;
- uint status;
- uint db_stat;
- uint derived_select_number;
- int current_lock;
- my_bool copy_blobs;
- uint maybe_null;
- my_bool null_row;
- my_bool force_index;
- my_bool distinct,const_table,no_rows;
- my_bool key_read, no_keyread;
- my_bool open_placeholder;
- my_bool locked_by_logger;
- my_bool no_replicate;
- my_bool locked_by_name;
- my_bool fulltext_searched;
- my_bool no_cache;
- my_bool open_by_handler;
- my_bool auto_increment_field_not_null;
- my_bool insert_or_update;
- my_bool alias_name_used;
- my_bool get_fields_in_item_tree;
- my_bool children_attached;
- REGINFO reginfo;
- MEM_ROOT mem_root;
- GRANT_INFO grant;
- FILESORT_INFO sort;
- In_C_you_should_use_my_bool_instead() fill_item_list(List<Item> *item_list) const;
- void reset_item_list(List<Item> *item_list) const;
- void clear_column_bitmaps(void);
- void prepare_for_position(void);
- void mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *map);
- void mark_columns_used_by_index(uint index);
- void restore_column_maps_after_mark_index();
- void mark_auto_increment_column(void);
- void mark_columns_needed_for_update(void);
- void mark_columns_needed_for_delete(void);
- void mark_columns_needed_for_insert(void);
- inline void column_bitmaps_set(MY_BITMAP *read_set_arg,
- MY_BITMAP *write_set_arg)
- {
- read_set= read_set_arg;
- write_set= write_set_arg;
- if (file)
- file->column_bitmaps_signal();
- }
- inline void column_bitmaps_set_no_signal(MY_BITMAP *read_set_arg,
- MY_BITMAP *write_set_arg)
- {
- read_set= read_set_arg;
- write_set= write_set_arg;
- }
- inline void use_all_columns()
- {
- column_bitmaps_set(&s->all_set, &s->all_set);
- }
- inline void default_column_bitmaps()
- {
- read_set= &def_read_set;
- write_set= &def_write_set;
- }
- inline In_C_you_should_use_my_bool_instead() is_name_opened() { return db_stat || open_placeholder; }
- inline In_C_you_should_use_my_bool_instead() needs_reopen_or_name_lock()
- { return s->version != refresh_version; }
- In_C_you_should_use_my_bool_instead() is_children_attached(void);
-};
-enum enum_schema_table_state
-{
- NOT_PROCESSED= 0,
- PROCESSED_BY_CREATE_SORT_INDEX,
- PROCESSED_BY_JOIN_EXEC
-};
-typedef struct st_foreign_key_info
-{
- LEX_STRING *forein_id;
- LEX_STRING *referenced_db;
- LEX_STRING *referenced_table;
- LEX_STRING *update_method;
- LEX_STRING *delete_method;
- LEX_STRING *referenced_key_name;
- List<LEX_STRING> foreign_fields;
- List<LEX_STRING> referenced_fields;
-} FOREIGN_KEY_INFO;
-enum enum_schema_tables
-{
- SCH_CHARSETS= 0,
- SCH_COLLATIONS,
- SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
- SCH_COLUMNS,
- SCH_COLUMN_PRIVILEGES,
- SCH_ENGINES,
- SCH_EVENTS,
- SCH_FILES,
- SCH_GLOBAL_STATUS,
- SCH_GLOBAL_VARIABLES,
- SCH_KEY_COLUMN_USAGE,
- SCH_OPEN_TABLES,
- SCH_PARTITIONS,
- SCH_PLUGINS,
- SCH_PROCESSLIST,
- SCH_PROFILES,
- SCH_REFERENTIAL_CONSTRAINTS,
- SCH_PROCEDURES,
- SCH_SCHEMATA,
- SCH_SCHEMA_PRIVILEGES,
- SCH_SESSION_STATUS,
- SCH_SESSION_VARIABLES,
- SCH_STATISTICS,
- SCH_STATUS,
- SCH_TABLES,
- SCH_TABLE_CONSTRAINTS,
- SCH_TABLE_NAMES,
- SCH_TABLE_PRIVILEGES,
- SCH_TRIGGERS,
- SCH_USER_PRIVILEGES,
- SCH_VARIABLES,
- SCH_VIEWS
-};
-typedef struct st_field_info
-{
- const char* field_name;
- uint field_length;
- enum enum_field_types field_type;
- int value;
- uint field_flags;
- const char* old_name;
- uint open_method;
-} ST_FIELD_INFO;
-struct TABLE_LIST;
-typedef class Item COND;
-typedef struct st_schema_table
-{
- const char* table_name;
- ST_FIELD_INFO *fields_info;
- TABLE *(*create_table) (THD *thd, TABLE_LIST *table_list);
- int (*fill_table) (THD *thd, TABLE_LIST *tables, COND *cond);
- int (*old_format) (THD *thd, struct st_schema_table *schema_table);
- int (*process_table) (THD *thd, TABLE_LIST *tables, TABLE *table,
- In_C_you_should_use_my_bool_instead() res, LEX_STRING *db_name, LEX_STRING *table_name);
- int idx_field1, idx_field2;
- In_C_you_should_use_my_bool_instead() hidden;
- uint i_s_requested_object;
-} ST_SCHEMA_TABLE;
-struct st_lex;
-class select_union;
-class TMP_TABLE_PARAM;
-Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
- const char *name);
-struct Field_translator
-{
- Item *item;
- const char *name;
-};
-class Natural_join_column: public Sql_alloc
-{
-public:
- Field_translator *view_field;
- Field *table_field;
- TABLE_LIST *table_ref;
- In_C_you_should_use_my_bool_instead() is_common;
-public:
- Natural_join_column(Field_translator *field_param, TABLE_LIST *tab);
- Natural_join_column(Field *field_param, TABLE_LIST *tab);
- const char *name();
- Item *create_item(THD *thd);
- Field *field();
- const char *table_name();
- const char *db_name();
- GRANT_INFO *grant();
-};
-class Index_hint;
-struct TABLE_LIST
-{
- TABLE_LIST() {}
- inline void init_one_table(const char *db_name_arg,
- const char *table_name_arg,
- enum thr_lock_type lock_type_arg)
- {
- bzero((char*) this, sizeof(*this));
- db= (char*) db_name_arg;
- table_name= alias= (char*) table_name_arg;
- lock_type= lock_type_arg;
- }
- TABLE_LIST *next_local;
- TABLE_LIST *next_global, **prev_global;
- char *db, *alias, *table_name, *schema_table_name;
- char *option;
- Item *on_expr;
- Item *prep_on_expr;
- COND_EQUAL *cond_equal;
- TABLE_LIST *natural_join;
- In_C_you_should_use_my_bool_instead() is_natural_join;
- List<String> *join_using_fields;
- List<Natural_join_column> *join_columns;
- In_C_you_should_use_my_bool_instead() is_join_columns_complete;
- TABLE_LIST *next_name_resolution_table;
- List<Index_hint> *index_hints;
- TABLE *table;
- uint table_id;
- select_union *derived_result;
- TABLE_LIST *correspondent_table;
- st_select_lex_unit *derived;
- ST_SCHEMA_TABLE *schema_table;
- st_select_lex *schema_select_lex;
- In_C_you_should_use_my_bool_instead() schema_table_reformed;
- TMP_TABLE_PARAM *schema_table_param;
- st_select_lex *select_lex;
- st_lex *view;
- Field_translator *field_translation;
- Field_translator *field_translation_end;
- TABLE_LIST *merge_underlying_list;
- List<TABLE_LIST> *view_tables;
- TABLE_LIST *belong_to_view;
- TABLE_LIST *referencing_view;
- TABLE_LIST *parent_l;
- Security_context *security_ctx;
- Security_context *view_sctx;
- In_C_you_should_use_my_bool_instead() allowed_show;
- TABLE_LIST *next_leaf;
- Item *where;
- Item *check_option;
- LEX_STRING select_stmt;
- LEX_STRING md5;
- LEX_STRING source;
- LEX_STRING view_db;
- LEX_STRING view_name;
- LEX_STRING timestamp;
- st_lex_user definer;
- ulonglong file_version;
- ulonglong updatable_view;
- ulonglong revision;
- ulonglong algorithm;
- ulonglong view_suid;
- ulonglong with_check;
- uint8 effective_with_check;
- uint8 effective_algorithm;
- GRANT_INFO grant;
- ulonglong engine_data;
- qc_engine_callback callback_func;
- thr_lock_type lock_type;
- uint outer_join;
- uint shared;
- size_t db_length;
- size_t table_name_length;
- In_C_you_should_use_my_bool_instead() updatable;
- In_C_you_should_use_my_bool_instead() straight;
- In_C_you_should_use_my_bool_instead() updating;
- In_C_you_should_use_my_bool_instead() force_index;
- In_C_you_should_use_my_bool_instead() ignore_leaves;
- table_map dep_tables;
- table_map on_expr_dep_tables;
- struct st_nested_join *nested_join;
- TABLE_LIST *embedding;
- List<TABLE_LIST> *join_list;
- In_C_you_should_use_my_bool_instead() cacheable_table;
- In_C_you_should_use_my_bool_instead() table_in_first_from_clause;
- In_C_you_should_use_my_bool_instead() skip_temporary;
- In_C_you_should_use_my_bool_instead() contain_auto_increment;
- In_C_you_should_use_my_bool_instead() multitable_view;
- In_C_you_should_use_my_bool_instead() compact_view_format;
- In_C_you_should_use_my_bool_instead() where_processed;
- In_C_you_should_use_my_bool_instead() check_option_processed;
- enum frm_type_enum required_type;
- handlerton *db_type;
- char timestamp_buffer[20];
- In_C_you_should_use_my_bool_instead() prelocking_placeholder;
- In_C_you_should_use_my_bool_instead() create;
- In_C_you_should_use_my_bool_instead() internal_tmp_table;
- View_creation_ctx *view_creation_ctx;
- LEX_STRING view_client_cs_name;
- LEX_STRING view_connection_cl_name;
- LEX_STRING view_body_utf8;
- uint8 trg_event_map;
- uint i_s_requested_object;
- In_C_you_should_use_my_bool_instead() has_db_lookup_value;
- In_C_you_should_use_my_bool_instead() has_table_lookup_value;
- uint table_open_method;
- enum enum_schema_table_state schema_table_state;
- void calc_md5(char *buffer);
- void set_underlying_merge();
- int view_check_option(THD *thd, In_C_you_should_use_my_bool_instead() ignore_failure);
- In_C_you_should_use_my_bool_instead() setup_underlying(THD *thd);
- void cleanup_items();
- In_C_you_should_use_my_bool_instead() placeholder()
- {
- return derived || view || schema_table || create && !table->db_stat ||
- !table;
- }
- void print(THD *thd, String *str, enum_query_type query_type);
- In_C_you_should_use_my_bool_instead() check_single_table(TABLE_LIST **table, table_map map,
- TABLE_LIST *view);
- In_C_you_should_use_my_bool_instead() set_insert_values(MEM_ROOT *mem_root);
- void hide_view_error(THD *thd);
- TABLE_LIST *find_underlying_table(TABLE *table);
- TABLE_LIST *first_leaf_for_name_resolution();
- TABLE_LIST *last_leaf_for_name_resolution();
- In_C_you_should_use_my_bool_instead() is_leaf_for_name_resolution();
- inline TABLE_LIST *top_table()
- { return belong_to_view ? belong_to_view : this; }
- inline In_C_you_should_use_my_bool_instead() prepare_check_option(THD *thd)
- {
- In_C_you_should_use_my_bool_instead() res= (0);
- if (effective_with_check)
- res= prep_check_option(thd, effective_with_check);
- return res;
- }
- inline In_C_you_should_use_my_bool_instead() prepare_where(THD *thd, Item **conds,
- In_C_you_should_use_my_bool_instead() no_where_clause)
- {
- if (effective_algorithm == 2)
- return prep_where(thd, conds, no_where_clause);
- return (0);
- }
- void register_want_access(ulong want_access);
- In_C_you_should_use_my_bool_instead() prepare_security(THD *thd);
- Security_context *find_view_security_context(THD *thd);
- In_C_you_should_use_my_bool_instead() prepare_view_securety_context(THD *thd);
- void reinit_before_use(THD *thd);
- Item_subselect *containing_subselect();
- In_C_you_should_use_my_bool_instead() process_index_hints(TABLE *table);
- inline ulong get_child_def_version()
- {
- return child_def_version;
- }
- inline void set_child_def_version(ulong version)
- {
- child_def_version= version;
- }
- inline void init_child_def_version()
- {
- child_def_version= ~0UL;
- }
- inline
- In_C_you_should_use_my_bool_instead() is_table_ref_id_equal(TABLE_SHARE *s) const
- {
- return (m_table_ref_type == s->get_table_ref_type() &&
- m_table_ref_version == s->get_table_ref_version());
- }
- inline
- void set_table_ref_id(TABLE_SHARE *s)
- {
- m_table_ref_type= s->get_table_ref_type();
- m_table_ref_version= s->get_table_ref_version();
- }
-private:
- In_C_you_should_use_my_bool_instead() prep_check_option(THD *thd, uint8 check_opt_type);
- In_C_you_should_use_my_bool_instead() prep_where(THD *thd, Item **conds, In_C_you_should_use_my_bool_instead() no_where_clause);
- ulong child_def_version;
- enum enum_table_ref_type m_table_ref_type;
- ulong m_table_ref_version;
-};
-class Item;
-class Field_iterator: public Sql_alloc
-{
-public:
- Field_iterator() {}
- virtual ~Field_iterator() {}
- virtual void set(TABLE_LIST *)= 0;
- virtual void next()= 0;
- virtual In_C_you_should_use_my_bool_instead() end_of_fields()= 0;
- virtual const char *name()= 0;
- virtual Item *create_item(THD *)= 0;
- virtual Field *field()= 0;
-};
-class Field_iterator_table: public Field_iterator
-{
- Field **ptr;
-public:
- Field_iterator_table() :ptr(0) {}
- void set(TABLE_LIST *table) { ptr= table->table->field; }
- void set_table(TABLE *table) { ptr= table->field; }
- void next() { ptr++; }
- In_C_you_should_use_my_bool_instead() end_of_fields() { return *ptr == 0; }
- const char *name();
- Item *create_item(THD *thd);
- Field *field() { return *ptr; }
-};
-class Field_iterator_view: public Field_iterator
-{
- Field_translator *ptr, *array_end;
- TABLE_LIST *view;
-public:
- Field_iterator_view() :ptr(0), array_end(0) {}
- void set(TABLE_LIST *table);
- void next() { ptr++; }
- In_C_you_should_use_my_bool_instead() end_of_fields() { return ptr == array_end; }
- const char *name();
- Item *create_item(THD *thd);
- Item **item_ptr() {return &ptr->item; }
- Field *field() { return 0; }
- inline Item *item() { return ptr->item; }
- Field_translator *field_translator() { return ptr; }
-};
-class Field_iterator_natural_join: public Field_iterator
-{
- List_iterator_fast<Natural_join_column> column_ref_it;
- Natural_join_column *cur_column_ref;
-public:
- Field_iterator_natural_join() :cur_column_ref(NULL) {}
- ~Field_iterator_natural_join() {}
- void set(TABLE_LIST *table);
- void next();
- In_C_you_should_use_my_bool_instead() end_of_fields() { return !cur_column_ref; }
- const char *name() { return cur_column_ref->name(); }
- Item *create_item(THD *thd) { return cur_column_ref->create_item(thd); }
- Field *field() { return cur_column_ref->field(); }
- Natural_join_column *column_ref() { return cur_column_ref; }
-};
-class Field_iterator_table_ref: public Field_iterator
-{
- TABLE_LIST *table_ref, *first_leaf, *last_leaf;
- Field_iterator_table table_field_it;
- Field_iterator_view view_field_it;
- Field_iterator_natural_join natural_join_it;
- Field_iterator *field_it;
- void set_field_iterator();
-public:
- Field_iterator_table_ref() :field_it(NULL) {}
- void set(TABLE_LIST *table);
- void next();
- In_C_you_should_use_my_bool_instead() end_of_fields()
- { return (table_ref == last_leaf && field_it->end_of_fields()); }
- const char *name() { return field_it->name(); }
- const char *table_name();
- const char *db_name();
- GRANT_INFO *grant();
- Item *create_item(THD *thd) { return field_it->create_item(thd); }
- Field *field() { return field_it->field(); }
- Natural_join_column *get_or_create_column_ref(TABLE_LIST *parent_table_ref);
- Natural_join_column *get_natural_column_ref();
-};
-typedef struct st_nested_join
-{
- List<TABLE_LIST> join_list;
- table_map used_tables;
- table_map not_null_tables;
- struct st_join_table *first_nested;
- uint counter;
- nested_join_map nj_map;
-} NESTED_JOIN;
-typedef struct st_changed_table_list
-{
- struct st_changed_table_list *next;
- char *key;
- uint32 key_length;
-} CHANGED_TABLE_LIST;
-typedef struct st_open_table_list{
- struct st_open_table_list *next;
- char *db,*table;
- uint32 in_use,locked;
-} OPEN_TABLE_LIST;
-typedef struct st_table_field_w_type
-{
- LEX_STRING name;
- LEX_STRING type;
- LEX_STRING cset;
-} TABLE_FIELD_W_TYPE;
-my_bool
-table_check_intact(TABLE *table, const uint table_f_count,
- const TABLE_FIELD_W_TYPE *table_def);
-static inline my_bitmap_map *tmp_use_all_columns(TABLE *table,
- MY_BITMAP *bitmap)
-{
- my_bitmap_map *old= bitmap->bitmap;
- bitmap->bitmap= table->s->all_set.bitmap;
- return old;
-}
-static inline void tmp_restore_column_map(MY_BITMAP *bitmap,
- my_bitmap_map *old)
-{
- bitmap->bitmap= old;
-}
-static inline my_bitmap_map *dbug_tmp_use_all_columns(TABLE *table,
- MY_BITMAP *bitmap)
-{
- return tmp_use_all_columns(table, bitmap);
-}
-static inline void dbug_tmp_restore_column_map(MY_BITMAP *bitmap,
- my_bitmap_map *old)
-{
- tmp_restore_column_map(bitmap, old);
-}
-size_t max_row_length(TABLE *table, const uchar *data);
-#include "sql_error.h"
-class MYSQL_ERROR: public Sql_alloc
-{
-public:
- enum enum_warning_level
- { WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
- uint code;
- enum_warning_level level;
- char *msg;
- MYSQL_ERROR(THD *thd, uint code_arg, enum_warning_level level_arg,
- const char *msg_arg)
- :code(code_arg), level(level_arg)
- {
- if (msg_arg)
- set_msg(thd, msg_arg);
- }
- void set_msg(THD *thd, const char *msg_arg);
-};
-MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
- uint code, const char *msg);
-void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
- uint code, const char *format, ...);
-void mysql_reset_errors(THD *thd, In_C_you_should_use_my_bool_instead() force);
-In_C_you_should_use_my_bool_instead() mysqld_show_warnings(THD *thd, ulong levels_to_show);
-extern const LEX_STRING warning_level_names[];
-#include "field.h"
-const uint32 max_field_size= (uint32) 4294967295U;
-class Send_field;
-class Protocol;
-class Create_field;
-struct st_cache_field;
-int field_conv(Field *to,Field *from);
-inline uint get_enum_pack_length(int elements)
-{
- return elements < 256 ? 1 : 2;
-}
-inline uint get_set_pack_length(int elements)
-{
- uint len= (elements + 7) / 8;
- return len > 4 ? 8 : len;
-}
-class Field
-{
- Field(const Item &);
- void operator=(Field &);
-public:
- static void *operator new(size_t size) {return sql_alloc(size); }
- static void operator delete(void *ptr_arg, size_t size) { ; }
- uchar *ptr;
- uchar *null_ptr;
- struct st_table *table;
- struct st_table *orig_table;
- const char **table_name, *field_name;
- LEX_STRING comment;
- key_map key_start, part_of_key, part_of_key_not_clustered;
- key_map part_of_sortkey;
- enum utype { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL,
- CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD,
- BIT_FIELD, TIMESTAMP_OLD_FIELD, CAPITALIZE, BLOB_FIELD,
- TIMESTAMP_DN_FIELD, TIMESTAMP_UN_FIELD, TIMESTAMP_DNUN_FIELD};
- enum geometry_type
- {
- GEOM_GEOMETRY = 0, GEOM_POINT = 1, GEOM_LINESTRING = 2, GEOM_POLYGON = 3,
- GEOM_MULTIPOINT = 4, GEOM_MULTILINESTRING = 5, GEOM_MULTIPOLYGON = 6,
- GEOM_GEOMETRYCOLLECTION = 7
- };
- enum imagetype { itRAW, itMBR};
- utype unireg_check;
- uint32 field_length;
- uint32 flags;
- uint16 field_index;
- uchar null_bit;
- In_C_you_should_use_my_bool_instead() is_created_from_null_item;
- Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
- uchar null_bit_arg, utype unireg_check_arg,
- const char *field_name_arg);
- virtual ~Field() {}
- virtual int store(const char *to, uint length,CHARSET_INFO *cs)=0;
- virtual int store(double nr)=0;
- virtual int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val)=0;
- virtual int store_decimal(const my_decimal *d)=0;
- virtual int store_time(MYSQL_TIME *ltime, timestamp_type t_type);
- int store(const char *to, uint length, CHARSET_INFO *cs,
- enum_check_fields check_level);
- virtual double val_real(void)=0;
- virtual longlong val_int(void)=0;
- virtual my_decimal *val_decimal(my_decimal *);
- inline String *val_str(String *str) { return val_str(str, str); }
- virtual String *val_str(String*,String *)=0;
- String *val_int_as_str(String *val_buffer, my_bool unsigned_flag);
- virtual In_C_you_should_use_my_bool_instead() str_needs_quotes() { return (0); }
- virtual Item_result result_type () const=0;
- virtual Item_result cmp_type () const { return result_type(); }
- virtual Item_result cast_to_int_type () const { return result_type(); }
- static In_C_you_should_use_my_bool_instead() type_can_have_key_part(enum_field_types);
- static enum_field_types field_type_merge(enum_field_types, enum_field_types);
- static Item_result result_merge_type(enum_field_types);
- virtual In_C_you_should_use_my_bool_instead() eq(Field *field)
- {
- return (ptr == field->ptr && null_ptr == field->null_ptr &&
- null_bit == field->null_bit);
- }
- virtual In_C_you_should_use_my_bool_instead() eq_def(Field *field);
- virtual uint32 pack_length() const { return (uint32) field_length; }
- virtual uint32 pack_length_in_rec() const { return pack_length(); }
- virtual int compatible_field_size(uint field_metadata);
- virtual uint pack_length_from_metadata(uint field_metadata)
- { return field_metadata; }
- virtual uint row_pack_length() { return 0; }
- virtual int save_field_metadata(uchar *first_byte)
- { return do_save_field_metadata(first_byte); }
- virtual uint32 data_length() { return pack_length(); }
- virtual uint32 sort_length() const { return pack_length(); }
- virtual uint32 max_data_length() const {
- return pack_length();
- };
- virtual int reset(void) { bzero(ptr,pack_length()); return 0; }
- virtual void reset_fields() {}
- virtual void set_default()
- {
- my_ptrdiff_t l_offset= (my_ptrdiff_t) (table->s->default_values -
- table->record[0]);
- memcpy(ptr, ptr + l_offset, pack_length());
- if (null_ptr)
- *null_ptr= ((*null_ptr & (uchar) ~null_bit) |
- null_ptr[l_offset] & null_bit);
- }
- virtual In_C_you_should_use_my_bool_instead() binary() const { return 1; }
- virtual In_C_you_should_use_my_bool_instead() zero_pack() const { return 1; }
- virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
- virtual uint32 key_length() const { return pack_length(); }
- virtual enum_field_types type() const =0;
- virtual enum_field_types real_type() const { return type(); }
- inline int cmp(const uchar *str) { return cmp(ptr,str); }
- virtual int cmp_max(const uchar *a, const uchar *b, uint max_len)
- { return cmp(a, b); }
- virtual int cmp(const uchar *,const uchar *)=0;
- virtual int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L)
- { return memcmp(a,b,pack_length()); }
- virtual int cmp_offset(uint row_offset)
- { return cmp(ptr,ptr+row_offset); }
- virtual int cmp_binary_offset(uint row_offset)
- { return cmp_binary(ptr, ptr+row_offset); };
- virtual int key_cmp(const uchar *a,const uchar *b)
- { return cmp(a, b); }
- virtual int key_cmp(const uchar *str, uint length)
- { return cmp(ptr,str); }
- virtual uint decimals() const { return 0; }
- virtual void sql_type(String &str) const =0;
- virtual uint size_of() const =0;
- inline In_C_you_should_use_my_bool_instead() is_null(my_ptrdiff_t row_offset= 0)
- { return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : table->null_row; }
- inline In_C_you_should_use_my_bool_instead() is_real_null(my_ptrdiff_t row_offset= 0)
- { return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : 0; }
- inline In_C_you_should_use_my_bool_instead() is_null_in_record(const uchar *record)
- {
- if (!null_ptr)
- return 0;
- return ((record[(uint) (null_ptr -table->record[0])] & null_bit) ? 1 : 0);
- }
- inline In_C_you_should_use_my_bool_instead() is_null_in_record_with_offset(my_ptrdiff_t offset)
- {
- if (!null_ptr)
- return 0;
- return ((null_ptr[offset] & null_bit) ? 1 : 0);
- }
- inline void set_null(my_ptrdiff_t row_offset= 0)
- { if (null_ptr) null_ptr[row_offset]|= null_bit; }
- inline void set_notnull(my_ptrdiff_t row_offset= 0)
- { if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
- inline In_C_you_should_use_my_bool_instead() maybe_null(void) { return null_ptr != 0 || table->maybe_null; }
- inline In_C_you_should_use_my_bool_instead() real_maybe_null(void) { return null_ptr != 0; }
- enum {
- LAST_NULL_BYTE_UNDEF= 0
- };
- size_t last_null_byte() const {
- size_t bytes= do_last_null_byte();
- do {_db_pargs_(284,"debug"); _db_doprnt_ ("last_null_byte() ==> %ld", (long) bytes);} while(0);
- assert(bytes <= table->s->null_bytes);
- return bytes;
- }
- virtual void make_field(Send_field *);
- virtual void sort_string(uchar *buff,uint length)=0;
- virtual In_C_you_should_use_my_bool_instead() optimize_range(uint idx, uint part);
- virtual In_C_you_should_use_my_bool_instead() can_be_compared_as_longlong() const { return (0); }
- virtual void free() {}
- virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table,
- In_C_you_should_use_my_bool_instead() keep_type);
- virtual Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit);
- Field *clone(MEM_ROOT *mem_root, struct st_table *new_table);
- inline void move_field(uchar *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
- {
- ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
- }
- inline void move_field(uchar *ptr_arg) { ptr=ptr_arg; }
- virtual void move_field_offset(my_ptrdiff_t ptr_diff)
- {
- ptr=(uchar*) ((uchar*) (ptr)+ptr_diff);
- if (null_ptr)
- null_ptr=(uchar*) ((uchar*) (null_ptr)+ptr_diff);
- }
- virtual void get_image(uchar *buff, uint length, CHARSET_INFO *cs)
- { memcpy(buff,ptr,length); }
- virtual void set_image(const uchar *buff,uint length, CHARSET_INFO *cs)
- { memcpy(ptr,buff,length); }
- virtual uint get_key_image(uchar *buff, uint length, imagetype type)
- {
- get_image(buff, length, &my_charset_bin);
- return length;
- }
- virtual void set_key_image(const uchar *buff,uint length)
- { set_image(buff,length, &my_charset_bin); }
- inline longlong val_int_offset(uint row_offset)
- {
- ptr+=row_offset;
- longlong tmp=val_int();
- ptr-=row_offset;
- return tmp;
- }
- inline longlong val_int(const uchar *new_ptr)
- {
- uchar *old_ptr= ptr;
- longlong return_value;
- ptr= (uchar*) new_ptr;
- return_value= val_int();
- ptr= old_ptr;
- return return_value;
- }
- inline String *val_str(String *str, const uchar *new_ptr)
- {
- uchar *old_ptr= ptr;
- ptr= (uchar*) new_ptr;
- val_str(str);
- ptr= old_ptr;
- return str;
- }
- virtual In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- uchar *pack(uchar *to, const uchar *from)
- {
- const char *_db_func_, *_db_file_; uint _db_level_; char **_db_framep_; _db_enter_ ("Field::pack","./sql/field.h",390,&_db_func_,&_db_file_,&_db_level_, &_db_framep_);
- uchar *result= this->pack(to, from, UINT_MAX, table->s->db_low_byte_first);
- do {_db_return_ (392, &_db_func_, &_db_file_, &_db_level_); return(result);} while(0);
- }
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first);
- const uchar *unpack(uchar* to, const uchar *from)
- {
- const char *_db_func_, *_db_file_; uint _db_level_; char **_db_framep_; _db_enter_ ("Field::unpack","./sql/field.h",402,&_db_func_,&_db_file_,&_db_level_, &_db_framep_);
- const uchar *result= unpack(to, from, 0U, table->s->db_low_byte_first);
- do {_db_return_ (404, &_db_func_, &_db_file_, &_db_level_); return(result);} while(0);
- }
- virtual uchar *pack_key(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- return pack(to, from, max_length, low_byte_first);
- }
- virtual uchar *pack_key_from_key_image(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- return pack(to, from, max_length, low_byte_first);
- }
- virtual const uchar *unpack_key(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- return unpack(to, from, max_length, low_byte_first);
- }
- virtual uint packed_col_length(const uchar *to, uint length)
- { return length;}
- virtual uint max_packed_col_length(uint max_length)
- { return max_length;}
- virtual int pack_cmp(const uchar *a,const uchar *b, uint key_length_arg,
- my_bool insert_or_update)
- { return cmp(a,b); }
- virtual int pack_cmp(const uchar *b, uint key_length_arg,
- my_bool insert_or_update)
- { return cmp(ptr,b); }
- uint offset(uchar *record)
- {
- return (uint) (ptr - record);
- }
- void copy_from_tmp(int offset);
- uint fill_cache_field(struct st_cache_field *copy);
- virtual In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime,uint fuzzydate);
- virtual In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *ltime);
- virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
- virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
- virtual In_C_you_should_use_my_bool_instead() has_charset(void) const { return (0); }
- virtual void set_charset(CHARSET_INFO *charset_arg) { }
- virtual enum Derivation derivation(void) const
- { return DERIVATION_IMPLICIT; }
- virtual void set_derivation(enum Derivation derivation_arg) { }
- In_C_you_should_use_my_bool_instead() set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
- int cuted_increment);
- void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
- const char *str, uint str_len,
- timestamp_type ts_type, int cuted_increment);
- void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
- longlong nr, timestamp_type ts_type,
- int cuted_increment);
- void set_datetime_warning(MYSQL_ERROR::enum_warning_level, const uint code,
- double nr, timestamp_type ts_type);
- inline In_C_you_should_use_my_bool_instead() check_overflow(int op_result)
- {
- return (op_result == 2);
- }
- int warn_if_overflow(int op_result);
- void init(TABLE *table_arg)
- {
- orig_table= table= table_arg;
- table_name= &table_arg->alias;
- }
- virtual uint32 max_display_length()= 0;
- virtual uint is_equal(Create_field *new_field);
- longlong convert_decimal2longlong(const my_decimal *val, In_C_you_should_use_my_bool_instead() unsigned_flag,
- int *err);
- inline uint32 char_length() const
- {
- return field_length / charset()->mbmaxlen;
- }
- virtual geometry_type get_geometry_type()
- {
- assert(0);
- return GEOM_GEOMETRY;
- }
- virtual void hash(ulong *nr, ulong *nr2);
- friend In_C_you_should_use_my_bool_instead() reopen_table(THD *,struct st_table *,In_C_you_should_use_my_bool_instead());
- friend int cre_myisam(char * name, register TABLE *form, uint options,
- ulonglong auto_increment_value);
- friend class Copy_field;
- friend class Item_avg_field;
- friend class Item_std_field;
- friend class Item_sum_num;
- friend class Item_sum_sum;
- friend class Item_sum_str;
- friend class Item_sum_count;
- friend class Item_sum_avg;
- friend class Item_sum_std;
- friend class Item_sum_min;
- friend class Item_sum_max;
- friend class Item_func_group_concat;
-private:
- virtual size_t do_last_null_byte() const;
- virtual int do_save_field_metadata(uchar *metadata_ptr)
- { return 0; }
-};
-class Field_num :public Field {
-public:
- const uint8 dec;
- In_C_you_should_use_my_bool_instead() zerofill,unsigned_flag;
- Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg, utype unireg_check_arg,
- const char *field_name_arg,
- uint8 dec_arg, In_C_you_should_use_my_bool_instead() zero_arg, In_C_you_should_use_my_bool_instead() unsigned_arg);
- Item_result result_type () const { return REAL_RESULT; }
- void prepend_zeros(String *value);
- void add_zerofill_and_unsigned(String &res) const;
- friend class Create_field;
- void make_field(Send_field *);
- uint decimals() const { return (uint) dec; }
- uint size_of() const { return sizeof(*this); }
- In_C_you_should_use_my_bool_instead() eq_def(Field *field);
- int store_decimal(const my_decimal *);
- my_decimal *val_decimal(my_decimal *);
- uint is_equal(Create_field *new_field);
- int check_int(CHARSET_INFO *cs, const char *str, int length,
- const char *int_end, int error);
- In_C_you_should_use_my_bool_instead() get_int(CHARSET_INFO *cs, const char *from, uint len,
- longlong *rnd, ulonglong unsigned_max,
- longlong signed_min, longlong signed_max);
-};
-class Field_str :public Field {
-protected:
- CHARSET_INFO *field_charset;
- enum Derivation field_derivation;
-public:
- Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg, utype unireg_check_arg,
- const char *field_name_arg, CHARSET_INFO *charset);
- Item_result result_type () const { return STRING_RESULT; }
- uint decimals() const { return 31; }
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val)=0;
- int store_decimal(const my_decimal *);
- int store(const char *to,uint length,CHARSET_INFO *cs)=0;
- uint size_of() const { return sizeof(*this); }
- CHARSET_INFO *charset(void) const { return field_charset; }
- void set_charset(CHARSET_INFO *charset_arg) { field_charset= charset_arg; }
- enum Derivation derivation(void) const { return field_derivation; }
- virtual void set_derivation(enum Derivation derivation_arg)
- { field_derivation= derivation_arg; }
- In_C_you_should_use_my_bool_instead() binary() const { return field_charset == &my_charset_bin; }
- uint32 max_display_length() { return field_length; }
- friend class Create_field;
- my_decimal *val_decimal(my_decimal *);
- virtual In_C_you_should_use_my_bool_instead() str_needs_quotes() { return (1); }
- In_C_you_should_use_my_bool_instead() compare_str_field_flags(Create_field *new_field, uint32 flags);
- uint is_equal(Create_field *new_field);
-};
-class Field_longstr :public Field_str
-{
-protected:
- int report_if_important_data(const char *ptr, const char *end,
- In_C_you_should_use_my_bool_instead() count_spaces);
-public:
- Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg, utype unireg_check_arg,
- const char *field_name_arg, CHARSET_INFO *charset_arg)
- :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
- field_name_arg, charset_arg)
- {}
- int store_decimal(const my_decimal *d);
- uint32 max_data_length() const;
-};
-class Field_real :public Field_num {
-public:
- my_bool not_fixed;
- Field_real(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg, utype unireg_check_arg,
- const char *field_name_arg,
- uint8 dec_arg, In_C_you_should_use_my_bool_instead() zero_arg, In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
- field_name_arg, dec_arg, zero_arg, unsigned_arg),
- not_fixed(dec_arg >= 31)
- {}
- int store_decimal(const my_decimal *);
- my_decimal *val_decimal(my_decimal *);
- int truncate(double *nr, double max_length);
- uint32 max_display_length() { return field_length; }
- uint size_of() const { return sizeof(*this); }
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first);
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
-};
-class Field_decimal :public Field_real {
-public:
- Field_decimal(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- uint8 dec_arg,In_C_you_should_use_my_bool_instead() zero_arg,In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- dec_arg, zero_arg, unsigned_arg)
- {}
- enum_field_types type() const { return MYSQL_TYPE_DECIMAL;}
- enum ha_base_keytype key_type() const
- { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
- int reset(void);
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- void overflow(In_C_you_should_use_my_bool_instead() negative);
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 0; }
- void sql_type(String &str) const;
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- return Field::unpack(to, from, param_data, low_byte_first);
- }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- return Field::pack(to, from, max_length, low_byte_first);
- }
-};
-class Field_new_decimal :public Field_num {
-private:
- int do_save_field_metadata(uchar *first_byte);
-public:
- uint precision;
- uint bin_size;
- Field_new_decimal(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- uint8 dec_arg, In_C_you_should_use_my_bool_instead() zero_arg, In_C_you_should_use_my_bool_instead() unsigned_arg);
- Field_new_decimal(uint32 len_arg, In_C_you_should_use_my_bool_instead() maybe_null_arg,
- const char *field_name_arg, uint8 dec_arg,
- In_C_you_should_use_my_bool_instead() unsigned_arg);
- enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
- Item_result result_type () const { return DECIMAL_RESULT; }
- int reset(void);
- In_C_you_should_use_my_bool_instead() store_value(const my_decimal *decimal_value);
- void set_value_on_overflow(my_decimal *decimal_value, In_C_you_should_use_my_bool_instead() sign);
- int store(const char *to, uint length, CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int store_time(MYSQL_TIME *ltime, timestamp_type t_type);
- int store_decimal(const my_decimal *);
- double val_real(void);
- longlong val_int(void);
- my_decimal *val_decimal(my_decimal *);
- String *val_str(String*, String *);
- int cmp(const uchar *, const uchar *);
- void sort_string(uchar *buff, uint length);
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 0; }
- void sql_type(String &str) const;
- uint32 max_display_length() { return field_length; }
- uint size_of() const { return sizeof(*this); }
- uint32 pack_length() const { return (uint32) bin_size; }
- uint pack_length_from_metadata(uint field_metadata);
- uint row_pack_length() { return pack_length(); }
- int compatible_field_size(uint field_metadata);
- uint is_equal(Create_field *new_field);
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first);
-};
-class Field_tiny :public Field_num {
-public:
- Field_tiny(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() zero_arg, In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- 0, zero_arg,unsigned_arg)
- {}
- enum Item_result result_type () const { return INT_RESULT; }
- enum_field_types type() const { return MYSQL_TYPE_TINY;}
- enum ha_base_keytype key_type() const
- { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { ptr[0]=0; return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 1; }
- void sql_type(String &str) const;
- uint32 max_display_length() { return 4; }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- *to= *from;
- return to + 1;
- }
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- *to= *from;
- return from + 1;
- }
-};
-class Field_short :public Field_num {
-public:
- Field_short(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() zero_arg, In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- 0, zero_arg,unsigned_arg)
- {}
- Field_short(uint32 len_arg,In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, 0, 0, unsigned_arg)
- {}
- enum Item_result result_type () const { return INT_RESULT; }
- enum_field_types type() const { return MYSQL_TYPE_SHORT;}
- enum ha_base_keytype key_type() const
- { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;}
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { ptr[0]=ptr[1]=0; return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 2; }
- void sql_type(String &str) const;
- uint32 max_display_length() { return 6; }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- int16 val;
- do { val = (*((int16 *) (from))); } while(0);
- *((uint16*) (to))= (uint16) (val);
- return to + sizeof(val);
- }
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- int16 val;
- do { val = (*((int16 *) (from))); } while(0);
- *((uint16*) (to))= (uint16) (val);
- return from + sizeof(val);
- }
-};
-class Field_medium :public Field_num {
-public:
- Field_medium(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() zero_arg, In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- 0, zero_arg,unsigned_arg)
- {}
- enum Item_result result_type () const { return INT_RESULT; }
- enum_field_types type() const { return MYSQL_TYPE_INT24;}
- enum ha_base_keytype key_type() const
- { return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 3; }
- void sql_type(String &str) const;
- uint32 max_display_length() { return 8; }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- return Field::pack(to, from, max_length, low_byte_first);
- }
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- return Field::unpack(to, from, param_data, low_byte_first);
- }
-};
-class Field_long :public Field_num {
-public:
- Field_long(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() zero_arg, In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- 0, zero_arg,unsigned_arg)
- {}
- Field_long(uint32 len_arg,In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg,0,0,unsigned_arg)
- {}
- enum Item_result result_type () const { return INT_RESULT; }
- enum_field_types type() const { return MYSQL_TYPE_LONG;}
- enum ha_base_keytype key_type() const
- { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
- double val_real(void);
- longlong val_int(void);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- String *val_str(String*,String *);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 4; }
- void sql_type(String &str) const;
- uint32 max_display_length() { return 11; }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- int32 val;
- do { val = (*((long *) (from))); } while(0);
- *((long *) (to))= (long) (val);
- return to + sizeof(val);
- }
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- int32 val;
- do { val = (*((long *) (from))); } while(0);
- *((long *) (to))= (long) (val);
- return from + sizeof(val);
- }
-};
-class Field_longlong :public Field_num {
-public:
- Field_longlong(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() zero_arg, In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- 0, zero_arg,unsigned_arg)
- {}
- Field_longlong(uint32 len_arg,In_C_you_should_use_my_bool_instead() maybe_null_arg,
- const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg,0,0,unsigned_arg)
- {}
- enum Item_result result_type () const { return INT_RESULT; }
- enum_field_types type() const { return MYSQL_TYPE_LONGLONG;}
- enum ha_base_keytype key_type() const
- { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void)
- {
- ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0;
- return 0;
- }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 8; }
- void sql_type(String &str) const;
- In_C_you_should_use_my_bool_instead() can_be_compared_as_longlong() const { return (1); }
- uint32 max_display_length() { return 20; }
- virtual uchar *pack(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- int64 val;
- memcpy(((uchar*) &val),((uchar*) (from)),(sizeof(ulonglong)));
- memcpy(((uchar*) (to)),((uchar*) &val),(sizeof(ulonglong)));
- return to + sizeof(val);
- }
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first)
- {
- int64 val;
- memcpy(((uchar*) &val),((uchar*) (from)),(sizeof(ulonglong)));
- memcpy(((uchar*) (to)),((uchar*) &val),(sizeof(ulonglong)));
- return from + sizeof(val);
- }
-};
-class Field_float :public Field_real {
-public:
- Field_float(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- uint8 dec_arg,In_C_you_should_use_my_bool_instead() zero_arg,In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- dec_arg, zero_arg, unsigned_arg)
- {}
- Field_float(uint32 len_arg, In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- uint8 dec_arg)
- :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
- NONE, field_name_arg, dec_arg, 0, 0)
- {}
- enum_field_types type() const { return MYSQL_TYPE_FLOAT;}
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { bzero(ptr,sizeof(float)); return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return sizeof(float); }
- uint row_pack_length() { return pack_length(); }
- void sql_type(String &str) const;
-private:
- int do_save_field_metadata(uchar *first_byte);
-};
-class Field_double :public Field_real {
-public:
- Field_double(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- uint8 dec_arg,In_C_you_should_use_my_bool_instead() zero_arg,In_C_you_should_use_my_bool_instead() unsigned_arg)
- :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- dec_arg, zero_arg, unsigned_arg)
- {}
- Field_double(uint32 len_arg, In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- uint8 dec_arg)
- :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
- NONE, field_name_arg, dec_arg, 0, 0)
- {}
- Field_double(uint32 len_arg, In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- uint8 dec_arg, my_bool not_fixed_arg)
- :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
- NONE, field_name_arg, dec_arg, 0, 0)
- {not_fixed= not_fixed_arg; }
- enum_field_types type() const { return MYSQL_TYPE_DOUBLE;}
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { bzero(ptr,sizeof(double)); return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return sizeof(double); }
- uint row_pack_length() { return pack_length(); }
- void sql_type(String &str) const;
-private:
- int do_save_field_metadata(uchar *first_byte);
-};
-class Field_null :public Field_str {
- static uchar null[1];
-public:
- Field_null(uchar *ptr_arg, uint32 len_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str(ptr_arg, len_arg, null, 1,
- unireg_check_arg, field_name_arg, cs)
- {}
- enum_field_types type() const { return MYSQL_TYPE_NULL;}
- int store(const char *to, uint length, CHARSET_INFO *cs)
- { null[0]=1; return 0; }
- int store(double nr) { null[0]=1; return 0; }
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val) { null[0]=1; return 0; }
- int store_decimal(const my_decimal *d) { null[0]=1; return 0; }
- int reset(void) { return 0; }
- double val_real(void) { return 0.0;}
- longlong val_int(void) { return 0;}
- my_decimal *val_decimal(my_decimal *) { return 0; }
- String *val_str(String *value,String *value2)
- { value2->length(0); return value2;}
- int cmp(const uchar *a, const uchar *b) { return 0;}
- void sort_string(uchar *buff, uint length) {}
- uint32 pack_length() const { return 0; }
- void sql_type(String &str) const;
- uint size_of() const { return sizeof(*this); }
- uint32 max_display_length() { return 4; }
-};
-class Field_timestamp :public Field_str {
-public:
- Field_timestamp(uchar *ptr_arg, uint32 len_arg,
- uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- TABLE_SHARE *share, CHARSET_INFO *cs);
- Field_timestamp(In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs);
- enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;}
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 4; }
- void sql_type(String &str) const;
- In_C_you_should_use_my_bool_instead() can_be_compared_as_longlong() const { return (1); }
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 0; }
- void set_time();
- virtual void set_default()
- {
- if (table->timestamp_field == this &&
- unireg_check != TIMESTAMP_UN_FIELD)
- set_time();
- else
- Field::set_default();
- }
- inline long get_timestamp(my_bool *null_value)
- {
- if ((*null_value= is_null()))
- return 0;
- long tmp;
- do { tmp = (*((long *) (ptr))); } while(0);
- return tmp;
- }
- inline void store_timestamp(my_time_t timestamp)
- {
- *((long *) (ptr))= (long) ((uint32) timestamp);
- }
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime,uint fuzzydate);
- In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *ltime);
- timestamp_auto_set_type get_auto_set_type() const;
-};
-class Field_year :public Field_tiny {
-public:
- Field_year(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg)
- :Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, 1, 1)
- {}
- enum_field_types type() const { return MYSQL_TYPE_YEAR;}
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- void sql_type(String &str) const;
- In_C_you_should_use_my_bool_instead() can_be_compared_as_longlong() const { return (1); }
-};
-class Field_date :public Field_str {
-public:
- Field_date(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs)
- {}
- Field_date(In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, cs) {}
- enum_field_types type() const { return MYSQL_TYPE_DATE;}
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *ltime);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 4; }
- void sql_type(String &str) const;
- In_C_you_should_use_my_bool_instead() can_be_compared_as_longlong() const { return (1); }
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 1; }
-};
-class Field_newdate :public Field_str {
-public:
- Field_newdate(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs)
- {}
- Field_newdate(In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, cs) {}
- enum_field_types type() const { return MYSQL_TYPE_DATE;}
- enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; }
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int store_time(MYSQL_TIME *ltime, timestamp_type type);
- int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 3; }
- void sql_type(String &str) const;
- In_C_you_should_use_my_bool_instead() can_be_compared_as_longlong() const { return (1); }
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 1; }
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime,uint fuzzydate);
- In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *ltime);
-};
-class Field_time :public Field_str {
-public:
- Field_time(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str(ptr_arg, 8, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs)
- {}
- Field_time(In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0,8, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, cs) {}
- enum_field_types type() const { return MYSQL_TYPE_TIME;}
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- int store_time(MYSQL_TIME *ltime, timestamp_type type);
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime, uint fuzzydate);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *ltime);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 3; }
- void sql_type(String &str) const;
- In_C_you_should_use_my_bool_instead() can_be_compared_as_longlong() const { return (1); }
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 1; }
-};
-class Field_datetime :public Field_str {
-public:
- Field_datetime(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs)
- {}
- Field_datetime(In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_str((uchar*) 0,19, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, cs) {}
- enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- uint decimals() const { return 6; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int store_time(MYSQL_TIME *ltime, timestamp_type type);
- int reset(void)
- {
- ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0;
- return 0;
- }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- In_C_you_should_use_my_bool_instead() send_binary(Protocol *protocol);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return 8; }
- void sql_type(String &str) const;
- In_C_you_should_use_my_bool_instead() can_be_compared_as_longlong() const { return (1); }
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 1; }
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime,uint fuzzydate);
- In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *ltime);
-};
-class Field_string :public Field_longstr {
-public:
- In_C_you_should_use_my_bool_instead() can_alter_field_type;
- Field_string(uchar *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs),
- can_alter_field_type(1) {};
- Field_string(uint32 len_arg,In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs),
- can_alter_field_type(1) {};
- enum_field_types type() const
- {
- return ((can_alter_field_type && orig_table &&
- orig_table->s->db_create_options & 1 &&
- field_length >= 4) &&
- orig_table->s->frm_version < (6 +4) ?
- MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING);
- }
- enum ha_base_keytype key_type() const
- { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 0; }
- int reset(void)
- {
- charset()->cset->fill(charset(),(char*) ptr, field_length,
- (has_charset() ? ' ' : 0));
- return 0;
- }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int store(double nr) { return Field_str::store(nr); }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- my_decimal *val_decimal(my_decimal *);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- void sql_type(String &str) const;
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first);
- uint pack_length_from_metadata(uint field_metadata)
- { return (field_metadata & 0x00ff); }
- uint row_pack_length() { return (field_length + 1); }
- int pack_cmp(const uchar *a,const uchar *b,uint key_length,
- my_bool insert_or_update);
- int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update);
- uint packed_col_length(const uchar *to, uint length);
- uint max_packed_col_length(uint max_length);
- uint size_of() const { return sizeof(*this); }
- enum_field_types real_type() const { return MYSQL_TYPE_STRING; }
- In_C_you_should_use_my_bool_instead() has_charset(void) const
- { return charset() == &my_charset_bin ? (0) : (1); }
- Field *new_field(MEM_ROOT *root, struct st_table *new_table, In_C_you_should_use_my_bool_instead() keep_type);
- virtual uint get_key_image(uchar *buff,uint length, imagetype type);
-private:
- int do_save_field_metadata(uchar *first_byte);
-};
-class Field_varstring :public Field_longstr {
-public:
- static const uint MAX_SIZE;
- uint32 length_bytes;
- Field_varstring(uchar *ptr_arg,
- uint32 len_arg, uint length_bytes_arg,
- uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- TABLE_SHARE *share, CHARSET_INFO *cs)
- :Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs),
- length_bytes(length_bytes_arg)
- {
- share->varchar_fields++;
- }
- Field_varstring(uint32 len_arg,In_C_you_should_use_my_bool_instead() maybe_null_arg,
- const char *field_name_arg,
- TABLE_SHARE *share, CHARSET_INFO *cs)
- :Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs),
- length_bytes(len_arg < 256 ? 1 :2)
- {
- share->varchar_fields++;
- }
- enum_field_types type() const { return MYSQL_TYPE_VARCHAR; }
- enum ha_base_keytype key_type() const;
- uint row_pack_length() { return field_length; }
- In_C_you_should_use_my_bool_instead() zero_pack() const { return 0; }
- int reset(void) { bzero(ptr,field_length+length_bytes); return 0; }
- uint32 pack_length() const { return (uint32) field_length+length_bytes; }
- uint32 key_length() const { return (uint32) field_length; }
- uint32 sort_length() const
- {
- return (uint32) field_length + (field_charset == &my_charset_bin ?
- length_bytes : 0);
- }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int store(double nr) { return Field_str::store(nr); }
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- my_decimal *val_decimal(my_decimal *);
- int cmp_max(const uchar *, const uchar *, uint max_length);
- int cmp(const uchar *a,const uchar *b)
- {
- return cmp_max(a, b, ~0L);
- }
- void sort_string(uchar *buff,uint length);
- uint get_key_image(uchar *buff,uint length, imagetype type);
- void set_key_image(const uchar *buff,uint length);
- void sql_type(String &str) const;
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- uchar *pack_key(uchar *to, const uchar *from, uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- uchar *pack_key_from_key_image(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- virtual const uchar *unpack(uchar* to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first);
- const uchar *unpack_key(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- int pack_cmp(const uchar *a, const uchar *b, uint key_length,
- my_bool insert_or_update);
- int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update);
- int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L);
- int key_cmp(const uchar *,const uchar*);
- int key_cmp(const uchar *str, uint length);
- uint packed_col_length(const uchar *to, uint length);
- uint max_packed_col_length(uint max_length);
- uint32 data_length();
- uint size_of() const { return sizeof(*this); }
- enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
- In_C_you_should_use_my_bool_instead() has_charset(void) const
- { return charset() == &my_charset_bin ? (0) : (1); }
- Field *new_field(MEM_ROOT *root, struct st_table *new_table, In_C_you_should_use_my_bool_instead() keep_type);
- Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit);
- uint is_equal(Create_field *new_field);
- void hash(ulong *nr, ulong *nr2);
-private:
- int do_save_field_metadata(uchar *first_byte);
-};
-class Field_blob :public Field_longstr {
-protected:
- uint packlength;
- String value;
-public:
- Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- TABLE_SHARE *share, uint blob_pack_length, CHARSET_INFO *cs);
- Field_blob(uint32 len_arg,In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
- :Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs),
- packlength(4)
- {
- flags|= 16;
- }
- Field_blob(uint32 len_arg,In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs, In_C_you_should_use_my_bool_instead() set_packlength)
- :Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs)
- {
- flags|= 16;
- packlength= 4;
- if (set_packlength)
- {
- uint32 l_char_length= len_arg/cs->mbmaxlen;
- packlength= l_char_length <= 255 ? 1 :
- l_char_length <= 65535 ? 2 :
- l_char_length <= 16777215 ? 3 : 4;
- }
- }
- Field_blob(uint32 packlength_arg)
- :Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, "temp", system_charset_info),
- packlength(packlength_arg) {}
- enum_field_types type() const { return MYSQL_TYPE_BLOB;}
- enum ha_base_keytype key_type() const
- { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- my_decimal *val_decimal(my_decimal *);
- int cmp_max(const uchar *, const uchar *, uint max_length);
- int cmp(const uchar *a,const uchar *b)
- { return cmp_max(a, b, ~0L); }
- int cmp(const uchar *a, uint32 a_length, const uchar *b, uint32 b_length);
- int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L);
- int key_cmp(const uchar *,const uchar*);
- int key_cmp(const uchar *str, uint length);
- uint32 key_length() const { return 0; }
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const
- { return (uint32) (packlength+table->s->blob_ptr_size); }
- uint32 pack_length_no_ptr() const
- { return (uint32) (packlength); }
- uint row_pack_length() { return pack_length_no_ptr(); }
- uint32 sort_length() const;
- virtual uint32 max_data_length() const
- {
- return (uint32) (((ulonglong) 1 << (packlength*8)) -1);
- }
- int reset(void) { bzero(ptr, packlength+sizeof(uchar*)); return 0; }
- void reset_fields() { bzero((uchar*) &value,sizeof(value)); }
- static
- void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number, In_C_you_should_use_my_bool_instead() low_byte_first);
- void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number)
- {
- store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
- }
- inline void store_length(uint32 number)
- {
- store_length(ptr, packlength, number);
- }
- uint32 get_packed_size(const uchar *ptr_arg, In_C_you_should_use_my_bool_instead() low_byte_first)
- {return packlength + get_length(ptr_arg, packlength, low_byte_first);}
- inline uint32 get_length(uint row_offset= 0)
- { return get_length(ptr+row_offset, this->packlength, table->s->db_low_byte_first); }
- uint32 get_length(const uchar *ptr, uint packlength, In_C_you_should_use_my_bool_instead() low_byte_first);
- uint32 get_length(const uchar *ptr_arg)
- { return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first); }
- void put_length(uchar *pos, uint32 length);
- inline void get_ptr(uchar **str)
- {
- memcpy(((uchar*) str),(ptr+packlength),(sizeof(uchar*)));
- }
- inline void get_ptr(uchar **str, uint row_offset)
- {
- memcpy(((uchar*) str),(ptr+packlength+row_offset),(sizeof(char*)));
- }
- inline void set_ptr(uchar *length, uchar *data)
- {
- memcpy(ptr,length,packlength);
- memcpy((ptr+packlength),(&data),(sizeof(char*)));
- }
- void set_ptr_offset(my_ptrdiff_t ptr_diff, uint32 length, uchar *data)
- {
- uchar *ptr_ofs= (uchar*) ((uchar*) (ptr)+ptr_diff);
- store_length(ptr_ofs, packlength, length);
- memcpy((ptr_ofs+packlength),(&data),(sizeof(char*)));
- }
- inline void set_ptr(uint32 length, uchar *data)
- {
- set_ptr_offset(0, length, data);
- }
- uint get_key_image(uchar *buff,uint length, imagetype type);
- void set_key_image(const uchar *buff,uint length);
- void sql_type(String &str) const;
- inline In_C_you_should_use_my_bool_instead() copy()
- {
- uchar *tmp;
- get_ptr(&tmp);
- if (value.copy((char*) tmp, get_length(), charset()))
- {
- Field_blob::reset();
- return 1;
- }
- tmp=(uchar*) value.ptr();
- memcpy((ptr+packlength),(&tmp),(sizeof(char*)));
- return 0;
- }
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- uchar *pack_key(uchar *to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- uchar *pack_key_from_key_image(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- virtual const uchar *unpack(uchar *to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first);
- const uchar *unpack_key(uchar* to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- int pack_cmp(const uchar *a, const uchar *b, uint key_length,
- my_bool insert_or_update);
- int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update);
- uint packed_col_length(const uchar *col_ptr, uint length);
- uint max_packed_col_length(uint max_length);
- void free() { value.free(); }
- inline void clear_temporary() { bzero((uchar*) &value,sizeof(value)); }
- friend int field_conv(Field *to,Field *from);
- uint size_of() const { return sizeof(*this); }
- In_C_you_should_use_my_bool_instead() has_charset(void) const
- { return charset() == &my_charset_bin ? (0) : (1); }
- uint32 max_display_length();
- uint is_equal(Create_field *new_field);
- inline In_C_you_should_use_my_bool_instead() in_read_set() { return bitmap_is_set(table->read_set, field_index); }
- inline In_C_you_should_use_my_bool_instead() in_write_set() { return bitmap_is_set(table->write_set, field_index); }
-private:
- int do_save_field_metadata(uchar *first_byte);
-};
-class Field_geom :public Field_blob {
-public:
- enum geometry_type geom_type;
- Field_geom(uchar *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- TABLE_SHARE *share, uint blob_pack_length,
- enum geometry_type geom_type_arg)
- :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
- field_name_arg, share, blob_pack_length, &my_charset_bin)
- { geom_type= geom_type_arg; }
- Field_geom(uint32 len_arg,In_C_you_should_use_my_bool_instead() maybe_null_arg, const char *field_name_arg,
- TABLE_SHARE *share, enum geometry_type geom_type_arg)
- :Field_blob(len_arg, maybe_null_arg, field_name_arg, &my_charset_bin)
- { geom_type= geom_type_arg; }
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
- enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; }
- void sql_type(String &str) const;
- int store(const char *to, uint length, CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int store_decimal(const my_decimal *);
- uint size_of() const { return sizeof(*this); }
- int reset(void) { return !maybe_null() || Field_blob::reset(); }
- geometry_type get_geometry_type() { return geom_type; };
-};
-class Field_enum :public Field_str {
-protected:
- uint packlength;
-public:
- TYPELIB *typelib;
- Field_enum(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- uint packlength_arg,
- TYPELIB *typelib_arg,
- CHARSET_INFO *charset_arg)
- :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, charset_arg),
- packlength(packlength_arg),typelib(typelib_arg)
- {
- flags|=256;
- }
- Field *new_field(MEM_ROOT *root, struct st_table *new_table, In_C_you_should_use_my_bool_instead() keep_type);
- enum_field_types type() const { return MYSQL_TYPE_STRING; }
- enum Item_result cmp_type () const { return INT_RESULT; }
- enum Item_result cast_to_int_type () const { return INT_RESULT; }
- enum ha_base_keytype key_type() const;
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*,String *);
- int cmp(const uchar *,const uchar *);
- void sort_string(uchar *buff,uint length);
- uint32 pack_length() const { return (uint32) packlength; }
- void store_type(ulonglong value);
- void sql_type(String &str) const;
- uint size_of() const { return sizeof(*this); }
- enum_field_types real_type() const { return MYSQL_TYPE_ENUM; }
- uint pack_length_from_metadata(uint field_metadata)
- { return (field_metadata & 0x00ff); }
- uint row_pack_length() { return pack_length(); }
- virtual In_C_you_should_use_my_bool_instead() zero_pack() const { return 0; }
- In_C_you_should_use_my_bool_instead() optimize_range(uint idx, uint part) { return 0; }
- In_C_you_should_use_my_bool_instead() eq_def(Field *field);
- In_C_you_should_use_my_bool_instead() has_charset(void) const { return (1); }
- CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
-private:
- int do_save_field_metadata(uchar *first_byte);
-};
-class Field_set :public Field_enum {
-public:
- Field_set(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- uint32 packlength_arg,
- TYPELIB *typelib_arg, CHARSET_INFO *charset_arg)
- :Field_enum(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg,
- packlength_arg,
- typelib_arg,charset_arg)
- {
- flags=(flags & ~256) | 2048;
- }
- int store(const char *to,uint length,CHARSET_INFO *charset);
- int store(double nr) { return Field_set::store((longlong) nr, (0)); }
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- virtual In_C_you_should_use_my_bool_instead() zero_pack() const { return 1; }
- String *val_str(String*,String *);
- void sql_type(String &str) const;
- enum_field_types real_type() const { return MYSQL_TYPE_SET; }
- In_C_you_should_use_my_bool_instead() has_charset(void) const { return (1); }
-};
-class Field_bit :public Field {
-public:
- uchar *bit_ptr;
- uchar bit_ofs;
- uint bit_len;
- uint bytes_in_rec;
- Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
- enum utype unireg_check_arg, const char *field_name_arg);
- enum_field_types type() const { return MYSQL_TYPE_BIT; }
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
- uint32 key_length() const { return (uint32) (field_length + 7) / 8; }
- uint32 max_data_length() const { return (field_length + 7) / 8; }
- uint32 max_display_length() { return field_length; }
- uint size_of() const { return sizeof(*this); }
- Item_result result_type () const { return INT_RESULT; }
- int reset(void) { bzero(ptr, bytes_in_rec); return 0; }
- int store(const char *to, uint length, CHARSET_INFO *charset);
- int store(double nr);
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val);
- int store_decimal(const my_decimal *);
- double val_real(void);
- longlong val_int(void);
- String *val_str(String*, String *);
- virtual In_C_you_should_use_my_bool_instead() str_needs_quotes() { return (1); }
- my_decimal *val_decimal(my_decimal *);
- int cmp(const uchar *a, const uchar *b)
- {
- assert(ptr == a);
- return Field_bit::key_cmp(b, bytes_in_rec+((bit_len) ? 1 : 0));
- }
- int cmp_binary_offset(uint row_offset)
- { return cmp_offset(row_offset); }
- int cmp_max(const uchar *a, const uchar *b, uint max_length);
- int key_cmp(const uchar *a, const uchar *b)
- { return cmp_binary((uchar *) a, (uchar *) b); }
- int key_cmp(const uchar *str, uint length);
- int cmp_offset(uint row_offset);
- void get_image(uchar *buff, uint length, CHARSET_INFO *cs)
- { get_key_image(buff, length, itRAW); }
- void set_image(const uchar *buff,uint length, CHARSET_INFO *cs)
- { Field_bit::store((char *) buff, length, cs); }
- uint get_key_image(uchar *buff, uint length, imagetype type);
- void set_key_image(const uchar *buff, uint length)
- { Field_bit::store((char*) buff, length, &my_charset_bin); }
- void sort_string(uchar *buff, uint length)
- { get_key_image(buff, length, itRAW); }
- uint32 pack_length() const { return (uint32) (field_length + 7) / 8; }
- uint32 pack_length_in_rec() const { return bytes_in_rec; }
- uint pack_length_from_metadata(uint field_metadata);
- uint row_pack_length()
- { return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); }
- int compatible_field_size(uint field_metadata);
- void sql_type(String &str) const;
- virtual uchar *pack(uchar *to, const uchar *from,
- uint max_length, In_C_you_should_use_my_bool_instead() low_byte_first);
- virtual const uchar *unpack(uchar *to, const uchar *from,
- uint param_data, In_C_you_should_use_my_bool_instead() low_byte_first);
- virtual void set_default();
- Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
- uchar *new_ptr, uchar *new_null_ptr,
- uint new_null_bit);
- void set_bit_ptr(uchar *bit_ptr_arg, uchar bit_ofs_arg)
- {
- bit_ptr= bit_ptr_arg;
- bit_ofs= bit_ofs_arg;
- }
- In_C_you_should_use_my_bool_instead() eq(Field *field)
- {
- return (Field::eq(field) &&
- field->type() == type() &&
- bit_ptr == ((Field_bit *)field)->bit_ptr &&
- bit_ofs == ((Field_bit *)field)->bit_ofs);
- }
- uint is_equal(Create_field *new_field);
- void move_field_offset(my_ptrdiff_t ptr_diff)
- {
- Field::move_field_offset(ptr_diff);
- bit_ptr= (uchar*) ((uchar*) (bit_ptr)+ptr_diff);
- }
- void hash(ulong *nr, ulong *nr2);
-private:
- virtual size_t do_last_null_byte() const;
- int do_save_field_metadata(uchar *first_byte);
-};
-class Field_bit_as_char: public Field_bit {
-public:
- Field_bit_as_char(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg);
- enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
- uint size_of() const { return sizeof(*this); }
- int store(const char *to, uint length, CHARSET_INFO *charset);
- int store(double nr) { return Field_bit::store(nr); }
- int store(longlong nr, In_C_you_should_use_my_bool_instead() unsigned_val)
- { return Field_bit::store(nr, unsigned_val); }
- void sql_type(String &str) const;
-};
-class Create_field :public Sql_alloc
-{
-public:
- const char *field_name;
- const char *change;
- const char *after;
- LEX_STRING comment;
- Item *def;
- enum enum_field_types sql_type;
- ulong length;
- uint32 char_length;
- uint decimals, flags, pack_length, key_length;
- Field::utype unireg_check;
- TYPELIB *interval;
- TYPELIB *save_interval;
- List<String> interval_list;
- CHARSET_INFO *charset;
- Field::geometry_type geom_type;
- Field *field;
- uint8 row,col,sc_length,interval_id;
- uint offset,pack_flag;
- Create_field() :after(0) {}
- Create_field(Field *field, Field *orig_field);
- Create_field *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Create_field(*this); }
- void create_length_to_internal_length(void);
- void init_for_tmp_table(enum_field_types sql_type_arg,
- uint32 max_length, uint32 decimals,
- In_C_you_should_use_my_bool_instead() maybe_null, In_C_you_should_use_my_bool_instead() is_unsigned);
- In_C_you_should_use_my_bool_instead() init(THD *thd, char *field_name, enum_field_types type, char *length,
- char *decimals, uint type_modifier, Item *default_value,
- Item *on_update_value, LEX_STRING *comment, char *change,
- List<String> *interval_list, CHARSET_INFO *cs,
- uint uint_geom_type);
-};
-class Send_field {
- public:
- const char *db_name;
- const char *table_name,*org_table_name;
- const char *col_name,*org_col_name;
- ulong length;
- uint charsetnr, flags, decimals;
- enum_field_types type;
- Send_field() {}
-};
-class Copy_field :public Sql_alloc {
- typedef void Copy_func(Copy_field*);
- Copy_func *get_copy_func(Field *to, Field *from);
-public:
- uchar *from_ptr,*to_ptr;
- uchar *from_null_ptr,*to_null_ptr;
- my_bool *null_row;
- uint from_bit,to_bit;
- uint from_length,to_length;
- Field *from_field,*to_field;
- String tmp;
- Copy_field() {}
- ~Copy_field() {}
- void set(Field *to,Field *from,In_C_you_should_use_my_bool_instead() save);
- void set(uchar *to,Field *from);
- void (*do_copy)(Copy_field *);
- void (*do_copy2)(Copy_field *);
-};
-Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length,
- uchar *null_pos, uchar null_bit,
- uint pack_flag, enum_field_types field_type,
- CHARSET_INFO *cs,
- Field::geometry_type geom_type,
- Field::utype unireg_check,
- TYPELIB *interval, const char *field_name);
-uint pack_length_to_packflag(uint type);
-enum_field_types get_blob_type_from_length(ulong length);
-uint32 calc_pack_length(enum_field_types type,uint32 length);
-int set_field_to_null(Field *field);
-int set_field_to_null_with_conversions(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
-#include "protocol.h"
-class i_string;
-class THD;
-typedef struct st_mysql_field MYSQL_FIELD;
-typedef struct st_mysql_rows MYSQL_ROWS;
-class Protocol
-{
-protected:
- THD *thd;
- String *packet;
- String *convert;
- uint field_pos;
- enum enum_field_types *field_types;
- uint field_count;
- In_C_you_should_use_my_bool_instead() net_store_data(const uchar *from, size_t length);
- In_C_you_should_use_my_bool_instead() store_string_aux(const char *from, size_t length,
- CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
-public:
- Protocol() {}
- Protocol(THD *thd_arg) { init(thd_arg); }
- virtual ~Protocol() {}
- void init(THD* thd_arg);
- enum { SEND_NUM_ROWS= 1, SEND_DEFAULTS= 2, SEND_EOF= 4 };
- virtual In_C_you_should_use_my_bool_instead() send_fields(List<Item> *list, uint flags);
- In_C_you_should_use_my_bool_instead() store(I_List<i_string> *str_list);
- In_C_you_should_use_my_bool_instead() store(const char *from, CHARSET_INFO *cs);
- String *storage_packet() { return packet; }
- inline void free() { packet->free(); }
- virtual In_C_you_should_use_my_bool_instead() write();
- inline In_C_you_should_use_my_bool_instead() store(int from)
- { return store_long((longlong) from); }
- inline In_C_you_should_use_my_bool_instead() store(uint32 from)
- { return store_long((longlong) from); }
- inline In_C_you_should_use_my_bool_instead() store(longlong from)
- { return store_longlong((longlong) from, 0); }
- inline In_C_you_should_use_my_bool_instead() store(ulonglong from)
- { return store_longlong((longlong) from, 1); }
- inline In_C_you_should_use_my_bool_instead() store(String *str)
- { return store((char*) str->ptr(), str->length(), str->charset()); }
- virtual In_C_you_should_use_my_bool_instead() prepare_for_send(List<Item> *item_list)
- {
- field_count=item_list->elements;
- return 0;
- }
- virtual In_C_you_should_use_my_bool_instead() flush();
- virtual void end_partial_result_set(THD *thd);
- virtual void prepare_for_resend()=0;
- virtual In_C_you_should_use_my_bool_instead() store_null()=0;
- virtual In_C_you_should_use_my_bool_instead() store_tiny(longlong from)=0;
- virtual In_C_you_should_use_my_bool_instead() store_short(longlong from)=0;
- virtual In_C_you_should_use_my_bool_instead() store_long(longlong from)=0;
- virtual In_C_you_should_use_my_bool_instead() store_longlong(longlong from, In_C_you_should_use_my_bool_instead() unsigned_flag)=0;
- virtual In_C_you_should_use_my_bool_instead() store_decimal(const my_decimal *)=0;
- virtual In_C_you_should_use_my_bool_instead() store(const char *from, size_t length, CHARSET_INFO *cs)=0;
- virtual In_C_you_should_use_my_bool_instead() store(const char *from, size_t length,
- CHARSET_INFO *fromcs, CHARSET_INFO *tocs)=0;
- virtual In_C_you_should_use_my_bool_instead() store(float from, uint32 decimals, String *buffer)=0;
- virtual In_C_you_should_use_my_bool_instead() store(double from, uint32 decimals, String *buffer)=0;
- virtual In_C_you_should_use_my_bool_instead() store(MYSQL_TIME *time)=0;
- virtual In_C_you_should_use_my_bool_instead() store_date(MYSQL_TIME *time)=0;
- virtual In_C_you_should_use_my_bool_instead() store_time(MYSQL_TIME *time)=0;
- virtual In_C_you_should_use_my_bool_instead() store(Field *field)=0;
- void remove_last_row() {}
- enum enum_protocol_type
- {
- PROTOCOL_TEXT= 0, PROTOCOL_BINARY= 1
- };
- virtual enum enum_protocol_type type()= 0;
-};
-class Protocol_text :public Protocol
-{
-public:
- Protocol_text() {}
- Protocol_text(THD *thd_arg) :Protocol(thd_arg) {}
- virtual void prepare_for_resend();
- virtual In_C_you_should_use_my_bool_instead() store_null();
- virtual In_C_you_should_use_my_bool_instead() store_tiny(longlong from);
- virtual In_C_you_should_use_my_bool_instead() store_short(longlong from);
- virtual In_C_you_should_use_my_bool_instead() store_long(longlong from);
- virtual In_C_you_should_use_my_bool_instead() store_longlong(longlong from, In_C_you_should_use_my_bool_instead() unsigned_flag);
- virtual In_C_you_should_use_my_bool_instead() store_decimal(const my_decimal *);
- virtual In_C_you_should_use_my_bool_instead() store(const char *from, size_t length, CHARSET_INFO *cs);
- virtual In_C_you_should_use_my_bool_instead() store(const char *from, size_t length,
- CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
- virtual In_C_you_should_use_my_bool_instead() store(MYSQL_TIME *time);
- virtual In_C_you_should_use_my_bool_instead() store_date(MYSQL_TIME *time);
- virtual In_C_you_should_use_my_bool_instead() store_time(MYSQL_TIME *time);
- virtual In_C_you_should_use_my_bool_instead() store(float nr, uint32 decimals, String *buffer);
- virtual In_C_you_should_use_my_bool_instead() store(double from, uint32 decimals, String *buffer);
- virtual In_C_you_should_use_my_bool_instead() store(Field *field);
- virtual enum enum_protocol_type type() { return PROTOCOL_TEXT; };
-};
-class Protocol_binary :public Protocol
-{
-private:
- uint bit_fields;
-public:
- Protocol_binary() {}
- Protocol_binary(THD *thd_arg) :Protocol(thd_arg) {}
- virtual In_C_you_should_use_my_bool_instead() prepare_for_send(List<Item> *item_list);
- virtual void prepare_for_resend();
- virtual In_C_you_should_use_my_bool_instead() store_null();
- virtual In_C_you_should_use_my_bool_instead() store_tiny(longlong from);
- virtual In_C_you_should_use_my_bool_instead() store_short(longlong from);
- virtual In_C_you_should_use_my_bool_instead() store_long(longlong from);
- virtual In_C_you_should_use_my_bool_instead() store_longlong(longlong from, In_C_you_should_use_my_bool_instead() unsigned_flag);
- virtual In_C_you_should_use_my_bool_instead() store_decimal(const my_decimal *);
- virtual In_C_you_should_use_my_bool_instead() store(const char *from, size_t length, CHARSET_INFO *cs);
- virtual In_C_you_should_use_my_bool_instead() store(const char *from, size_t length,
- CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
- virtual In_C_you_should_use_my_bool_instead() store(MYSQL_TIME *time);
- virtual In_C_you_should_use_my_bool_instead() store_date(MYSQL_TIME *time);
- virtual In_C_you_should_use_my_bool_instead() store_time(MYSQL_TIME *time);
- virtual In_C_you_should_use_my_bool_instead() store(float nr, uint32 decimals, String *buffer);
- virtual In_C_you_should_use_my_bool_instead() store(double from, uint32 decimals, String *buffer);
- virtual In_C_you_should_use_my_bool_instead() store(Field *field);
- virtual enum enum_protocol_type type() { return PROTOCOL_BINARY; };
-};
-void send_warning(THD *thd, uint sql_errno, const char *err=0);
-void net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
-void net_end_statement(THD *thd);
-In_C_you_should_use_my_bool_instead() send_old_password_request(THD *thd);
-uchar *net_store_data(uchar *to,const uchar *from, size_t length);
-uchar *net_store_data(uchar *to,int32 from);
-uchar *net_store_data(uchar *to,longlong from);
-#include "sql_udf.h"
-enum Item_udftype {UDFTYPE_FUNCTION=1,UDFTYPE_AGGREGATE};
-typedef void (*Udf_func_clear)(UDF_INIT *, uchar *, uchar *);
-typedef void (*Udf_func_add)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *);
-typedef void (*Udf_func_deinit)(UDF_INIT*);
-typedef my_bool (*Udf_func_init)(UDF_INIT *, UDF_ARGS *, char *);
-typedef void (*Udf_func_any)();
-typedef double (*Udf_func_double)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *);
-typedef longlong (*Udf_func_longlong)(UDF_INIT *, UDF_ARGS *, uchar *,
- uchar *);
-typedef struct st_udf_func
-{
- LEX_STRING name;
- Item_result returns;
- Item_udftype type;
- char *dl;
- void *dlhandle;
- Udf_func_any func;
- Udf_func_init func_init;
- Udf_func_deinit func_deinit;
- Udf_func_clear func_clear;
- Udf_func_add func_add;
- ulong usage_count;
-} udf_func;
-class Item_result_field;
-class udf_handler :public Sql_alloc
-{
- protected:
- udf_func *u_d;
- String *buffers;
- UDF_ARGS f_args;
- UDF_INIT initid;
- char *num_buffer;
- uchar error, is_null;
- In_C_you_should_use_my_bool_instead() initialized;
- Item **args;
- public:
- table_map used_tables_cache;
- In_C_you_should_use_my_bool_instead() const_item_cache;
- In_C_you_should_use_my_bool_instead() not_original;
- udf_handler(udf_func *udf_arg) :u_d(udf_arg), buffers(0), error(0),
- is_null(0), initialized(0), not_original(0)
- {}
- ~udf_handler();
- const char *name() const { return u_d ? u_d->name.str : "?"; }
- Item_result result_type () const
- { return u_d ? u_d->returns : STRING_RESULT;}
- In_C_you_should_use_my_bool_instead() get_arguments();
- In_C_you_should_use_my_bool_instead() fix_fields(THD *thd, Item_result_field *item,
- uint arg_count, Item **args);
- void cleanup();
- double val(my_bool *null_value)
- {
- is_null= 0;
- if (get_arguments())
- {
- *null_value=1;
- return 0.0;
- }
- Udf_func_double func= (Udf_func_double) u_d->func;
- double tmp=func(&initid, &f_args, &is_null, &error);
- if (is_null || error)
- {
- *null_value=1;
- return 0.0;
- }
- *null_value=0;
- return tmp;
- }
- longlong val_int(my_bool *null_value)
- {
- is_null= 0;
- if (get_arguments())
- {
- *null_value=1;
- return 0LL;
- }
- Udf_func_longlong func= (Udf_func_longlong) u_d->func;
- longlong tmp=func(&initid, &f_args, &is_null, &error);
- if (is_null || error)
- {
- *null_value=1;
- return 0LL;
- }
- *null_value=0;
- return tmp;
- }
- my_decimal *val_decimal(my_bool *null_value, my_decimal *dec_buf);
- void clear()
- {
- is_null= 0;
- Udf_func_clear func= u_d->func_clear;
- func(&initid, &is_null, &error);
- }
- void add(my_bool *null_value)
- {
- if (get_arguments())
- {
- *null_value=1;
- return;
- }
- Udf_func_add func= u_d->func_add;
- func(&initid, &f_args, &is_null, &error);
- *null_value= (my_bool) (is_null || error);
- }
- String *val_str(String *str,String *save_str);
-};
-void udf_init(void),udf_free(void);
-udf_func *find_udf(const char *name, uint len=0,In_C_you_should_use_my_bool_instead() mark_used=0);
-void free_udf(udf_func *udf);
-int mysql_create_function(THD *thd,udf_func *udf);
-int mysql_drop_function(THD *thd,const LEX_STRING *name);
-#include "sql_profile.h"
-extern ST_FIELD_INFO query_profile_statistics_info[];
-int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
-int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table);
-#include "sql_partition.h"
-#pragma interface
-typedef struct {
- longlong list_value;
- uint32 partition_id;
-} LIST_PART_ENTRY;
-typedef struct {
- uint32 start_part;
- uint32 end_part;
-} part_id_range;
-struct st_partition_iter;
-In_C_you_should_use_my_bool_instead() is_partition_in_list(char *part_name, List<char> list_part_names);
-char *are_partitions_in_table(partition_info *new_part_info,
- partition_info *old_part_info);
-In_C_you_should_use_my_bool_instead() check_reorganise_list(partition_info *new_part_info,
- partition_info *old_part_info,
- List<char> list_part_names);
-handler *get_ha_partition(partition_info *part_info);
-int get_parts_for_update(const uchar *old_data, uchar *new_data,
- const uchar *rec0, partition_info *part_info,
- uint32 *old_part_id, uint32 *new_part_id,
- longlong *func_value);
-int get_part_for_delete(const uchar *buf, const uchar *rec0,
- partition_info *part_info, uint32 *part_id);
-void prune_partition_set(const TABLE *table, part_id_range *part_spec);
-In_C_you_should_use_my_bool_instead() check_partition_info(partition_info *part_info,handlerton **eng_type,
- TABLE *table, handler *file, HA_CREATE_INFO *info);
-void set_linear_hash_mask(partition_info *part_info, uint no_parts);
-In_C_you_should_use_my_bool_instead() fix_partition_func(THD *thd, TABLE *table, In_C_you_should_use_my_bool_instead() create_table_ind);
-char *generate_partition_syntax(partition_info *part_info,
- uint *buf_length, In_C_you_should_use_my_bool_instead() use_sql_alloc,
- In_C_you_should_use_my_bool_instead() show_partition_options);
-In_C_you_should_use_my_bool_instead() partition_key_modified(TABLE *table, const MY_BITMAP *fields);
-void get_partition_set(const TABLE *table, uchar *buf, const uint index,
- const key_range *key_spec,
- part_id_range *part_spec);
-void get_full_part_id_from_key(const TABLE *table, uchar *buf,
- KEY *key_info,
- const key_range *key_spec,
- part_id_range *part_spec);
-In_C_you_should_use_my_bool_instead() mysql_unpack_partition(THD *thd, const char *part_buf,
- uint part_info_len,
- const char *part_state, uint part_state_len,
- TABLE *table, In_C_you_should_use_my_bool_instead() is_create_table_ind,
- handlerton *default_db_type,
- In_C_you_should_use_my_bool_instead() *work_part_info_used);
-void make_used_partitions_str(partition_info *part_info, String *parts_str);
-uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
- In_C_you_should_use_my_bool_instead() left_endpoint,
- In_C_you_should_use_my_bool_instead() include_endpoint);
-uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
- In_C_you_should_use_my_bool_instead() left_endpoint,
- In_C_you_should_use_my_bool_instead() include_endpoint);
-In_C_you_should_use_my_bool_instead() fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
- In_C_you_should_use_my_bool_instead() is_sub_part, In_C_you_should_use_my_bool_instead() is_field_to_be_setup);
-In_C_you_should_use_my_bool_instead() check_part_func_fields(Field **ptr, In_C_you_should_use_my_bool_instead() ok_with_charsets);
-In_C_you_should_use_my_bool_instead() field_is_partition_charset(Field *field);
-typedef uint32 (*partition_iter_func)(st_partition_iter* part_iter);
-typedef struct st_partition_iter
-{
- partition_iter_func get_next;
- In_C_you_should_use_my_bool_instead() ret_null_part, ret_null_part_orig;
- struct st_part_num_range
- {
- uint32 start;
- uint32 cur;
- uint32 end;
- };
- struct st_field_value_range
- {
- longlong start;
- longlong cur;
- longlong end;
- };
- union
- {
- struct st_part_num_range part_nums;
- struct st_field_value_range field_vals;
- };
- partition_info *part_info;
-} PARTITION_ITERATOR;
-typedef int (*get_partitions_in_range_iter)(partition_info *part_info,
- In_C_you_should_use_my_bool_instead() is_subpart,
- uchar *min_val, uchar *max_val,
- uint flags,
- PARTITION_ITERATOR *part_iter);
-#include "partition_info.h"
-#include "partition_element.h"
-enum partition_type {
- NOT_A_PARTITION= 0,
- RANGE_PARTITION,
- HASH_PARTITION,
- LIST_PARTITION
-};
-enum partition_state {
- PART_NORMAL= 0,
- PART_IS_DROPPED= 1,
- PART_TO_BE_DROPPED= 2,
- PART_TO_BE_ADDED= 3,
- PART_TO_BE_REORGED= 4,
- PART_REORGED_DROPPED= 5,
- PART_CHANGED= 6,
- PART_IS_CHANGED= 7,
- PART_IS_ADDED= 8
-};
-typedef struct p_elem_val
-{
- longlong value;
- In_C_you_should_use_my_bool_instead() null_value;
- In_C_you_should_use_my_bool_instead() unsigned_flag;
-} part_elem_value;
-struct st_ddl_log_memory_entry;
-class partition_element :public Sql_alloc {
-public:
- List<partition_element> subpartitions;
- List<part_elem_value> list_val_list;
- ha_rows part_max_rows;
- ha_rows part_min_rows;
- longlong range_value;
- char *partition_name;
- char *tablespace_name;
- struct st_ddl_log_memory_entry *log_entry;
- char* part_comment;
- char* data_file_name;
- char* index_file_name;
- handlerton *engine_type;
- enum partition_state part_state;
- uint16 nodegroup_id;
- In_C_you_should_use_my_bool_instead() has_null_value;
- In_C_you_should_use_my_bool_instead() signed_flag;
- In_C_you_should_use_my_bool_instead() max_value;
- partition_element()
- : part_max_rows(0), part_min_rows(0), range_value(0),
- partition_name(NULL), tablespace_name(NULL),
- log_entry(NULL), part_comment(NULL),
- data_file_name(NULL), index_file_name(NULL),
- engine_type(NULL), part_state(PART_NORMAL),
- nodegroup_id(65535), has_null_value((0)),
- signed_flag((0)), max_value((0))
- {
- }
- partition_element(partition_element *part_elem)
- : part_max_rows(part_elem->part_max_rows),
- part_min_rows(part_elem->part_min_rows),
- range_value(0), partition_name(NULL),
- tablespace_name(part_elem->tablespace_name),
- part_comment(part_elem->part_comment),
- data_file_name(part_elem->data_file_name),
- index_file_name(part_elem->index_file_name),
- engine_type(part_elem->engine_type),
- part_state(part_elem->part_state),
- nodegroup_id(part_elem->nodegroup_id),
- has_null_value((0))
- {
- }
- ~partition_element() {}
-};
-class partition_info;
-typedef int (*get_part_id_func)(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
-typedef uint32 (*get_subpart_id_func)(partition_info *part_info);
-struct st_ddl_log_memory_entry;
-class partition_info : public Sql_alloc
-{
-public:
- List<partition_element> partitions;
- List<partition_element> temp_partitions;
- List<char> part_field_list;
- List<char> subpart_field_list;
- get_part_id_func get_partition_id;
- get_part_id_func get_part_partition_id;
- get_subpart_id_func get_subpartition_id;
- get_part_id_func get_partition_id_charset;
- get_part_id_func get_part_partition_id_charset;
- get_subpart_id_func get_subpartition_id_charset;
- Field **part_field_array;
- Field **subpart_field_array;
- Field **part_charset_field_array;
- Field **subpart_charset_field_array;
- Field **full_part_field_array;
- Field **full_part_charset_field_array;
- MY_BITMAP full_part_field_set;
- uchar **part_field_buffers;
- uchar **subpart_field_buffers;
- uchar **full_part_field_buffers;
- uchar **restore_part_field_ptrs;
- uchar **restore_subpart_field_ptrs;
- uchar **restore_full_part_field_ptrs;
- Item *part_expr;
- Item *subpart_expr;
- Item *item_free_list;
- struct st_ddl_log_memory_entry *first_log_entry;
- struct st_ddl_log_memory_entry *exec_log_entry;
- struct st_ddl_log_memory_entry *frm_log_entry;
- MY_BITMAP used_partitions;
- union {
- longlong *range_int_array;
- LIST_PART_ENTRY *list_array;
- };
- get_partitions_in_range_iter get_part_iter_for_interval;
- get_partitions_in_range_iter get_subpart_iter_for_interval;
- longlong err_value;
- char* part_info_string;
- char *part_func_string;
- char *subpart_func_string;
- const char *part_state;
- partition_element *curr_part_elem;
- partition_element *current_partition;
- key_map all_fields_in_PF, all_fields_in_PPF, all_fields_in_SPF;
- key_map some_fields_in_PF;
- handlerton *default_engine_type;
- Item_result part_result_type;
- partition_type part_type;
- partition_type subpart_type;
- uint part_info_len;
- uint part_state_len;
- uint part_func_len;
- uint subpart_func_len;
- uint no_parts;
- uint no_subparts;
- uint count_curr_subparts;
- uint part_error_code;
- uint no_list_values;
- uint no_part_fields;
- uint no_subpart_fields;
- uint no_full_part_fields;
- uint has_null_part_id;
- uint16 linear_hash_mask;
- In_C_you_should_use_my_bool_instead() use_default_partitions;
- In_C_you_should_use_my_bool_instead() use_default_no_partitions;
- In_C_you_should_use_my_bool_instead() use_default_subpartitions;
- In_C_you_should_use_my_bool_instead() use_default_no_subpartitions;
- In_C_you_should_use_my_bool_instead() default_partitions_setup;
- In_C_you_should_use_my_bool_instead() defined_max_value;
- In_C_you_should_use_my_bool_instead() list_of_part_fields;
- In_C_you_should_use_my_bool_instead() list_of_subpart_fields;
- In_C_you_should_use_my_bool_instead() linear_hash_ind;
- In_C_you_should_use_my_bool_instead() fixed;
- In_C_you_should_use_my_bool_instead() is_auto_partitioned;
- In_C_you_should_use_my_bool_instead() from_openfrm;
- In_C_you_should_use_my_bool_instead() has_null_value;
- partition_info()
- : get_partition_id(NULL), get_part_partition_id(NULL),
- get_subpartition_id(NULL),
- part_field_array(NULL), subpart_field_array(NULL),
- part_charset_field_array(NULL),
- subpart_charset_field_array(NULL),
- full_part_field_array(NULL),
- full_part_charset_field_array(NULL),
- part_field_buffers(NULL), subpart_field_buffers(NULL),
- full_part_field_buffers(NULL),
- restore_part_field_ptrs(NULL), restore_subpart_field_ptrs(NULL),
- restore_full_part_field_ptrs(NULL),
- part_expr(NULL), subpart_expr(NULL), item_free_list(NULL),
- first_log_entry(NULL), exec_log_entry(NULL), frm_log_entry(NULL),
- list_array(NULL), err_value(0),
- part_info_string(NULL),
- part_func_string(NULL), subpart_func_string(NULL),
- part_state(NULL),
- curr_part_elem(NULL), current_partition(NULL),
- default_engine_type(NULL),
- part_result_type(INT_RESULT),
- part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION),
- part_info_len(0), part_state_len(0),
- part_func_len(0), subpart_func_len(0),
- no_parts(0), no_subparts(0),
- count_curr_subparts(0), part_error_code(0),
- no_list_values(0), no_part_fields(0), no_subpart_fields(0),
- no_full_part_fields(0), has_null_part_id(0), linear_hash_mask(0),
- use_default_partitions((1)), use_default_no_partitions((1)),
- use_default_subpartitions((1)), use_default_no_subpartitions((1)),
- default_partitions_setup((0)), defined_max_value((0)),
- list_of_part_fields((0)), list_of_subpart_fields((0)),
- linear_hash_ind((0)), fixed((0)),
- is_auto_partitioned((0)), from_openfrm((0)),
- has_null_value((0))
- {
- all_fields_in_PF.clear_all();
- all_fields_in_PPF.clear_all();
- all_fields_in_SPF.clear_all();
- some_fields_in_PF.clear_all();
- partitions.empty();
- temp_partitions.empty();
- part_field_list.empty();
- subpart_field_list.empty();
- }
- ~partition_info() {}
- partition_info *get_clone();
- In_C_you_should_use_my_bool_instead() is_sub_partitioned()
- {
- return (subpart_type == NOT_A_PARTITION ? (0) : (1));
- }
- uint get_tot_partitions()
- {
- return no_parts * (is_sub_partitioned() ? no_subparts : 1);
- }
- In_C_you_should_use_my_bool_instead() set_up_defaults_for_partitioning(handler *file, HA_CREATE_INFO *info,
- uint start_no);
- char *has_unique_names();
- In_C_you_should_use_my_bool_instead() check_engine_mix(handlerton *engine_type, In_C_you_should_use_my_bool_instead() default_engine);
- In_C_you_should_use_my_bool_instead() check_range_constants();
- In_C_you_should_use_my_bool_instead() check_list_constants();
- In_C_you_should_use_my_bool_instead() check_partition_info(THD *thd, handlerton **eng_type,
- handler *file, HA_CREATE_INFO *info,
- In_C_you_should_use_my_bool_instead() check_partition_function);
- void print_no_partition_found(TABLE *table);
- In_C_you_should_use_my_bool_instead() set_up_charset_field_preps();
-private:
- static int list_part_cmp(const void* a, const void* b);
- static int list_part_cmp_unsigned(const void* a, const void* b);
- In_C_you_should_use_my_bool_instead() set_up_default_partitions(handler *file, HA_CREATE_INFO *info,
- uint start_no);
- In_C_you_should_use_my_bool_instead() set_up_default_subpartitions(handler *file, HA_CREATE_INFO *info);
- char *create_default_partition_names(uint part_no, uint no_parts,
- uint start_no);
- char *create_subpartition_name(uint subpart_no, const char *part_name);
- In_C_you_should_use_my_bool_instead() has_unique_name(partition_element *element);
-};
-uint32 get_next_partition_id_range(struct st_partition_iter* part_iter);
-In_C_you_should_use_my_bool_instead() check_partition_dirs(partition_info *part_info);
-static inline void init_single_partition_iterator(uint32 part_id,
- PARTITION_ITERATOR *part_iter)
-{
- part_iter->part_nums.start= part_iter->part_nums.cur= part_id;
- part_iter->part_nums.end= part_id+1;
- part_iter->get_next= get_next_partition_id_range;
-}
-static inline
-void init_all_partitions_iterator(partition_info *part_info,
- PARTITION_ITERATOR *part_iter)
-{
- part_iter->part_nums.start= part_iter->part_nums.cur= 0;
- part_iter->part_nums.end= part_info->no_parts;
- part_iter->get_next= get_next_partition_id_range;
-}
-class user_var_entry;
-class Security_context;
-enum enum_var_type
-{
- OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL
-};
-class sys_var;
-#include "item.h"
-class Protocol;
-struct TABLE_LIST;
-void item_init(void);
-class Item_field;
-class DTCollation {
-public:
- CHARSET_INFO *collation;
- enum Derivation derivation;
- uint repertoire;
- void set_repertoire_from_charset(CHARSET_INFO *cs)
- {
- repertoire= cs->state & 4096 ?
- 1 : 3;
- }
- DTCollation()
- {
- collation= &my_charset_bin;
- derivation= DERIVATION_NONE;
- repertoire= 3;
- }
- DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg)
- {
- collation= collation_arg;
- derivation= derivation_arg;
- set_repertoire_from_charset(collation_arg);
- }
- void set(DTCollation &dt)
- {
- collation= dt.collation;
- derivation= dt.derivation;
- repertoire= dt.repertoire;
- }
- void set(CHARSET_INFO *collation_arg, Derivation derivation_arg)
- {
- collation= collation_arg;
- derivation= derivation_arg;
- set_repertoire_from_charset(collation_arg);
- }
- void set(CHARSET_INFO *collation_arg,
- Derivation derivation_arg,
- uint repertoire_arg)
- {
- collation= collation_arg;
- derivation= derivation_arg;
- repertoire= repertoire_arg;
- }
- void set(CHARSET_INFO *collation_arg)
- {
- collation= collation_arg;
- set_repertoire_from_charset(collation_arg);
- }
- void set(Derivation derivation_arg)
- { derivation= derivation_arg; }
- In_C_you_should_use_my_bool_instead() aggregate(DTCollation &dt, uint flags= 0);
- In_C_you_should_use_my_bool_instead() set(DTCollation &dt1, DTCollation &dt2, uint flags= 0)
- { set(dt1); return aggregate(dt2, flags); }
- const char *derivation_name() const
- {
- switch(derivation)
- {
- case DERIVATION_IGNORABLE: return "IGNORABLE";
- case DERIVATION_COERCIBLE: return "COERCIBLE";
- case DERIVATION_IMPLICIT: return "IMPLICIT";
- case DERIVATION_SYSCONST: return "SYSCONST";
- case DERIVATION_EXPLICIT: return "EXPLICIT";
- case DERIVATION_NONE: return "NONE";
- default: return "UNKNOWN";
- }
- }
-};
-struct Hybrid_type_traits;
-struct Hybrid_type
-{
- longlong integer;
- double real;
- my_decimal dec_buf[3];
- int used_dec_buf_no;
- const Hybrid_type_traits *traits;
- Hybrid_type() {}
- Hybrid_type(const Hybrid_type &rhs) :traits(rhs.traits) {}
-};
-struct Hybrid_type_traits
-{
- virtual Item_result type() const { return REAL_RESULT; }
- virtual void
- fix_length_and_dec(Item *item, Item *arg) const;
- virtual void set_zero(Hybrid_type *val) const { val->real= 0.0; }
- virtual void add(Hybrid_type *val, Field *f) const
- { val->real+= f->val_real(); }
- virtual void div(Hybrid_type *val, ulonglong u) const
- { val->real/= ((double) (ulonglong) (u)); }
- virtual longlong val_int(Hybrid_type *val, In_C_you_should_use_my_bool_instead() unsigned_flag) const
- { return (longlong) rint(val->real); }
- virtual double val_real(Hybrid_type *val) const { return val->real; }
- virtual my_decimal *val_decimal(Hybrid_type *val, my_decimal *buf) const;
- virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const;
- static const Hybrid_type_traits *instance();
- Hybrid_type_traits() {}
- virtual ~Hybrid_type_traits() {}
-};
-struct Hybrid_type_traits_decimal: public Hybrid_type_traits
-{
- virtual Item_result type() const { return DECIMAL_RESULT; }
- virtual void
- fix_length_and_dec(Item *arg, Item *item) const;
- virtual void set_zero(Hybrid_type *val) const;
- virtual void add(Hybrid_type *val, Field *f) const;
- virtual void div(Hybrid_type *val, ulonglong u) const;
- virtual longlong val_int(Hybrid_type *val, In_C_you_should_use_my_bool_instead() unsigned_flag) const;
- virtual double val_real(Hybrid_type *val) const;
- virtual my_decimal *val_decimal(Hybrid_type *val, my_decimal *buf) const
- { return &val->dec_buf[val->used_dec_buf_no]; }
- virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const;
- static const Hybrid_type_traits_decimal *instance();
- Hybrid_type_traits_decimal() {};
-};
-struct Hybrid_type_traits_integer: public Hybrid_type_traits
-{
- virtual Item_result type() const { return INT_RESULT; }
- virtual void
- fix_length_and_dec(Item *arg, Item *item) const;
- virtual void set_zero(Hybrid_type *val) const
- { val->integer= 0; }
- virtual void add(Hybrid_type *val, Field *f) const
- { val->integer+= f->val_int(); }
- virtual void div(Hybrid_type *val, ulonglong u) const
- { val->integer/= (longlong) u; }
- virtual longlong val_int(Hybrid_type *val, In_C_you_should_use_my_bool_instead() unsigned_flag) const
- { return val->integer; }
- virtual double val_real(Hybrid_type *val) const
- { return (double) val->integer; }
- virtual my_decimal *val_decimal(Hybrid_type *val, my_decimal *buf) const
- {
- int2my_decimal(30, val->integer, 0, &val->dec_buf[2]);
- return &val->dec_buf[2];
- }
- virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const
- { buf->set(val->integer, &my_charset_bin); return buf;}
- static const Hybrid_type_traits_integer *instance();
- Hybrid_type_traits_integer() {};
-};
-void dummy_error_processor(THD *thd, void *data);
-void view_error_processor(THD *thd, void *data);
-struct Name_resolution_context: Sql_alloc
-{
- Name_resolution_context *outer_context;
- TABLE_LIST *table_list;
- TABLE_LIST *first_name_resolution_table;
- TABLE_LIST *last_name_resolution_table;
- st_select_lex *select_lex;
- void (*error_processor)(THD *, void *);
- void *error_processor_data;
- In_C_you_should_use_my_bool_instead() resolve_in_select_list;
- Security_context *security_ctx;
- Name_resolution_context()
- :outer_context(0), table_list(0), select_lex(0),
- error_processor_data(0),
- security_ctx(0)
- {}
- void init()
- {
- resolve_in_select_list= (0);
- error_processor= &dummy_error_processor;
- first_name_resolution_table= NULL;
- last_name_resolution_table= NULL;
- }
- void resolve_in_table_list_only(TABLE_LIST *tables)
- {
- table_list= first_name_resolution_table= tables;
- resolve_in_select_list= (0);
- }
- void process_error(THD *thd)
- {
- (*error_processor)(thd, error_processor_data);
- }
-};
-class Name_resolution_context_state
-{
-private:
- TABLE_LIST *save_table_list;
- TABLE_LIST *save_first_name_resolution_table;
- TABLE_LIST *save_next_name_resolution_table;
- In_C_you_should_use_my_bool_instead() save_resolve_in_select_list;
- TABLE_LIST *save_next_local;
-public:
- Name_resolution_context_state() {}
-public:
- void save_state(Name_resolution_context *context, TABLE_LIST *table_list)
- {
- save_table_list= context->table_list;
- save_first_name_resolution_table= context->first_name_resolution_table;
- save_resolve_in_select_list= context->resolve_in_select_list;
- save_next_local= table_list->next_local;
- save_next_name_resolution_table= table_list->next_name_resolution_table;
- }
- void restore_state(Name_resolution_context *context, TABLE_LIST *table_list)
- {
- table_list->next_local= save_next_local;
- table_list->next_name_resolution_table= save_next_name_resolution_table;
- context->table_list= save_table_list;
- context->first_name_resolution_table= save_first_name_resolution_table;
- context->resolve_in_select_list= save_resolve_in_select_list;
- }
- TABLE_LIST *get_first_name_resolution_table()
- {
- return save_first_name_resolution_table;
- }
-};
-typedef enum monotonicity_info
-{
- NON_MONOTONIC,
- MONOTONIC_INCREASING,
- MONOTONIC_STRICT_INCREASING
-} enum_monotonicity_info;
-class sp_rcontext;
-class Settable_routine_parameter
-{
-public:
- Settable_routine_parameter() {}
- virtual ~Settable_routine_parameter() {}
- virtual void set_required_privilege(In_C_you_should_use_my_bool_instead() rw) {};
- virtual In_C_you_should_use_my_bool_instead() set_value(THD *thd, sp_rcontext *ctx, Item **it)= 0;
-};
-typedef In_C_you_should_use_my_bool_instead() (Item::*Item_processor) (uchar *arg);
-typedef In_C_you_should_use_my_bool_instead() (Item::*Item_analyzer) (uchar **argp);
-typedef Item* (Item::*Item_transformer) (uchar *arg);
-typedef void (*Cond_traverser) (const Item *item, void *arg);
-class Item {
- Item(const Item &);
- void operator=(Item &);
-public:
- static void *operator new(size_t size)
- { return sql_alloc(size); }
- static void *operator new(size_t size, MEM_ROOT *mem_root)
- { return alloc_root(mem_root, size); }
- static void operator delete(void *ptr,size_t size) { ; }
- static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
- enum Type {FIELD_ITEM= 0, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM,
- INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
- COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
- PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
- FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
- SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
- PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
- XPATH_NODESET, XPATH_NODESET_CMP,
- VIEW_FIXER_ITEM};
- enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
- enum traverse_order { POSTFIX, PREFIX };
- uint rsize;
- String str_value;
- char * name;
- char * orig_name;
- Item *next;
- uint32 max_length;
- uint name_length;
- int8 marker;
- uint8 decimals;
- my_bool maybe_null;
- my_bool null_value;
- my_bool unsigned_flag;
- my_bool with_sum_func;
- my_bool fixed;
- my_bool is_autogenerated_name;
- DTCollation collation;
- my_bool with_subselect;
- Item_result cmp_context;
- Item();
- Item(THD *thd, Item *item);
- virtual ~Item()
- {
- }
- void set_name(const char *str, uint length, CHARSET_INFO *cs);
- void rename(char *new_name);
- void init_make_field(Send_field *tmp_field,enum enum_field_types type);
- virtual void cleanup();
- virtual void make_field(Send_field *field);
- Field *make_string_field(TABLE *table);
- virtual In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- inline void quick_fix_field() { fixed= 1; }
- int save_in_field_no_warnings(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- virtual int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- virtual void save_org_in_field(Field *field)
- { (void) save_in_field(field, 1); }
- virtual int save_safe_in_field(Field *field)
- { return save_in_field(field, 1); }
- virtual In_C_you_should_use_my_bool_instead() send(Protocol *protocol, String *str);
- virtual In_C_you_should_use_my_bool_instead() eq(const Item *, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- virtual Item_result result_type() const { return REAL_RESULT; }
- virtual Item_result cast_to_int_type() const { return result_type(); }
- virtual enum_field_types string_field_type() const;
- virtual enum_field_types field_type() const;
- virtual enum Type type() const =0;
- virtual enum_monotonicity_info get_monotonicity_info() const
- { return NON_MONOTONIC; }
- virtual longlong val_int_endpoint(In_C_you_should_use_my_bool_instead() left_endp, In_C_you_should_use_my_bool_instead() *incl_endp)
- { assert(0); return 0; }
- virtual double val_real()=0;
- virtual longlong val_int()=0;
- inline ulonglong val_uint() { return (ulonglong) val_int(); }
- virtual String *val_str(String *str)=0;
- virtual my_decimal *val_decimal(my_decimal *decimal_buffer)= 0;
- virtual In_C_you_should_use_my_bool_instead() val_bool();
- virtual String *val_nodeset(String*) { return 0; }
- String *val_string_from_real(String *str);
- String *val_string_from_int(String *str);
- String *val_string_from_decimal(String *str);
- my_decimal *val_decimal_from_real(my_decimal *decimal_value);
- my_decimal *val_decimal_from_int(my_decimal *decimal_value);
- my_decimal *val_decimal_from_string(my_decimal *decimal_value);
- my_decimal *val_decimal_from_date(my_decimal *decimal_value);
- my_decimal *val_decimal_from_time(my_decimal *decimal_value);
- longlong val_int_from_decimal();
- double val_real_from_decimal();
- int save_time_in_field(Field *field);
- int save_date_in_field(Field *field);
- int save_str_value_in_field(Field *field, String *result);
- virtual Field *get_tmp_table_field() { return 0; }
- virtual Field *tmp_table_field(TABLE *t_arg) { return 0; }
- virtual const char *full_name() const { return name ? name : "???"; }
- virtual double val_result() { return val_real(); }
- virtual longlong val_int_result() { return val_int(); }
- virtual String *str_result(String* tmp) { return val_str(tmp); }
- virtual my_decimal *val_decimal_result(my_decimal *val)
- { return val_decimal(val); }
- virtual In_C_you_should_use_my_bool_instead() val_bool_result() { return val_bool(); }
- virtual table_map used_tables() const { return (table_map) 0L; }
- virtual table_map not_null_tables() const { return used_tables(); }
- virtual In_C_you_should_use_my_bool_instead() basic_const_item() const { return 0; }
- virtual Item *clone_item() { return 0; }
- virtual cond_result eq_cmp_result() const { return COND_OK; }
- inline uint float_length(uint decimals_par) const
- { return decimals != 31 ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
- virtual uint decimal_precision() const;
- inline int decimal_int_part() const
- { return my_decimal_int_part(decimal_precision(), decimals); }
- virtual In_C_you_should_use_my_bool_instead() const_item() const { return used_tables() == 0; }
- virtual In_C_you_should_use_my_bool_instead() const_during_execution() const
- { return (used_tables() & ~(((table_map) 1) << (sizeof(table_map)*8-3))) == 0; }
- virtual inline void print(String *str, enum_query_type query_type)
- {
- str->append(full_name());
- }
- void print_item_w_name(String *, enum_query_type query_type);
- virtual void update_used_tables() {}
- virtual void split_sum_func(THD *thd, Item **ref_pointer_array,
- List<Item> &fields) {}
- void split_sum_func2(THD *thd, Item **ref_pointer_array, List<Item> &fields,
- Item **ref, In_C_you_should_use_my_bool_instead() skip_registered);
- virtual In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime,uint fuzzydate);
- virtual In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *ltime);
- virtual In_C_you_should_use_my_bool_instead() get_date_result(MYSQL_TIME *ltime,uint fuzzydate)
- { return get_date(ltime,fuzzydate); }
- virtual In_C_you_should_use_my_bool_instead() is_null() { return 0; }
- virtual void update_null_value () { (void) val_int(); }
- virtual void top_level_item() {}
- virtual void set_result_field(Field *field) {}
- virtual In_C_you_should_use_my_bool_instead() is_result_field() { return 0; }
- virtual In_C_you_should_use_my_bool_instead() is_bool_func() { return 0; }
- virtual void save_in_result_field(In_C_you_should_use_my_bool_instead() no_conversions) {}
- virtual void no_rows_in_result() {}
- virtual Item *copy_or_same(THD *thd) { return this; }
- virtual Item *copy_andor_structure(THD *thd) { return this; }
- virtual Item *real_item() { return this; }
- virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); }
- static CHARSET_INFO *default_charset();
- virtual CHARSET_INFO *compare_collation() { return NULL; }
- virtual In_C_you_should_use_my_bool_instead() walk(Item_processor processor, In_C_you_should_use_my_bool_instead() walk_subquery, uchar *arg)
- {
- return (this->*processor)(arg);
- }
- virtual Item* transform(Item_transformer transformer, uchar *arg);
- virtual Item* compile(Item_analyzer analyzer, uchar **arg_p,
- Item_transformer transformer, uchar *arg_t)
- {
- if ((this->*analyzer) (arg_p))
- return ((this->*transformer) (arg_t));
- return 0;
- }
- virtual void traverse_cond(Cond_traverser traverser,
- void *arg, traverse_order order)
- {
- (*traverser)(this, arg);
- }
- virtual In_C_you_should_use_my_bool_instead() remove_dependence_processor(uchar * arg) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() remove_fixed(uchar * arg) { fixed= 0; return 0; }
- virtual In_C_you_should_use_my_bool_instead() cleanup_processor(uchar *arg);
- virtual In_C_you_should_use_my_bool_instead() collect_item_field_processor(uchar * arg) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() find_item_in_field_list_processor(uchar *arg) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() change_context_processor(uchar *context) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() reset_query_id_processor(uchar *query_id_arg) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() is_expensive_processor(uchar *arg) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() register_field_in_read_map(uchar *arg) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *bool_arg) { return (1);}
- virtual In_C_you_should_use_my_bool_instead() subst_argument_checker(uchar **arg)
- {
- if (*arg)
- *arg= NULL;
- return (1);
- }
- virtual Item *equal_fields_propagator(uchar * arg) { return this; }
- virtual In_C_you_should_use_my_bool_instead() set_no_const_sub(uchar *arg) { return (0); }
- virtual Item *replace_equal_field(uchar * arg) { return this; }
- virtual Item *this_item() { return this; }
- virtual const Item *this_item() const { return this; }
- virtual Item **this_item_addr(THD *thd, Item **addr_arg) { return addr_arg; }
- virtual uint cols() { return 1; }
- virtual Item* element_index(uint i) { return this; }
- virtual Item** addr(uint i) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() check_cols(uint c);
- virtual In_C_you_should_use_my_bool_instead() null_inside() { return 0; }
- virtual void bring_value() {}
- Field *tmp_table_field_from_field_type(TABLE *table, In_C_you_should_use_my_bool_instead() fixed_length);
- virtual Item_field *filed_for_view_update() { return 0; }
- virtual Item *neg_transformer(THD *thd) { return NULL; }
- virtual Item *update_value_transformer(uchar *select_arg) { return this; }
- virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
- void delete_self()
- {
- cleanup();
- delete this;
- }
- virtual In_C_you_should_use_my_bool_instead() is_splocal() { return 0; }
- virtual Settable_routine_parameter *get_settable_routine_parameter()
- {
- return 0;
- }
- virtual In_C_you_should_use_my_bool_instead() result_as_longlong() { return (0); }
- In_C_you_should_use_my_bool_instead() is_datetime();
- virtual Field::geometry_type get_geometry_type() const
- { return Field::GEOM_GEOMETRY; };
- String *check_well_formed_result(String *str, In_C_you_should_use_my_bool_instead() send_error= 0);
- In_C_you_should_use_my_bool_instead() eq_by_collation(Item *item, In_C_you_should_use_my_bool_instead() binary_cmp, CHARSET_INFO *cs);
-};
-class sp_head;
-class Item_basic_constant :public Item
-{
-public:
- void cleanup()
- {
- if (orig_name)
- name= orig_name;
- }
-};
-class Item_sp_variable :public Item
-{
-protected:
- THD *m_thd;
-public:
- LEX_STRING m_name;
-public:
- sp_head *m_sp;
-public:
- Item_sp_variable(char *sp_var_name_str, uint sp_var_name_length);
-public:
- In_C_you_should_use_my_bool_instead() fix_fields(THD *thd, Item **);
- double val_real();
- longlong val_int();
- String *val_str(String *sp);
- my_decimal *val_decimal(my_decimal *decimal_value);
- In_C_you_should_use_my_bool_instead() is_null();
-public:
- inline void make_field(Send_field *field);
- inline In_C_you_should_use_my_bool_instead() const_item() const;
- inline int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- inline In_C_you_should_use_my_bool_instead() send(Protocol *protocol, String *str);
-};
-inline void Item_sp_variable::make_field(Send_field *field)
-{
- Item *it= this_item();
- if (name)
- it->set_name(name, (uint) strlen(name), system_charset_info);
- else
- it->set_name(m_name.str, m_name.length, system_charset_info);
- it->make_field(field);
-}
-inline In_C_you_should_use_my_bool_instead() Item_sp_variable::const_item() const
-{
- return (1);
-}
-inline int Item_sp_variable::save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions)
-{
- return this_item()->save_in_field(field, no_conversions);
-}
-inline In_C_you_should_use_my_bool_instead() Item_sp_variable::send(Protocol *protocol, String *str)
-{
- return this_item()->send(protocol, str);
-}
-class Item_splocal :public Item_sp_variable,
- private Settable_routine_parameter
-{
- uint m_var_idx;
- Type m_type;
- Item_result m_result_type;
- enum_field_types m_field_type;
-public:
- uint pos_in_query;
- uint len_in_query;
- Item_splocal(const LEX_STRING &sp_var_name, uint sp_var_idx,
- enum_field_types sp_var_type,
- uint pos_in_q= 0, uint len_in_q= 0);
- In_C_you_should_use_my_bool_instead() is_splocal() { return 1; }
- Item *this_item();
- const Item *this_item() const;
- Item **this_item_addr(THD *thd, Item **);
- virtual void print(String *str, enum_query_type query_type);
-public:
- inline const LEX_STRING *my_name() const;
- inline uint get_var_idx() const;
- inline enum Type type() const;
- inline Item_result result_type() const;
- inline enum_field_types field_type() const { return m_field_type; }
-private:
- In_C_you_should_use_my_bool_instead() set_value(THD *thd, sp_rcontext *ctx, Item **it);
-public:
- Settable_routine_parameter *get_settable_routine_parameter()
- {
- return this;
- }
-};
-inline const LEX_STRING *Item_splocal::my_name() const
-{
- return &m_name;
-}
-inline uint Item_splocal::get_var_idx() const
-{
- return m_var_idx;
-}
-inline enum Item::Type Item_splocal::type() const
-{
- return m_type;
-}
-inline Item_result Item_splocal::result_type() const
-{
- return m_result_type;
-}
-class Item_case_expr :public Item_sp_variable
-{
-public:
- Item_case_expr(uint case_expr_id);
-public:
- Item *this_item();
- const Item *this_item() const;
- Item **this_item_addr(THD *thd, Item **);
- inline enum Type type() const;
- inline Item_result result_type() const;
-public:
- virtual void print(String *str, enum_query_type query_type);
-private:
- uint m_case_expr_id;
-};
-inline enum Item::Type Item_case_expr::type() const
-{
- return this_item()->type();
-}
-inline Item_result Item_case_expr::result_type() const
-{
- return this_item()->result_type();
-}
-class Item_name_const : public Item
-{
- Item *value_item;
- Item *name_item;
- In_C_you_should_use_my_bool_instead() valid_args;
-public:
- Item_name_const(Item *name_arg, Item *val);
- In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- enum Type type() const;
- double val_real();
- longlong val_int();
- String *val_str(String *sp);
- my_decimal *val_decimal(my_decimal *);
- In_C_you_should_use_my_bool_instead() is_null();
- virtual void print(String *str, enum_query_type query_type);
- Item_result result_type() const
- {
- return value_item->result_type();
- }
- In_C_you_should_use_my_bool_instead() const_item() const
- {
- return (1);
- }
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions)
- {
- return value_item->save_in_field(field, no_conversions);
- }
- In_C_you_should_use_my_bool_instead() send(Protocol *protocol, String *str)
- {
- return value_item->send(protocol, str);
- }
-};
-In_C_you_should_use_my_bool_instead() agg_item_collations(DTCollation &c, const char *name,
- Item **items, uint nitems, uint flags, int item_sep);
-In_C_you_should_use_my_bool_instead() agg_item_collations_for_comparison(DTCollation &c, const char *name,
- Item **items, uint nitems, uint flags);
-In_C_you_should_use_my_bool_instead() agg_item_charsets(DTCollation &c, const char *name,
- Item **items, uint nitems, uint flags, int item_sep);
-class Item_num: public Item_basic_constant
-{
-public:
- Item_num() {}
- virtual Item_num *neg()= 0;
- Item *safe_charset_converter(CHARSET_INFO *tocs);
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *int_arg) { return (0);}
-};
-class st_select_lex;
-class Item_ident :public Item
-{
-protected:
- const char *orig_db_name;
- const char *orig_table_name;
- const char *orig_field_name;
-public:
- Name_resolution_context *context;
- const char *db_name;
- const char *table_name;
- const char *field_name;
- In_C_you_should_use_my_bool_instead() alias_name_used;
- uint cached_field_index;
- TABLE_LIST *cached_table;
- st_select_lex *depended_from;
- Item_ident(Name_resolution_context *context_arg,
- const char *db_name_arg, const char *table_name_arg,
- const char *field_name_arg);
- Item_ident(THD *thd, Item_ident *item);
- const char *full_name() const;
- void cleanup();
- In_C_you_should_use_my_bool_instead() remove_dependence_processor(uchar * arg);
- virtual void print(String *str, enum_query_type query_type);
- virtual In_C_you_should_use_my_bool_instead() change_context_processor(uchar *cntx)
- { context= (Name_resolution_context *)cntx; return (0); }
- friend In_C_you_should_use_my_bool_instead() insert_fields(THD *thd, Name_resolution_context *context,
- const char *db_name,
- const char *table_name, List_iterator<Item> *it,
- In_C_you_should_use_my_bool_instead() any_privileges);
-};
-class Item_ident_for_show :public Item
-{
-public:
- Field *field;
- const char *db_name;
- const char *table_name;
- Item_ident_for_show(Field *par_field, const char *db_arg,
- const char *table_name_arg)
- :field(par_field), db_name(db_arg), table_name(table_name_arg)
- {}
- enum Type type() const { return FIELD_ITEM; }
- double val_real() { return field->val_real(); }
- longlong val_int() { return field->val_int(); }
- String *val_str(String *str) { return field->val_str(str); }
- my_decimal *val_decimal(my_decimal *dec) { return field->val_decimal(dec); }
- void make_field(Send_field *tmp_field);
-};
-class Item_equal;
-class COND_EQUAL;
-class Item_field :public Item_ident
-{
-protected:
- void set_field(Field *field);
-public:
- Field *field,*result_field;
- Item_equal *item_equal;
- In_C_you_should_use_my_bool_instead() no_const_subst;
- uint have_privileges;
- In_C_you_should_use_my_bool_instead() any_privileges;
- Item_field(Name_resolution_context *context_arg,
- const char *db_arg,const char *table_name_arg,
- const char *field_name_arg);
- Item_field(THD *thd, Item_field *item);
- Item_field(THD *thd, Name_resolution_context *context_arg, Field *field);
- Item_field(Field *field);
- enum Type type() const { return FIELD_ITEM; }
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- double val_real();
- longlong val_int();
- my_decimal *val_decimal(my_decimal *);
- String *val_str(String*);
- double val_result();
- longlong val_int_result();
- String *str_result(String* tmp);
- my_decimal *val_decimal_result(my_decimal *);
- In_C_you_should_use_my_bool_instead() val_bool_result();
- In_C_you_should_use_my_bool_instead() send(Protocol *protocol, String *str_arg);
- void reset_field(Field *f);
- In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- void make_field(Send_field *tmp_field);
- int save_in_field(Field *field,In_C_you_should_use_my_bool_instead() no_conversions);
- void save_org_in_field(Field *field);
- table_map used_tables() const;
- enum Item_result result_type () const
- {
- return field->result_type();
- }
- Item_result cast_to_int_type() const
- {
- return field->cast_to_int_type();
- }
- enum_field_types field_type() const
- {
- return field->type();
- }
- enum_monotonicity_info get_monotonicity_info() const
- {
- return MONOTONIC_STRICT_INCREASING;
- }
- longlong val_int_endpoint(In_C_you_should_use_my_bool_instead() left_endp, In_C_you_should_use_my_bool_instead() *incl_endp);
- Field *get_tmp_table_field() { return result_field; }
- Field *tmp_table_field(TABLE *t_arg) { return result_field; }
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime,uint fuzzydate);
- In_C_you_should_use_my_bool_instead() get_date_result(MYSQL_TIME *ltime,uint fuzzydate);
- In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *ltime);
- In_C_you_should_use_my_bool_instead() is_null() { return field->is_null(); }
- void update_null_value();
- Item *get_tmp_table_item(THD *thd);
- In_C_you_should_use_my_bool_instead() collect_item_field_processor(uchar * arg);
- In_C_you_should_use_my_bool_instead() find_item_in_field_list_processor(uchar *arg);
- In_C_you_should_use_my_bool_instead() register_field_in_read_map(uchar *arg);
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *int_arg) {return (0);}
- void cleanup();
- In_C_you_should_use_my_bool_instead() result_as_longlong()
- {
- return field->can_be_compared_as_longlong();
- }
- Item_equal *find_item_equal(COND_EQUAL *cond_equal);
- In_C_you_should_use_my_bool_instead() subst_argument_checker(uchar **arg);
- Item *equal_fields_propagator(uchar *arg);
- In_C_you_should_use_my_bool_instead() set_no_const_sub(uchar *arg);
- Item *replace_equal_field(uchar *arg);
- inline uint32 max_disp_length() { return field->max_display_length(); }
- Item_field *filed_for_view_update() { return this; }
- Item *safe_charset_converter(CHARSET_INFO *tocs);
- int fix_outer_field(THD *thd, Field **field, Item **reference);
- virtual Item *update_value_transformer(uchar *select_arg);
- virtual void print(String *str, enum_query_type query_type);
- Field::geometry_type get_geometry_type() const
- {
- assert(field_type() == MYSQL_TYPE_GEOMETRY);
- return field->get_geometry_type();
- }
- friend class Item_default_value;
- friend class Item_insert_value;
- friend class st_select_lex_unit;
-};
-class Item_null :public Item_basic_constant
-{
-public:
- Item_null(char *name_par=0)
- {
- maybe_null= null_value= (1);
- max_length= 0;
- name= name_par ? name_par : (char*) "NULL";
- fixed= 1;
- collation.set(&my_charset_bin, DERIVATION_IGNORABLE);
- }
- enum Type type() const { return NULL_ITEM; }
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- double val_real();
- longlong val_int();
- String *val_str(String *str);
- my_decimal *val_decimal(my_decimal *);
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- int save_safe_in_field(Field *field);
- In_C_you_should_use_my_bool_instead() send(Protocol *protocol, String *str);
- enum Item_result result_type () const { return STRING_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_NULL; }
- In_C_you_should_use_my_bool_instead() basic_const_item() const { return 1; }
- Item *clone_item() { return new Item_null(name); }
- In_C_you_should_use_my_bool_instead() is_null() { return 1; }
- virtual inline void print(String *str, enum_query_type query_type)
- {
- str->append(("NULL"), ((size_t) (sizeof("NULL") - 1)));
- }
- Item *safe_charset_converter(CHARSET_INFO *tocs);
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *int_arg) {return (0);}
-};
-class Item_null_result :public Item_null
-{
-public:
- Field *result_field;
- Item_null_result() : Item_null(), result_field(0) {}
- In_C_you_should_use_my_bool_instead() is_result_field() { return result_field != 0; }
- void save_in_result_field(In_C_you_should_use_my_bool_instead() no_conversions)
- {
- save_in_field(result_field, no_conversions);
- }
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *int_arg) {return (1);}
-};
-class Item_param :public Item
-{
- char cnvbuf[(255*3 +1)];
- String cnvstr;
- Item *cnvitem;
-public:
- enum enum_item_param_state
- {
- NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE,
- STRING_VALUE, TIME_VALUE, LONG_DATA_VALUE,
- DECIMAL_VALUE
- } state;
- String str_value_ptr;
- my_decimal decimal_value;
- union
- {
- longlong integer;
- double real;
- struct CONVERSION_INFO
- {
- CHARSET_INFO *character_set_client;
- CHARSET_INFO *character_set_of_placeholder;
- CHARSET_INFO *final_character_set_of_str_value;
- } cs_info;
- MYSQL_TIME time;
- } value;
- enum Item_result item_result_type;
- enum Type item_type;
- enum enum_field_types param_type;
- uint pos_in_query;
- Item_param(uint pos_in_query_arg);
- enum Item_result result_type () const { return item_result_type; }
- enum Type type() const { return item_type; }
- enum_field_types field_type() const { return param_type; }
- double val_real();
- longlong val_int();
- my_decimal *val_decimal(my_decimal*);
- String *val_str(String*);
- In_C_you_should_use_my_bool_instead() get_time(MYSQL_TIME *tm);
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *tm, uint fuzzydate);
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- void set_null();
- void set_int(longlong i, uint32 max_length_arg);
- void set_double(double i);
- void set_decimal(const char *str, ulong length);
- In_C_you_should_use_my_bool_instead() set_str(const char *str, ulong length);
- In_C_you_should_use_my_bool_instead() set_longdata(const char *str, ulong length);
- void set_time(MYSQL_TIME *tm, timestamp_type type, uint32 max_length_arg);
- In_C_you_should_use_my_bool_instead() set_from_user_var(THD *thd, const user_var_entry *entry);
- void reset();
- void (*set_param_func)(Item_param *param, uchar **pos, ulong len);
- const String *query_val_str(String *str) const;
- In_C_you_should_use_my_bool_instead() convert_str_value(THD *thd);
- virtual table_map used_tables() const
- { return state != NO_VALUE ? (table_map)0 : (((table_map) 1) << (sizeof(table_map)*8-3)); }
- virtual void print(String *str, enum_query_type query_type);
- In_C_you_should_use_my_bool_instead() is_null()
- { assert(state != NO_VALUE); return state == NULL_VALUE; }
- In_C_you_should_use_my_bool_instead() basic_const_item() const;
- Item *safe_charset_converter(CHARSET_INFO *tocs);
- Item *clone_item();
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- In_C_you_should_use_my_bool_instead() limit_clause_param;
- void set_param_type_and_swap_value(Item_param *from);
-};
-class Item_int :public Item_num
-{
-public:
- longlong value;
- Item_int(int32 i,uint length= 11)
- :value((longlong) i)
- { max_length=length; fixed= 1; }
- Item_int(longlong i,uint length= 21)
- :value(i)
- { max_length=length; fixed= 1; }
- Item_int(ulonglong i, uint length= 21)
- :value((longlong)i)
- { max_length=length; fixed= 1; unsigned_flag= 1; }
- Item_int(const char *str_arg,longlong i,uint length) :value(i)
- { max_length=length; name=(char*) str_arg; fixed= 1; }
- Item_int(const char *str_arg, uint length=64);
- enum Type type() const { return INT_ITEM; }
- enum Item_result result_type () const { return INT_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- longlong val_int() { assert(fixed == 1); return value; }
- double val_real() { assert(fixed == 1); return (double) value; }
- my_decimal *val_decimal(my_decimal *);
- String *val_str(String*);
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- In_C_you_should_use_my_bool_instead() basic_const_item() const { return 1; }
- Item *clone_item() { return new Item_int(name,value,max_length); }
- virtual void print(String *str, enum_query_type query_type);
- Item_num *neg() { value= -value; return this; }
- uint decimal_precision() const
- { return (uint)(max_length - ((value < 0) ? 1 : 0)); }
- In_C_you_should_use_my_bool_instead() eq(const Item *, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *bool_arg) { return (0);}
-};
-class Item_uint :public Item_int
-{
-public:
- Item_uint(const char *str_arg, uint length);
- Item_uint(ulonglong i) :Item_int((ulonglong) i, 10) {}
- Item_uint(const char *str_arg, longlong i, uint length);
- double val_real()
- { assert(fixed == 1); return ((double) (ulonglong) ((ulonglong)value)); }
- String *val_str(String*);
- Item *clone_item() { return new Item_uint(name, value, max_length); }
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- virtual void print(String *str, enum_query_type query_type);
- Item_num *neg ();
- uint decimal_precision() const { return max_length; }
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *bool_arg) { return (0);}
-};
-class Item_decimal :public Item_num
-{
-protected:
- my_decimal decimal_value;
-public:
- Item_decimal(const char *str_arg, uint length, CHARSET_INFO *charset);
- Item_decimal(const char *str, const my_decimal *val_arg,
- uint decimal_par, uint length);
- Item_decimal(my_decimal *value_par);
- Item_decimal(longlong val, In_C_you_should_use_my_bool_instead() unsig);
- Item_decimal(double val, int precision, int scale);
- Item_decimal(const uchar *bin, int precision, int scale);
- enum Type type() const { return DECIMAL_ITEM; }
- enum Item_result result_type () const { return DECIMAL_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
- longlong val_int();
- double val_real();
- String *val_str(String*);
- my_decimal *val_decimal(my_decimal *val) { return &decimal_value; }
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- In_C_you_should_use_my_bool_instead() basic_const_item() const { return 1; }
- Item *clone_item()
- {
- return new Item_decimal(name, &decimal_value, decimals, max_length);
- }
- virtual void print(String *str, enum_query_type query_type);
- Item_num *neg()
- {
- my_decimal_neg(&decimal_value);
- unsigned_flag= !decimal_value.sign();
- return this;
- }
- uint decimal_precision() const { return decimal_value.precision(); }
- In_C_you_should_use_my_bool_instead() eq(const Item *, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- void set_decimal_value(my_decimal *value_par);
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *bool_arg) { return (0);}
-};
-class Item_float :public Item_num
-{
- char *presentation;
-public:
- double value;
- Item_float(const char *str_arg, uint length);
- Item_float(const char *str,double val_arg,uint decimal_par,uint length)
- :value(val_arg)
- {
- presentation= name=(char*) str;
- decimals=(uint8) decimal_par;
- max_length=length;
- fixed= 1;
- }
- Item_float(double value_par, uint decimal_par) :presentation(0), value(value_par)
- {
- decimals= (uint8) decimal_par;
- fixed= 1;
- }
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- enum Type type() const { return REAL_ITEM; }
- enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- double val_real() { assert(fixed == 1); return value; }
- longlong val_int()
- {
- assert(fixed == 1);
- if (value <= (double) ((long long) 0x8000000000000000LL))
- {
- return ((long long) 0x8000000000000000LL);
- }
- else if (value >= (double) (ulonglong) ((long long) 0x7FFFFFFFFFFFFFFFLL))
- {
- return ((long long) 0x7FFFFFFFFFFFFFFFLL);
- }
- return (longlong) rint(value);
- }
- String *val_str(String*);
- my_decimal *val_decimal(my_decimal *);
- In_C_you_should_use_my_bool_instead() basic_const_item() const { return 1; }
- Item *clone_item()
- { return new Item_float(name, value, decimals, max_length); }
- Item_num *neg() { value= -value; return this; }
- virtual void print(String *str, enum_query_type query_type);
- In_C_you_should_use_my_bool_instead() eq(const Item *, In_C_you_should_use_my_bool_instead() binary_cmp) const;
-};
-class Item_static_float_func :public Item_float
-{
- const char *func_name;
-public:
- Item_static_float_func(const char *str, double val_arg, uint decimal_par,
- uint length)
- :Item_float((char *) 0, val_arg, decimal_par, length), func_name(str)
- {}
- virtual inline void print(String *str, enum_query_type query_type)
- {
- str->append(func_name);
- }
- Item *safe_charset_converter(CHARSET_INFO *tocs);
-};
-class Item_string :public Item_basic_constant
-{
-public:
- Item_string(const char *str,uint length,
- CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE,
- uint repertoire= 3)
- : m_cs_specified((0))
- {
- str_value.set_or_copy_aligned(str, length, cs);
- collation.set(cs, dv, repertoire);
- max_length= str_value.numchars()*cs->mbmaxlen;
- set_name(str, length, cs);
- decimals=31;
- fixed= 1;
- }
- Item_string(CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
- : m_cs_specified((0))
- {
- collation.set(cs, dv);
- max_length= 0;
- set_name(NULL, 0, cs);
- decimals= 31;
- fixed= 1;
- }
- Item_string(const char *name_par, const char *str, uint length,
- CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE,
- uint repertoire= 3)
- : m_cs_specified((0))
- {
- str_value.set_or_copy_aligned(str, length, cs);
- collation.set(cs, dv, repertoire);
- max_length= str_value.numchars()*cs->mbmaxlen;
- set_name(name_par, 0, cs);
- decimals=31;
- fixed= 1;
- }
- void set_str_with_copy(const char *str_arg, uint length_arg)
- {
- str_value.copy(str_arg, length_arg, collation.collation);
- max_length= str_value.numchars() * collation.collation->mbmaxlen;
- }
- void set_repertoire_from_value()
- {
- collation.repertoire= my_string_repertoire(str_value.charset(),
- str_value.ptr(),
- str_value.length());
- }
- enum Type type() const { return STRING_ITEM; }
- double val_real();
- longlong val_int();
- String *val_str(String*)
- {
- assert(fixed == 1);
- return (String*) &str_value;
- }
- my_decimal *val_decimal(my_decimal *);
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- enum Item_result result_type () const { return STRING_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
- In_C_you_should_use_my_bool_instead() basic_const_item() const { return 1; }
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- Item *clone_item()
- {
- return new Item_string(name, str_value.ptr(),
- str_value.length(), collation.collation);
- }
- Item *safe_charset_converter(CHARSET_INFO *tocs);
- inline void append(char *str, uint length)
- {
- str_value.append(str, length);
- max_length= str_value.numchars() * collation.collation->mbmaxlen;
- }
- virtual void print(String *str, enum_query_type query_type);
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *int_arg) {return (0);}
- inline In_C_you_should_use_my_bool_instead() is_cs_specified() const
- {
- return m_cs_specified;
- }
- inline void set_cs_specified(In_C_you_should_use_my_bool_instead() cs_specified)
- {
- m_cs_specified= cs_specified;
- }
-private:
- In_C_you_should_use_my_bool_instead() m_cs_specified;
-};
-class Item_static_string_func :public Item_string
-{
- const char *func_name;
-public:
- Item_static_string_func(const char *name_par, const char *str, uint length,
- CHARSET_INFO *cs,
- Derivation dv= DERIVATION_COERCIBLE)
- :Item_string((char *) 0, str, length, cs, dv), func_name(name_par)
- {}
- Item *safe_charset_converter(CHARSET_INFO *tocs);
- virtual inline void print(String *str, enum_query_type query_type)
- {
- str->append(func_name);
- }
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *int_arg) {return (1);}
-};
-class Item_partition_func_safe_string: public Item_string
-{
-public:
- Item_partition_func_safe_string(const char *name, uint length,
- CHARSET_INFO *cs= NULL):
- Item_string(name, length, cs)
- {}
-};
-class Item_return_date_time :public Item_partition_func_safe_string
-{
- enum_field_types date_time_field_type;
-public:
- Item_return_date_time(const char *name_arg, enum_field_types field_type_arg)
- :Item_partition_func_safe_string(name_arg, 0, &my_charset_bin),
- date_time_field_type(field_type_arg)
- { }
- enum_field_types field_type() const { return date_time_field_type; }
-};
-class Item_blob :public Item_partition_func_safe_string
-{
-public:
- Item_blob(const char *name, uint length) :
- Item_partition_func_safe_string(name, length, &my_charset_bin)
- { max_length= length; }
- enum Type type() const { return TYPE_HOLDER; }
- enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
-};
-class Item_empty_string :public Item_partition_func_safe_string
-{
-public:
- Item_empty_string(const char *header,uint length, CHARSET_INFO *cs= NULL) :
- Item_partition_func_safe_string("",0, cs ? cs : &my_charset_utf8_general_ci)
- { name=(char*) header; max_length= cs ? length * cs->mbmaxlen : length; }
- void make_field(Send_field *field);
-};
-class Item_return_int :public Item_int
-{
- enum_field_types int_field_type;
-public:
- Item_return_int(const char *name_arg, uint length,
- enum_field_types field_type_arg, longlong value= 0)
- :Item_int(name_arg, value, length), int_field_type(field_type_arg)
- {
- unsigned_flag=1;
- }
- enum_field_types field_type() const { return int_field_type; }
-};
-class Item_hex_string: public Item_basic_constant
-{
-public:
- Item_hex_string() {}
- Item_hex_string(const char *str,uint str_length);
- enum Type type() const { return VARBIN_ITEM; }
- double val_real()
- {
- assert(fixed == 1);
- return (double) (ulonglong) Item_hex_string::val_int();
- }
- longlong val_int();
- In_C_you_should_use_my_bool_instead() basic_const_item() const { return 1; }
- String *val_str(String*) { assert(fixed == 1); return &str_value; }
- my_decimal *val_decimal(my_decimal *);
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- enum Item_result result_type () const { return STRING_RESULT; }
- enum Item_result cast_to_int_type() const { return INT_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
- virtual void print(String *str, enum_query_type query_type);
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
- In_C_you_should_use_my_bool_instead() check_partition_func_processor(uchar *int_arg) {return (0);}
-};
-class Item_bin_string: public Item_hex_string
-{
-public:
- Item_bin_string(const char *str,uint str_length);
-};
-class Item_result_field :public Item
-{
-public:
- Field *result_field;
- Item_result_field() :result_field(0) {}
- Item_result_field(THD *thd, Item_result_field *item):
- Item(thd, item), result_field(item->result_field)
- {}
- ~Item_result_field() {}
- Field *get_tmp_table_field() { return result_field; }
- Field *tmp_table_field(TABLE *t_arg) { return result_field; }
- table_map used_tables() const { return 1; }
- virtual void fix_length_and_dec()=0;
- void set_result_field(Field *field) { result_field= field; }
- In_C_you_should_use_my_bool_instead() is_result_field() { return 1; }
- void save_in_result_field(In_C_you_should_use_my_bool_instead() no_conversions)
- {
- save_in_field(result_field, no_conversions);
- }
- void cleanup();
-};
-class Item_ref :public Item_ident
-{
-protected:
- void set_properties();
-public:
- enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF };
- Field *result_field;
- Item **ref;
- Item_ref(Name_resolution_context *context_arg,
- const char *db_arg, const char *table_name_arg,
- const char *field_name_arg)
- :Item_ident(context_arg, db_arg, table_name_arg, field_name_arg),
- result_field(0), ref(0) {}
- Item_ref(Name_resolution_context *context_arg, Item **item,
- const char *table_name_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() alias_name_used_arg= (0));
- Item_ref(THD *thd, Item_ref *item)
- :Item_ident(thd, item), result_field(item->result_field), ref(item->ref) {}
- enum Type type() const { return REF_ITEM; }
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const
- {
- Item *it= ((Item *) item)->real_item();
- return ref && (*ref)->eq(it, binary_cmp);
- }
- double val_real();
- longlong val_int();
- my_decimal *val_decimal(my_decimal *);
- In_C_you_should_use_my_bool_instead() val_bool();
- String *val_str(String* tmp);
- In_C_you_should_use_my_bool_instead() is_null();
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime,uint fuzzydate);
- double val_result();
- longlong val_int_result();
- String *str_result(String* tmp);
- my_decimal *val_decimal_result(my_decimal *);
- In_C_you_should_use_my_bool_instead() val_bool_result();
- In_C_you_should_use_my_bool_instead() send(Protocol *prot, String *tmp);
- void make_field(Send_field *field);
- In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
- void save_org_in_field(Field *field);
- enum Item_result result_type () const { return (*ref)->result_type(); }
- enum_field_types field_type() const { return (*ref)->field_type(); }
- Field *get_tmp_table_field()
- { return result_field ? result_field : (*ref)->get_tmp_table_field(); }
- Item *get_tmp_table_item(THD *thd);
- table_map used_tables() const
- {
- return depended_from ? (((table_map) 1) << (sizeof(table_map)*8-2)) : (*ref)->used_tables();
- }
- void update_used_tables()
- {
- if (!depended_from)
- (*ref)->update_used_tables();
- }
- table_map not_null_tables() const { return (*ref)->not_null_tables(); }
- void set_result_field(Field *field) { result_field= field; }
- In_C_you_should_use_my_bool_instead() is_result_field() { return 1; }
- void save_in_result_field(In_C_you_should_use_my_bool_instead() no_conversions)
- {
- (*ref)->save_in_field(result_field, no_conversions);
- }
- Item *real_item()
- {
- return ref ? (*ref)->real_item() : this;
- }
- In_C_you_should_use_my_bool_instead() walk(Item_processor processor, In_C_you_should_use_my_bool_instead() walk_subquery, uchar *arg)
- { return (*ref)->walk(processor, walk_subquery, arg); }
- virtual void print(String *str, enum_query_type query_type);
- In_C_you_should_use_my_bool_instead() result_as_longlong()
- {
- return (*ref)->result_as_longlong();
- }
- void cleanup();
- Item_field *filed_for_view_update()
- { return (*ref)->filed_for_view_update(); }
- virtual Ref_Type ref_type() { return REF; }
- uint cols()
- {
- return ref && result_type() == ROW_RESULT ? (*ref)->cols() : 1;
- }
- Item* element_index(uint i)
- {
- return ref && result_type() == ROW_RESULT ? (*ref)->element_index(i) : this;
- }
- Item** addr(uint i)
- {
- return ref && result_type() == ROW_RESULT ? (*ref)->addr(i) : 0;
- }
- In_C_you_should_use_my_bool_instead() check_cols(uint c)
- {
- return ref && result_type() == ROW_RESULT ? (*ref)->check_cols(c)
- : Item::check_cols(c);
- }
- In_C_you_should_use_my_bool_instead() null_inside()
- {
- return ref && result_type() == ROW_RESULT ? (*ref)->null_inside() : 0;
- }
- void bring_value()
- {
- if (ref && result_type() == ROW_RESULT)
- (*ref)->bring_value();
- }
-};
-class Item_direct_ref :public Item_ref
-{
-public:
- Item_direct_ref(Name_resolution_context *context_arg, Item **item,
- const char *table_name_arg,
- const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() alias_name_used_arg= (0))
- :Item_ref(context_arg, item, table_name_arg,
- field_name_arg, alias_name_used_arg)
- {}
- Item_direct_ref(THD *thd, Item_direct_ref *item) : Item_ref(thd, item) {}
- double val_real();
- longlong val_int();
- String *val_str(String* tmp);
- my_decimal *val_decimal(my_decimal *);
- In_C_you_should_use_my_bool_instead() val_bool();
- In_C_you_should_use_my_bool_instead() is_null();
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime,uint fuzzydate);
- virtual Ref_Type ref_type() { return DIRECT_REF; }
-};
-class Item_direct_view_ref :public Item_direct_ref
-{
-public:
- Item_direct_view_ref(Name_resolution_context *context_arg, Item **item,
- const char *table_name_arg,
- const char *field_name_arg)
- :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg) {}
- Item_direct_view_ref(THD *thd, Item_direct_ref *item)
- :Item_direct_ref(thd, item) {}
- In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- Item *get_tmp_table_item(THD *thd)
- {
- Item *item= Item_ref::get_tmp_table_item(thd);
- item->name= name;
- return item;
- }
- virtual Ref_Type ref_type() { return VIEW_REF; }
-};
-class Item_sum;
-class Item_outer_ref :public Item_direct_ref
-{
-public:
- Item *outer_ref;
- Item_sum *in_sum_func;
- In_C_you_should_use_my_bool_instead() found_in_select_list;
- Item_outer_ref(Name_resolution_context *context_arg,
- Item_field *outer_field_arg)
- :Item_direct_ref(context_arg, 0, outer_field_arg->table_name,
- outer_field_arg->field_name),
- outer_ref(outer_field_arg), in_sum_func(0),
- found_in_select_list(0)
- {
- ref= &outer_ref;
- set_properties();
- fixed= 0;
- }
- Item_outer_ref(Name_resolution_context *context_arg, Item **item,
- const char *table_name_arg, const char *field_name_arg,
- In_C_you_should_use_my_bool_instead() alias_name_used_arg)
- :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg,
- alias_name_used_arg),
- outer_ref(0), in_sum_func(0), found_in_select_list(1)
- {}
- void save_in_result_field(In_C_you_should_use_my_bool_instead() no_conversions)
- {
- outer_ref->save_org_in_field(result_field);
- }
- In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- table_map used_tables() const
- {
- return (*ref)->const_item() ? 0 : (((table_map) 1) << (sizeof(table_map)*8-2));
- }
- virtual Ref_Type ref_type() { return OUTER_REF; }
-};
-class Item_in_subselect;
-class Item_ref_null_helper: public Item_ref
-{
-protected:
- Item_in_subselect* owner;
-public:
- Item_ref_null_helper(Name_resolution_context *context_arg,
- Item_in_subselect* master, Item **item,
- const char *table_name_arg, const char *field_name_arg)
- :Item_ref(context_arg, item, table_name_arg, field_name_arg),
- owner(master) {}
- double val_real();
- longlong val_int();
- String* val_str(String* s);
- my_decimal *val_decimal(my_decimal *);
- In_C_you_should_use_my_bool_instead() val_bool();
- In_C_you_should_use_my_bool_instead() get_date(MYSQL_TIME *ltime, uint fuzzydate);
- virtual void print(String *str, enum_query_type query_type);
- table_map used_tables() const
- {
- return (depended_from ?
- (((table_map) 1) << (sizeof(table_map)*8-2)) :
- (*ref)->used_tables() | (((table_map) 1) << (sizeof(table_map)*8-1)));
- }
-};
-class Item_int_with_ref :public Item_int
-{
- Item *ref;
-public:
- Item_int_with_ref(longlong i, Item *ref_arg, my_bool unsigned_arg) :
- Item_int(i), ref(ref_arg)
- {
- unsigned_flag= unsigned_arg;
- }
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions)
- {
- return ref->save_in_field(field, no_conversions);
- }
- Item *clone_item();
- virtual Item *real_item() { return ref; }
-};
-class Item_copy_string :public Item
-{
- enum enum_field_types cached_field_type;
-public:
- Item *item;
- Item_copy_string(Item *i) :item(i)
- {
- null_value=maybe_null=item->maybe_null;
- decimals=item->decimals;
- max_length=item->max_length;
- name=item->name;
- cached_field_type= item->field_type();
- }
- enum Type type() const { return COPY_STR_ITEM; }
- enum Item_result result_type () const { return STRING_RESULT; }
- enum_field_types field_type() const { return cached_field_type; }
- double val_real()
- {
- int err_not_used;
- char *end_not_used;
- return (null_value ? 0.0 :
- ((str_value.charset())->cset->strntod((str_value.charset()),((char*) str_value.ptr()),(str_value.length()),(&end_not_used),(&err_not_used))));
- }
- longlong val_int()
- {
- int err;
- return null_value ? 0LL : ((str_value.charset())->cset->strntoll((str_value.charset()),(str_value.ptr()),(str_value.length()),(10),((char**) 0),(&err)));
- }
- String *val_str(String*);
- my_decimal *val_decimal(my_decimal *);
- void make_field(Send_field *field) { item->make_field(field); }
- void copy();
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions)
- {
- return save_str_value_in_field(field, &str_value);
- }
- table_map used_tables() const { return (table_map) 1L; }
- In_C_you_should_use_my_bool_instead() const_item() const { return 0; }
- In_C_you_should_use_my_bool_instead() is_null() { return null_value; }
-};
-class Cached_item :public Sql_alloc
-{
-public:
- my_bool null_value;
- Cached_item() :null_value(0) {}
- virtual In_C_you_should_use_my_bool_instead() cmp(void)=0;
- virtual ~Cached_item();
-};
-class Cached_item_str :public Cached_item
-{
- Item *item;
- String value,tmp_value;
-public:
- Cached_item_str(THD *thd, Item *arg);
- In_C_you_should_use_my_bool_instead() cmp(void);
- ~Cached_item_str();
-};
-class Cached_item_real :public Cached_item
-{
- Item *item;
- double value;
-public:
- Cached_item_real(Item *item_par) :item(item_par),value(0.0) {}
- In_C_you_should_use_my_bool_instead() cmp(void);
-};
-class Cached_item_int :public Cached_item
-{
- Item *item;
- longlong value;
-public:
- Cached_item_int(Item *item_par) :item(item_par),value(0) {}
- In_C_you_should_use_my_bool_instead() cmp(void);
-};
-class Cached_item_decimal :public Cached_item
-{
- Item *item;
- my_decimal value;
-public:
- Cached_item_decimal(Item *item_par);
- In_C_you_should_use_my_bool_instead() cmp(void);
-};
-class Cached_item_field :public Cached_item
-{
- uchar *buff;
- Field *field;
- uint length;
-public:
- Cached_item_field(Item_field *item)
- {
- field= item->field;
- buff= (uchar*) sql_calloc(length=field->pack_length());
- }
- In_C_you_should_use_my_bool_instead() cmp(void);
-};
-class Item_default_value : public Item_field
-{
-public:
- Item *arg;
- Item_default_value(Name_resolution_context *context_arg)
- :Item_field(context_arg, (const char *)NULL, (const char *)NULL,
- (const char *)NULL),
- arg(NULL) {}
- Item_default_value(Name_resolution_context *context_arg, Item *a)
- :Item_field(context_arg, (const char *)NULL, (const char *)NULL,
- (const char *)NULL),
- arg(a) {}
- enum Type type() const { return DEFAULT_VALUE_ITEM; }
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- virtual void print(String *str, enum_query_type query_type);
- int save_in_field(Field *field_arg, In_C_you_should_use_my_bool_instead() no_conversions);
- table_map used_tables() const { return (table_map)0L; }
- In_C_you_should_use_my_bool_instead() walk(Item_processor processor, In_C_you_should_use_my_bool_instead() walk_subquery, uchar *args)
- {
- return arg->walk(processor, walk_subquery, args) ||
- (this->*processor)(args);
- }
- Item *transform(Item_transformer transformer, uchar *args);
-};
-class Item_insert_value : public Item_field
-{
-public:
- Item *arg;
- Item_insert_value(Name_resolution_context *context_arg, Item *a)
- :Item_field(context_arg, (const char *)NULL, (const char *)NULL,
- (const char *)NULL),
- arg(a) {}
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- virtual void print(String *str, enum_query_type query_type);
- int save_in_field(Field *field_arg, In_C_you_should_use_my_bool_instead() no_conversions)
- {
- return Item_field::save_in_field(field_arg, no_conversions);
- }
- table_map used_tables() const { return (((table_map) 1) << (sizeof(table_map)*8-1)); }
- In_C_you_should_use_my_bool_instead() walk(Item_processor processor, In_C_you_should_use_my_bool_instead() walk_subquery, uchar *args)
- {
- return arg->walk(processor, walk_subquery, args) ||
- (this->*processor)(args);
- }
-};
-enum trg_action_time_type
-{
- TRG_ACTION_BEFORE= 0, TRG_ACTION_AFTER= 1, TRG_ACTION_MAX
-};
-class Table_triggers_list;
-class Item_trigger_field : public Item_field,
- private Settable_routine_parameter
-{
-public:
- enum row_version_type {OLD_ROW, NEW_ROW};
- row_version_type row_version;
- Item_trigger_field *next_trg_field;
- uint field_idx;
- Table_triggers_list *triggers;
- Item_trigger_field(Name_resolution_context *context_arg,
- row_version_type row_ver_arg,
- const char *field_name_arg,
- ulong priv, const In_C_you_should_use_my_bool_instead() ro)
- :Item_field(context_arg,
- (const char *)NULL, (const char *)NULL, field_name_arg),
- row_version(row_ver_arg), field_idx((uint)-1), original_privilege(priv),
- want_privilege(priv), table_grants(NULL), read_only (ro)
- {}
- void setup_field(THD *thd, TABLE *table, GRANT_INFO *table_grant_info);
- enum Type type() const { return TRIGGER_FIELD_ITEM; }
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const;
- In_C_you_should_use_my_bool_instead() fix_fields(THD *, Item **);
- virtual void print(String *str, enum_query_type query_type);
- table_map used_tables() const { return (table_map)0L; }
- Field *get_tmp_table_field() { return 0; }
- Item *copy_or_same(THD *thd) { return this; }
- Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); }
- void cleanup();
-private:
- void set_required_privilege(In_C_you_should_use_my_bool_instead() rw);
- In_C_you_should_use_my_bool_instead() set_value(THD *thd, sp_rcontext *ctx, Item **it);
-public:
- Settable_routine_parameter *get_settable_routine_parameter()
- {
- return (read_only ? 0 : this);
- }
- In_C_you_should_use_my_bool_instead() set_value(THD *thd, Item **it)
- {
- return set_value(thd, NULL, it);
- }
-private:
- ulong original_privilege;
- ulong want_privilege;
- GRANT_INFO *table_grants;
- In_C_you_should_use_my_bool_instead() read_only;
-};
-class Item_cache: public Item_basic_constant
-{
-protected:
- Item *example;
- table_map used_table_map;
- Field *cached_field;
- enum enum_field_types cached_field_type;
-public:
- Item_cache():
- example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING)
- {
- fixed= 1;
- null_value= 1;
- }
- Item_cache(enum_field_types field_type_arg):
- example(0), used_table_map(0), cached_field(0), cached_field_type(field_type_arg)
- {
- fixed= 1;
- null_value= 1;
- }
- void set_used_tables(table_map map) { used_table_map= map; }
- virtual In_C_you_should_use_my_bool_instead() allocate(uint i) { return 0; }
- virtual In_C_you_should_use_my_bool_instead() setup(Item *item)
- {
- example= item;
- max_length= item->max_length;
- decimals= item->decimals;
- collation.set(item->collation);
- unsigned_flag= item->unsigned_flag;
- if (item->type() == FIELD_ITEM)
- cached_field= ((Item_field *)item)->field;
- return 0;
- };
- virtual void store(Item *)= 0;
- enum Type type() const { return CACHE_ITEM; }
- enum_field_types field_type() const { return cached_field_type; }
- static Item_cache* get_cache(const Item *item);
- table_map used_tables() const { return used_table_map; }
- virtual void keep_array() {}
- virtual void print(String *str, enum_query_type query_type);
- In_C_you_should_use_my_bool_instead() eq_def(Field *field)
- {
- return cached_field ? cached_field->eq_def (field) : (0);
- }
- In_C_you_should_use_my_bool_instead() eq(const Item *item, In_C_you_should_use_my_bool_instead() binary_cmp) const
- {
- return this == item;
- }
-};
-class Item_cache_int: public Item_cache
-{
-protected:
- longlong value;
-public:
- Item_cache_int(): Item_cache(), value(0) {}
- Item_cache_int(enum_field_types field_type_arg):
- Item_cache(field_type_arg), value(0) {}
- void store(Item *item);
- void store(Item *item, longlong val_arg);
- double val_real() { assert(fixed == 1); return (double) value; }
- longlong val_int() { assert(fixed == 1); return value; }
- String* val_str(String *str);
- my_decimal *val_decimal(my_decimal *);
- enum Item_result result_type() const { return INT_RESULT; }
- In_C_you_should_use_my_bool_instead() result_as_longlong() { return (1); }
-};
-class Item_cache_real: public Item_cache
-{
- double value;
-public:
- Item_cache_real(): Item_cache(), value(0) {}
- void store(Item *item);
- double val_real() { assert(fixed == 1); return value; }
- longlong val_int();
- String* val_str(String *str);
- my_decimal *val_decimal(my_decimal *);
- enum Item_result result_type() const { return REAL_RESULT; }
-};
-class Item_cache_decimal: public Item_cache
-{
-protected:
- my_decimal decimal_value;
-public:
- Item_cache_decimal(): Item_cache() {}
- void store(Item *item);
- double val_real();
- longlong val_int();
- String* val_str(String *str);
- my_decimal *val_decimal(my_decimal *);
- enum Item_result result_type() const { return DECIMAL_RESULT; }
-};
-class Item_cache_str: public Item_cache
-{
- char buffer[80];
- String *value, value_buff;
- In_C_you_should_use_my_bool_instead() is_varbinary;
-public:
- Item_cache_str(const Item *item) :
- Item_cache(), value(0),
- is_varbinary(item->type() == FIELD_ITEM &&
- ((const Item_field *) item)->field->type() ==
- MYSQL_TYPE_VARCHAR &&
- !((const Item_field *) item)->field->has_charset())
- {}
- void store(Item *item);
- double val_real();
- longlong val_int();
- String* val_str(String *) { assert(fixed == 1); return value; }
- my_decimal *val_decimal(my_decimal *);
- enum Item_result result_type() const { return STRING_RESULT; }
- CHARSET_INFO *charset() const { return value->charset(); };
- int save_in_field(Field *field, In_C_you_should_use_my_bool_instead() no_conversions);
-};
-class Item_cache_row: public Item_cache
-{
- Item_cache **values;
- uint item_count;
- In_C_you_should_use_my_bool_instead() save_array;
-public:
- Item_cache_row()
- :Item_cache(), values(0), item_count(2), save_array(0) {}
- In_C_you_should_use_my_bool_instead() allocate(uint num);
- In_C_you_should_use_my_bool_instead() setup(Item *item);
- void store(Item *item);
- void illegal_method_call(const char *);
- void make_field(Send_field *)
- {
- illegal_method_call((const char*)"make_field");
- };
- double val_real()
- {
- illegal_method_call((const char*)"val");
- return 0;
- };
- longlong val_int()
- {
- illegal_method_call((const char*)"val_int");
- return 0;
- };
- String *val_str(String *)
- {
- illegal_method_call((const char*)"val_str");
- return 0;
- };
- my_decimal *val_decimal(my_decimal *val)
- {
- illegal_method_call((const char*)"val_decimal");
- return 0;
- };
- enum Item_result result_type() const { return ROW_RESULT; }
- uint cols() { return item_count; }
- Item *element_index(uint i) { return values[i]; }
- Item **addr(uint i) { return (Item **) (values + i); }
- In_C_you_should_use_my_bool_instead() check_cols(uint c);
- In_C_you_should_use_my_bool_instead() null_inside();
- void bring_value();
- void keep_array() { save_array= 1; }
- void cleanup()
- {
- const char *_db_func_, *_db_file_; uint _db_level_; char **_db_framep_; _db_enter_ ("Item_cache_row::cleanup","./sql/item.h",2898,&_db_func_,&_db_file_,&_db_level_, &_db_framep_);
- Item_cache::cleanup();
- if (save_array)
- bzero(values, item_count*sizeof(Item**));
- else
- values= 0;
- do {_db_return_ (2904, &_db_func_, &_db_file_, &_db_level_); return;} while(0);
- }
-};
-class Item_type_holder: public Item
-{
-protected:
- TYPELIB *enum_set_typelib;
- enum_field_types fld_type;
- Field::geometry_type geometry_type;
- void get_full_info(Item *item);
- int prev_decimal_int_part;
-public:
- Item_type_holder(THD*, Item*);
- Item_result result_type() const;
- enum_field_types field_type() const { return fld_type; };
- enum Type type() const { return TYPE_HOLDER; }
- double val_real();
- longlong val_int();
- my_decimal *val_decimal(my_decimal *);
- String *val_str(String*);
- In_C_you_should_use_my_bool_instead() join_types(THD *thd, Item *);
- Field *make_field_by_type(TABLE *table);
- static uint32 display_length(Item *item);
- static enum_field_types get_real_type(Item *);
- Field::geometry_type get_geometry_type() const { return geometry_type; };
-};
-class st_select_lex;
-void mark_select_range_as_dependent(THD *thd,
- st_select_lex *last_select,
- st_select_lex *current_sel,
- Field *found_field, Item *found_item,
- Item_ident *resolved_item);
-extern Cached_item *new_Cached_item(THD *thd, Item *item);
-extern Item_result item_cmp_type(Item_result a,Item_result b);
-extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item);
-extern In_C_you_should_use_my_bool_instead() field_is_equal_to_item(Field *field,Item *item);
-extern my_decimal decimal_zero;
-void free_items(Item *item);
-void cleanup_items(Item *item);
-class THD;
-void close_thread_tables(THD *thd);
-In_C_you_should_use_my_bool_instead() check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables);
-In_C_you_should_use_my_bool_instead() check_single_table_access(THD *thd, ulong privilege,
- TABLE_LIST *tables, In_C_you_should_use_my_bool_instead() no_errors);
-In_C_you_should_use_my_bool_instead() check_routine_access(THD *thd,ulong want_access,char *db,char *name,
- In_C_you_should_use_my_bool_instead() is_proc, In_C_you_should_use_my_bool_instead() no_errors);
-In_C_you_should_use_my_bool_instead() check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);
-In_C_you_should_use_my_bool_instead() check_some_routine_access(THD *thd, const char *db, const char *name, In_C_you_should_use_my_bool_instead() is_proc);
-In_C_you_should_use_my_bool_instead() multi_update_precheck(THD *thd, TABLE_LIST *tables);
-In_C_you_should_use_my_bool_instead() multi_delete_precheck(THD *thd, TABLE_LIST *tables);
-int mysql_multi_update_prepare(THD *thd);
-int mysql_multi_delete_prepare(THD *thd);
-In_C_you_should_use_my_bool_instead() mysql_insert_select_prepare(THD *thd);
-In_C_you_should_use_my_bool_instead() update_precheck(THD *thd, TABLE_LIST *tables);
-In_C_you_should_use_my_bool_instead() delete_precheck(THD *thd, TABLE_LIST *tables);
-In_C_you_should_use_my_bool_instead() insert_precheck(THD *thd, TABLE_LIST *tables);
-In_C_you_should_use_my_bool_instead() create_table_precheck(THD *thd, TABLE_LIST *tables,
- TABLE_LIST *create_table);
-int append_query_string(CHARSET_INFO *csinfo,
- String const *from, String *to);
-void get_default_definer(THD *thd, LEX_USER *definer);
-LEX_USER *create_default_definer(THD *thd);
-LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
-LEX_USER *get_current_user(THD *thd, LEX_USER *user);
-In_C_you_should_use_my_bool_instead() check_string_byte_length(LEX_STRING *str, const char *err_msg,
- uint max_byte_length);
-In_C_you_should_use_my_bool_instead() check_string_char_length(LEX_STRING *str, const char *err_msg,
- uint max_char_length, CHARSET_INFO *cs,
- In_C_you_should_use_my_bool_instead() no_error);
-In_C_you_should_use_my_bool_instead() test_if_data_home_dir(const char *dir);
-In_C_you_should_use_my_bool_instead() parse_sql(THD *thd,
- class Lex_input_stream *lip,
- class Object_creation_ctx *creation_ctx);
-enum enum_mysql_completiontype {
- ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
- COMMIT_RELEASE=-1, COMMIT=0, COMMIT_AND_CHAIN=6
-};
-In_C_you_should_use_my_bool_instead() begin_trans(THD *thd);
-In_C_you_should_use_my_bool_instead() end_active_trans(THD *thd);
-int end_trans(THD *thd, enum enum_mysql_completiontype completion);
-Item *negate_expression(THD *thd, Item *expr);
-int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
-void sql_print_error(const char *format, ...) __attribute__((format(printf, 1, 2)));
-void sql_print_warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
-void sql_print_information(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-typedef void (*sql_print_message_func)(const char *format, ...)
- __attribute__((format(printf, 1, 2)));
-extern sql_print_message_func sql_print_message_handlers[];
-int error_log_print(enum loglevel level, const char *format,
- va_list args);
-In_C_you_should_use_my_bool_instead() slow_log_print(THD *thd, const char *query, uint query_length,
- ulonglong current_utime);
-In_C_you_should_use_my_bool_instead() general_log_print(THD *thd, enum enum_server_command command,
- const char *format,...);
-In_C_you_should_use_my_bool_instead() general_log_write(THD *thd, enum enum_server_command command,
- const char *query, uint query_length);
-#include "sql_class.h"
-#include "log.h"
-class Relay_log_info;
-class Format_description_log_event;
-class TC_LOG
-{
- public:
- int using_heuristic_recover();
- TC_LOG() {}
- virtual ~TC_LOG() {}
- virtual int open(const char *opt_name)=0;
- virtual void close()=0;
- virtual int log_xid(THD *thd, my_xid xid)=0;
- virtual void unlog(ulong cookie, my_xid xid)=0;
-};
-class TC_LOG_DUMMY: public TC_LOG
-{
-public:
- TC_LOG_DUMMY() {}
- int open(const char *opt_name) { return 0; }
- void close() { }
- int log_xid(THD *thd, my_xid xid) { return 1; }
- void unlog(ulong cookie, my_xid xid) { }
-};
-class TC_LOG_MMAP: public TC_LOG
-{
- public:
- typedef enum {
- POOL,
- ERROR,
- DIRTY
- } PAGE_STATE;
- private:
- typedef struct st_page {
- struct st_page *next;
- my_xid *start, *end;
- my_xid *ptr;
- int size, free;
- int waiters;
- PAGE_STATE state;
- pthread_mutex_t lock;
- pthread_cond_t cond;
- } PAGE;
- char logname[512];
- File fd;
- my_off_t file_length;
- uint npages, inited;
- uchar *data;
- struct st_page *pages, *syncing, *active, *pool, *pool_last;
- pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
- pthread_cond_t COND_pool, COND_active;
- public:
- TC_LOG_MMAP(): inited(0) {}
- int open(const char *opt_name);
- void close();
- int log_xid(THD *thd, my_xid xid);
- void unlog(ulong cookie, my_xid xid);
- int recover();
- private:
- void get_active_from_pool();
- int sync();
- int overflow();
-};
-extern TC_LOG *tc_log;
-extern TC_LOG_MMAP tc_log_mmap;
-extern TC_LOG_DUMMY tc_log_dummy;
-class Relay_log_info;
-typedef struct st_log_info
-{
- char log_file_name[512];
- my_off_t index_file_offset, index_file_start_offset;
- my_off_t pos;
- In_C_you_should_use_my_bool_instead() fatal;
- pthread_mutex_t lock;
- st_log_info()
- : index_file_offset(0), index_file_start_offset(0),
- pos(0), fatal(0)
- {
- log_file_name[0] = '\0';
- pthread_mutex_init(&lock, NULL);
- }
- ~st_log_info() { pthread_mutex_destroy(&lock);}
-} LOG_INFO;
-class Log_event;
-class Rows_log_event;
-enum enum_log_type { LOG_UNKNOWN, LOG_NORMAL, LOG_BIN };
-enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
-class MYSQL_LOG
-{
-public:
- MYSQL_LOG();
- void init_pthread_objects();
- void cleanup();
- In_C_you_should_use_my_bool_instead() open(const char *log_name,
- enum_log_type log_type,
- const char *new_name,
- enum cache_type io_cache_type_arg);
- void init(enum_log_type log_type_arg,
- enum cache_type io_cache_type_arg);
- void close(uint exiting);
- inline In_C_you_should_use_my_bool_instead() is_open() { return log_state != LOG_CLOSED; }
- const char *generate_name(const char *log_name, const char *suffix,
- In_C_you_should_use_my_bool_instead() strip_ext, char *buff);
- int generate_new_name(char *new_name, const char *log_name);
- protected:
- pthread_mutex_t LOCK_log;
- char *name;
- char log_file_name[512];
- char time_buff[20], db[(64*3) + 1];
- In_C_you_should_use_my_bool_instead() write_error, inited;
- IO_CACHE log_file;
- enum_log_type log_type;
- volatile enum_log_state log_state;
- enum cache_type io_cache_type;
- friend class Log_event;
-};
-class MYSQL_QUERY_LOG: public MYSQL_LOG
-{
-public:
- MYSQL_QUERY_LOG() : last_time(0) {}
- void reopen_file();
- In_C_you_should_use_my_bool_instead() write(time_t event_time, const char *user_host,
- uint user_host_len, int thread_id,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len);
- In_C_you_should_use_my_bool_instead() write(THD *thd, time_t current_time, time_t query_start_arg,
- const char *user_host, uint user_host_len,
- ulonglong query_utime, ulonglong lock_utime, In_C_you_should_use_my_bool_instead() is_command,
- const char *sql_text, uint sql_text_len);
- In_C_you_should_use_my_bool_instead() open_slow_log(const char *log_name)
- {
- char buf[512];
- return open(generate_name(log_name, "-slow.log", 0, buf), LOG_NORMAL, 0,
- WRITE_CACHE);
- }
- In_C_you_should_use_my_bool_instead() open_query_log(const char *log_name)
- {
- char buf[512];
- return open(generate_name(log_name, ".log", 0, buf), LOG_NORMAL, 0,
- WRITE_CACHE);
- }
-private:
- time_t last_time;
-};
-class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
-{
- private:
- pthread_mutex_t LOCK_index;
- pthread_mutex_t LOCK_prep_xids;
- pthread_cond_t COND_prep_xids;
- pthread_cond_t update_cond;
- ulonglong bytes_written;
- IO_CACHE index_file;
- char index_file_name[512];
- ulong max_size;
- long prepared_xids;
- uint file_id;
- uint open_count;
- int readers_count;
- In_C_you_should_use_my_bool_instead() need_start_event;
- In_C_you_should_use_my_bool_instead() no_auto_events;
- ulonglong m_table_map_version;
- int write_to_file(IO_CACHE *cache);
- void new_file_without_locking();
- void new_file_impl(In_C_you_should_use_my_bool_instead() need_lock);
-public:
- MYSQL_LOG::generate_name;
- MYSQL_LOG::is_open;
- Format_description_log_event *description_event_for_exec,
- *description_event_for_queue;
- MYSQL_BIN_LOG();
- int open(const char *opt_name);
- void close();
- int log_xid(THD *thd, my_xid xid);
- void unlog(ulong cookie, my_xid xid);
- int recover(IO_CACHE *log, Format_description_log_event *fdle);
- In_C_you_should_use_my_bool_instead() is_table_mapped(TABLE *table) const
- {
- return table->s->table_map_version == table_map_version();
- }
- ulonglong table_map_version() const { return m_table_map_version; }
- void update_table_map_version() { ++m_table_map_version; }
- int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event);
- void reset_bytes_written()
- {
- bytes_written = 0;
- }
- void harvest_bytes_written(ulonglong* counter)
- {
- char buf1[22],buf2[22];
- const char *_db_func_, *_db_file_; uint _db_level_; char **_db_framep_; _db_enter_ ("harvest_bytes_written","./sql/log.h",321,&_db_func_,&_db_file_,&_db_level_, &_db_framep_);
- (*counter)+=bytes_written;
- do {_db_pargs_(324,"info"); _db_doprnt_ ("counter: %s bytes_written: %s", llstr(*counter,buf1), llstr(bytes_written,buf2));} while(0);
- bytes_written=0;
- do {_db_return_ (326, &_db_func_, &_db_file_, &_db_level_); return;} while(0);
- }
- void set_max_size(ulong max_size_arg);
- void signal_update();
- void wait_for_update(THD* thd, In_C_you_should_use_my_bool_instead() master_or_slave);
- void set_need_start_event() { need_start_event = 1; }
- void init(In_C_you_should_use_my_bool_instead() no_auto_events_arg, ulong max_size);
- void init_pthread_objects();
- void cleanup();
- In_C_you_should_use_my_bool_instead() open(const char *log_name,
- enum_log_type log_type,
- const char *new_name,
- enum cache_type io_cache_type_arg,
- In_C_you_should_use_my_bool_instead() no_auto_events_arg, ulong max_size,
- In_C_you_should_use_my_bool_instead() null_created);
- In_C_you_should_use_my_bool_instead() open_index_file(const char *index_file_name_arg,
- const char *log_name);
- void new_file();
- In_C_you_should_use_my_bool_instead() write(Log_event* event_info);
- In_C_you_should_use_my_bool_instead() write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
- int write_cache(IO_CACHE *cache, In_C_you_should_use_my_bool_instead() lock_log, In_C_you_should_use_my_bool_instead() flush_and_sync);
- void start_union_events(THD *thd, query_id_t query_id_param);
- void stop_union_events(THD *thd);
- In_C_you_should_use_my_bool_instead() is_query_in_union(THD *thd, query_id_t query_id_param);
- In_C_you_should_use_my_bool_instead() appendv(const char* buf,uint len,...);
- In_C_you_should_use_my_bool_instead() append(Log_event* ev);
- void make_log_name(char* buf, const char* log_ident);
- In_C_you_should_use_my_bool_instead() is_active(const char* log_file_name);
- int update_log_index(LOG_INFO* linfo, In_C_you_should_use_my_bool_instead() need_update_threads);
- void rotate_and_purge(uint flags);
- In_C_you_should_use_my_bool_instead() flush_and_sync();
- int purge_logs(const char *to_log, In_C_you_should_use_my_bool_instead() included,
- In_C_you_should_use_my_bool_instead() need_mutex, In_C_you_should_use_my_bool_instead() need_update_threads,
- ulonglong *decrease_log_space);
- int purge_logs_before_date(time_t purge_time);
- int purge_first_log(Relay_log_info* rli, In_C_you_should_use_my_bool_instead() included);
- In_C_you_should_use_my_bool_instead() reset_logs(THD* thd);
- void close(uint exiting);
- int find_log_pos(LOG_INFO* linfo, const char* log_name,
- In_C_you_should_use_my_bool_instead() need_mutex);
- int find_next_log(LOG_INFO* linfo, In_C_you_should_use_my_bool_instead() need_mutex);
- int get_current_log(LOG_INFO* linfo);
- int raw_get_current_log(LOG_INFO* linfo);
- uint next_file_id();
- inline char* get_index_fname() { return index_file_name;}
- inline char* get_log_fname() { return log_file_name; }
- inline char* get_name() { return name; }
- inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
- inline IO_CACHE* get_log_file() { return &log_file; }
- inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
- inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
- inline IO_CACHE *get_index_file() { return &index_file;}
- inline uint32 get_open_count() { return open_count; }
-};
-class Log_event_handler
-{
-public:
- Log_event_handler() {}
- virtual In_C_you_should_use_my_bool_instead() init()= 0;
- virtual void cleanup()= 0;
- virtual In_C_you_should_use_my_bool_instead() log_slow(THD *thd, time_t current_time,
- time_t query_start_arg, const char *user_host,
- uint user_host_len, ulonglong query_utime,
- ulonglong lock_utime, In_C_you_should_use_my_bool_instead() is_command,
- const char *sql_text, uint sql_text_len)= 0;
- virtual In_C_you_should_use_my_bool_instead() log_error(enum loglevel level, const char *format,
- va_list args)= 0;
- virtual In_C_you_should_use_my_bool_instead() log_general(THD *thd, time_t event_time, const char *user_host,
- uint user_host_len, int thread_id,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len,
- CHARSET_INFO *client_cs)= 0;
- virtual ~Log_event_handler() {}
-};
-int check_if_log_table(uint db_len, const char *db, uint table_name_len,
- const char *table_name, uint check_if_opened);
-class Log_to_csv_event_handler: public Log_event_handler
-{
- friend class LOGGER;
-public:
- Log_to_csv_event_handler();
- ~Log_to_csv_event_handler();
- virtual In_C_you_should_use_my_bool_instead() init();
- virtual void cleanup();
- virtual In_C_you_should_use_my_bool_instead() log_slow(THD *thd, time_t current_time,
- time_t query_start_arg, const char *user_host,
- uint user_host_len, ulonglong query_utime,
- ulonglong lock_utime, In_C_you_should_use_my_bool_instead() is_command,
- const char *sql_text, uint sql_text_len);
- virtual In_C_you_should_use_my_bool_instead() log_error(enum loglevel level, const char *format,
- va_list args);
- virtual In_C_you_should_use_my_bool_instead() log_general(THD *thd, time_t event_time, const char *user_host,
- uint user_host_len, int thread_id,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len,
- CHARSET_INFO *client_cs);
- int activate_log(THD *thd, uint log_type);
-};
-class Log_to_file_event_handler: public Log_event_handler
-{
- MYSQL_QUERY_LOG mysql_log;
- MYSQL_QUERY_LOG mysql_slow_log;
- In_C_you_should_use_my_bool_instead() is_initialized;
-public:
- Log_to_file_event_handler(): is_initialized((0))
- {}
- virtual In_C_you_should_use_my_bool_instead() init();
- virtual void cleanup();
- virtual In_C_you_should_use_my_bool_instead() log_slow(THD *thd, time_t current_time,
- time_t query_start_arg, const char *user_host,
- uint user_host_len, ulonglong query_utime,
- ulonglong lock_utime, In_C_you_should_use_my_bool_instead() is_command,
- const char *sql_text, uint sql_text_len);
- virtual In_C_you_should_use_my_bool_instead() log_error(enum loglevel level, const char *format,
- va_list args);
- virtual In_C_you_should_use_my_bool_instead() log_general(THD *thd, time_t event_time, const char *user_host,
- uint user_host_len, int thread_id,
- const char *command_type, uint command_type_len,
- const char *sql_text, uint sql_text_len,
- CHARSET_INFO *client_cs);
- void flush();
- void init_pthread_objects();
- MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
- MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
-};
-class LOGGER
-{
- pthread_rwlock_t LOCK_logger;
- uint inited;
- Log_to_csv_event_handler *table_log_handler;
- Log_to_file_event_handler *file_log_handler;
- Log_event_handler *error_log_handler_list[3 + 1];
- Log_event_handler *slow_log_handler_list[3 + 1];
- Log_event_handler *general_log_handler_list[3 + 1];
-public:
- In_C_you_should_use_my_bool_instead() is_log_tables_initialized;
- LOGGER() : inited(0), table_log_handler(NULL),
- file_log_handler(NULL), is_log_tables_initialized((0))
- {}
- void lock_shared() { pthread_rwlock_rdlock(&LOCK_logger); }
- void lock_exclusive() { pthread_rwlock_wrlock(&LOCK_logger); }
- void unlock() { pthread_rwlock_unlock(&LOCK_logger); }
- In_C_you_should_use_my_bool_instead() is_log_table_enabled(uint log_table_type);
- In_C_you_should_use_my_bool_instead() log_command(THD *thd, enum enum_server_command command);
- void init_base();
- void init_log_tables();
- In_C_you_should_use_my_bool_instead() flush_logs(THD *thd);
- void cleanup_base();
- void cleanup_end();
- In_C_you_should_use_my_bool_instead() error_log_print(enum loglevel level, const char *format,
- va_list args);
- In_C_you_should_use_my_bool_instead() slow_log_print(THD *thd, const char *query, uint query_length,
- ulonglong current_utime);
- In_C_you_should_use_my_bool_instead() general_log_print(THD *thd,enum enum_server_command command,
- const char *format, va_list args);
- In_C_you_should_use_my_bool_instead() general_log_write(THD *thd, enum enum_server_command command,
- const char *query, uint query_length);
- int set_handlers(uint error_log_printer,
- uint slow_log_printer,
- uint general_log_printer);
- void init_error_log(uint error_log_printer);
- void init_slow_log(uint slow_log_printer);
- void init_general_log(uint general_log_printer);
- void deactivate_log_handler(THD* thd, uint log_type);
- In_C_you_should_use_my_bool_instead() activate_log_handler(THD* thd, uint log_type);
- MYSQL_QUERY_LOG *get_slow_log_file_handler()
- {
- if (file_log_handler)
- return file_log_handler->get_mysql_slow_log();
- return NULL;
- }
- MYSQL_QUERY_LOG *get_log_file_handler()
- {
- if (file_log_handler)
- return file_log_handler->get_mysql_log();
- return NULL;
- }
-};
-enum enum_binlog_format {
- BINLOG_FORMAT_MIXED= 0,
- BINLOG_FORMAT_STMT= 1,
- BINLOG_FORMAT_ROW= 2,
- BINLOG_FORMAT_UNSPEC= 3
-};
-extern TYPELIB binlog_format_typelib;
-#include "rpl_tblmap.h"
-struct st_table;
-typedef st_table TABLE;
-class table_mapping {
-private:
- MEM_ROOT m_mem_root;
-public:
- enum enum_error {
- ERR_NO_ERROR = 0,
- ERR_LIMIT_EXCEEDED,
- ERR_MEMORY_ALLOCATION
- };
- table_mapping();
- ~table_mapping();
- TABLE* get_table(ulong table_id);
- int set_table(ulong table_id, TABLE* table);
- int remove_table(ulong table_id);
- void clear_tables();
- ulong count() const { return m_table_ids.records; }
-private:
- struct entry {
- ulong table_id;
- union {
- TABLE *table;
- entry *next;
- };
- };
- entry *find_entry(ulong table_id)
- {
- return (entry *)hash_search(&m_table_ids,
- (uchar*)&table_id,
- sizeof(table_id));
- }
- int expand();
- entry *m_free;
- HASH m_table_ids;
-};
-class Reprepare_observer
-{
-public:
- In_C_you_should_use_my_bool_instead() report_error(THD *thd);
- In_C_you_should_use_my_bool_instead() is_invalidated() const { return m_invalidated; }
- void reset_reprepare_observer() { m_invalidated= (0); }
-private:
- In_C_you_should_use_my_bool_instead() m_invalidated;
-};
-class Relay_log_info;
-class Query_log_event;
-class Load_log_event;
-class Slave_log_event;
-class sp_rcontext;
-class sp_cache;
-class Lex_input_stream;
-class Rows_log_event;
-enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
-enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
-enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
-enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
- DELAY_KEY_WRITE_ALL };
-enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT,
- SLAVE_EXEC_MODE_IDEMPOTENT,
- SLAVE_EXEC_MODE_LAST_BIT};
-enum enum_mark_columns
-{ MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE};
-extern char internal_table_name[2];
-extern char empty_c_string[1];
-extern const char **errmesg;
-extern uint tc_heuristic_recover;
-typedef struct st_user_var_events
-{
- user_var_entry *user_var_event;
- char *value;
- ulong length;
- Item_result type;
- uint charset_number;
-} BINLOG_USER_VAR_EVENT;
-typedef struct st_copy_info {
- ha_rows records;
- ha_rows deleted;
- ha_rows updated;
- ha_rows copied;
- ha_rows error_count;
- ha_rows touched;
- enum enum_duplicates handle_duplicates;
- int escape_char, last_errno;
- In_C_you_should_use_my_bool_instead() ignore;
- List<Item> *update_fields;
- List<Item> *update_values;
- TABLE_LIST *view;
-} COPY_INFO;
-class Key_part_spec :public Sql_alloc {
-public:
- const char *field_name;
- uint length;
- Key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {}
- In_C_you_should_use_my_bool_instead() operator==(const Key_part_spec& other) const;
- Key_part_spec *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Key_part_spec(*this); }
-};
-class Alter_drop :public Sql_alloc {
-public:
- enum drop_type {KEY, COLUMN };
- const char *name;
- enum drop_type type;
- Alter_drop(enum drop_type par_type,const char *par_name)
- :name(par_name), type(par_type) {}
- Alter_drop *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Alter_drop(*this); }
-};
-class Alter_column :public Sql_alloc {
-public:
- const char *name;
- Item *def;
- Alter_column(const char *par_name,Item *literal)
- :name(par_name), def(literal) {}
- Alter_column *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Alter_column(*this); }
-};
-class Key :public Sql_alloc {
-public:
- enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY};
- enum Keytype type;
- KEY_CREATE_INFO key_create_info;
- List<Key_part_spec> columns;
- const char *name;
- In_C_you_should_use_my_bool_instead() generated;
- Key(enum Keytype type_par, const char *name_arg,
- KEY_CREATE_INFO *key_info_arg,
- In_C_you_should_use_my_bool_instead() generated_arg, List<Key_part_spec> &cols)
- :type(type_par), key_create_info(*key_info_arg), columns(cols),
- name(name_arg), generated(generated_arg)
- {}
- Key(const Key &rhs, MEM_ROOT *mem_root);
- virtual ~Key() {}
- friend In_C_you_should_use_my_bool_instead() foreign_key_prefix(Key *a, Key *b);
- virtual Key *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Key(*this, mem_root); }
-};
-class Table_ident;
-class Foreign_key: public Key {
-public:
- enum fk_match_opt { FK_MATCH_UNDEF, FK_MATCH_FULL,
- FK_MATCH_PARTIAL, FK_MATCH_SIMPLE};
- enum fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_CASCADE,
- FK_OPTION_SET_NULL, FK_OPTION_NO_ACTION, FK_OPTION_DEFAULT};
- Table_ident *ref_table;
- List<Key_part_spec> ref_columns;
- uint delete_opt, update_opt, match_opt;
- Foreign_key(const char *name_arg, List<Key_part_spec> &cols,
- Table_ident *table, List<Key_part_spec> &ref_cols,
- uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
- :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols),
- ref_table(table), ref_columns(ref_cols),
- delete_opt(delete_opt_arg), update_opt(update_opt_arg),
- match_opt(match_opt_arg)
- {}
- Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root);
- virtual Key *clone(MEM_ROOT *mem_root) const
- { return new (mem_root) Foreign_key(*this, mem_root); }
-};
-typedef struct st_mysql_lock
-{
- TABLE **table;
- uint table_count,lock_count;
- THR_LOCK_DATA **locks;
-} MYSQL_LOCK;
-class LEX_COLUMN : public Sql_alloc
-{
-public:
- String column;
- uint rights;
- LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {}
-};
-#include "sql_lex.h"
-class Table_ident;
-class sql_exchange;
-class LEX_COLUMN;
-class sp_head;
-class sp_name;
-class sp_instr;
-class sp_pcontext;
-class st_alter_tablespace;
-class partition_info;
-class Event_parse_data;
-enum enum_sql_command {
- SQLCOM_SELECT, SQLCOM_CREATE_TABLE, SQLCOM_CREATE_INDEX, SQLCOM_ALTER_TABLE,
- SQLCOM_UPDATE, SQLCOM_INSERT, SQLCOM_INSERT_SELECT,
- SQLCOM_DELETE, SQLCOM_TRUNCATE, SQLCOM_DROP_TABLE, SQLCOM_DROP_INDEX,
- SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS,
- SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_STATUS,
- SQLCOM_SHOW_ENGINE_LOGS, SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_MUTEX,
- SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT,
- SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS,
- SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS,
- SQLCOM_SHOW_TRIGGERS,
- SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
- SQLCOM_GRANT,
- SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB,
- SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
- SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
- SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
- SQLCOM_ASSIGN_TO_KEYCACHE, SQLCOM_PRELOAD_KEYS,
- SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
- SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT,
- SQLCOM_COMMIT, SQLCOM_SAVEPOINT, SQLCOM_RELEASE_SAVEPOINT,
- SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
- SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
- SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
- SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_PURGE_BEFORE, SQLCOM_SHOW_BINLOGS,
- SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
- SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
- SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_UPDATE_MULTI,
- SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_DO,
- SQLCOM_SHOW_WARNS, SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS,
- SQLCOM_SHOW_COLUMN_TYPES, SQLCOM_SHOW_STORAGE_ENGINES, SQLCOM_SHOW_PRIVILEGES,
- SQLCOM_HELP, SQLCOM_CREATE_USER, SQLCOM_DROP_USER, SQLCOM_RENAME_USER,
- SQLCOM_REVOKE_ALL, SQLCOM_CHECKSUM,
- SQLCOM_CREATE_PROCEDURE, SQLCOM_CREATE_SPFUNCTION, SQLCOM_CALL,
- SQLCOM_DROP_PROCEDURE, SQLCOM_ALTER_PROCEDURE,SQLCOM_ALTER_FUNCTION,
- SQLCOM_SHOW_CREATE_PROC, SQLCOM_SHOW_CREATE_FUNC,
- SQLCOM_SHOW_STATUS_PROC, SQLCOM_SHOW_STATUS_FUNC,
- SQLCOM_PREPARE, SQLCOM_EXECUTE, SQLCOM_DEALLOCATE_PREPARE,
- SQLCOM_CREATE_VIEW, SQLCOM_DROP_VIEW,
- SQLCOM_CREATE_TRIGGER, SQLCOM_DROP_TRIGGER,
- SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE,
- SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
- SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
- SQLCOM_ALTER_TABLESPACE,
- SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN,
- SQLCOM_SHOW_AUTHORS, SQLCOM_BINLOG_BASE64_EVENT,
- SQLCOM_SHOW_PLUGINS,
- SQLCOM_SHOW_CONTRIBUTORS,
- SQLCOM_CREATE_SERVER, SQLCOM_DROP_SERVER, SQLCOM_ALTER_SERVER,
- SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT,
- SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS,
- SQLCOM_SHOW_CREATE_TRIGGER,
- SQLCOM_ALTER_DB_UPGRADE,
- SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
- SQLCOM_END
-};
-class Delayed_insert;
-class select_result;
-class Time_zone;
-struct system_variables
-{
- ulong dynamic_variables_version;
- char* dynamic_variables_ptr;
- uint dynamic_variables_head;
- uint dynamic_variables_size;
- ulonglong myisam_max_extra_sort_file_size;
- ulonglong myisam_max_sort_file_size;
- ulonglong max_heap_table_size;
- ulonglong tmp_table_size;
- ulonglong long_query_time;
- ha_rows select_limit;
- ha_rows max_join_size;
- ulong auto_increment_increment, auto_increment_offset;
- ulong bulk_insert_buff_size;
- ulong join_buff_size;
- ulong max_allowed_packet;
- ulong max_error_count;
- ulong max_length_for_sort_data;
- ulong max_sort_length;
- ulong max_tmp_tables;
- ulong max_insert_delayed_threads;
- ulong min_examined_row_limit;
- ulong multi_range_count;
- ulong myisam_repair_threads;
- ulong myisam_sort_buff_size;
- ulong myisam_stats_method;
- ulong net_buffer_length;
- ulong net_interactive_timeout;
- ulong net_read_timeout;
- ulong net_retry_count;
- ulong net_wait_timeout;
- ulong net_write_timeout;
- ulong optimizer_prune_level;
- ulong optimizer_search_depth;
- ulong preload_buff_size;
- ulong profiling_history_size;
- ulong query_cache_type;
- ulong read_buff_size;
- ulong read_rnd_buff_size;
- ulong div_precincrement;
- ulong sortbuff_size;
- ulong thread_handling;
- ulong tx_isolation;
- ulong completion_type;
- ulong sql_mode;
- ulong max_sp_recursion_depth;
- ulong updatable_views_with_limit;
- ulong default_week_format;
- ulong max_seeks_for_key;
- ulong range_alloc_block_size;
- ulong query_alloc_block_size;
- ulong query_prealloc_size;
- ulong trans_alloc_block_size;
- ulong trans_prealloc_size;
- ulong log_warnings;
- ulong group_concat_max_len;
- ulong ndb_autoincrement_prefetch_sz;
- ulong ndb_index_stat_cache_entries;
- ulong ndb_index_stat_update_freq;
- ulong binlog_format;
- my_thread_id pseudo_thread_id;
- my_bool low_priority_updates;
- my_bool new_mode;
- my_bool old_mode;
- my_bool query_cache_wlock_invalidate;
- my_bool engine_condition_pushdown;
- my_bool keep_files_on_create;
- my_bool ndb_force_send;
- my_bool ndb_use_copying_alter_table;
- my_bool ndb_use_exact_count;
- my_bool ndb_use_transactions;
- my_bool ndb_index_stat_enable;
- my_bool old_alter_table;
- my_bool old_passwords;
- plugin_ref table_plugin;
- CHARSET_INFO *character_set_filesystem;
- CHARSET_INFO *character_set_client;
- CHARSET_INFO *character_set_results;
- CHARSET_INFO *collation_server;
- CHARSET_INFO *collation_database;
- CHARSET_INFO *collation_connection;
- MY_LOCALE *lc_time_names;
- Time_zone *time_zone;
- DATE_TIME_FORMAT *date_format;
- DATE_TIME_FORMAT *datetime_format;
- DATE_TIME_FORMAT *time_format;
- my_bool sysdate_is_now;
-};
-typedef struct system_status_var
-{
- ulonglong bytes_received;
- ulonglong bytes_sent;
- ulong com_other;
- ulong com_stat[(uint) SQLCOM_END];
- ulong created_tmp_disk_tables;
- ulong created_tmp_tables;
- ulong ha_commit_count;
- ulong ha_delete_count;
- ulong ha_read_first_count;
- ulong ha_read_last_count;
- ulong ha_read_key_count;
- ulong ha_read_next_count;
- ulong ha_read_prev_count;
- ulong ha_read_rnd_count;
- ulong ha_read_rnd_next_count;
- ulong ha_rollback_count;
- ulong ha_update_count;
- ulong ha_write_count;
- ulong ha_prepare_count;
- ulong ha_discover_count;
- ulong ha_savepoint_count;
- ulong ha_savepoint_rollback_count;
- ulong key_blocks_changed;
- ulong key_blocks_used;
- ulong key_cache_r_requests;
- ulong key_cache_read;
- ulong key_cache_w_requests;
- ulong key_cache_write;
- ulong net_big_packet_count;
- ulong opened_tables;
- ulong opened_shares;
- ulong select_full_join_count;
- ulong select_full_range_join_count;
- ulong select_range_count;
- ulong select_range_check_count;
- ulong select_scan_count;
- ulong long_query_count;
- ulong filesort_merge_passes;
- ulong filesort_range_count;
- ulong filesort_rows;
- ulong filesort_scan_count;
- ulong com_stmt_prepare;
- ulong com_stmt_reprepare;
- ulong com_stmt_execute;
- ulong com_stmt_send_long_data;
- ulong com_stmt_fetch;
- ulong com_stmt_reset;
- ulong com_stmt_close;
- double last_query_cost;
-} STATUS_VAR;
-void mark_transaction_to_rollback(THD *thd, In_C_you_should_use_my_bool_instead() all);
-#include "sql_acl.h"
-#include "slave.h"
-#include "log.h"
-#include "my_list.h"
-#include "rpl_filter.h"
-#include "mysql.h"
-#include "mysql_version.h"
-#include "mysql_com.h"
-#include "mysql_time.h"
-#include "my_list.h"
-extern unsigned int mysql_port;
-extern char *mysql_unix_port;
-typedef struct st_mysql_field {
- char *name;
- char *org_name;
- char *table;
- char *org_table;
- char *db;
- char *catalog;
- char *def;
- unsigned long length;
- unsigned long max_length;
- unsigned int name_length;
- unsigned int org_name_length;
- unsigned int table_length;
- unsigned int org_table_length;
- unsigned int db_length;
- unsigned int catalog_length;
- unsigned int def_length;
- unsigned int flags;
- unsigned int decimals;
- unsigned int charsetnr;
- enum enum_field_types type;
- void *extension;
-} MYSQL_FIELD;
-typedef char **MYSQL_ROW;
-typedef unsigned int MYSQL_FIELD_OFFSET;
-#include "typelib.h"
-typedef struct st_mysql_rows {
- struct st_mysql_rows *next;
- MYSQL_ROW data;
- unsigned long length;
-} MYSQL_ROWS;
-typedef MYSQL_ROWS *MYSQL_ROW_OFFSET;
-#include "my_alloc.h"
-typedef struct embedded_query_result EMBEDDED_QUERY_RESULT;
-typedef struct st_mysql_data {
- MYSQL_ROWS *data;
- struct embedded_query_result *embedded_info;
- MEM_ROOT alloc;
- my_ulonglong rows;
- unsigned int fields;
- void *extension;
-} MYSQL_DATA;
-enum mysql_option
-{
- MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
- MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
- MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
- MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
- MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
- MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
- MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
- MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT
-};
-struct st_mysql_options {
- unsigned int connect_timeout, read_timeout, write_timeout;
- unsigned int port, protocol;
- unsigned long client_flag;
- char *host,*user,*password,*unix_socket,*db;
- struct st_dynamic_array *init_commands;
- char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
- char *ssl_key;
- char *ssl_cert;
- char *ssl_ca;
- char *ssl_capath;
- char *ssl_cipher;
- char *shared_memory_base_name;
- unsigned long max_allowed_packet;
- my_bool use_ssl;
- my_bool compress,named_pipe;
- my_bool rpl_probe;
- my_bool rpl_parse;
- my_bool no_master_reads;
- my_bool separate_thread;
- enum mysql_option methods_to_use;
- char *client_ip;
- my_bool secure_auth;
- my_bool report_data_truncation;
- int (*local_infile_init)(void **, const char *, void *);
- int (*local_infile_read)(void *, char *, unsigned int);
- void (*local_infile_end)(void *);
- int (*local_infile_error)(void *, char *, unsigned int);
- void *local_infile_userdata;
- void *extension;
-};
-enum mysql_status
-{
- MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
-};
-enum mysql_protocol_type
-{
- MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
- MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
-};
-enum mysql_rpl_type
-{
- MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
-};
-typedef struct character_set
-{
- unsigned int number;
- unsigned int state;
- const char *csname;
- const char *name;
- const char *comment;
- const char *dir;
- unsigned int mbminlen;
- unsigned int mbmaxlen;
-} MY_CHARSET_INFO;
-struct st_mysql_methods;
-struct st_mysql_stmt;
-typedef struct st_mysql
-{
- NET net;
- unsigned char *connector_fd;
- char *host,*user,*passwd,*unix_socket,*server_version,*host_info;
- char *info, *db;
- struct charset_info_st *charset;
- MYSQL_FIELD *fields;
- MEM_ROOT field_alloc;
- my_ulonglong affected_rows;
- my_ulonglong insert_id;
- my_ulonglong extra_info;
- unsigned long thread_id;
- unsigned long packet_length;
- unsigned int port;
- unsigned long client_flag,server_capabilities;
- unsigned int protocol_version;
- unsigned int field_count;
- unsigned int server_status;
- unsigned int server_language;
- unsigned int warning_count;
- struct st_mysql_options options;
- enum mysql_status status;
- my_bool free_me;
- my_bool reconnect;
- char scramble[20 +1];
- my_bool rpl_pivot;
- struct st_mysql* master, *next_slave;
- struct st_mysql* last_used_slave;
- struct st_mysql* last_used_con;
- LIST *stmts;
- const struct st_mysql_methods *methods;
- void *thd;
- my_bool *unbuffered_fetch_owner;
- char *info_buffer;
- void *extension;
-} MYSQL;
-typedef struct st_mysql_res {
- my_ulonglong row_count;
- MYSQL_FIELD *fields;
- MYSQL_DATA *data;
- MYSQL_ROWS *data_cursor;
- unsigned long *lengths;
- MYSQL *handle;
- const struct st_mysql_methods *methods;
- MYSQL_ROW row;
- MYSQL_ROW current_row;
- MEM_ROOT field_alloc;
- unsigned int field_count, current_field;
- my_bool eof;
- my_bool unbuffered_fetch_cancelled;
- void *extension;
-} MYSQL_RES;
-typedef struct st_mysql_manager
-{
- NET net;
- char *host, *user, *passwd;
- char *net_buf, *net_buf_pos, *net_data_end;
- unsigned int port;
- int cmd_status;
- int last_errno;
- int net_buf_size;
- my_bool free_me;
- my_bool eof;
- char last_error[256];
- void *extension;
-} MYSQL_MANAGER;
-typedef struct st_mysql_parameters
-{
- unsigned long *p_max_allowed_packet;
- unsigned long *p_net_buffer_length;
- void *extension;
-} MYSQL_PARAMETERS;
-int mysql_server_init(int argc, char **argv, char **groups);
-void mysql_server_end(void);
-MYSQL_PARAMETERS * mysql_get_parameters(void);
-my_bool mysql_thread_init(void);
-void mysql_thread_end(void);
-my_ulonglong mysql_num_rows(MYSQL_RES *res);
-unsigned int mysql_num_fields(MYSQL_RES *res);
-my_bool mysql_eof(MYSQL_RES *res);
-MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES *res,
- unsigned int fieldnr);
-MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES *res);
-MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *res);
-MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *res);
-unsigned int mysql_field_count(MYSQL *mysql);
-my_ulonglong mysql_affected_rows(MYSQL *mysql);
-my_ulonglong mysql_insert_id(MYSQL *mysql);
-unsigned int mysql_errno(MYSQL *mysql);
-const char * mysql_error(MYSQL *mysql);
-const char * mysql_sqlstate(MYSQL *mysql);
-unsigned int mysql_warning_count(MYSQL *mysql);
-const char * mysql_info(MYSQL *mysql);
-unsigned long mysql_thread_id(MYSQL *mysql);
-const char * mysql_character_set_name(MYSQL *mysql);
-int mysql_set_character_set(MYSQL *mysql, const char *csname);
-MYSQL * mysql_init(MYSQL *mysql);
-my_bool mysql_ssl_set(MYSQL *mysql, const char *key,
- const char *cert, const char *ca,
- const char *capath, const char *cipher);
-const char * mysql_get_ssl_cipher(MYSQL *mysql);
-my_bool mysql_change_user(MYSQL *mysql, const char *user,
- const char *passwd, const char *db);
-MYSQL * mysql_real_connect(MYSQL *mysql, const char *host,
- const char *user,
- const char *passwd,
- const char *db,
- unsigned int port,
- const char *unix_socket,
- unsigned long clientflag);
-int mysql_select_db(MYSQL *mysql, const char *db);
-int mysql_query(MYSQL *mysql, const char *q);
-int mysql_send_query(MYSQL *mysql, const char *q,
- unsigned long length);
-int mysql_real_query(MYSQL *mysql, const char *q,
- unsigned long length);
-MYSQL_RES * mysql_store_result(MYSQL *mysql);
-MYSQL_RES * mysql_use_result(MYSQL *mysql);
-my_bool mysql_master_query(MYSQL *mysql, const char *q,
- unsigned long length);
-my_bool mysql_master_send_query(MYSQL *mysql, const char *q,
- unsigned long length);
-my_bool mysql_slave_query(MYSQL *mysql, const char *q,
- unsigned long length);
-my_bool mysql_slave_send_query(MYSQL *mysql, const char *q,
- unsigned long length);
-void mysql_get_character_set_info(MYSQL *mysql,
- MY_CHARSET_INFO *charset);
-void
-mysql_set_local_infile_handler(MYSQL *mysql,
- int (*local_infile_init)(void **, const char *,
- void *),
- int (*local_infile_read)(void *, char *,
- unsigned int),
- void (*local_infile_end)(void *),
- int (*local_infile_error)(void *, char*,
- unsigned int),
- void *);
-void
-mysql_set_local_infile_default(MYSQL *mysql);
-void mysql_enable_rpl_parse(MYSQL* mysql);
-void mysql_disable_rpl_parse(MYSQL* mysql);
-int mysql_rpl_parse_enabled(MYSQL* mysql);
-void mysql_enable_reads_from_master(MYSQL* mysql);
-void mysql_disable_reads_from_master(MYSQL* mysql);
-my_bool mysql_reads_from_master_enabled(MYSQL* mysql);
-enum mysql_rpl_type mysql_rpl_query_type(const char* q, int len);
-my_bool mysql_rpl_probe(MYSQL* mysql);
-int mysql_set_master(MYSQL* mysql, const char* host,
- unsigned int port,
- const char* user,
- const char* passwd);
-int mysql_add_slave(MYSQL* mysql, const char* host,
- unsigned int port,
- const char* user,
- const char* passwd);
-int mysql_shutdown(MYSQL *mysql,
- enum mysql_enum_shutdown_level
- shutdown_level);
-int mysql_dump_debug_info(MYSQL *mysql);
-int mysql_refresh(MYSQL *mysql,
- unsigned int refresh_options);
-int mysql_kill(MYSQL *mysql,unsigned long pid);
-int mysql_set_server_option(MYSQL *mysql,
- enum enum_mysql_set_option
- option);
-int mysql_ping(MYSQL *mysql);
-const char * mysql_stat(MYSQL *mysql);
-const char * mysql_get_server_info(MYSQL *mysql);
-const char * mysql_get_client_info(void);
-unsigned long mysql_get_client_version(void);
-const char * mysql_get_host_info(MYSQL *mysql);
-unsigned long mysql_get_server_version(MYSQL *mysql);
-unsigned int mysql_get_proto_info(MYSQL *mysql);
-MYSQL_RES * mysql_list_dbs(MYSQL *mysql,const char *wild);
-MYSQL_RES * mysql_list_tables(MYSQL *mysql,const char *wild);
-MYSQL_RES * mysql_list_processes(MYSQL *mysql);
-int mysql_options(MYSQL *mysql,enum mysql_option option,
- const void *arg);
-void mysql_free_result(MYSQL_RES *result);
-void mysql_data_seek(MYSQL_RES *result,
- my_ulonglong offset);
-MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result,
- MYSQL_ROW_OFFSET offset);
-MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result,
- MYSQL_FIELD_OFFSET offset);
-MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
-unsigned long * mysql_fetch_lengths(MYSQL_RES *result);
-MYSQL_FIELD * mysql_fetch_field(MYSQL_RES *result);
-MYSQL_RES * mysql_list_fields(MYSQL *mysql, const char *table,
- const char *wild);
-unsigned long mysql_escape_string(char *to,const char *from,
- unsigned long from_length);
-unsigned long mysql_hex_string(char *to,const char *from,
- unsigned long from_length);
-unsigned long mysql_real_escape_string(MYSQL *mysql,
- char *to,const char *from,
- unsigned long length);
-void mysql_debug(const char *debug);
-void myodbc_remove_escape(MYSQL *mysql,char *name);
-unsigned int mysql_thread_safe(void);
-my_bool mysql_embedded(void);
-MYSQL_MANAGER* mysql_manager_init(MYSQL_MANAGER* con);
-MYSQL_MANAGER* mysql_manager_connect(MYSQL_MANAGER* con,
- const char* host,
- const char* user,
- const char* passwd,
- unsigned int port);
-void mysql_manager_close(MYSQL_MANAGER* con);
-int mysql_manager_command(MYSQL_MANAGER* con,
- const char* cmd, int cmd_len);
-int mysql_manager_fetch_line(MYSQL_MANAGER* con,
- char* res_buf,
- int res_buf_size);
-my_bool mysql_read_query_result(MYSQL *mysql);
-enum enum_mysql_stmt_state
-{
- MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
- MYSQL_STMT_FETCH_DONE
-};
-typedef struct st_mysql_bind
-{
- unsigned long *length;
- my_bool *is_null;
- void *buffer;
- my_bool *error;
- unsigned char *row_ptr;
- void (*store_param_func)(NET *net, struct st_mysql_bind *param);
- void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *,
- unsigned char **row);
- void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
- unsigned char **row);
- unsigned long buffer_length;
- unsigned long offset;
- unsigned long length_value;
- unsigned int param_number;
- unsigned int pack_length;
- enum enum_field_types buffer_type;
- my_bool error_value;
- my_bool is_unsigned;
- my_bool long_data_used;
- my_bool is_null_value;
- void *extension;
-} MYSQL_BIND;
-typedef struct st_mysql_stmt
-{
- MEM_ROOT mem_root;
- LIST list;
- MYSQL *mysql;
- MYSQL_BIND *params;
- MYSQL_BIND *bind;
- MYSQL_FIELD *fields;
- MYSQL_DATA result;
- MYSQL_ROWS *data_cursor;
- int (*read_row_func)(struct st_mysql_stmt *stmt,
- unsigned char **row);
- my_ulonglong affected_rows;
- my_ulonglong insert_id;
- unsigned long stmt_id;
- unsigned long flags;
- unsigned long prefetch_rows;
- unsigned int server_status;
- unsigned int last_errno;
- unsigned int param_count;
- unsigned int field_count;
- enum enum_mysql_stmt_state state;
- char last_error[512];
- char sqlstate[5 +1];
- my_bool send_types_to_server;
- my_bool bind_param_done;
- unsigned char bind_result_done;
- my_bool unbuffered_fetch_cancelled;
- my_bool update_max_length;
- void *extension;
-} MYSQL_STMT;
-enum enum_stmt_attr_type
-{
- STMT_ATTR_UPDATE_MAX_LENGTH,
- STMT_ATTR_CURSOR_TYPE,
- STMT_ATTR_PREFETCH_ROWS
-};
-typedef struct st_mysql_methods
-{
- my_bool (*read_query_result)(MYSQL *mysql);
- my_bool (*advanced_command)(MYSQL *mysql,
- enum enum_server_command command,
- const unsigned char *header,
- unsigned long header_length,
- const unsigned char *arg,
- unsigned long arg_length,
- my_bool skip_check,
- MYSQL_STMT *stmt);
- MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
- unsigned int fields);
- MYSQL_RES * (*use_result)(MYSQL *mysql);
- void (*fetch_lengths)(unsigned long *to,
- MYSQL_ROW column, unsigned int field_count);
- void (*flush_use_result)(MYSQL *mysql);
- MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
- my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
- int (*stmt_execute)(MYSQL_STMT *stmt);
- int (*read_binary_rows)(MYSQL_STMT *stmt);
- int (*unbuffered_fetch)(MYSQL *mysql, char **row);
- void (*free_embedded_thd)(MYSQL *mysql);
- const char *(*read_statistics)(MYSQL *mysql);
- my_bool (*next_result)(MYSQL *mysql);
- int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
- int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
-} MYSQL_METHODS;
-MYSQL_STMT * mysql_stmt_init(MYSQL *mysql);
-int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
- unsigned long length);
-int mysql_stmt_execute(MYSQL_STMT *stmt);
-int mysql_stmt_fetch(MYSQL_STMT *stmt);
-int mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg,
- unsigned int column,
- unsigned long offset);
-int mysql_stmt_store_result(MYSQL_STMT *stmt);
-unsigned long mysql_stmt_param_count(MYSQL_STMT * stmt);
-my_bool mysql_stmt_attr_set(MYSQL_STMT *stmt,
- enum enum_stmt_attr_type attr_type,
- const void *attr);
-my_bool mysql_stmt_attr_get(MYSQL_STMT *stmt,
- enum enum_stmt_attr_type attr_type,
- void *attr);
-my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
-my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
-my_bool mysql_stmt_close(MYSQL_STMT * stmt);
-my_bool mysql_stmt_reset(MYSQL_STMT * stmt);
-my_bool mysql_stmt_free_result(MYSQL_STMT *stmt);
-my_bool mysql_stmt_send_long_data(MYSQL_STMT *stmt,
- unsigned int param_number,
- const char *data,
- unsigned long length);
-MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT *stmt);
-MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT *stmt);
-unsigned int mysql_stmt_errno(MYSQL_STMT * stmt);
-const char * mysql_stmt_error(MYSQL_STMT * stmt);
-const char * mysql_stmt_sqlstate(MYSQL_STMT * stmt);
-MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT *stmt,
- MYSQL_ROW_OFFSET offset);
-MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT *stmt);
-void mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset);
-my_ulonglong mysql_stmt_num_rows(MYSQL_STMT *stmt);
-my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt);
-my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt);
-unsigned int mysql_stmt_field_count(MYSQL_STMT *stmt);
-my_bool mysql_commit(MYSQL * mysql);
-my_bool mysql_rollback(MYSQL * mysql);
-my_bool mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
-my_bool mysql_more_results(MYSQL *mysql);
-int mysql_next_result(MYSQL *mysql);
-void mysql_close(MYSQL *sock);
-typedef struct st_table_rule_ent
-{
- char* db;
- char* tbl_name;
- uint key_len;
-} TABLE_RULE_ENT;
-class Rpl_filter
-{
-public:
- Rpl_filter();
- ~Rpl_filter();
- Rpl_filter(Rpl_filter const&);
- Rpl_filter& operator=(Rpl_filter const&);
- In_C_you_should_use_my_bool_instead() tables_ok(const char* db, TABLE_LIST* tables);
- In_C_you_should_use_my_bool_instead() db_ok(const char* db);
- In_C_you_should_use_my_bool_instead() db_ok_with_wild_table(const char *db);
- In_C_you_should_use_my_bool_instead() is_on();
- int add_do_table(const char* table_spec);
- int add_ignore_table(const char* table_spec);
- int add_wild_do_table(const char* table_spec);
- int add_wild_ignore_table(const char* table_spec);
- void add_do_db(const char* db_spec);
- void add_ignore_db(const char* db_spec);
- void add_db_rewrite(const char* from_db, const char* to_db);
- void get_do_table(String* str);
- void get_ignore_table(String* str);
- void get_wild_do_table(String* str);
- void get_wild_ignore_table(String* str);
- const char* get_rewrite_db(const char* db, size_t *new_len);
- I_List<i_string>* get_do_db();
- I_List<i_string>* get_ignore_db();
-private:
- In_C_you_should_use_my_bool_instead() table_rules_on;
- void init_table_rule_hash(HASH* h, In_C_you_should_use_my_bool_instead()* h_inited);
- void init_table_rule_array(DYNAMIC_ARRAY* a, In_C_you_should_use_my_bool_instead()* a_inited);
- int add_table_rule(HASH* h, const char* table_spec);
- int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
- void free_string_array(DYNAMIC_ARRAY *a);
- void table_rule_ent_hash_to_str(String* s, HASH* h, In_C_you_should_use_my_bool_instead() inited);
- void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a,
- In_C_you_should_use_my_bool_instead() inited);
- TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len);
- HASH do_table;
- HASH ignore_table;
- DYNAMIC_ARRAY wild_do_table;
- DYNAMIC_ARRAY wild_ignore_table;
- In_C_you_should_use_my_bool_instead() do_table_inited;
- In_C_you_should_use_my_bool_instead() ignore_table_inited;
- In_C_you_should_use_my_bool_instead() wild_do_table_inited;
- In_C_you_should_use_my_bool_instead() wild_ignore_table_inited;
- I_List<i_string> do_db;
- I_List<i_string> ignore_db;
- I_List<i_string_pair> rewrite_db;
-};
-extern Rpl_filter *rpl_filter;
-extern Rpl_filter *binlog_filter;
-#include "rpl_tblmap.h"
-class Relay_log_info;
-class Master_info;
-extern ulong master_retry_count;
-extern MY_BITMAP slave_error_mask;
-extern In_C_you_should_use_my_bool_instead() use_slave_mask;
-extern char *slave_load_tmpdir;
-extern char *master_info_file, *relay_log_info_file;
-extern char *opt_relay_logname, *opt_relaylog_index_name;
-extern my_bool opt_skip_slave_start, opt_reckless_slave;
-extern my_bool opt_log_slave_updates;
-extern ulonglong relay_log_space_limit;
-int init_slave();
-void init_slave_skip_errors(const char* arg);
-In_C_you_should_use_my_bool_instead() flush_relay_log_info(Relay_log_info* rli);
-int register_slave_on_master(MYSQL* mysql);
-int terminate_slave_threads(Master_info* mi, int thread_mask,
- In_C_you_should_use_my_bool_instead() skip_lock = 0);
-int start_slave_threads(In_C_you_should_use_my_bool_instead() need_slave_mutex, In_C_you_should_use_my_bool_instead() wait_for_start,
- Master_info* mi, const char* master_info_fname,
- const char* slave_info_fname, int thread_mask);
-int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock,
- pthread_mutex_t *cond_lock,
- pthread_cond_t* start_cond,
- volatile uint *slave_running,
- volatile ulong *slave_run_id,
- Master_info* mi,
- In_C_you_should_use_my_bool_instead() high_priority);
-int mysql_table_dump(THD* thd, const char* db,
- const char* tbl_name, int fd = -1);
-int fetch_master_table(THD* thd, const char* db_name, const char* table_name,
- Master_info* mi, MYSQL* mysql, In_C_you_should_use_my_bool_instead() overwrite);
-In_C_you_should_use_my_bool_instead() show_master_info(THD* thd, Master_info* mi);
-In_C_you_should_use_my_bool_instead() show_binlog_info(THD* thd);
-In_C_you_should_use_my_bool_instead() rpl_master_has_bug(Relay_log_info *rli, uint bug_id, In_C_you_should_use_my_bool_instead() report=(1));
-In_C_you_should_use_my_bool_instead() rpl_master_erroneous_autoinc(THD* thd);
-const char *print_slave_db_safe(const char *db);
-int check_expected_error(THD* thd, Relay_log_info const *rli, int error_code);
-void skip_load_data_infile(NET* net);
-void end_slave();
-void clear_until_condition(Relay_log_info* rli);
-void clear_slave_error(Relay_log_info* rli);
-void end_relay_log_info(Relay_log_info* rli);
-void lock_slave_threads(Master_info* mi);
-void unlock_slave_threads(Master_info* mi);
-void init_thread_mask(int* mask,Master_info* mi,In_C_you_should_use_my_bool_instead() inverse);
-int init_relay_log_pos(Relay_log_info* rli,const char* log,ulonglong pos,
- In_C_you_should_use_my_bool_instead() need_data_lock, const char** errmsg,
- In_C_you_should_use_my_bool_instead() look_for_description_event);
-int purge_relay_logs(Relay_log_info* rli, THD *thd, In_C_you_should_use_my_bool_instead() just_reset,
- const char** errmsg);
-void set_slave_thread_options(THD* thd);
-void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
-void rotate_relay_log(Master_info* mi);
-int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
- In_C_you_should_use_my_bool_instead() skip);
- void * handle_slave_io(void *arg);
- void * handle_slave_sql(void *arg);
-extern In_C_you_should_use_my_bool_instead() volatile abort_loop;
-extern Master_info main_mi, *active_mi;
-extern LIST master_list;
-extern my_bool replicate_same_server_id;
-extern int disconnect_slave_event_count, abort_slave_event_count ;
-extern uint master_port, master_connect_retry, report_port;
-extern char * master_user, *master_password, *master_host;
-extern char *master_info_file, *relay_log_info_file, *report_user;
-extern char *report_host, *report_password;
-extern my_bool master_ssl;
-extern char *master_ssl_ca, *master_ssl_capath, *master_ssl_cert;
-extern char *master_ssl_cipher, *master_ssl_key;
-extern I_List<THD> threads;
-enum mysql_db_table_field
-{
- MYSQL_DB_FIELD_HOST = 0,
- MYSQL_DB_FIELD_DB,
- MYSQL_DB_FIELD_USER,
- MYSQL_DB_FIELD_SELECT_PRIV,
- MYSQL_DB_FIELD_INSERT_PRIV,
- MYSQL_DB_FIELD_UPDATE_PRIV,
- MYSQL_DB_FIELD_DELETE_PRIV,
- MYSQL_DB_FIELD_CREATE_PRIV,
- MYSQL_DB_FIELD_DROP_PRIV,
- MYSQL_DB_FIELD_GRANT_PRIV,
- MYSQL_DB_FIELD_REFERENCES_PRIV,
- MYSQL_DB_FIELD_INDEX_PRIV,
- MYSQL_DB_FIELD_ALTER_PRIV,
- MYSQL_DB_FIELD_CREATE_TMP_TABLE_PRIV,
- MYSQL_DB_FIELD_LOCK_TABLES_PRIV,
- MYSQL_DB_FIELD_CREATE_VIEW_PRIV,
- MYSQL_DB_FIELD_SHOW_VIEW_PRIV,
- MYSQL_DB_FIELD_CREATE_ROUTINE_PRIV,
- MYSQL_DB_FIELD_ALTER_ROUTINE_PRIV,
- MYSQL_DB_FIELD_EXECUTE_PRIV,
- MYSQL_DB_FIELD_EVENT_PRIV,
- MYSQL_DB_FIELD_TRIGGER_PRIV,
- MYSQL_DB_FIELD_COUNT
-};
-extern TABLE_FIELD_W_TYPE mysql_db_table_fields[];
-extern time_t mysql_db_table_last_check;
-struct acl_host_and_ip
-{
- char *hostname;
- long ip,ip_mask;
-};
-class ACL_ACCESS {
-public:
- ulong sort;
- ulong access;
-};
-class ACL_HOST :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- char *db;
-};
-class ACL_USER :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- uint hostname_length;
- USER_RESOURCES user_resource;
- char *user;
- uint8 salt[20 +1];
- uint8 salt_len;
- enum SSL_type ssl_type;
- const char *ssl_cipher, *x509_issuer, *x509_subject;
-};
-class ACL_DB :public ACL_ACCESS
-{
-public:
- acl_host_and_ip host;
- char *user,*db;
-};
-In_C_you_should_use_my_bool_instead() hostname_requires_resolving(const char *hostname);
-my_bool acl_init(In_C_you_should_use_my_bool_instead() dont_read_acl_tables);
-my_bool acl_reload(THD *thd);
-void acl_free(In_C_you_should_use_my_bool_instead() end=0);
-ulong acl_get(const char *host, const char *ip,
- const char *user, const char *db, my_bool db_is_pattern);
-int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd,
- uint passwd_len);
-In_C_you_should_use_my_bool_instead() acl_getroot_no_password(Security_context *sctx, char *user, char *host,
- char *ip, char *db);
-In_C_you_should_use_my_bool_instead() acl_check_host(const char *host, const char *ip);
-int check_change_password(THD *thd, const char *host, const char *user,
- char *password, uint password_len);
-In_C_you_should_use_my_bool_instead() change_password(THD *thd, const char *host, const char *user,
- char *password);
-In_C_you_should_use_my_bool_instead() mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
- ulong rights, In_C_you_should_use_my_bool_instead() revoke);
-int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
- List <LEX_COLUMN> &column_list, ulong rights,
- In_C_you_should_use_my_bool_instead() revoke);
-In_C_you_should_use_my_bool_instead() mysql_routine_grant(THD *thd, TABLE_LIST *table, In_C_you_should_use_my_bool_instead() is_proc,
- List <LEX_USER> &user_list, ulong rights,
- In_C_you_should_use_my_bool_instead() revoke, In_C_you_should_use_my_bool_instead() no_error);
-my_bool grant_init();
-void grant_free(void);
-my_bool grant_reload(THD *thd);
-In_C_you_should_use_my_bool_instead() check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
- uint show_command, uint number, In_C_you_should_use_my_bool_instead() dont_print_error);
-In_C_you_should_use_my_bool_instead() check_grant_column (THD *thd, GRANT_INFO *grant,
- const char *db_name, const char *table_name,
- const char *name, uint length, Security_context *sctx);
-In_C_you_should_use_my_bool_instead() check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
- const char *name, uint length);
-In_C_you_should_use_my_bool_instead() check_grant_all_columns(THD *thd, ulong want_access,
- Field_iterator_table_ref *fields);
-In_C_you_should_use_my_bool_instead() check_grant_routine(THD *thd, ulong want_access,
- TABLE_LIST *procs, In_C_you_should_use_my_bool_instead() is_proc, In_C_you_should_use_my_bool_instead() no_error);
-In_C_you_should_use_my_bool_instead() check_grant_db(THD *thd,const char *db);
-ulong get_table_grant(THD *thd, TABLE_LIST *table);
-ulong get_column_grant(THD *thd, GRANT_INFO *grant,
- const char *db_name, const char *table_name,
- const char *field_name);
-In_C_you_should_use_my_bool_instead() mysql_show_grants(THD *thd, LEX_USER *user);
-void get_privilege_desc(char *to, uint max_length, ulong access);
-void get_mqh(const char *user, const char *host, USER_CONN *uc);
-In_C_you_should_use_my_bool_instead() mysql_create_user(THD *thd, List <LEX_USER> &list);
-In_C_you_should_use_my_bool_instead() mysql_drop_user(THD *thd, List <LEX_USER> &list);
-In_C_you_should_use_my_bool_instead() mysql_rename_user(THD *thd, List <LEX_USER> &list);
-In_C_you_should_use_my_bool_instead() mysql_revoke_all(THD *thd, List <LEX_USER> &list);
-void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
- const char *db, const char *table);
-In_C_you_should_use_my_bool_instead() sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
- In_C_you_should_use_my_bool_instead() is_proc);
-int sp_grant_privileges(THD *thd, const char *sp_db, const char *sp_name,
- In_C_you_should_use_my_bool_instead() is_proc);
-In_C_you_should_use_my_bool_instead() check_routine_level_acl(THD *thd, const char *db, const char *name,
- In_C_you_should_use_my_bool_instead() is_proc);
-In_C_you_should_use_my_bool_instead() is_acl_user(const char *host, const char *user);
-#include "tztime.h"
-class Time_zone: public Sql_alloc
-{
-public:
- Time_zone() {}
- virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
- my_bool *in_dst_time_gap) const = 0;
- virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const = 0;
- virtual const String * get_name() const = 0;
- virtual ~Time_zone() {};
-};
-extern Time_zone * my_tz_UTC;
-extern Time_zone * my_tz_SYSTEM;
-extern Time_zone * my_tz_OFFSET0;
-extern Time_zone * my_tz_find(THD *thd, const String *name);
-extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
-extern void my_tz_free();
-extern my_time_t sec_since_epoch_TIME(MYSQL_TIME *t);
-static const int MY_TZ_TABLES_COUNT= 4;
-In_C_you_should_use_my_bool_instead() check_global_access(THD *thd, ulong want_access);
-int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
-void sql_perror(const char *message);
-In_C_you_should_use_my_bool_instead() fn_format_relative_to_data_home(char * to, const char *name,
- const char *dir, const char *extension);
-extern uint mysql_data_home_len;
-extern char *mysql_data_home,server_version[60],
- mysql_real_data_home[], mysql_unpacked_real_data_home[];
-extern CHARSET_INFO *character_set_filesystem;
-extern char reg_ext[20];
-extern uint reg_ext_length;
-extern ulong specialflag;
-extern uint lower_case_table_names;
-extern In_C_you_should_use_my_bool_instead() mysqld_embedded;
-extern my_bool opt_large_pages;
-extern uint opt_large_page_size;
-extern struct system_variables global_system_variables;
-uint strconvert(CHARSET_INFO *from_cs, const char *from,
- CHARSET_INFO *to_cs, char *to, uint to_length, uint *errors);
-uint filename_to_tablename(const char *from, char *to, uint to_length);
-uint tablename_to_filename(const char *from, char *to, uint to_length);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 37eb6d95ce8..c4ec0b741f0 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,6 +15,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define DEFINE_VARIABLES_LOG_SLOW // Declare variables in log_slow.h
#include "mysql_priv.h"
#include <m_ctype.h>
#include <my_dir.h>
@@ -27,6 +29,7 @@
#include "mysqld_suffix.h"
#include "mysys_err.h"
#include "events.h"
+#include <waiting_threads.h>
#include "debug_sync.h"
#include "../storage/myisam/ha_myisam.h"
@@ -58,26 +61,15 @@
#define mysqld_charset &my_charset_latin1
-#ifdef HAVE_purify
-#define IF_PURIFY(A,B) (A)
-#else
-#define IF_PURIFY(A,B) (B)
-#endif
-
#if SIZEOF_CHARP == 4
#define MAX_MEM_TABLE_SIZE ~(ulong) 0
#else
#define MAX_MEM_TABLE_SIZE ~(ulonglong) 0
#endif
-/* stack traces are only supported on linux intel */
-#if defined(__linux__) && defined(__i386__)
-#define HAVE_STACK_TRACE_ON_SEGV
-#endif /* __linux__ */
+/* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */
-/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
-
-#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__)
+#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_valgrind) && defined(__linux__)
#define HAVE_CLOSE_SERVER_SOCK 1
#endif
@@ -166,7 +158,7 @@ static void registerwithneb();
static void getvolumename();
static void getvolumeID(BYTE *volumeName);
#endif /* __NETWARE__ */
-
+
#ifdef _AIX41
int initgroups(const char *,unsigned int);
@@ -279,8 +271,6 @@ extern "C" sig_handler handle_segfault(int sig);
/* Constants */
-#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
-
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
/*
WARNING: When adding new SQL modes don't forget to update the
@@ -346,9 +336,14 @@ TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
static const char *optimizer_switch_names[]=
{
- "index_merge","index_merge_union","index_merge_sort_union",
- "index_merge_intersection", "default", NullS
+ "index_merge","index_merge_union","index_merge_sort_union",
+ "index_merge_intersection",
+#ifndef DBUG_OFF
+ "table_elimination",
+#endif
+ "default", NullS
};
+
/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
static const unsigned int optimizer_switch_names_len[]=
{
@@ -356,6 +351,9 @@ static const unsigned int optimizer_switch_names_len[]=
sizeof("index_merge_union") - 1,
sizeof("index_merge_sort_union") - 1,
sizeof("index_merge_intersection") - 1,
+#ifndef DBUG_OFF
+ sizeof("table_elimination") - 1,
+#endif
sizeof("default") - 1
};
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
@@ -410,7 +408,7 @@ arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
- log_output_names,
+ log_output_names,
(unsigned int *) log_output_names_len};
/* static variables */
@@ -422,8 +420,10 @@ static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_short_log_format= 0;
+static my_bool opt_ignore_wrong_options= 0, opt_expect_abort= 0;
+static my_bool opt_sync= 0;
static uint kill_cached_threads, wake_thread;
-static ulong killed_threads, thread_created;
+ulong thread_created;
static ulong max_used_connections;
static ulong my_bind_addr; /**< the address we bind to */
static volatile ulong cached_thread_count= 0;
@@ -431,25 +431,31 @@ static const char *sql_mode_str= "OFF";
/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
"index_merge_sort_union=on,"
- "index_merge_intersection=on";
+ "index_merge_intersection=on"
+#ifndef DBUG_OFF
+ ",table_elimination=on";
+#else
+ ;
+#endif
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
static char *opt_init_slave, *language_ptr, *opt_init_connect;
static char *default_character_set_name;
static char *character_set_filesystem_name;
static char *lc_time_names_name;
static char *my_bind_addr_str;
-static char *default_collation_name;
+static char *default_collation_name;
static char *default_storage_engine_str;
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
static I_List<THD> thread_cache;
static double long_query_time;
+static ulong opt_my_crc_dbug_check;
static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
/* Global variables */
bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0;
-my_bool opt_log, opt_slow_log;
+my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table;
ulong log_output_options;
my_bool opt_log_queries_not_using_indexes= 0;
bool opt_error_log= IF_WIN(1,0);
@@ -481,7 +487,7 @@ bool in_bootstrap= FALSE;
@brief 'grant_option' is used to indicate if privileges needs
to be checked, in which case the lock, LOCK_grant, is used
to protect access to the grant table.
- @note This flag is dropped in 5.1
+ @note This flag is dropped in 5.1
@see grant_init()
*/
bool volatile grant_option;
@@ -493,7 +499,7 @@ my_bool opt_local_infile, opt_slave_compressed_protocol;
my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
my_bool opt_log_slave_updates= 0;
-bool slave_warning_issued = false;
+bool slave_warning_issued = false;
/*
Legacy global handlerton. These will be removed (please do not add more).
@@ -556,6 +562,7 @@ const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
#endif
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
+uint mysqld_extra_port;
uint mysqld_port_timeout;
uint delay_key_write_options, protocol_version;
uint lower_case_table_names;
@@ -583,11 +590,13 @@ ulong delayed_insert_errors,flush_time;
ulong specialflag=0;
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
ulong max_connections, max_connect_errors;
+ulong extra_max_connections;
/*
Maximum length of parameter value which can be set through
mysql_send_long_data() call.
*/
ulong max_long_data_size;
+
uint max_user_connections= 0;
/**
Limit of the total number of prepared statements in the server.
@@ -635,6 +644,7 @@ char *mysqld_unix_port, *opt_mysql_tmpdir;
const char **errmesg; /**< Error messages */
const char *myisam_recover_options_str="OFF";
const char *myisam_stats_method_str="nulls_unequal";
+const char *opt_thread_handling= thread_handling_typelib.type_names[0];
/** name of reference on left espression in rewritten IN subquery */
const char *in_left_expr_name= "<left expr>";
@@ -684,12 +694,12 @@ pthread_key(MEM_ROOT**,THR_MALLOC);
pthread_key(THD*, THR_THD);
pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_mapped_file, LOCK_status, LOCK_global_read_lock,
- LOCK_error_log, LOCK_uuid_generator,
+ LOCK_error_log,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
LOCK_global_system_variables,
- LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
- LOCK_connection_count;
+ LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
+ LOCK_connection_count, LOCK_short_uuid_generator;
/**
The below lock protects access to two global server variables:
max_prepared_stmt_count and prepared_stmt_count. These variables
@@ -718,7 +728,8 @@ uint master_port= MYSQL_PORT, master_connect_retry = 60;
uint report_port= MYSQL_PORT;
ulong master_retry_count=0;
char *master_user, *master_password, *master_host, *master_info_file;
-char *relay_log_info_file, *report_user, *report_password, *report_host;
+char *relay_log_info_file;
+char *report_user, *report_password, *report_host;
char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
my_bool master_ssl;
char *master_ssl_key, *master_ssl_cert;
@@ -728,9 +739,7 @@ char *opt_logname, *opt_slow_logname;
/* Static variables */
static bool kill_in_progress, segfaulted;
-#ifdef HAVE_STACK_TRACE_ON_SEGV
-static my_bool opt_do_pstack;
-#endif /* HAVE_STACK_TRACE_ON_SEGV */
+static my_bool opt_stack_trace;
static my_bool opt_bootstrap, opt_myisam_log;
static int cleanup_done;
static ulong opt_specialflag, opt_myisam_block_size;
@@ -744,13 +753,12 @@ static char *opt_bin_logname;
int orig_argc;
char **orig_argv;
-static my_socket unix_sock,ip_sock;
-struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
+static my_socket unix_sock, base_ip_sock, extra_ip_sock;
+struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
#ifndef EMBEDDED_LIBRARY
struct passwd *user_info;
static pthread_t select_thread;
-static uint thr_kill_signal;
#endif
/* OS specific variables */
@@ -789,7 +797,7 @@ bool mysqld_embedded=1;
static my_bool plugins_are_initialized= FALSE;
#ifndef DBUG_OFF
-static const char* default_dbug_option;
+static const char* default_dbug_option, *current_dbug_option;
#endif
#ifdef HAVE_LIBWRAP
const char *libwrapName= NULL;
@@ -807,7 +815,7 @@ my_bool opt_enable_shared_memory;
HANDLE smem_event_connect_request= 0;
#endif
-scheduler_functions thread_scheduler;
+scheduler_functions thread_scheduler, extra_thread_scheduler;
#define SSL_VARS_NOT_STATIC
#include "sslopt-vars.h"
@@ -834,7 +842,7 @@ struct st_VioSSLFd *ssl_acceptor_fd;
Number of currently active user connections. The variable is protected by
LOCK_connection_count.
*/
-uint connection_count= 0;
+uint connection_count= 0, extra_connection_count= 0;
/* Function declarations */
@@ -862,6 +870,7 @@ static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
const char *option, int *error);
static void clean_up(bool print_message);
static int test_if_case_insensitive(const char *dir_name);
+static void register_mutex_order();
#ifndef EMBEDDED_LIBRARY
static void usage(void);
@@ -916,7 +925,7 @@ static void close_connections(void)
break;
}
#ifdef EXTRA_DEBUG
- if (error != 0 && !count++)
+ if (error != 0 && error != ETIMEDOUT && !count++)
sql_print_error("Got error %d from pthread_cond_timedwait",error);
#endif
close_server_sock();
@@ -929,11 +938,17 @@ static void close_connections(void)
DBUG_PRINT("quit",("Closing sockets"));
if (!opt_disable_networking )
{
- if (ip_sock != INVALID_SOCKET)
+ if (base_ip_sock != INVALID_SOCKET)
+ {
+ (void) shutdown(base_ip_sock, SHUT_RDWR);
+ (void) closesocket(base_ip_sock);
+ base_ip_sock= INVALID_SOCKET;
+ }
+ if (extra_ip_sock != INVALID_SOCKET)
{
- (void) shutdown(ip_sock, SHUT_RDWR);
- (void) closesocket(ip_sock);
- ip_sock= INVALID_SOCKET;
+ (void) shutdown(extra_ip_sock, SHUT_RDWR);
+ (void) closesocket(extra_ip_sock);
+ extra_ip_sock= INVALID_SOCKET;
}
}
#ifdef __NT__
@@ -991,26 +1006,39 @@ static void close_connections(void)
tmp->killed= THD::KILL_CONNECTION;
thread_scheduler.post_kill_notification(tmp);
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->mysys_var)
{
tmp->mysys_var->abort=1;
pthread_mutex_lock(&tmp->mysys_var->mutex);
if (tmp->mysys_var->current_cond)
{
- pthread_mutex_lock(tmp->mysys_var->current_mutex);
- pthread_cond_broadcast(tmp->mysys_var->current_cond);
- pthread_mutex_unlock(tmp->mysys_var->current_mutex);
+ uint i;
+ for (i=0; i < 2; i++)
+ {
+ int ret= pthread_mutex_trylock(tmp->mysys_var->current_mutex);
+ pthread_cond_broadcast(tmp->mysys_var->current_cond);
+ if (!ret)
+ {
+ /* Thread has surely got the signal, unlock and abort */
+ pthread_mutex_unlock(tmp->mysys_var->current_mutex);
+ break;
+ }
+ sleep(1);
+ }
}
pthread_mutex_unlock(&tmp->mysys_var->mutex);
}
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
}
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
Events::deinit();
end_slave();
- if (thread_count)
- sleep(2); // Give threads time to die
+ /* Give threads time to die. */
+ for (int i= 0; thread_count && i < 100; i++)
+ my_sleep(20000);
/*
Force remaining threads to die by closing the connection to the client
@@ -1058,42 +1086,41 @@ static void close_connections(void)
}
-static void close_server_sock()
-{
#ifdef HAVE_CLOSE_SERVER_SOCK
- DBUG_ENTER("close_server_sock");
- my_socket tmp_sock;
- tmp_sock=ip_sock;
- if (tmp_sock != INVALID_SOCKET)
+static void close_socket(my_socket sock, const char *info)
+{
+ DBUG_ENTER("close_socket");
+
+ if (sock != INVALID_SOCKET)
{
- ip_sock=INVALID_SOCKET;
- DBUG_PRINT("info",("calling shutdown on TCP/IP socket"));
- VOID(shutdown(tmp_sock, SHUT_RDWR));
+ DBUG_PRINT("info", ("calling shutdown on %s socket", info));
+ (void) shutdown(sock, SHUT_RDWR);
#if defined(__NETWARE__)
/*
The following code is disabled for normal systems as it causes MySQL
to hang on AIX 4.3 during shutdown
*/
- DBUG_PRINT("info",("calling closesocket on TCP/IP socket"));
- VOID(closesocket(tmp_sock));
+ DBUG_PRINT("info", ("calling closesocket on %s socket", info));
+ (void) closesocket(tmp_sock);
#endif
}
- tmp_sock=unix_sock;
- if (tmp_sock != INVALID_SOCKET)
- {
- unix_sock=INVALID_SOCKET;
- DBUG_PRINT("info",("calling shutdown on unix socket"));
- VOID(shutdown(tmp_sock, SHUT_RDWR));
-#if defined(__NETWARE__)
- /*
- The following code is disabled for normal systems as it may cause MySQL
- to hang on AIX 4.3 during shutdown
- */
- DBUG_PRINT("info",("calling closesocket on unix/IP socket"));
- VOID(closesocket(tmp_sock));
+ DBUG_VOID_RETURN;
+}
#endif
+
+
+static void close_server_sock()
+{
+#ifdef HAVE_CLOSE_SERVER_SOCK
+ DBUG_ENTER("close_server_sock");
+
+ close_socket(base_ip_sock, "TCP/IP");
+ close_socket(extra_ip_sock, "TCP/IP");
+ close_socket(unix_sock, "unix/IP");
+
+ if (unix_sock != INVALID_SOCKET)
VOID(unlink(mysqld_unix_port));
- }
+ base_ip_sock= extra_ip_sock= unix_sock= INVALID_SOCKET;
DBUG_VOID_RETURN;
#endif
}
@@ -1188,18 +1215,21 @@ static void __cdecl kill_server(int sig_ptr)
else
sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
-#if defined(HAVE_SMEM) && defined(__WIN__)
- /*
- Send event to smem_event_connect_request for aborting
- */
- if (!SetEvent(smem_event_connect_request))
- {
- DBUG_PRINT("error",
- ("Got error: %ld from SetEvent of smem_event_connect_request",
- GetLastError()));
- }
-#endif
-
+#if defined(HAVE_SMEM) && defined(__WIN__)
+ /*
+ Send event to smem_event_connect_request for aborting
+ */
+ if (opt_enable_shared_memory)
+ {
+ if (!SetEvent(smem_event_connect_request))
+ {
+ DBUG_PRINT("error",
+ ("Got error: %ld from SetEvent of smem_event_connect_request",
+ GetLastError()));
+ }
+ }
+#endif
+
close_connections();
if (sig != MYSQL_KILL_SIGNAL &&
sig != 0)
@@ -1349,8 +1379,10 @@ void clean_up(bool print_message)
if (tc_log)
tc_log->close();
xid_cache_free();
+ wt_end();
delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache);
multi_keycache_free();
+ sp_cache_end();
free_status_vars();
end_thr_alarm(1); /* Free allocated memory */
my_free_open_file_info();
@@ -1378,6 +1410,7 @@ void clean_up(bool print_message)
#ifdef HAVE_REPLICATION
end_slave_list();
#endif
+ my_uuid_end();
delete binlog_filter;
delete rpl_filter;
#ifndef EMBEDDED_LIBRARY
@@ -1443,9 +1476,11 @@ static void wait_for_signal_thread_to_end()
#endif
}
+#endif /*EMBEDDED_LIBRARY*/
static void clean_up_mutexes()
{
+ DBUG_ENTER("clean_up_mutexes");
(void) pthread_mutex_destroy(&LOCK_mysql_create_db);
(void) pthread_mutex_destroy(&LOCK_lock_db);
(void) pthread_mutex_destroy(&LOCK_Acl);
@@ -1464,7 +1499,9 @@ static void clean_up_mutexes()
(void) pthread_mutex_destroy(&LOCK_bytes_received);
(void) pthread_mutex_destroy(&LOCK_user_conn);
(void) pthread_mutex_destroy(&LOCK_connection_count);
+#ifndef EMBEDDED_LIBRARY
Events::destroy_mutexes();
+#endif
#ifdef HAVE_OPENSSL
(void) pthread_mutex_destroy(&LOCK_des_key_file);
#ifndef HAVE_YASSL
@@ -1477,13 +1514,15 @@ static void clean_up_mutexes()
(void) pthread_mutex_destroy(&LOCK_rpl_status);
(void) pthread_cond_destroy(&COND_rpl_status);
#endif
+ (void) pthread_mutex_destroy(&LOCK_server_started);
+ (void) pthread_cond_destroy(&COND_server_started);
(void) pthread_mutex_destroy(&LOCK_active_mi);
(void) rwlock_destroy(&LOCK_sys_init_connect);
(void) rwlock_destroy(&LOCK_sys_init_slave);
(void) pthread_mutex_destroy(&LOCK_global_system_variables);
+ (void) pthread_mutex_destroy(&LOCK_short_uuid_generator);
(void) rwlock_destroy(&LOCK_system_variables_hash);
(void) pthread_mutex_destroy(&LOCK_global_read_lock);
- (void) pthread_mutex_destroy(&LOCK_uuid_generator);
(void) pthread_mutex_destroy(&LOCK_prepared_stmt_count);
(void) pthread_cond_destroy(&COND_thread_count);
(void) pthread_cond_destroy(&COND_refresh);
@@ -1491,9 +1530,31 @@ static void clean_up_mutexes()
(void) pthread_cond_destroy(&COND_thread_cache);
(void) pthread_cond_destroy(&COND_flush_thread_cache);
(void) pthread_cond_destroy(&COND_manager);
+ DBUG_VOID_RETURN;
}
-#endif /*EMBEDDED_LIBRARY*/
+
+/**
+ Register order of mutex for wrong mutex deadlock detector
+
+ By aquiring all mutex in order here, the mutex order detector in
+ mysys/thr_mutex.c, will give a warning on first wrong mutex usage!
+*/
+
+static void register_mutex_order()
+{
+#ifdef SAFE_MUTEX
+ /*
+ We must have LOCK_open before LOCK_global_system_variables because
+ LOCK_open is hold while sql_plugin.c::intern_sys_var_ptr() is called.
+ */
+ pthread_mutex_lock(&LOCK_open);
+ pthread_mutex_lock(&LOCK_global_system_variables);
+
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ pthread_mutex_unlock(&LOCK_open);
+#endif
+}
/****************************************************************************
@@ -1666,80 +1727,100 @@ static void set_root(const char *path)
#endif
}
-static void network_init(void)
+/**
+ Activate usage of a tcp port
+*/
+
+static my_socket activate_tcp_port(uint port)
{
- struct sockaddr_in IPaddr;
-#ifdef HAVE_SYS_UN_H
- struct sockaddr_un UNIXaddr;
-#endif
+ struct sockaddr_in IPaddr;
+ my_socket ip_sock;
int arg=1;
int ret;
uint waited;
uint this_wait;
uint retry;
- DBUG_ENTER("network_init");
+ DBUG_ENTER("activate_tcp_port");
+ DBUG_PRINT("enter",("port: %u", port));
LINT_INIT(ret);
+ ip_sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (ip_sock == INVALID_SOCKET)
+ {
+ DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
+ sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
+ unireg_abort(1); /* purecov: tested */
+ }
+ bzero((char*) &IPaddr, sizeof(IPaddr));
+ IPaddr.sin_family = AF_INET;
+ IPaddr.sin_addr.s_addr = my_bind_addr;
+ IPaddr.sin_port = (unsigned short) htons((unsigned short) port);
+
+#ifndef __WIN__
+ /*
+ We should not use SO_REUSEADDR on windows as this would enable a
+ user to open two mysqld servers with the same TCP/IP port.
+ */
+ (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
+#endif /* __WIN__ */
+ /*
+ Sometimes the port is not released fast enough when stopping and
+ restarting the server. This happens quite often with the test suite
+ on busy Linux systems. Retry to bind the address at these intervals:
+ Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...
+ Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
+ Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
+ */
+
+ for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
+ {
+ if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
+ sizeof(IPaddr))) >= 0) ||
+ (socket_errno != SOCKET_EADDRINUSE) ||
+ (waited >= mysqld_port_timeout))
+ break;
+ sql_print_information("Retrying bind on TCP/IP port %u", port);
+ this_wait= retry * retry / 3 + 1;
+ sleep(this_wait);
+ }
+ if (ret < 0)
+ {
+ DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
+ sql_perror("Can't start server: Bind on TCP/IP port");
+ sql_print_error("Do you already have another mysqld server running on "
+ "port: %u ?", port);
+ unireg_abort(1);
+ }
+ if (listen(ip_sock,(int) back_log) < 0)
+ {
+ sql_perror("Can't start server: listen() on TCP/IP port");
+ sql_print_error("listen() on TCP/IP failed with error %d",
+ socket_errno);
+ unireg_abort(1);
+ }
+ DBUG_RETURN(ip_sock);
+}
+
+
+static void network_init(void)
+{
+#ifdef HAVE_SYS_UN_H
+ struct sockaddr_un UNIXaddr;
+#endif
+ int arg=1;
+ DBUG_ENTER("network_init");
+
if (thread_scheduler.init())
unireg_abort(1); /* purecov: inspected */
set_ports();
- if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap)
+ if (!opt_disable_networking && !opt_bootstrap)
{
- DBUG_PRINT("general",("IP Socket is %d",mysqld_port));
- ip_sock = socket(AF_INET, SOCK_STREAM, 0);
- if (ip_sock == INVALID_SOCKET)
- {
- DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
- sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
- unireg_abort(1); /* purecov: tested */
- }
- bzero((char*) &IPaddr, sizeof(IPaddr));
- IPaddr.sin_family = AF_INET;
- IPaddr.sin_addr.s_addr = my_bind_addr;
- IPaddr.sin_port = (unsigned short) htons((unsigned short) mysqld_port);
-
-#ifndef __WIN__
- /*
- We should not use SO_REUSEADDR on windows as this would enable a
- user to open two mysqld servers with the same TCP/IP port.
- */
- (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
-#endif /* __WIN__ */
- /*
- Sometimes the port is not released fast enough when stopping and
- restarting the server. This happens quite often with the test suite
- on busy Linux systems. Retry to bind the address at these intervals:
- Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...
- Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
- Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
- */
- for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
- {
- if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
- sizeof(IPaddr))) >= 0) ||
- (socket_errno != SOCKET_EADDRINUSE) ||
- (waited >= mysqld_port_timeout))
- break;
- sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port);
- this_wait= retry * retry / 3 + 1;
- sleep(this_wait);
- }
- if (ret < 0)
- {
- DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
- sql_perror("Can't start server: Bind on TCP/IP port");
- sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port);
- unireg_abort(1);
- }
- if (listen(ip_sock,(int) back_log) < 0)
- {
- sql_perror("Can't start server: listen() on TCP/IP port");
- sql_print_error("listen() on TCP/IP failed with error %d",
- socket_errno);
- unireg_abort(1);
- }
+ if (mysqld_port)
+ base_ip_sock= activate_tcp_port(mysqld_port);
+ if (mysqld_extra_port)
+ extra_ip_sock= activate_tcp_port(mysqld_extra_port);
}
#ifdef __NT__
@@ -1747,7 +1828,7 @@ static void network_init(void)
if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
opt_enable_named_pipe)
{
-
+
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
mysqld_unix_port, NullS);
bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
@@ -1874,17 +1955,14 @@ void close_connection(THD *thd, uint errcode, bool lock)
#endif /* EMBEDDED_LIBRARY */
-/** Called when a thread is aborted. */
+/** Called when mysqld is aborted with ^C */
/* ARGSUSED */
-extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
+extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused)))
{
- THD *thd=current_thd;
- DBUG_ENTER("end_thread_signal");
- if (thd && ! thd->bootstrap)
- {
- statistic_increment(killed_threads, &LOCK_status);
- thread_scheduler.end_thread(thd,0); /* purecov: inspected */
- }
+ DBUG_ENTER("end_mysqld_signal");
+ /* Don't call kill_mysql() if signal thread is not running */
+ if (signal_thread_in_use)
+ kill_mysql(); // Take down mysqld nicely
DBUG_VOID_RETURN; /* purecov: deadcode */
}
@@ -1907,7 +1985,7 @@ void unlink_thd(THD *thd)
thd->cleanup();
pthread_mutex_lock(&LOCK_connection_count);
- --connection_count;
+ (*thd->scheduler->connection_count)--;
pthread_mutex_unlock(&LOCK_connection_count);
(void) pthread_mutex_lock(&LOCK_thread_count);
@@ -1998,6 +2076,8 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
{
DBUG_ENTER("one_thread_per_connection_end");
unlink_thd(thd);
+ /* Mark that current_thd is not valid anymore */
+ my_pthread_setspecific_ptr(THR_THD, 0);
if (put_in_cache)
put_in_cache= cache_thread();
pthread_mutex_unlock(&LOCK_thread_count);
@@ -2117,8 +2197,8 @@ void win_install_sigabrt_handler(void)
#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
#define DEBUGGER_ATTACH_TIMEOUT 120
/*
- Wait for debugger to attach and break into debugger. If debugger is not attached,
- resume after timeout.
+ Wait for debugger to attach and break into debugger. If debugger is
+ not attached, resume after timeout.
*/
static void wait_for_debugger(int timeout_sec)
{
@@ -2297,7 +2377,7 @@ static void registerwithneb()
{
ConsumerRegistrationInfo reg_info;
-
+
/* Clear NEB registration structure */
bzero((char*) &reg_info, sizeof(struct ConsumerRegistrationInfo));
@@ -2313,7 +2393,7 @@ static void registerwithneb()
reg_info.CRIOwnerID= (LoadDefinitionStructure *)getnlmhandle();
reg_info.CRIConsumerESR= NULL; // No consumer ESR required
reg_info.CRISecurityToken= 0; // No security token for the event
- reg_info.CRIConsumerFlags= 0; // SMP_ENABLED_BIT;
+ reg_info.CRIConsumerFlags= 0; // SMP_ENABLED_BIT;
reg_info.CRIFilterName= 0; // No event filtering
reg_info.CRIFilterDataLength= 0; // No filtering data
reg_info.CRIFilterData= 0; // No filtering data
@@ -2338,7 +2418,7 @@ static void registerwithneb()
Get the NSS volume ID of the MySQL Data volume.
Volume ID is stored in a global variable
*/
- getvolumeID((BYTE*) datavolname);
+ getvolumeID((BYTE*) datavolname);
}
@@ -2402,7 +2482,7 @@ static void getvolumeID(BYTE *volumeName)
strxmov(path, (const char *) ADMIN_VOL_PATH, (const char *) volumeName,
NullS);
- if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8,
+ if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8,
(BYTE *) path, zRR_READ_ACCESS, &fileKey)) != zOK)
{
consoleprintf("\nGetNSSVolumeProperties - Failed to get file, status: %d\n.", (int) status);
@@ -2410,7 +2490,7 @@ static void getvolumeID(BYTE *volumeName)
}
getInfoMask= zGET_IDS | zGET_VOLUME_INFO ;
- if ((status= zGetInfo(fileKey, getInfoMask, sizeof(info),
+ if ((status= zGetInfo(fileKey, getInfoMask, sizeof(info),
zINFO_VERSION_A, &info)) != zOK)
{
consoleprintf("\nGetNSSVolumeProperties - Failed in zGetInfo, status: %d\n.", (int) status);
@@ -2485,6 +2565,9 @@ extern "C" sig_handler handle_segfault(int sig)
{
time_t curr_time;
struct tm tm;
+#ifdef HAVE_STACKTRACE
+ THD *thd=current_thd;
+#endif
/*
Strictly speaking, one needs a mutex here
@@ -2503,13 +2586,19 @@ extern "C" sig_handler handle_segfault(int sig)
curr_time= my_time(0);
localtime_r(&curr_time, &tm);
- fprintf(stderr,"\
-%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\
+ fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d ",
+ tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ if (opt_expect_abort && sig == SIGABRT)
+ {
+ fprintf(stderr,"[Note] mysqld did an expected abort\n");
+ goto end;
+ }
+
+ fprintf(stderr,"[ERROR] mysqld got " SIGNAL_FMT " ;\n\
This could be because you hit a bug. It is also possible that this binary\n\
or one of the libraries it was linked against is corrupt, improperly built,\n\
or misconfigured. This error can also be caused by malfunctioning hardware.\n",
- tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec,
sig);
fprintf(stderr, "\
We will try our best to scrape up some info that will hopefully help diagnose\n\
@@ -2519,15 +2608,17 @@ and this may fail.\n\n");
(ulong) dflt_key_cache->key_cache_mem_size);
fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
- fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
+ fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads +
+ (uint) extra_max_connections);
fprintf(stderr, "threads_connected=%u\n", thread_count);
fprintf(stderr, "It is possible that mysqld could use up to \n\
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
(global_system_variables.read_buff_size +
global_system_variables.sortbuff_size) *
- thread_scheduler.max_threads +
- max_connections * sizeof(THD)) / 1024);
+ (thread_scheduler.max_threads + extra_max_connections) +
+ (max_connections + extra_max_connections)* sizeof(THD))
+ / 1024);
fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
#if defined(HAVE_LINUXTHREADS)
@@ -2543,9 +2634,8 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
#endif /* HAVE_LINUXTHREADS */
#ifdef HAVE_STACKTRACE
- THD *thd=current_thd;
- if (!(test_flags & TEST_NO_STACKTRACE))
+ if (opt_stack_trace)
{
fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd);
fprintf(stderr, "Attempting backtrace. You can use the following "
@@ -2609,7 +2699,7 @@ You should either build a dynamically-linked binary, or force LinuxThreads\n\
to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
the documentation for your distribution on how to do that.\n");
#endif
-
+
if (locked_in_memory)
{
fprintf(stderr, "\n\
@@ -2630,9 +2720,13 @@ bugs.\n");
}
#endif
+end:
#ifndef __WIN__
- /* On Windows, do not terminate, but pass control to exception filter */
+ /* Terminate */
exit(1);
+#else
+ /* On Windows, do not terminate, but pass control to exception filter */
+ ;
#endif
}
@@ -2654,7 +2748,7 @@ static void init_signals(void)
my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
- if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
+ if (opt_stack_trace || (test_flags & TEST_CORE_ON_SIGNAL))
{
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
sigemptyset(&sa.sa_mask);
@@ -2682,7 +2776,7 @@ static void init_signals(void)
{
/* Change limits so that we will get a core file */
STRUCT_RLIMIT rl;
- rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+ rl.rlim_cur = rl.rlim_max = (rlim_t) RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals");
}
@@ -2711,12 +2805,13 @@ static void init_signals(void)
sigaddset(&set,THR_SERVER_ALARM);
if (test_flags & TEST_SIGINT)
{
- my_sigset(thr_kill_signal, end_thread_signal);
- // May be SIGINT
- sigdelset(&set, thr_kill_signal);
+ /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
+ my_sigset(SIGINT, end_mysqld_signal);
+ sigdelset(&set, SIGINT);
}
else
sigaddset(&set,SIGINT);
+
sigprocmask(SIG_SETMASK,&set,NULL);
pthread_sigmask(SIG_SETMASK,&set,NULL);
DBUG_VOID_RETURN;
@@ -2776,12 +2871,13 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
This should actually be '+ max_number_of_slaves' instead of +10,
but the +10 should be quite safe.
*/
- init_thr_alarm(thread_scheduler.max_threads +
+ init_thr_alarm(thread_scheduler.max_threads + extra_max_connections +
global_system_variables.max_insert_delayed_threads + 10);
- if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
+ if (test_flags & TEST_SIGINT)
{
- (void) sigemptyset(&set); // Setup up SIGINT for debug
- (void) sigaddset(&set,SIGINT); // For debugging
+ /* Allow SIGINT to break mysqld. This is for debugging with --gdb */
+ (void) sigemptyset(&set);
+ (void) sigaddset(&set,SIGINT);
(void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
}
(void) sigemptyset(&set); // Setup up SIGINT for debug
@@ -2913,6 +3009,8 @@ extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
int my_message_sql(uint error, const char *str, myf MyFlags)
{
THD *thd;
+ MYSQL_ERROR::enum_warning_level level;
+ sql_print_message_func func;
DBUG_ENTER("my_message_sql");
DBUG_PRINT("error", ("error: %u message: '%s'", error, str));
@@ -2926,24 +3024,44 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
TODO:
DBUG_ASSERT(error != 0);
*/
-
if (error == 0)
{
/* At least, prevent new abuse ... */
- DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0);
+ DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0 ||
+ strncmp(str, "MARIA table", 11) == 0);
error= ER_UNKNOWN_ERROR;
}
+ if (MyFlags & ME_JUST_INFO)
+ {
+ level= MYSQL_ERROR::WARN_LEVEL_NOTE;
+ func= sql_print_information;
+ }
+ else if (MyFlags & ME_JUST_WARNING)
+ {
+ level= MYSQL_ERROR::WARN_LEVEL_WARN;
+ func= sql_print_warning;
+ }
+ else
+ {
+ level= MYSQL_ERROR::WARN_LEVEL_ERROR;
+ func= sql_print_error;
+ }
+
if ((thd= current_thd))
{
/*
TODO: There are two exceptions mechanism (THD and sp_rcontext),
this could be improved by having a common stack of handlers.
*/
- if (thd->handle_error(error, str,
- MYSQL_ERROR::WARN_LEVEL_ERROR))
+ if (thd->handle_error(error, str, level))
DBUG_RETURN(0);
+ if (level == MYSQL_ERROR::WARN_LEVEL_WARN)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, error, str);
+ if (level != MYSQL_ERROR::WARN_LEVEL_ERROR)
+ goto to_error_log;
+
thd->is_slave_error= 1; // needed to catch query errors during replication
/*
@@ -2962,7 +3080,20 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
}
else
{
- if (! thd->main_da.is_error()) // Return only first message
+ if (thd->main_da.is_ok() && !thd->main_da.can_overwrite_status)
+ {
+ /*
+ Client has already got ok packet and we are not in net_flush(), so
+ we write a message to error log.
+ This could happen if we get an error in implicit commit.
+ This should never happen in normal operation, so lets
+ assert here in debug builds.
+ */
+ DBUG_ASSERT(0);
+ func= sql_print_error;
+ MyFlags|= ME_NOREFRESH;
+ }
+ else if (! thd->main_da.is_error()) // Return only first message
{
thd->main_da.set_error_status(thd, error, str);
}
@@ -2999,11 +3130,12 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
}
}
+to_error_log:
/* When simulating OOM, skip writing to error log to avoid mtr errors */
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););
- if (!thd || MyFlags & ME_NOREFRESH)
- sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
+ if (!thd || (MyFlags & ME_NOREFRESH))
+ (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */
DBUG_RETURN(0);
}
@@ -3046,7 +3178,9 @@ const char *load_default_groups[]= {
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
"mysql_cluster",
#endif
-"mysqld","server", MYSQL_BASE_VERSION, 0, 0};
+"mysqld", "server", MYSQL_BASE_VERSION,
+"mariadb", MARIADB_BASE_VERSION,
+0, 0};
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
static const int load_default_groups_sz=
@@ -3077,10 +3211,8 @@ check_enough_stack_size()
The default value is taken from either opt_date_time_formats[] or
the ISO format (ANSI SQL)
- @retval
- 0 ok
- @retval
- 1 error
+ @retval 0 ok
+ @retval 1 error
*/
static bool init_global_datetime_format(timestamp_type format_type,
@@ -3386,7 +3518,8 @@ static int init_common_variables(const char *conf_file_name, int argc,
uint files, wanted_files, max_open_files;
/* MyISAM requires two file handles per table. */
- wanted_files= 10+max_connections+table_cache_size*2;
+ wanted_files= (10 + max_connections + extra_max_connections +
+ table_cache_size*2);
/*
We are trying to allocate no less than max_connections*5 file
handles (i.e. we are trying to set the limit so that they will
@@ -3397,7 +3530,8 @@ static int init_common_variables(const char *conf_file_name, int argc,
can't get max_connections*5 but still got no less than was
requested (value of wanted_files).
*/
- max_open_files= max(max(wanted_files, max_connections*5),
+ max_open_files= max(max(wanted_files,
+ (max_connections + extra_max_connections)*5),
open_files_limit);
files= my_set_max_open_files(max_open_files);
@@ -3506,7 +3640,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
global_system_variables.character_set_results= default_charset_info;
global_system_variables.character_set_client= default_charset_info;
- if (!(character_set_filesystem=
+ if (!(character_set_filesystem=
get_charset_by_csname(character_set_filesystem_name,
MY_CS_PRIMARY, MYF(MY_WME))))
return 1;
@@ -3519,7 +3653,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
return 1;
}
global_system_variables.lc_time_names= my_default_lc_time_names;
-
+
sys_init_connect.value_length= 0;
if ((sys_init_connect.value= opt_init_connect))
sys_init_connect.value_length= strlen(opt_init_connect);
@@ -3535,23 +3669,23 @@ static int init_common_variables(const char *conf_file_name, int argc,
sys_init_slave.is_os_charset= TRUE;
/* check log options and issue warnings if needed */
- if (opt_log && opt_logname && !(log_output_options & LOG_FILE) &&
- !(log_output_options & LOG_NONE))
+ if (opt_log && opt_logname && *opt_logname &&
+ !(log_output_options & (LOG_FILE | LOG_NONE)))
sql_print_warning("Although a path was specified for the "
"--log option, log tables are used. "
"To enable logging to files use the --log-output option.");
- if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
- && !(log_output_options & LOG_NONE))
+ if (opt_slow_log && opt_slow_logname && *opt_slow_logname &&
+ !(log_output_options & (LOG_FILE | LOG_NONE)))
sql_print_warning("Although a path was specified for the "
"--log_slow_queries option, log tables are used. "
"To enable logging to files use the --log-output=file option.");
- s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
+ s= opt_logname && *opt_logname ? opt_logname : make_default_log_name(buff, ".log");
sys_var_general_log_path.value= my_strdup(s, MYF(0));
sys_var_general_log_path.value_length= strlen(s);
- s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
+ s= opt_slow_logname && *opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
sys_var_slow_log_path.value= my_strdup(s, MYF(0));
sys_var_slow_log_path.value_length= strlen(s);
@@ -3646,7 +3780,7 @@ static int init_thread_environment()
(void) my_rwlock_init(&LOCK_system_variables_hash, NULL);
(void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
- (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
+ (void) pthread_mutex_init(&LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST);
#ifdef HAVE_OPENSSL
(void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
@@ -3654,7 +3788,7 @@ static int init_thread_environment()
openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
sizeof(openssl_lock_t));
for (int i= 0; i < CRYPTO_num_locks(); ++i)
- (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL);
+ (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL);
CRYPTO_set_dynlock_create_callback(openssl_dynlock_create);
CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy);
CRYPTO_set_dynlock_lock_callback(openssl_lock);
@@ -3695,26 +3829,27 @@ static int init_thread_environment()
sql_print_error("Can't create thread-keys");
return 1;
}
+ register_mutex_order();
return 0;
}
#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
static unsigned long openssl_id_function()
-{
+{
return (unsigned long) pthread_self();
-}
+}
static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
-{
+{
openssl_lock_t *lock= new openssl_lock_t;
my_rwlock_init(&lock->lock, NULL);
return lock;
}
-static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
+static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
int line)
{
rwlock_destroy(&lock->lock);
@@ -3734,7 +3869,7 @@ static void openssl_lock_function(int mode, int n, const char *file, int line)
}
-static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
+static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
int line)
{
int err;
@@ -3759,7 +3894,7 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
abort();
}
- if (err)
+ if (err)
{
sql_print_error("Fatal: can't %s OpenSSL lock", what);
abort();
@@ -3828,12 +3963,14 @@ static int init_server_components()
query_cache_set_min_res_unit(query_cache_min_res_unit);
query_cache_init();
query_cache_resize(query_cache_size);
- randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
+ my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
setup_fpu();
init_thr_lock();
+ my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345);
#ifdef HAVE_REPLICATION
init_slave_list();
#endif
+ wt_init();
/* Setup logs */
@@ -3866,6 +4003,12 @@ static int init_server_components()
}
}
+ /* set up the hook before initializing plugins which may use it */
+ error_handler_hook= my_message_sql;
+ proc_info_hook= (const char *(*)(void *, const char *, const char *,
+ const char *, const unsigned int))
+ set_thd_proc_info;
+
if (xid_cache_init())
{
sql_print_error("Out of memory");
@@ -3951,7 +4094,7 @@ with --log-bin instead.");
if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
else
- {
+ {
DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
}
@@ -4040,9 +4183,6 @@ a file name for --log-bin-index option", opt_binlog_index_name);
plugins_are_initialized= TRUE; /* Don't separate from init function */
}
- if (opt_help)
- unireg_abort(0);
-
/* we do want to exit if there are any other unknown options */
if (defaults_argc > 1)
{
@@ -4067,13 +4207,15 @@ a file name for --log-bin-index option", opt_binlog_index_name);
if (defaults_argc)
{
- fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
- "Use --verbose --help to get a list of available options\n",
+ fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n",
my_progname, *tmp_argv);
unireg_abort(1);
}
}
+ if (opt_help)
+ unireg_abort(0);
+
/* if the errmsg.sys is not loaded, terminate to maintain behaviour */
if (!errmesg[0][0])
unireg_abort(1);
@@ -4085,7 +4227,6 @@ a file name for --log-bin-index option", opt_binlog_index_name);
unireg_abort(1);
}
-#ifdef WITH_CSV_STORAGE_ENGINE
if (opt_bootstrap)
log_output_options= LOG_FILE;
else
@@ -4119,10 +4260,6 @@ a file name for --log-bin-index option", opt_binlog_index_name);
logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE,
opt_log ? log_output_options:LOG_NONE);
}
-#else
- logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
- opt_log ? LOG_FILE:LOG_NONE);
-#endif
/*
Check that the default storage engine is actually available.
@@ -4133,7 +4270,7 @@ a file name for --log-bin-index option", opt_binlog_index_name);
strlen(default_storage_engine_str) };
plugin_ref plugin;
handlerton *hton;
-
+
if ((plugin= ha_resolve_by_name(0, &name)))
hton= plugin_data(plugin, handlerton*);
else
@@ -4155,13 +4292,22 @@ a file name for --log-bin-index option", opt_binlog_index_name);
else
{
/*
- Need to unlock as global_system_variables.table_plugin
+ Need to unlock as global_system_variables.table_plugin
was acquired during plugin_init()
*/
+ pthread_mutex_lock(&LOCK_global_system_variables);
plugin_unlock(0, global_system_variables.table_plugin);
global_system_variables.table_plugin= plugin;
+ pthread_mutex_unlock(&LOCK_global_system_variables);
}
}
+#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
+ if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap)
+ {
+ sql_print_error("Maria engine is not enabled or did not start. The Maria engine must be enabled to continue as mysqld was configured with --with-maria-tmp-tables");
+ unireg_abort(1);
+ }
+#endif
tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
(TC_LOG *) &mysql_bin_log :
@@ -4297,7 +4443,7 @@ static void handle_connections_methods()
handler_count--;
}
}
-#endif
+#endif
while (handler_count > 0)
pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
@@ -4310,7 +4456,7 @@ void decrement_handler_count()
pthread_mutex_lock(&LOCK_thread_count);
handler_count--;
pthread_cond_signal(&COND_handler_count);
- pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_mutex_unlock(&LOCK_thread_count);
my_thread_end();
}
#else
@@ -4366,13 +4512,6 @@ int main(int argc, char **argv)
MY_INIT(argv[0]); // init my_sys library & pthreads
/* nothing should come before this line ^^^ */
- /* Set signal used to kill MySQL */
-#if defined(SIGUSR2)
- thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
-#else
- thr_kill_signal= SIGINT;
-#endif
-
/*
Perform basic logger initialization logger. Should be called after
MY_INIT, as it initializes mutexes. Log tables are inited later.
@@ -4527,7 +4666,6 @@ we force server id to 2, but this MySQL server will not act as a slave.");
init signals & alarm
After this we can't quit by a simple unireg_abort
*/
- error_handler_hook= my_message_sql;
start_signal_handler(); // Creates pidfile
if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
@@ -4582,7 +4720,13 @@ we force server id to 2, but this MySQL server will not act as a slave.");
{
select_thread_in_use= 0; // Allow 'kill' to work
bootstrap(stdin);
- unireg_abort(bootstrap_error ? 1 : 0);
+ if (!kill_in_progress)
+ unireg_abort(bootstrap_error ? 1 : 0);
+ else
+ {
+ sleep(2); // Wait for kill
+ exit(0);
+ }
}
if (opt_init_file)
{
@@ -4623,7 +4767,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
#endif /* __NT__ */
/* (void) pthread_attr_destroy(&connection_attrib); */
-
+
DBUG_PRINT("quit",("Exiting main thread"));
#ifndef __WIN__
@@ -4705,10 +4849,8 @@ static char *add_quoted_string(char *to, const char *from, char *to_end)
@param file_path Path to this program
@param startup_option Startup option to mysqld
- @retval
- 0 option handled
- @retval
- 1 Could not handle option
+ @retval 0 option handled
+ @retval 1 Could not handle option
*/
static bool
@@ -4939,12 +5081,13 @@ static bool read_init_file(char *file_name)
When we enter this function, LOCK_thread_count is hold!
*/
-
+
void handle_connection_in_main_thread(THD *thd)
{
safe_mutex_assert_owner(&LOCK_thread_count);
thread_cache_size=0; // Safety
threads.append(thd);
+ thd->start_utime= my_micro_time();
pthread_mutex_unlock(&LOCK_thread_count);
thd->start_utime= my_micro_time();
handle_one_connection(thd);
@@ -4986,7 +5129,7 @@ void create_thread_to_handle_connection(THD *thd)
(void) pthread_mutex_unlock(&LOCK_thread_count);
pthread_mutex_lock(&LOCK_connection_count);
- --connection_count;
+ (*thd->scheduler->connection_count)--;
pthread_mutex_unlock(&LOCK_connection_count);
statistic_increment(aborted_connects,&LOCK_status);
@@ -5035,7 +5178,8 @@ static void create_new_thread(THD *thd)
pthread_mutex_lock(&LOCK_connection_count);
- if (connection_count >= max_connections + 1 || abort_loop)
+ if (*thd->scheduler->connection_count >=
+ *thd->scheduler->max_connections + 1|| abort_loop)
{
pthread_mutex_unlock(&LOCK_connection_count);
@@ -5045,10 +5189,10 @@ static void create_new_thread(THD *thd)
DBUG_VOID_RETURN;
}
- ++connection_count;
+ ++*thd->scheduler->connection_count;
- if (connection_count > max_used_connections)
- max_used_connections= connection_count;
+ if (connection_count + extra_connection_count > max_used_connections)
+ max_used_connections= connection_count + extra_connection_count;
pthread_mutex_unlock(&LOCK_connection_count);
@@ -5065,7 +5209,7 @@ static void create_new_thread(THD *thd)
thread_count++;
- thread_scheduler.add_connection(thd);
+ thd->scheduler->add_connection(thd);
DBUG_VOID_RETURN;
}
@@ -5080,10 +5224,11 @@ inline void kill_broken_server()
#if !defined(__NETWARE__)
unix_sock == INVALID_SOCKET ||
#endif
- (!opt_disable_networking && ip_sock == INVALID_SOCKET))
+ (!opt_disable_networking && base_ip_sock == INVALID_SOCKET))
{
select_thread_in_use = 0;
/* The following call will never return */
+ DBUG_PRINT("general", ("killing server because socket is closed"));
kill_server(IF_NETWARE(MYSQL_KILL_SIGNAL, (void*) MYSQL_KILL_SIGNAL));
}
}
@@ -5099,26 +5244,38 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
{
my_socket sock,new_sock;
uint error_count=0;
- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
+ uint max_used_connection;
fd_set readFDs,clientFDs;
THD *thd;
struct sockaddr_in cAddr;
- int ip_flags=0,socket_flags=0,flags;
+ int base_ip_flags=0, extra_ip_flags= 0, socket_flags=0, flags;
st_vio *vio_tmp;
DBUG_ENTER("handle_connections_sockets");
+ max_used_connection= (uint) (max(base_ip_sock, unix_sock));
+ max_used_connection= (uint) (max(extra_ip_sock, (int) max_used_connection));
+ max_used_connection++;
+
LINT_INIT(new_sock);
(void) my_pthread_getprio(pthread_self()); // For debugging
FD_ZERO(&clientFDs);
- if (ip_sock != INVALID_SOCKET)
+ if (base_ip_sock != INVALID_SOCKET)
+ {
+ FD_SET(base_ip_sock, &clientFDs);
+#ifdef HAVE_FCNTL
+ base_ip_flags = fcntl(base_ip_sock, F_GETFL, 0);
+#endif
+ }
+ if (extra_ip_sock != INVALID_SOCKET)
{
- FD_SET(ip_sock,&clientFDs);
+ FD_SET(extra_ip_sock, &clientFDs);
#ifdef HAVE_FCNTL
- ip_flags = fcntl(ip_sock, F_GETFL, 0);
+ extra_ip_flags = fcntl(extra_ip_sock, F_GETFL, 0);
#endif
}
+
#ifdef HAVE_SYS_UN_H
FD_SET(unix_sock,&clientFDs);
#ifdef HAVE_FCNTL
@@ -5156,14 +5313,22 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
#ifdef HAVE_SYS_UN_H
if (FD_ISSET(unix_sock,&readFDs))
{
- sock = unix_sock;
+ sock= unix_sock;
flags= socket_flags;
}
else
#endif
{
- sock = ip_sock;
- flags= ip_flags;
+ if (FD_ISSET(base_ip_sock,&readFDs))
+ {
+ sock= base_ip_sock;
+ flags= base_ip_flags;
+ }
+ else
+ {
+ sock= extra_ip_sock;
+ flags= extra_ip_flags;
+ }
}
#if !defined(NO_FCNTL_NONBLOCK)
@@ -5181,7 +5346,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
size_socket length=sizeof(struct sockaddr_in);
new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
&length);
-#ifdef __NETWARE__
+#ifdef __NETWARE__
// TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149
if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL))
{
@@ -5216,7 +5381,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
#ifdef HAVE_LIBWRAP
{
- if (sock == ip_sock)
+ if (sock == base_ip_sock || sock == extra_ip_sock)
{
struct request_info req;
signal(SIGCHLD, SIG_DFL);
@@ -5296,6 +5461,11 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
if (sock == unix_sock)
thd->security_ctx->host=(char*) my_localhost;
+ if (sock == extra_ip_sock)
+ {
+ thd->extra_port= 1;
+ thd->scheduler= &extra_thread_scheduler;
+ }
create_new_thread(thd);
}
DBUG_LEAVE;
@@ -5600,7 +5770,7 @@ errorconn:
NullS);
sql_perror(buff);
}
- if (handle_client_file_map)
+ if (handle_client_file_map)
CloseHandle(handle_client_file_map);
if (handle_client_map)
UnmapViewOfFile(handle_client_map);
@@ -5648,10 +5818,11 @@ error:
enum options_mysqld
{
- OPT_ISAM_LOG=256, OPT_SKIP_NEW,
- OPT_SKIP_GRANT, OPT_SKIP_LOCK,
+ OPT_ISAM_LOG=256, OPT_SKIP_NEW,
+ OPT_SKIP_GRANT, OPT_SKIP_LOCK,
OPT_ENABLE_LOCK, OPT_USE_LOCKING,
OPT_SOCKET, OPT_UPDATE_LOG,
+ OPT_EXTRA_PORT,
OPT_BIN_LOG, OPT_SKIP_RESOLVE,
OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
OPT_BIND_ADDRESS, OPT_PID_FILE,
@@ -5678,11 +5849,11 @@ enum options_mysqld
#ifndef DBUG_OFF
OPT_BINLOG_SHOW_XID,
#endif
- OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
+ OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
OPT_WANT_CORE, OPT_CONCURRENT_INSERT,
OPT_MEMLOCK, OPT_MYISAM_RECOVER,
OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
- OPT_SKIP_SLAVE_START, OPT_SAFE_SHOW_DB,
+ OPT_SKIP_SLAVE_START, OPT_SAFE_SHOW_DB,
OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
@@ -5690,7 +5861,7 @@ enum options_mysqld
OPT_ABORT_SLAVE_EVENT_COUNT,
OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
- OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING,
+ OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING,
OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS,
OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
@@ -5701,9 +5872,9 @@ enum options_mysqld
OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
OPT_NDB_USE_COPYING_ALTER_TABLE,
- OPT_SKIP_SAFEMALLOC,
+ OPT_SKIP_SAFEMALLOC, OPT_MUTEX_DEADLOCK_DETECTOR,
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
- OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
+ OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
OPT_HAVE_NAMED_PIPE,
@@ -5735,11 +5906,16 @@ enum options_mysqld
OPT_MAX_LENGTH_FOR_SORT_DATA,
OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
+
OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
OPT_MYISAM_MMAP_SIZE,
OPT_MYISAM_STATS_METHOD,
+
+ OPT_PAGECACHE_BUFFER_SIZE,
+ OPT_PAGECACHE_DIVISION_LIMIT, OPT_PAGECACHE_AGE_THRESHOLD,
+
OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
OPT_OPEN_FILES_LIMIT,
@@ -5749,7 +5925,7 @@ enum options_mysqld
OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
OPT_RELAY_LOG_PURGE,
OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
- OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING,
+ OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING, OPT_DEBUG_FLUSH,
OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
@@ -5759,7 +5935,7 @@ enum options_mysqld
OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
- OPT_SYNC_FRM, OPT_SYNC_BINLOG,
+ OPT_SYNC_FRM, OPT_SYNC_BINLOG, OPT_SYNC,
OPT_SYNC_REPLICATION,
OPT_SYNC_REPLICATION_SLAVE_ID,
OPT_SYNC_REPLICATION_TIMEOUT,
@@ -5811,11 +5987,20 @@ enum options_mysqld
OPT_SECURE_FILE_PRIV,
OPT_MIN_EXAMINED_ROW_LIMIT,
OPT_LOG_SLOW_SLAVE_STATEMENTS,
+ OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_DEBUG_ASSERT_IF_CRASHED_TABLE, OPT_OLD_MODE,
+ OPT_TEST_IGNORE_WRONG_OPTIONS, OPT_TEST_RESTART,
#if defined(ENABLED_DEBUG_SYNC)
OPT_DEBUG_SYNC_TIMEOUT,
#endif /* defined(ENABLED_DEBUG_SYNC) */
- OPT_OLD_MODE,
+ OPT_DEPRECATED_OPTION,
OPT_SLAVE_EXEC_MODE,
+ OPT_DEADLOCK_SEARCH_DEPTH_SHORT,
+ OPT_DEADLOCK_SEARCH_DEPTH_LONG,
+ OPT_DEADLOCK_TIMEOUT_SHORT,
+ OPT_DEADLOCK_TIMEOUT_LONG,
+ OPT_LOG_SLOW_RATE_LIMIT,
+ OPT_LOG_SLOW_VERBOSITY,
+ OPT_LOG_SLOW_FILTER,
OPT_GENERAL_LOG_FILE,
OPT_SLOW_QUERY_LOG_FILE,
OPT_IGNORE_BUILTIN_INNODB,
@@ -5943,9 +6128,39 @@ struct my_option my_long_options[] =
NO_ARG, 0, 0, 0, 0, 0, 0},
{"datadir", 'h', "Path to the database root.", &mysql_data_home,
&mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"deadlock-search-depth-short", OPT_DEADLOCK_SEARCH_DEPTH_SHORT,
+ "Short search depth for the two-step deadlock detection",
+ &global_system_variables.wt_deadlock_search_depth_short,
+ &max_system_variables.wt_deadlock_search_depth_short,
+ 0, GET_ULONG, REQUIRED_ARG, 4, 0, 32, 0, 0, 0},
+ {"deadlock-search-depth-long", OPT_DEADLOCK_SEARCH_DEPTH_LONG,
+ "Long search depth for the two-step deadlock detection",
+ &global_system_variables.wt_deadlock_search_depth_long,
+ &max_system_variables.wt_deadlock_search_depth_long,
+ 0, GET_ULONG, REQUIRED_ARG, 15, 0, 33, 0, 0, 0},
+ {"deadlock-timeout-short", OPT_DEADLOCK_TIMEOUT_SHORT,
+ "Short timeout for the two-step deadlock detection (in microseconds)",
+ &global_system_variables.wt_timeout_short,
+ &max_system_variables.wt_timeout_short,
+ 0, GET_ULONG, REQUIRED_ARG, 10000, 0, ULONG_MAX, 0, 0, 0},
+ {"deadlock-timeout-long", OPT_DEADLOCK_TIMEOUT_LONG,
+ "Long timeout for the two-step deadlock detection (in microseconds)",
+ &global_system_variables.wt_timeout_long,
+ &max_system_variables.wt_timeout_long,
+ 0, GET_ULONG, REQUIRED_ARG, 50000000, 0, ULONG_MAX, 0, 0, 0},
#ifndef DBUG_OFF
- {"debug", '#', "Debug log.", &default_dbug_option,
- &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug", '#', "Debug log.", &current_dbug_option,
+ &current_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-crc-break", OPT_DEBUG_CRC,
+ "Call my_debug_put_break_here() if crc matches this number (for debug).",
+ &opt_my_crc_dbug_check, &opt_my_crc_dbug_check,
+ 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~(ulong) 0L, 0, 0, 0},
+ {"debug-flush", OPT_DEBUG_FLUSH, "Default debug log with flush after write",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-assert-if-crashed-table", OPT_DEBUG_ASSERT_IF_CRASHED_TABLE,
+ "Do an assert in handler::print_error() if we get a crashed table",
+ &debug_assert_if_crashed_table, &debug_assert_if_crashed_table,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD,
"Set the default character set (deprecated option, use --character-set-server instead).",
@@ -5993,12 +6208,11 @@ struct my_option my_long_options[] =
&opt_enable_named_pipe, &opt_enable_named_pipe, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
-#ifdef HAVE_STACK_TRACE_ON_SEGV
- {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure. "
- "This option is deprecated and has no effect; a symbolic stack trace will "
- "be printed after a crash whenever possible.", &opt_do_pstack, &opt_do_pstack,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-#endif /* HAVE_STACK_TRACE_ON_SEGV */
+#ifdef HAVE_STACKTRACE
+ {"stack-trace", OPT_DO_PSTACK, "Print a symbolic stack trace on failure. "
+ "On by default. Disable with --disable-stack-trace.",
+ &opt_stack_trace, &opt_stack_trace, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+#endif /* HAVE_STACKTRACE */
{"engine-condition-pushdown",
OPT_ENGINE_CONDITION_PUSHDOWN,
"Push supported query conditions to the storage engine.",
@@ -6020,6 +6234,15 @@ struct my_option my_long_options[] =
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
/* We must always support the next option to make scripts like mysqltest
easier to do */
+ {"extra-port", OPT_EXTRA_PORT,
+ "Extra port number to use for tcp-connections in a one-thread-per-connection manner. 0 means don't use another port",
+ &mysqld_extra_port,
+ &mysqld_extra_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"extra-max-connections", OPT_MAX_CONNECTIONS,
+ "The number of connections on 'extra-port.",
+ &extra_max_connections,
+ &extra_max_connections, 0, GET_ULONG, REQUIRED_ARG, 1, 1, 100000,
+ 0, 1, 0},
{"gdb", OPT_DEBUGGING,
"Set up signals usable for debugging.",
&opt_debugging, &opt_debugging,
@@ -6114,13 +6337,11 @@ each time the SQL thread starts.",
"Log some extra information to update log. Please note that this option "
"is deprecated; see --log-short-format option.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef WITH_CSV_STORAGE_ENGINE
{"log-output", OPT_LOG_OUTPUT,
"Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
"FILE or NONE.",
&log_output_str, &log_output_str, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-#endif
{"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
"Log queries that are executed without benefit of any index to the slow log if it is open.",
&opt_log_queries_not_using_indexes, &opt_log_queries_not_using_indexes,
@@ -6143,7 +6364,7 @@ each time the SQL thread starts.",
&opt_log_slow_slave_statements,
&opt_log_slow_slave_statements,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"log_slow_queries", OPT_SLOW_QUERY_LOG,
+ {"log-slow-queries", OPT_SLOW_QUERY_LOG,
"Log slow queries to a table or log file. Defaults logging to table "
"mysql.slow_log or hostname-slow.log if --log-output=file is used. "
"Must be enabled to activate other slow log options. "
@@ -6163,7 +6384,7 @@ each time the SQL thread starts.",
#ifdef HAVE_MMAP
{"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
&opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG,
- REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
+ REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, (longlong) ULONG_MAX, 0,
TC_LOG_PAGE_SIZE, 0},
#endif
{"log-update", OPT_UPDATE_LOG,
@@ -6253,8 +6474,15 @@ each time the SQL thread starts.",
#endif /* HAVE_REPLICATION */
{"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", &locked_in_memory,
&locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef SAFE_MUTEX
+ {"mutex-deadlock-detector", OPT_MUTEX_DEADLOCK_DETECTOR,
+ "Enable checking of wrong mutex usage.",
+ &safe_mutex_deadlock_detector,
+ &safe_mutex_deadlock_detector,
+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+#endif
{"myisam-recover", OPT_MYISAM_RECOVER,
- "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
+ "Syntax: myisam-recover=OFF or myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, BACKUP_ALL, FORCE or QUICK.",
&myisam_recover_options_str, &myisam_recover_options_str, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
@@ -6547,6 +6775,9 @@ thread is in the relay logs.",
"Show user and password in SHOW SLAVE HOSTS on this master.",
&opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"skip-bdb", OPT_DEPRECATED_OPTION,
+ "Deprecated option; Exist only for compatiblity with old my.cnf files",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DISABLE_GRANT_OPTIONS
{"skip-grant-tables", OPT_SKIP_GRANT,
"Start without grant tables. This gives all users FULL ACCESS to all tables.",
@@ -6579,9 +6810,6 @@ thread is in the relay logs.",
{"skip-slave-start", OPT_SKIP_SLAVE_START,
"If set, slave is not autostarted.", &opt_skip_slave_start,
&opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
- "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
- 0, 0, 0, 0},
{"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. "
"Deprecated option. Use --skip-symbolic-links instead.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -6642,7 +6870,7 @@ thread is in the relay logs.",
purify. These are not suppressed: instead we disable symlinks
option if compiled with valgrind support.
*/
- IF_PURIFY(0,1), 0, 0, 0, 0, 0},
+ IF_VALGRIND(0,1), 0, 0, 0, 0, 0},
{"sysdate-is-now", OPT_SYSDATE_IS_NOW,
"Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. "
"Since 5.0, SYSDATE() returns a `dynamic' value different for different "
@@ -6670,6 +6898,14 @@ thread is in the relay logs.",
#endif
&use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
0, 0, 0, 0, 0},
+ {"test-ignore-wrong-options", OPT_TEST_IGNORE_WRONG_OPTIONS,
+ "Ignore wrong enums values in command line arguments. Useful only for test scripts",
+ &opt_ignore_wrong_options, &opt_ignore_wrong_options,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"test-expect-abort", OPT_TEST_RESTART,
+ "Expect that server aborts with 'abort'; Don't write out server variables on 'abort'. Useful only for test scripts",
+ &opt_expect_abort, &opt_expect_abort,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"timed_mutexes", OPT_TIMED_MUTEXES,
"Specify whether to time mutexes (only InnoDB mutexes are currently supported).",
&timed_mutexes, &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
@@ -6687,10 +6923,11 @@ thread is in the relay logs.",
{"transaction-isolation", OPT_TX_ISOLATION,
"Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
0, 0, 0, 0, 0},
- {"use-symbolic-links", OPT_SYMBOLIC_LINKS, "Enable symbolic link support. "
+ {"use-symbolic-links", OPT_SYMBOLIC_LINKS,
+ "Enable symbolic link support. "
"Deprecated option; use --symbolic-links instead.",
&my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
- IF_PURIFY(0,1), 0, 0, 0, 0, 0},
+ IF_VALGRIND(0,1), 0, 0, 0, 0, 0},
{"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Used with --help option for detailed help.",
@@ -6711,12 +6948,12 @@ thread is in the relay logs.",
"during a transaction. If you often use big, multi-statement "
"transactions you can increase this to get more performance.",
&binlog_cache_size, &binlog_cache_size, 0, GET_ULONG,
- REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
+ REQUIRED_ARG, 32*1024L, IO_SIZE, (longlong) ULONG_MAX, 0, IO_SIZE, 0},
{"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
"Size of tree cache used in bulk insert optimization. Note that this "
"is a limit per thread.", &global_system_variables.bulk_insert_buff_size,
&max_system_variables.bulk_insert_buff_size,
- 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
+ 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, (longlong) ULONG_MAX, 0, 1, 0},
{"connect_timeout", OPT_CONNECT_TIMEOUT,
"The number of seconds the mysqld server is waiting for a connect packet "
"before responding with 'Bad handshake'.", &connect_timeout, &connect_timeout,
@@ -6741,7 +6978,7 @@ thread is in the relay logs.",
"will check if there are any SELECT statements pending. If so, it allows "
"these to execute before continuing.",
&delayed_insert_limit, &delayed_insert_limit, 0, GET_ULONG,
- REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, DELAYED_LIMIT, 1, (longlong) ULONG_MAX, 0, 1, 0},
{"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
"How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
&delayed_insert_timeout, &delayed_insert_timeout, 0,
@@ -6751,7 +6988,7 @@ thread is in the relay logs.",
"If the queue becomes full, any client that does INSERT DELAYED will wait "
"until there is room in the queue again.",
&delayed_queue_size, &delayed_queue_size, 0, GET_ULONG,
- REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, (longlong) ULONG_MAX, 0, 1, 0},
{"div_precision_increment", OPT_DIV_PRECINCREMENT,
"Precision of the result of '/' operator will be increased on that value.",
&global_system_variables.div_precincrement,
@@ -6791,7 +7028,7 @@ thread is in the relay logs.",
"The maximum length of the result of function group_concat.",
&global_system_variables.group_concat_max_len,
&max_system_variables.group_concat_max_len, 0, GET_ULONG,
- REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, 1024, 4, (longlong) ULONG_MAX, 0, 1, 0},
{"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
"The number of seconds the server waits for activity on an interactive "
"connection before closing it.",
@@ -6802,7 +7039,7 @@ thread is in the relay logs.",
"The size of the buffer that is used for full joins.",
&global_system_variables.join_buff_size,
&max_system_variables.join_buff_size, 0, GET_ULONG,
- REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
+ REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, (longlong) ULONG_MAX,
MALLOC_OVERHEAD, IO_SIZE, 0},
{"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
"Don't overwrite stale .MYD and .MYI even if no directory is specified.",
@@ -6822,22 +7059,48 @@ thread is in the relay logs.",
"until it is considered aged enough to be downgraded to a warm block. "
"This specifies the percentage ratio of that number of hits to the total "
"number of blocks in key cache.",
- &dflt_key_cache_var.param_age_threshold, NULL, NULL,
- (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 300, 100, ULONG_MAX, 0, 100, 0},
+ &dflt_key_cache_var.param_age_threshold, 0, 0,
+ (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 300, 100, (longlong) ULONG_MAX,
+ 0, 100, 0},
{"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
"The default size of key cache blocks.",
&dflt_key_cache_var.param_block_size, NULL, NULL, (GET_ULONG | GET_ASK_ADDR),
REQUIRED_ARG, KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
{"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
"The minimum percentage of warm blocks in key cache.",
- &dflt_key_cache_var.param_division_limit, NULL, NULL,
+ &dflt_key_cache_var.param_division_limit, 0, 0,
(GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0},
+ {"log-slow-filter", OPT_LOG_SLOW_FILTER,
+ "Log only the queries that followed certain execution plan. Multiple flags "
+ "allowed in a comma-separated string. [admin, filesort, filesort_on_disk, "
+ "full_join, full_scan, query_cache, query_cache_miss, tmp_table, "
+ "tmp_table_on_disk]. Sets log-slow-admin-command to ON",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, QPLAN_ALWAYS_SET, 0, 0},
+ {"log-slow-rate_limit", OPT_LOG_SLOW_RATE_LIMIT,
+ "If set, only write to slow log every 'log_slow_rate_limit' query (use "
+ "this to reduce output on slow query log)",
+ &global_system_variables.log_slow_rate_limit,
+ &max_system_variables.log_slow_rate_limit, 0, GET_ULONG,
+ REQUIRED_ARG, 1, 1, ~0L, 0, 1L, 0},
+ {"log-slow-verbosity", OPT_LOG_SLOW_VERBOSITY,
+ "Choose how verbose the messages to your slow log will be. Multiple flags "
+ "allowed in a comma-separated string. [query_plan, innodb]",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ {"log-slow-file", OPT_SLOW_QUERY_LOG_FILE,
+ "Log slow queries to given log file. Defaults logging to hostname-slow.log",
+ &opt_slow_logname, &opt_slow_logname, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"long_query_time", OPT_LONG_QUERY_TIME,
"Log all queries that have taken more than long_query_time seconds to "
"execute. The argument will be treated as a decimal value with "
"microsecond precision.",
&long_query_time, &long_query_time, 0, GET_DOUBLE,
REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
+ {"log-slow-time", OPT_LONG_QUERY_TIME,
+ "Log all queries that have taken more than long_query_time seconds to execute to file. "
+ "The argument will be treated as a decimal value with microsecond precission.",
+ &long_query_time, &long_query_time, 0, GET_DOUBLE,
+ REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
{"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
"If set to 1, table names are stored in lowercase on disk and table names "
"will be case-insensitive. Should be set to 2 if you are using a case-"
@@ -6868,7 +7131,7 @@ thread is in the relay logs.",
"If there is more than this number of interrupted connections from a host "
"this host will be blocked from further connections.",
&max_connect_errors, &max_connect_errors, 0, GET_ULONG,
- REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, (longlong) ULONG_MAX, 0, 1, 0},
// Default max_connections of 151 is larger than Apache's default max
// children, to avoid "too many connections" error in a common setup
{"max_connections", OPT_MAX_CONNECTIONS,
@@ -6903,10 +7166,9 @@ thread is in the relay logs.",
REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
{"max_long_data_size", OPT_MAX_LONG_DATA_SIZE,
"The maximum size of prepared statement parameter which can be provided "
- "through mysql_send_long_data() API call. "
- "Deprecated option; use max_allowed_packet instead.",
- &max_long_data_size,
- &max_long_data_size, 0, GET_ULONG,
+ "through mysql_send_long_data() API call. To be used when limit of "
+ "max_allowed_packet is too small",
+ &max_long_data_size, &max_long_data_size, 0, GET_ULONG,
REQUIRED_ARG, 1024*1024L, 1024, UINT_MAX32, MALLOC_OVERHEAD, 1, 0},
{"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT,
"Maximum number of prepared statements in the server.",
@@ -6922,7 +7184,7 @@ thread is in the relay logs.",
"Limit assumed max number of seeks when looking up rows based on a key.",
&global_system_variables.max_seeks_for_key,
&max_system_variables.max_seeks_for_key, 0, GET_ULONG,
- REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
+ REQUIRED_ARG, (longlong) ULONG_MAX, 1, (longlong) ULONG_MAX, 0, 1, 0 },
{"max_sort_length", OPT_MAX_SORT_LENGTH,
"The number of bytes to use when sorting BLOB or TEXT values (only the "
"first max_sort_length bytes of each value are used; the rest are ignored).",
@@ -6938,7 +7200,7 @@ thread is in the relay logs.",
"Maximum number of temporary tables a client can keep open at a time.",
&global_system_variables.max_tmp_tables,
&max_system_variables.max_tmp_tables, 0, GET_ULONG,
- REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, 32, 1, (longlong) ULONG_MAX, 0, 1, 0},
{"max_user_connections", OPT_MAX_USER_CONNECTIONS,
"The maximum number of active connections for a single user (0 = no limit).",
&max_user_connections, &max_user_connections, 0, GET_UINT,
@@ -6946,17 +7208,17 @@ thread is in the relay logs.",
{"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
"After this many write locks, allow some read locks to run in between.",
&max_write_lock_count, &max_write_lock_count, 0, GET_ULONG,
- REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, (longlong) ULONG_MAX, 1, (longlong) ULONG_MAX, 0, 1, 0},
{"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
"Don't log queries which examine less than min_examined_row_limit rows to file.",
&global_system_variables.min_examined_row_limit,
&max_system_variables.min_examined_row_limit, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
+ REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1L, 0},
{"multi_range_count", OPT_MULTI_RANGE_COUNT,
"Number of key ranges to request at once.",
&global_system_variables.multi_range_count,
&max_system_variables.multi_range_count, 0,
- GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0},
+ GET_ULONG, REQUIRED_ARG, 256, 1, (longlong) ULONG_MAX, 0, 1, 0},
{"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
"Block size to be used for MyISAM index pages.",
&opt_myisam_block_size, &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
@@ -6991,13 +7253,13 @@ thread is in the relay logs.",
"disables parallel repair.",
&global_system_variables.myisam_repair_threads,
&max_system_variables.myisam_repair_threads, 0,
- GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
+ GET_ULONG, REQUIRED_ARG, 1, 1, (longlong) ULONG_MAX, 0, 1, 0},
{"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
"The buffer that is allocated when sorting the index when doing a REPAIR "
"or when creating indexes with CREATE INDEX or ALTER TABLE.",
&global_system_variables.myisam_sort_buff_size,
&max_system_variables.myisam_sort_buff_size, 0,
- GET_ULONG, REQUIRED_ARG, 8192 * 1024, 4096, ~0L, 0, 1, 0},
+ GET_ULONG, REQUIRED_ARG, 8192 * 1024, 4096, (longlong) ULONG_MAX, 0, 1, 0},
{"myisam_use_mmap", OPT_MYISAM_USE_MMAP,
"Use memory mapping for reading and writing MyISAM tables.",
&opt_myisam_use_mmap, &opt_myisam_use_mmap, 0, GET_BOOL, NO_ARG,
@@ -7022,7 +7284,8 @@ thread is in the relay logs.",
"If a read on a communication port is interrupted, retry this many times before giving up.",
&global_system_variables.net_retry_count,
&max_system_variables.net_retry_count,0,
- GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
+ GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, (longlong) ULONG_MAX,
+ 0, 1, 0},
{"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
"Number of seconds to wait for a block to be written to a connection before "
"aborting the write.",
@@ -7061,9 +7324,12 @@ thread is in the relay logs.",
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
{"optimizer_switch", OPT_OPTIMIZER_SWITCH,
"optimizer_switch=option=val[,option=val...], where option={index_merge, "
- "index_merge_union, index_merge_sort_union, index_merge_intersection} and "
- "val={on, off, default}.",
- &optimizer_switch_str, &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
+ "index_merge_union, index_merge_sort_union, index_merge_intersection"
+#ifndef DBUG_OFF
+ ", table_elimination"
+#endif
+ "} and val={on, off, default}.",
+ &optimizer_switch_str, &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
/*OPTIMIZER_SWITCH_DEFAULT*/0, 0, 0, 0, 0, 0},
{"plugin_dir", OPT_PLUGIN_DIR,
"Directory for plugins.",
@@ -7084,18 +7350,19 @@ thread is in the relay logs.",
"Allocation block size for query parsing and execution.",
&global_system_variables.query_alloc_block_size,
&max_system_variables.query_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
+ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, (longlong) ULONG_MAX, 0, 1024,
+ 0},
#ifdef HAVE_QUERY_CACHE
{"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
"Don't cache results that are bigger than this.",
&query_cache_limit, &query_cache_limit, 0, GET_ULONG,
- REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, 1024*1024L, 0, (longlong) ULONG_MAX, 0, 1, 0},
{"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT,
"Minimal size of unit in which space for results is allocated (last unit "
"will be trimmed after writing all result data).",
&query_cache_min_res_unit, &query_cache_min_res_unit,
0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE,
- 0, ULONG_MAX, 0, 1, 0},
+ 0, (longlong) ULONG_MAX, 0, 1, 0},
#endif /*HAVE_QUERY_CACHE*/
{"query_cache_size", OPT_QUERY_CACHE_SIZE,
"The memory allocated to store results from old queries.",
@@ -7119,13 +7386,13 @@ thread is in the relay logs.",
&global_system_variables.query_prealloc_size,
&max_system_variables.query_prealloc_size, 0, GET_ULONG,
REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
- ULONG_MAX, 0, 1024, 0},
+ (longlong) ULONG_MAX, 0, 1024, 0},
{"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
"Allocation block size for storing ranges during optimization.",
&global_system_variables.range_alloc_block_size,
&max_system_variables.range_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
- 0, 1024, 0},
+ REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE,
+ (longlong) ULONG_MAX, 0, 1024, 0},
{"read_buffer_size", OPT_RECORD_BUFFER,
"Each thread that does a sequential scan allocates a buffer of this size "
"for each table it scans. If you do many sequential scans, you may want "
@@ -7188,16 +7455,20 @@ thread is in the relay logs.",
"Each thread that needs to do a sort allocates a buffer of this size.",
&global_system_variables.sortbuff_size,
&max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
- MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
- 1, 0},
+ MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, (longlong) ULONG_MAX,
+ MALLOC_OVERHEAD, 1, 0},
{"sync-binlog", OPT_SYNC_BINLOG,
"Synchronously flush binary log to disk after every #th event. "
"Use 0 (default) to disable synchronous flushing.",
&sync_binlog_period, &sync_binlog_period, 0, GET_ULONG,
- REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
+ REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1, 0},
{"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
&opt_sync_frm, &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
0, 0, 0, 0},
+ {"sync-sys", OPT_SYNC,
+ "Enable/disable system sync calls. Should only be turned off when running "
+ "tests or debugging!!",
+ &opt_sync, &opt_sync, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"table_cache", OPT_TABLE_OPEN_CACHE,
"Deprecated; use --table_open_cache instead.",
&table_cache_size, &table_cache_size, 0, GET_ULONG,
@@ -7235,15 +7506,15 @@ thread is in the relay logs.",
{"thread_stack", OPT_THREAD_STACK,
"The stack size for each thread.", &my_thread_stack_size,
&my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
- 1024L*128L, ULONG_MAX, 0, 1024, 0},
+ (sizeof(void*)<=4)?1024L*128L: ((256-16)*1024L), (longlong) ULONG_MAX, 0, 1024, 0},
{ "time_format", OPT_TIME_FORMAT,
"The TIME format (for future).",
&opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
&opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"tmp_table_size", OPT_TMP_TABLE_SIZE,
- "If an internal in-memory temporary table exceeds this size, MySQL will"
- " automatically convert it to an on-disk MyISAM table.",
+ "If an internal in-memory temporary table exceeds this size, MySQL will "
+ "automatically convert it to an on-disk MyISAM/Maria table.",
&global_system_variables.tmp_table_size,
&max_system_variables.tmp_table_size, 0, GET_ULL,
REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
@@ -7251,15 +7522,22 @@ thread is in the relay logs.",
"Allocation block size for transactions to be stored in binary log.",
&global_system_variables.trans_alloc_block_size,
&max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
- REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
+ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, (longlong) ULONG_MAX, 0, 1024,
+ 0},
{"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
"Persistent buffer for transactions to be stored in binary log.",
&global_system_variables.trans_prealloc_size,
&max_system_variables.trans_prealloc_size, 0, GET_ULONG,
- REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
+ REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, (longlong) ULONG_MAX, 0,
+ 1024, 0},
{"thread_handling", OPT_THREAD_HANDLING,
"Define threads usage for handling queries: "
- "one-thread-per-connection or no-threads.", 0, 0,
+ "one-thread-per-connection"
+#if HAVE_POOL_OF_THREADS == 1
+ ", pool-of-threads "
+#endif
+ "or no-threads.",
+ &opt_thread_handling, &opt_thread_handling,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT,
"1 = YES = Don't issue an error message (warning only) if a VIEW without "
@@ -7554,7 +7832,7 @@ static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *bu
}
/*
- Functions relying on SSL
+ Functions relying on SSL
Note: In the show_ssl_* functions, we need to check if we have a
valid vio-object since this isn't always true, specifically
when session_status or global_status is requested from
@@ -7688,6 +7966,7 @@ SHOW_VAR status_vars[]= {
{"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
{"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
{"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
+ {"Key_blocks_warm", (char*) offsetof(KEY_CACHE, warm_blocks), SHOW_KEY_CACHE_LONG},
{"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
{"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
{"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
@@ -7759,6 +8038,7 @@ SHOW_VAR status_vars[]= {
{"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC},
{"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC},
#endif /* HAVE_OPENSSL */
+ {"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH},
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
#ifdef HAVE_MMAP
@@ -7798,8 +8078,14 @@ static void usage(void)
if (!default_collation_name)
default_collation_name= (char*) default_charset_info->name;
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
- puts("Starts the MySQL database server.\n");
+ puts("\
+Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\
+Copyright (C) 2000, 2011 Oracle.\n\
+Copyright (C) 2009-2011 Monty Program Ab.\n\
+This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license\n\n\
+Starts the MariaDB database server.\n");
+
printf("Usage: %s [OPTIONS]\n", my_progname);
if (!opt_verbose)
puts("\nFor more help options (several pages), use mysqld --verbose --help.");
@@ -7862,7 +8148,10 @@ static int mysql_init_variables(void)
/* Things reset to zero */
opt_skip_slave_start= opt_reckless_slave = 0;
mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
+#if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH)
+ /* We can only test for sub paths if my_symlink.c is using realpath */
myisam_test_invalid_symlink= test_if_data_home_dir;
+#endif
opt_log= opt_slow_log= 0;
opt_update_log= 0;
log_output_options= find_bit_type(log_output_str, &log_output_typelib);
@@ -7926,7 +8215,7 @@ static int mysql_init_variables(void)
if (error)
return 1;
opt_specialflag= SPECIAL_ENGLISH;
- unix_sock= ip_sock= INVALID_SOCKET;
+ unix_sock= base_ip_sock= extra_ip_sock= INVALID_SOCKET;
mysql_home_ptr= mysql_home;
pidfile_name_ptr= pidfile_name;
log_error_file_ptr= log_error_file;
@@ -7939,7 +8228,13 @@ static int mysql_init_variables(void)
refresh_version= 1L; /* Increments on each reload */
global_query_id= thread_id= 1L;
strmov(server_version, MYSQL_SERVER_VERSION);
- myisam_recover_options_str= sql_mode_str= "OFF";
+ sql_mode_str= "";
+
+ /* By default, auto-repair MyISAM tables after crash */
+ myisam_recover_options_str= "DEFAULT";
+ myisam_recover_options= HA_RECOVER_DEFAULT;
+ ha_open_options|= HA_OPEN_ABORT_IF_CRASHED;
+
myisam_stats_method_str= "nulls_unequal";
my_bind_addr = htonl(INADDR_ANY);
threads.empty();
@@ -7951,6 +8246,7 @@ static int mysql_init_variables(void)
sql_print_error("Cannot allocate the keycache");
return 1;
}
+
/* set key_cache_hash.default_value = dflt_key_cache */
multi_keycache_init();
@@ -7990,6 +8286,9 @@ static int mysql_init_variables(void)
global_system_variables.old_passwords= 0;
global_system_variables.old_alter_table= 0;
global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
+ global_system_variables.log_slow_verbosity= LOG_SLOW_VERBOSITY_INIT;
+ global_system_variables.log_slow_filter= QPLAN_ALWAYS_SET;
+
/*
Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
when collecting index statistics for MyISAM tables.
@@ -8001,6 +8300,7 @@ static int mysql_init_variables(void)
#ifndef DBUG_OFF
default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
"d:t:i:o,/tmp/mysqld.trace");
+ current_dbug_option= default_dbug_option;
#endif
opt_error_log= IF_WIN(1,0);
#ifdef COMMUNITY_SERVER
@@ -8098,6 +8398,38 @@ static int mysql_init_variables(void)
}
+/**
+ Find type for option
+
+ If opt_ignore_wrong_options is set ignore wrong values
+ otherwise exit
+
+ @return
+ @retval 0 ok ; *result is updated
+ @retval 1 error ; *result is not touched
+*/
+
+static my_bool find_opt_type(const char *x, TYPELIB *typelib,
+ const char *option, int *result)
+{
+ int res;
+
+ if (opt_ignore_wrong_options)
+ {
+ if ((res= find_type_with_warning(x, typelib, option)) <= 0)
+ return 1;
+ }
+ else
+ res= find_type_or_exit(x, typelib, option);
+ *result= res;
+ return 0;
+}
+
+
+/**
+ Get next option from the command line
+*/
+
my_bool
mysqld_get_one_option(int optid,
const struct my_option *opt __attribute__((unused)),
@@ -8106,15 +8438,32 @@ mysqld_get_one_option(int optid,
int error;
switch(optid) {
- case '#':
#ifndef DBUG_OFF
- DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
-#endif
+ case OPT_DEBUG_FLUSH:
+ argument= IF_WIN((char*) default_dbug_option, (char*) "d:t:i:O,/tmp/mysqld.trace");
+ /* fall through */
+ case '#':
+ if (!argument)
+ argument= (char*) default_dbug_option;
+ if (argument[0] == '0' && !argument[1])
+ {
+ DEBUGGER_OFF;
+ break;
+ }
+ DEBUGGER_ON;
+ if (argument[0] == '1' && !argument[1])
+ break;
+ DBUG_SET_INITIAL(argument);
opt_endinfo=1; /* unireg: memory allocation */
break;
+#endif
case '0':
WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-long-format", "--log-short-format");
break;
+ case OPT_DEPRECATED_OPTION:
+ sql_print_warning("'%s' is deprecated and exists only for compatiblity with old my.cnf files; Please remove this option from all your my.cnf files!",
+ opt->name);
+ break;
case 'a':
global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
global_system_variables.tx_isolation= ISO_SERIALIZABLE;
@@ -8226,9 +8575,13 @@ mysqld_get_one_option(int optid,
case (int) OPT_INIT_RPL_ROLE:
{
int role;
- role= find_type_or_exit(argument, &rpl_role_typelib, opt->name);
- rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
- break;
+ LINT_INIT(role);
+
+ if (!find_opt_type(argument, &rpl_role_typelib, opt->name, &role))
+ {
+ rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
+ break;
+ }
}
case (int)OPT_REPLICATE_IGNORE_DB:
{
@@ -8279,8 +8632,12 @@ mysqld_get_one_option(int optid,
case OPT_BINLOG_FORMAT:
{
int id;
- id= find_type_or_exit(argument, &binlog_format_typelib, opt->name);
- global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
+ LINT_INIT(id);
+
+ if (!find_opt_type(argument, &binlog_format_typelib, opt->name, &id))
+ {
+ global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
+ }
break;
}
case (int)OPT_BINLOG_DO_DB:
@@ -8326,10 +8683,9 @@ mysqld_get_one_option(int optid,
}
#endif /* HAVE_REPLICATION */
case (int) OPT_SLOW_QUERY_LOG:
- WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--slow_query_log_file'");
+ WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--log-slow-file'");
opt_slow_log= 1;
break;
-#ifdef WITH_CSV_STORAGE_ENGINE
case OPT_LOG_OUTPUT:
{
if (!argument || !argument[0])
@@ -8347,7 +8703,6 @@ mysqld_get_one_option(int optid,
}
break;
}
-#endif
case OPT_EVENT_SCHEDULER:
#ifndef HAVE_EVENT_SCHEDULER
sql_perror("Event scheduler is not supported in embedded build.");
@@ -8406,7 +8761,7 @@ mysqld_get_one_option(int optid,
return 1;
#endif
opt_disable_networking=1;
- mysqld_port=0;
+ mysqld_port= mysqld_extra_port= 0;
break;
case (int) OPT_SKIP_SHOW_DB:
opt_skip_show_db=1;
@@ -8415,9 +8770,6 @@ mysqld_get_one_option(int optid,
case (int) OPT_WANT_CORE:
test_flags |= TEST_CORE_ON_SIGNAL;
break;
- case (int) OPT_SKIP_STACK_TRACE:
- test_flags|=TEST_NO_STACKTRACE;
- break;
case (int) OPT_SKIP_SYMLINKS:
WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-symlink", "--skip-symbolic-links");
my_use_symdir=0;
@@ -8463,17 +8815,16 @@ mysqld_get_one_option(int optid,
case OPT_MASTER_PASSWORD:
case OPT_MASTER_PORT:
case OPT_MASTER_CONNECT_RETRY:
- case OPT_MASTER_SSL:
+ case OPT_MASTER_SSL:
case OPT_MASTER_SSL_KEY:
- case OPT_MASTER_SSL_CERT:
+ case OPT_MASTER_SSL_CERT:
case OPT_MASTER_SSL_CAPATH:
case OPT_MASTER_SSL_CIPHER:
case OPT_MASTER_SSL_CA:
if (!slave_warning_issued) //only show the warning once
{
slave_warning_issued = true;
- WARN_DEPRECATED(NULL, "6.0", "for replication startup options",
- "'CHANGE MASTER'");
+ WARN_DEPRECATED(NULL, "6.0", opt->name, "'CHANGE MASTER'");
}
break;
case OPT_CONSOLE:
@@ -8491,6 +8842,25 @@ mysqld_get_one_option(int optid,
case OPT_BOOTSTRAP:
opt_noacl=opt_bootstrap=1;
break;
+ case OPT_LOG_SLOW_FILTER:
+ global_system_variables.log_slow_filter=
+ find_bit_type_or_exit(argument, &log_slow_filter_typelib,
+ opt->name, &error);
+ /*
+ If we are using filters, we set opt_slow_admin_statements to be always
+ true so we can maintain everything with filters
+ */
+ opt_log_slow_admin_statements= 1;
+ if (error)
+ return 1;
+ break;
+ case OPT_LOG_SLOW_VERBOSITY:
+ global_system_variables.log_slow_verbosity=
+ find_bit_type_or_exit(argument, &log_slow_verbosity_typelib,
+ opt->name, &error);
+ if (error)
+ return 1;
+ break;
case OPT_SERVER_ID:
server_id_supplied = 1;
break;
@@ -8509,15 +8879,12 @@ mysqld_get_one_option(int optid,
else
{
int type;
- type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
- delay_key_write_options= (uint) type-1;
+ LINT_INIT(type);
+
+ if (!find_opt_type(argument, &delay_key_write_typelib, opt->name, &type))
+ delay_key_write_options= (uint) type-1;
}
break;
- case OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE:
- sql_print_warning("--myisam_max_extra_sort_file_size is deprecated and "
- "does nothing in this version. It will be removed in "
- "a future release.");
- break;
case OPT_CHARSETS_DIR:
strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
charsets_dir = mysql_charsets_dir;
@@ -8525,8 +8892,10 @@ mysqld_get_one_option(int optid,
case OPT_TX_ISOLATION:
{
int type;
- type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
- global_system_variables.tx_isolation= (type-1);
+ LINT_INIT(type);
+
+ if (!find_opt_type(argument, &tx_isolation_typelib, opt->name, &type))
+ global_system_variables.tx_isolation= (type-1);
break;
}
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
@@ -8555,8 +8924,8 @@ mysqld_get_one_option(int optid,
break;
case OPT_NDB_DISTRIBUTION:
int id;
- id= find_type_or_exit(argument, &ndb_distribution_typelib, opt->name);
- opt_ndb_distribution_id= (enum ndb_distribution)(id-1);
+ if (!find_opt_type(argument, &ndb_distribution_typelib, opt->name, &id))
+ opt_ndb_distribution_id= (enum ndb_distribution)(id-1);
break;
case OPT_NDB_EXTRA_LOGGING:
if (!argument)
@@ -8569,26 +8938,31 @@ mysqld_get_one_option(int optid,
#endif
case OPT_MYISAM_RECOVER:
{
- if (!argument)
- {
- myisam_recover_options= HA_RECOVER_DEFAULT;
- myisam_recover_options_str= myisam_recover_typelib.type_names[0];
- }
- else if (!argument[0])
+ if (argument && (!argument[0] ||
+ my_strcasecmp(system_charset_info, argument, "OFF") == 0))
{
myisam_recover_options= HA_RECOVER_NONE;
myisam_recover_options_str= "OFF";
+ ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
}
else
{
- myisam_recover_options_str=argument;
- myisam_recover_options=
- find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
- &error);
- if (error)
- return 1;
+ if (!argument)
+ {
+ myisam_recover_options= HA_RECOVER_DEFAULT;
+ myisam_recover_options_str= myisam_recover_typelib.type_names[0];
+ }
+ else
+ {
+ myisam_recover_options_str=argument;
+ myisam_recover_options=
+ find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
+ &error);
+ if (error)
+ return 1;
+ }
+ ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
}
- ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
break;
}
case OPT_CONCURRENT_INSERT:
@@ -8599,32 +8973,34 @@ mysqld_get_one_option(int optid,
myisam_concurrent_insert= 0; /* --skip-concurrent-insert */
break;
case OPT_TC_HEURISTIC_RECOVER:
- tc_heuristic_recover= find_type_or_exit(argument,
- &tc_heuristic_recover_typelib,
- opt->name);
+ find_opt_type(argument, &tc_heuristic_recover_typelib,
+ opt->name, (int*) &tc_heuristic_recover);
break;
case OPT_MYISAM_STATS_METHOD:
{
ulong method_conv;
int method;
LINT_INIT(method_conv);
+ LINT_INIT(method);
myisam_stats_method_str= argument;
- method= find_type_or_exit(argument, &myisam_stats_method_typelib,
- opt->name);
- switch (method-1) {
- case 2:
- method_conv= MI_STATS_METHOD_IGNORE_NULLS;
- break;
- case 1:
- method_conv= MI_STATS_METHOD_NULLS_EQUAL;
- break;
- case 0:
- default:
- method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
- break;
+ if (!find_opt_type(argument, &myisam_stats_method_typelib,
+ opt->name, &method))
+ {
+ switch (method-1) {
+ case 2:
+ method_conv= MI_STATS_METHOD_IGNORE_NULLS;
+ break;
+ case 1:
+ method_conv= MI_STATS_METHOD_NULLS_EQUAL;
+ break;
+ case 0:
+ default:
+ method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
+ break;
+ }
+ global_system_variables.myisam_stats_method= method_conv;
}
- global_system_variables.myisam_stats_method= method_conv;
break;
}
case OPT_SQL_MODE:
@@ -8662,13 +9038,16 @@ mysqld_get_one_option(int optid,
break;
}
case OPT_ONE_THREAD:
- global_system_variables.thread_handling=
- SCHEDULER_ONE_THREAD_PER_CONNECTION;
+ global_system_variables.thread_handling= SCHEDULER_NO_THREADS;
+ opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
break;
case OPT_THREAD_HANDLING:
{
- global_system_variables.thread_handling=
- find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1;
+ int id;
+ LINT_INIT(id);
+ if (!find_opt_type(argument, &thread_handling_typelib, opt->name, &id))
+ global_system_variables.thread_handling= id - 1;
+ opt_thread_handling= thread_handling_typelib.type_names[global_system_variables.thread_handling];
break;
}
case OPT_FT_BOOLEAN_SYNTAX:
@@ -8688,13 +9067,10 @@ mysqld_get_one_option(int optid,
lower_case_table_names= argument ? atoi(argument) : 1;
lower_case_table_names_used= 1;
break;
-#ifdef HAVE_STACK_TRACE_ON_SEGV
- case OPT_DO_PSTACK:
- sql_print_warning("'--enable-pstack' is deprecated and will be removed "
- "in a future release. A symbolic stack trace will be "
- "printed after a crash whenever possible.");
+ case OPT_TEST_IGNORE_WRONG_OPTIONS:
+ /* Used for testing options */
+ opt_ignore_wrong_options= 1;
break;
-#endif
#if defined(ENABLED_DEBUG_SYNC)
case OPT_DEBUG_SYNC_TIMEOUT:
/*
@@ -8713,7 +9089,6 @@ mysqld_get_one_option(int optid,
#endif /* defined(ENABLED_DEBUG_SYNC) */
case OPT_MAX_LONG_DATA_SIZE:
max_long_data_size_used= true;
- WARN_DEPRECATED(NULL, VER_CELOSIA, "--max_long_data_size", "--max_allowed_packet");
break;
}
return 0;
@@ -8827,7 +9202,8 @@ static int get_options(int *argc,char **argv)
if (opt_debugging)
{
/* Allow break with SIGINT, no core or stack trace */
- test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
+ test_flags|= TEST_SIGINT;
+ opt_stack_trace= 1;
test_flags&= ~TEST_CORE_ON_SIGNAL;
}
/* Set global MyISAM variables from delay_key_write_options */
@@ -8835,6 +9211,8 @@ static int get_options(int *argc,char **argv)
/* Set global slave_exec_mode from its option */
fix_slave_exec_mode();
+ global_system_variables.log_slow_filter=
+ fix_log_slow_filter(global_system_variables.log_slow_filter);
#ifndef EMBEDDED_LIBRARY
if (mysqld_chroot)
set_root(mysqld_chroot);
@@ -8851,12 +9229,14 @@ static int get_options(int *argc,char **argv)
In most cases the global variables will not be used
*/
my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
+ my_disable_sync= opt_sync == 0;
my_default_record_cache_size=global_system_variables.read_buff_size;
myisam_max_temp_length=
(my_off_t) global_system_variables.myisam_max_sort_file_size;
/* Set global variables based on startup options */
myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
+ my_crc_dbug_check= opt_my_crc_dbug_check;
/* long_query_time is in microseconds */
global_system_variables.long_query_time= max_system_variables.long_query_time=
@@ -8875,14 +9255,19 @@ static int get_options(int *argc,char **argv)
#ifdef EMBEDDED_LIBRARY
one_thread_scheduler(&thread_scheduler);
+ one_thread_scheduler(&extra_thread_scheduler);
#else
if (global_system_variables.thread_handling <=
SCHEDULER_ONE_THREAD_PER_CONNECTION)
- one_thread_per_connection_scheduler(&thread_scheduler);
+ one_thread_per_connection_scheduler(&thread_scheduler, &max_connections,
+ &connection_count);
else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS)
one_thread_scheduler(&thread_scheduler);
else
pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */
+ one_thread_per_connection_scheduler(&extra_thread_scheduler,
+ &extra_max_connections,
+ &extra_connection_count);
#endif
/*
@@ -8987,9 +9372,7 @@ bool is_secure_file_path(char *path)
/*
The supplied file path might have been a file and not a directory.
*/
- int length= (int)dirname_length(path);
- if (length >= FN_REFLEN)
- return FALSE;
+ size_t length= dirname_length(path); // Guaranteed to be < FN_REFLEN
memcpy(buff2, path, length);
buff2[length]= '\0';
if (length == 0 || my_realpath(buff1, buff2, 0))
@@ -9017,6 +9400,8 @@ bool is_secure_file_path(char *path)
static int fix_paths(void)
{
char buff[FN_REFLEN],*pos;
+ DBUG_ENTER("fix_paths");
+
convert_dirname(mysql_home,mysql_home,NullS);
/* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
my_realpath(mysql_home,mysql_home,MYF(0));
@@ -9061,18 +9446,18 @@ static int fix_paths(void)
charsets_dir=mysql_charsets_dir;
if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
- return 1;
+ DBUG_RETURN(1);
#ifdef HAVE_REPLICATION
if (!slave_load_tmpdir)
{
if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
- return 1;
+ DBUG_RETURN(1);
}
#endif /* HAVE_REPLICATION */
/*
Convert the secure-file-priv option to system format, allowing
a quick strcmp to check if read or write is in an allowed dir
- */
+ */
if (opt_secure_file_priv)
{
if (*opt_secure_file_priv == 0)
@@ -9082,21 +9467,19 @@ static int fix_paths(void)
}
else
{
- if (strlen(opt_secure_file_priv) >= FN_REFLEN)
- opt_secure_file_priv[FN_REFLEN-1]= '\0';
+ char *secure_file_real_path;
if (my_realpath(buff, opt_secure_file_priv, 0))
{
sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
- return 1;
+ DBUG_RETURN(1);
}
- char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
+ secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
convert_dirname(secure_file_real_path, buff, NullS);
my_free(opt_secure_file_priv, MYF(0));
opt_secure_file_priv= secure_file_real_path;
}
}
-
- return 0;
+ DBUG_RETURN(0);
}
@@ -9198,12 +9581,9 @@ skip: ;
@param dir_name Directory to test
- @retval
- -1 Don't know (Test failed)
- @retval
- 0 File system is case sensitive
- @retval
- 1 File system is case insensitive
+ @retval -1 Don't know (Test failed)
+ @retval 0 File system is case sensitive
+ @retval 1 File system is case insensitive
*/
static int test_if_case_insensitive(const char *dir_name)
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index e45d57e57dc..eb5f45bbced 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -126,15 +126,13 @@ my_bool my_net_init(NET *net, Vio* vio)
net->last_error[0]=0;
net->compress=0; net->reading_or_writing=0;
net->where_b = net->remain_in_buf=0;
+ net->net_skip_rest_factor= 0;
net->last_errno=0;
#ifdef USE_QUERY_CACHE
query_cache_init_query(net);
#else
net->query_cache_query= 0;
#endif
-#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
- net->skip_big_packet= FALSE;
-#endif
if (vio != 0) /* If real connection */
{
@@ -218,7 +216,7 @@ my_bool net_realloc(NET *net, size_t length)
-1 Don't know if data is ready or not
*/
-#if !defined(EMBEDDED_LIBRARY)
+#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
static int net_data_is_ready(my_socket sd)
{
@@ -277,15 +275,20 @@ static int net_data_is_ready(my_socket sd)
@param clear_buffer if <> 0, then clear all data from comm buff
*/
-void net_clear(NET *net, my_bool clear_buffer)
+void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
-#if !defined(EMBEDDED_LIBRARY)
+#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
size_t count;
int ready;
#endif
DBUG_ENTER("net_clear");
-#if !defined(EMBEDDED_LIBRARY)
+/*
+ We don't do a clear in case of DBUG_OFF to catch bugs
+ in the protocol handling
+*/
+
+#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
if (clear_buffer)
{
while ((ready= net_data_is_ready(net->vio->sd)) > 0)
@@ -737,6 +740,7 @@ static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
ALARM *alarm_buff)
{
+ longlong limit= net->max_packet_size*net->net_skip_rest_factor;
uint32 old=remain;
DBUG_ENTER("my_net_skip_rest");
DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
@@ -760,11 +764,15 @@ static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
DBUG_RETURN(1);
update_statistics(thd_increment_bytes_received(length));
remain -= (uint32) length;
+ limit-= length;
+ if (limit < 0)
+ DBUG_RETURN(1);
}
if (old != MAX_PACKET_LENGTH)
break;
if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed))
DBUG_RETURN(1);
+ limit-= NET_HEADER_SIZE;
old=remain= uint3korr(net->buff);
net->pkt_nr++;
}
@@ -914,7 +922,6 @@ my_real_read(NET *net, size_t *complen)
(int) net->buff[net->where_b + 3],
(uint) (uchar) net->pkt_nr);
fflush(stderr);
- DBUG_ASSERT(0);
#endif
}
len= packet_error;
@@ -954,7 +961,6 @@ my_real_read(NET *net, size_t *complen)
{
#if defined(MYSQL_SERVER) && !defined(NO_ALARM)
if (!net->compress &&
- net->skip_big_packet &&
!my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
net->error= 3; /* Successfully skiped packet */
#endif
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 6a539198d12..a42a03f4c86 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -709,8 +710,6 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
double read_time);
static
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
-static double get_index_only_read_time(const PARAM* param, ha_rows records,
- int keynr);
#ifndef DBUG_OFF
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
@@ -1100,7 +1099,7 @@ QUICK_SELECT_I::QUICK_SELECT_I()
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
bool no_alloc, MEM_ROOT *parent_alloc)
- :dont_free(0),error(0),free_file(0),in_range(0),cur_range(NULL),last_range(0)
+ :dont_free(0),doing_key_read(0),error(0),free_file(0),in_range(0),cur_range(NULL),last_range(0)
{
my_bitmap_map *bitmap;
DBUG_ENTER("QUICK_RANGE_SELECT::QUICK_RANGE_SELECT");
@@ -1171,7 +1170,8 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
if (file)
{
range_end();
- head->set_keyread(FALSE);
+ if (doing_key_read)
+ file->extra(HA_EXTRA_NO_KEYREAD);
if (free_file)
{
DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file,
@@ -1312,6 +1312,7 @@ int QUICK_ROR_INTERSECT_SELECT::init()
int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
{
handler *save_file= file, *org_file;
+ my_bool org_key_read;
THD *thd;
DBUG_ENTER("QUICK_RANGE_SELECT::init_ror_merged_scan");
@@ -1371,12 +1372,17 @@ end:
The now bitmap is stored in 'column_bitmap' which is used in ::get_next()
*/
org_file= head->file;
+ org_key_read= head->key_read;
head->file= file;
- /* We don't have to set 'head->keyread' here as the 'file' is unique */
+ head->key_read= 0;
if (!head->no_keyread)
+ {
+ doing_key_read= 1;
head->mark_columns_used_by_index(index);
+ }
head->prepare_for_position();
head->file= org_file;
+ head->key_read= org_key_read;
bitmap_copy(&column_bitmap, head->read_set);
head->column_bitmaps_set(&column_bitmap, &column_bitmap);
@@ -1402,15 +1408,17 @@ failure:
*/
int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
{
- List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
- QUICK_RANGE_SELECT* quick;
+ List_iterator_fast<QUICK_SELECT_WITH_RECORD> quick_it(quick_selects);
+ QUICK_SELECT_WITH_RECORD *cur;
+ QUICK_RANGE_SELECT *quick;
DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan");
/* Initialize all merged "children" quick selects */
DBUG_ASSERT(!need_to_fetch_row || reuse_handler);
if (!need_to_fetch_row && reuse_handler)
{
- quick= quick_it++;
+ cur= quick_it++;
+ quick= cur->quick;
/*
There is no use of this->file. Use it for the first of merged range
selects.
@@ -1419,8 +1427,9 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler)
DBUG_RETURN(1);
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
}
- while ((quick= quick_it++))
+ while ((cur= quick_it++))
{
+ quick= cur->quick;
if (quick->init_ror_merged_scan(FALSE))
DBUG_RETURN(1);
quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
@@ -1452,10 +1461,10 @@ int QUICK_ROR_INTERSECT_SELECT::reset()
if (!scans_inited && init_ror_merged_scan(TRUE))
DBUG_RETURN(1);
scans_inited= TRUE;
- List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
- QUICK_RANGE_SELECT *quick;
- while ((quick= it++))
- quick->reset();
+ List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
+ QUICK_SELECT_WITH_RECORD *qr;
+ while ((qr= it++))
+ qr->quick->reset();
DBUG_RETURN(0);
}
@@ -1465,6 +1474,7 @@ int QUICK_ROR_INTERSECT_SELECT::reset()
SYNOPSIS
QUICK_ROR_INTERSECT_SELECT::push_quick_back()
+ alloc Mem root to create auxiliary structures on
quick Quick select to be added. The quick select must return
rows in rowid order.
NOTES
@@ -1476,11 +1486,17 @@ int QUICK_ROR_INTERSECT_SELECT::reset()
*/
bool
-QUICK_ROR_INTERSECT_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick)
+QUICK_ROR_INTERSECT_SELECT::push_quick_back(MEM_ROOT *alloc, QUICK_RANGE_SELECT *quick)
{
- return quick_selects.push_back(quick);
+ QUICK_SELECT_WITH_RECORD *qr;
+ if (!(qr= new QUICK_SELECT_WITH_RECORD) ||
+ !(qr->key_tuple= (uchar*)alloc_root(alloc, quick->max_used_key_length)))
+ return TRUE;
+ qr->quick= quick;
+ return quick_selects.push_back(qr);
}
+
QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT()
{
DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT");
@@ -2308,9 +2324,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
if (!head->covering_keys.is_clear_all())
{
int key_for_use= find_shortest_key(head, &head->covering_keys);
- double key_read_time= (get_index_only_read_time(&param, records,
- key_for_use) +
- (double) records / TIME_FOR_COMPARE);
+ double key_read_time= head->file->keyread_time(key_for_use, 1, records) +
+ (double) records / TIME_FOR_COMPARE;
DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, "
"read time %g", key_for_use, key_read_time));
if (key_read_time < read_time)
@@ -3755,8 +3770,9 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
DBUG_PRINT("info", ("index_merge scans cost %g", imerge_cost));
if (imerge_too_expensive || (imerge_cost > read_time) ||
- ((non_cpk_scan_records+cpk_scan_records >= param->table->file->stats.records) &&
- read_time != DBL_MAX))
+ ((non_cpk_scan_records+cpk_scan_records >=
+ param->table->file->stats.records) &&
+ read_time != DBL_MAX))
{
/*
Bail out if it is obvious that both index_merge and ROR-union will be
@@ -3930,43 +3946,6 @@ skip_to_ror_scan:
DBUG_RETURN(imerge_trp);
}
-
-/*
- Calculate cost of 'index only' scan for given index and number of records.
-
- SYNOPSIS
- get_index_only_read_time()
- param parameters structure
- records #of records to read
- keynr key to read
-
- NOTES
- It is assumed that we will read trough the whole key range and that all
- key blocks are half full (normally things are much better). It is also
- assumed that each time we read the next key from the index, the handler
- performs a random seek, thus the cost is proportional to the number of
- blocks read.
-
- TODO:
- Move this to handler->read_time() by adding a flag 'index-only-read' to
- this call. The reason for doing this is that the current function doesn't
- handle the case when the row is stored in the b-tree (like in innodb
- clustered index)
-*/
-
-static double get_index_only_read_time(const PARAM* param, ha_rows records,
- int keynr)
-{
- double read_time;
- uint keys_per_block= (param->table->file->stats.block_size/2/
- (param->table->key_info[keynr].key_length+
- param->table->file->ref_length) + 1);
- read_time=((double) (records+keys_per_block-1)/
- (double) keys_per_block);
- return read_time;
-}
-
-
typedef struct st_ror_scan_info
{
uint idx; /* # of used key in param->keys */
@@ -4043,8 +4022,8 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg)
bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1);
}
ror_scan->index_read_cost=
- get_index_only_read_time(param, param->table->quick_rows[ror_scan->keynr],
- ror_scan->keynr);
+ param->table->file->keyread_time(ror_scan->keynr, 1,
+ param->table->quick_rows[ror_scan->keynr]);
DBUG_RETURN(ror_scan);
}
@@ -4879,7 +4858,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
We can resolve this by only reading through this key.
0.01 is added to avoid races between range and 'index' scan.
*/
- found_read_time= get_index_only_read_time(param,found_records,keynr) +
+ found_read_time= param->table->file->keyread_time(keynr, 1, found_records) +
cpu_cost + 0.01;
}
else
@@ -4980,7 +4959,7 @@ QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
{
if (!(quick= get_quick_select(param, (*first_scan)->idx,
(*first_scan)->sel_arg, alloc)) ||
- quick_intrsect->push_quick_back(quick))
+ quick_intrsect->push_quick_back(alloc, quick))
{
delete quick_intrsect;
DBUG_RETURN(NULL);
@@ -8010,11 +7989,11 @@ bool QUICK_INDEX_MERGE_SELECT::is_keys_used(const MY_BITMAP *fields)
bool QUICK_ROR_INTERSECT_SELECT::is_keys_used(const MY_BITMAP *fields)
{
- QUICK_RANGE_SELECT *quick;
- List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
- while ((quick= it++))
+ QUICK_SELECT_WITH_RECORD *qr;
+ List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
+ while ((qr= it++))
{
- if (is_key_used(head, quick->index, fields))
+ if (is_key_used(head, qr->quick->index, fields))
return 1;
}
return 0;
@@ -8162,7 +8141,10 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
/* We're going to just read rowids. */
- head->set_keyread(TRUE);
+ if (!head->key_read)
+ {
+ head->enable_keyread();
+ }
head->prepare_for_position();
cur_quick_it.rewind();
@@ -8174,7 +8156,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
reset here.
*/
if (cur_quick->init() || cur_quick->reset())
- DBUG_RETURN(1);
+ goto err;
if (unique == NULL)
{
@@ -8185,6 +8167,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
unique= new Unique(refpos_order_cmp, (void *)file,
file->ref_length,
thd->variables.sortbuff_size);
+ if (!unique)
+ goto err;
}
else
unique->reset();
@@ -8192,8 +8176,6 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
DBUG_ASSERT(file->ref_length == unique->get_size());
DBUG_ASSERT(thd->variables.sortbuff_size == unique->get_max_in_memory_size());
- if (!unique)
- DBUG_RETURN(1);
for (;;)
{
while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
@@ -8206,7 +8188,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
if (cur_quick->file->inited != handler::NONE)
cur_quick->file->ha_index_end();
if (cur_quick->init() || cur_quick->reset())
- DBUG_RETURN(1);
+ goto err;
}
if (result)
@@ -8214,22 +8196,21 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
if (result != HA_ERR_END_OF_FILE)
{
cur_quick->range_end();
- DBUG_RETURN(result);
+ goto err;
}
break;
}
if (thd->killed)
- DBUG_RETURN(1);
+ goto err;
/* skip row if it will be retrieved by clustered PK scan */
if (pk_quick_select && pk_quick_select->row_in_ranges())
continue;
cur_quick->file->position(cur_quick->record);
- result= unique->unique_add((char*)cur_quick->file->ref);
- if (result)
- DBUG_RETURN(1);
+ if (unique->unique_add((char*)cur_quick->file->ref))
+ goto err;
}
/*
@@ -8239,10 +8220,16 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
*/
result= unique->get(head);
doing_pk_scan= FALSE;
- /* index_merge currently doesn't support "using index" at all */
- head->set_keyread(FALSE);
+ /*
+ index_merge currently doesn't support "using index" at all
+ */
+ head->disable_keyread();
init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE);
DBUG_RETURN(result);
+
+err:
+ head->disable_keyread();
+ DBUG_RETURN(1);
}
@@ -8305,7 +8292,8 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
int QUICK_ROR_INTERSECT_SELECT::get_next()
{
- List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
+ List_iterator_fast<QUICK_SELECT_WITH_RECORD> quick_it(quick_selects);
+ QUICK_SELECT_WITH_RECORD *qr;
QUICK_RANGE_SELECT* quick;
int error, cmp;
uint last_rowid_count=0;
@@ -8314,7 +8302,8 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
do
{
/* Get a rowid for first quick and save it as a 'candidate' */
- quick= quick_it++;
+ qr= quick_it++;
+ quick= qr->quick;
error= quick->get_next();
if (cpk_quick)
{
@@ -8324,17 +8313,22 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
if (error)
DBUG_RETURN(error);
+ /* Save the read key tuple */
+ key_copy(qr->key_tuple, record, head->key_info + quick->index,
+ quick->max_used_key_length);
+
quick->file->position(quick->record);
memcpy(last_rowid, quick->file->ref, head->file->ref_length);
last_rowid_count= 1;
while (last_rowid_count < quick_selects.elements)
{
- if (!(quick= quick_it++))
+ if (!(qr= quick_it++))
{
quick_it.rewind();
- quick= quick_it++;
+ qr= quick_it++;
}
+ quick= qr->quick;
do
{
@@ -8344,6 +8338,9 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
cmp= head->file->cmp_ref(quick->file->ref, last_rowid);
} while (cmp < 0);
+ key_copy(qr->key_tuple, record, head->key_info + quick->index,
+ quick->max_used_key_length);
+
/* Ok, current select 'caught up' and returned ref >= cur_ref */
if (cmp > 0)
{
@@ -8359,6 +8356,10 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
}
memcpy(last_rowid, quick->file->ref, head->file->ref_length);
last_rowid_count= 1;
+
+ //save the fields here
+ key_copy(qr->key_tuple, record, head->key_info + quick->index,
+ quick->max_used_key_length);
}
else
{
@@ -8371,6 +8372,21 @@ int QUICK_ROR_INTERSECT_SELECT::get_next()
if (need_to_fetch_row)
error= head->file->rnd_pos(head->record[0], last_rowid);
} while (error == HA_ERR_RECORD_DELETED);
+
+ if (!need_to_fetch_row)
+ {
+ /* Restore the columns we've read/saved with other quick selects */
+ quick_it.rewind();
+ while ((qr= quick_it++))
+ {
+ if (qr->quick != quick)
+ {
+ key_restore(record, qr->key_tuple, head->key_info + qr->quick->index,
+ qr->quick->max_used_key_length);
+ }
+ }
+ }
+
DBUG_RETURN(error);
}
@@ -8512,7 +8528,7 @@ int QUICK_RANGE_SELECT::reset()
multi_range_buff->buffer= mrange_buff;
multi_range_buff->buffer_end= mrange_buff + mrange_bufsiz;
multi_range_buff->end_of_used_area= mrange_buff;
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
/*
We need this until ndb will use the buffer efficiently
(Now ndb stores complete row in here, instead of only the used fields
@@ -8993,12 +9009,12 @@ void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
{
bool first= TRUE;
- QUICK_RANGE_SELECT *quick;
- List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
+ QUICK_SELECT_WITH_RECORD *qr;
+ List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
str->append(STRING_WITH_LEN("intersect("));
- while ((quick= it++))
+ while ((qr= it++))
{
- KEY *key_info= head->key_info + quick->index;
+ KEY *key_info= head->key_info + qr->quick->index;
if (!first)
str->append(',');
else
@@ -9084,11 +9100,11 @@ void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
char buf[64];
uint length;
bool first= TRUE;
- QUICK_RANGE_SELECT *quick;
- List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
- while ((quick= it++))
+ QUICK_SELECT_WITH_RECORD *qr;
+ List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
+ while ((qr= it++))
{
- KEY *key_info= head->key_info + quick->index;
+ KEY *key_info= head->key_info + qr->quick->index;
if (first)
first= FALSE;
else
@@ -9097,7 +9113,7 @@ void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names,
used_lengths->append(',');
}
key_names->append(key_info->name);
- length= longlong2str(quick->max_used_key_length, buf, 10) - buf;
+ length= longlong2str(qr->quick->max_used_key_length, buf, 10) - buf;
used_lengths->append(buf, length);
}
@@ -10291,7 +10307,7 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
:file(table->file), join(join_arg), index_info(index_info_arg),
group_prefix_len(group_prefix_len_arg),
group_key_parts(group_key_parts_arg), have_min(have_min_arg),
- have_max(have_max_arg), seen_first_key(FALSE),
+ have_max(have_max_arg), seen_first_key(FALSE), doing_key_read(FALSE),
min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg),
key_infix_len(key_infix_len_arg), min_functions_it(NULL),
max_functions_it(NULL)
@@ -10421,7 +10437,12 @@ QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT()
{
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::~QUICK_GROUP_MIN_MAX_SELECT");
if (file->inited != handler::NONE)
+ {
+ DBUG_ASSERT(file == head->file);
+ if (doing_key_read)
+ head->disable_keyread();
file->ha_index_end();
+ }
if (min_max_arg_part)
delete_dynamic(&min_max_ranges);
free_root(&alloc,MYF(0));
@@ -10604,7 +10625,11 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
int result;
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
- head->set_keyread(TRUE); /* We need only the key attributes */
+ if (!head->key_read)
+ {
+ doing_key_read= 1;
+ head->enable_keyread(); /* We need only the key attributes */
+ }
if ((result= file->ha_index_init(index,1)))
DBUG_RETURN(result);
if (quick_prefix_select && quick_prefix_select->reset())
@@ -11442,13 +11467,13 @@ void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
void QUICK_ROR_INTERSECT_SELECT::dbug_dump(int indent, bool verbose)
{
- List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
- QUICK_RANGE_SELECT *quick;
+ List_iterator_fast<QUICK_SELECT_WITH_RECORD> it(quick_selects);
+ QUICK_SELECT_WITH_RECORD *qr;
fprintf(DBUG_FILE, "%*squick ROR-intersect select, %scovering\n",
indent, "", need_to_fetch_row? "":"non-");
fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
- while ((quick= it++))
- quick->dbug_dump(indent+2, verbose);
+ while ((qr= it++))
+ qr->quick->dbug_dump(indent+2, verbose);
if (cpk_quick)
{
fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
diff --git a/sql/opt_range.h b/sql/opt_range.h
index a18296cd957..d4852671717 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -40,13 +40,19 @@ typedef struct st_key_part {
} KEY_PART;
+/*
+ A "MIN_TUPLE < tbl.key_tuple < MAX_TUPLE" interval.
+
+ One of endpoints may be absent. 'flags' member has flags which tell whether
+ the endpoints are '<' or '<='.
+*/
class QUICK_RANGE :public Sql_alloc {
public:
uchar *min_key,*max_key;
uint16 min_length,max_length,flag;
key_part_map min_keypart_map, // bitmap of used keyparts in min_key
max_keypart_map; // bitmap of used keyparts in max_key
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
uint16 dummy; /* Avoid warnings on 'flag' */
#endif
QUICK_RANGE(); /* Full range */
@@ -63,7 +69,7 @@ class QUICK_RANGE :public Sql_alloc {
min_keypart_map(min_keypart_map_arg),
max_keypart_map(max_keypart_map_arg)
{
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
dummy=0;
#endif
}
@@ -267,7 +273,6 @@ public:
virtual bool reverse_sorted() = 0;
virtual bool unique_key_range() { return false; }
- virtual bool clustered_pk_range() { return false; }
enum {
QS_TYPE_RANGE = 0,
@@ -356,6 +361,8 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
{
protected:
bool next,dont_free,in_ror_merged_scan;
+ /* true if we enabled key only reads */
+ bool doing_key_read;
public:
int error;
protected:
@@ -536,8 +543,6 @@ public:
THD *thd;
int read_keys_and_merge();
- bool clustered_pk_range() { return test(pk_quick_select); }
-
/* used to get rows collected in Unique */
READ_RECORD read_record;
};
@@ -582,13 +587,21 @@ public:
void dbug_dump(int indent, bool verbose);
#endif
int init_ror_merged_scan(bool reuse_handler);
- bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
+ bool push_quick_back(MEM_ROOT *alloc, QUICK_RANGE_SELECT *quick_sel_range);
+
+ class QUICK_SELECT_WITH_RECORD : public Sql_alloc
+ {
+ public:
+ QUICK_RANGE_SELECT *quick;
+ uchar *key_tuple;
+ ~QUICK_SELECT_WITH_RECORD() { delete quick; }
+ };
/*
Range quick selects this intersection consists of, not including
cpk_quick.
*/
- List<QUICK_RANGE_SELECT> quick_selects;
+ List<QUICK_SELECT_WITH_RECORD> quick_selects;
/*
Merged quick select that uses Clustered PK, if there is one. This quick
@@ -702,6 +715,8 @@ private:
bool have_min; /* Specify whether we are computing */
bool have_max; /* a MIN, a MAX, or both. */
bool seen_first_key; /* Denotes whether the first key was retrieved.*/
+ bool doing_key_read; /* true if we enabled key only reads */
+
KEY_PART_INFO *min_max_arg_part; /* The keypart of the only argument field */
/* of all MIN/MAX functions. */
uint min_max_arg_len; /* The length of the MIN/MAX argument field */
@@ -793,10 +808,18 @@ class SQL_SELECT :public Sql_alloc {
tmp.set_all();
return test_quick_select(thd, tmp, 0, limit, force_quick_range) < 0;
}
- inline bool skip_record(THD *thd, bool *skip_record)
+ /*
+ RETURN
+ 0 if record must be skipped <-> (cond && cond->val_int() == 0)
+ -1 if error
+ 1 otherwise
+ */
+ inline int skip_record(THD *thd)
{
- *skip_record= cond ? cond->val_int() == FALSE : FALSE;
- return thd->is_error();
+ int rc= test(!cond || cond->val_int());
+ if (thd->is_error())
+ rc= -1;
+ return rc;
}
int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
ha_rows limit, bool force_quick_range);
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 5747ea55087..7bb75c3175d 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -246,7 +247,6 @@ int opt_sum_query(THD *thd,
table_map where_tables= 0;
Item *item;
int error;
-
DBUG_ENTER("opt_sum_query");
if (conds)
@@ -392,7 +392,7 @@ int opt_sum_query(THD *thd,
if (!error && reckey_in_range(is_max, &ref, item_field->field,
conds, range_fl, prefix_len))
error= HA_ERR_KEY_NOT_FOUND;
- table->set_keyread(FALSE);
+ table->disable_keyread();
table->file->ha_index_end();
if (error)
{
@@ -748,7 +748,7 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
since set_null will be ignored, and we will compare uninitialized data.
*/
if (!part->field->real_maybe_null())
- DBUG_RETURN(false);
+ DBUG_RETURN(FALSE);
part->field->set_null();
*key_ptr= (uchar) 1;
}
@@ -836,7 +836,7 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
uint *range_fl, uint *prefix_len)
{
if (!(field->flags & PART_KEY_FLAG))
- return false; // Not key field
+ return FALSE; // Not key field
DBUG_ENTER("find_key_for_maxmin");
@@ -863,7 +863,7 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
part++, jdx++, key_part_to_use= (key_part_to_use << 1) | 1)
{
if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER))
- DBUG_RETURN(false);
+ DBUG_RETURN(FALSE);
/* Check whether the index component is partial */
Field *part_field= table->field[part->fieldnr-1];
@@ -911,13 +911,13 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
converted (for example to upper case)
*/
if (field->part_of_key.is_set(idx))
- table->set_keyread(TRUE);
- DBUG_RETURN(true);
+ table->enable_keyread();
+ DBUG_RETURN(TRUE);
}
}
}
}
- DBUG_RETURN(false);
+ DBUG_RETURN(FALSE);
}
@@ -999,15 +999,11 @@ static int maxmin_in_range(bool max_fl, Field* field, COND *cond)
SELECT MAX(b) FROM t1 WHERE a=const AND b<const
*/
if (max_fl != less_fl)
- return cond->val_int() == 0; // Return 1 if WHERE is false
+ return cond->val_int() == 0; // Return 1 if WHERE is false
return 0;
}
- case Item_func::EQ_FUNC:
- case Item_func::EQUAL_FUNC:
- break;
- default: // Keep compiler happy
- DBUG_ASSERT(1); // Impossible
- break;
+ default:
+ break; // Ignore
}
return 0;
}
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc
new file mode 100644
index 00000000000..5d952021365
--- /dev/null
+++ b/sql/opt_table_elimination.cc
@@ -0,0 +1,1861 @@
+/**
+ @file
+
+ @brief
+ Table Elimination Module
+
+ @defgroup Table_Elimination Table Elimination Module
+ @{
+*/
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "my_bit.h"
+#include "sql_select.h"
+
+/*
+ OVERVIEW
+ ========
+
+ This file contains table elimination module. The idea behind table
+ elimination is as follows: suppose we have a left join
+
+ SELECT * FROM t1 LEFT JOIN
+ (t2 JOIN t3) ON t2.primary_key=t1.col AND
+ t2.primary_key=t2.col
+ WHERE ...
+
+ such that
+ * columns of the inner tables are not used anywhere ouside the outer join
+ (not in WHERE, not in GROUP/ORDER BY clause, not in select list etc etc),
+ * inner side of the outer join is guaranteed to produce at most one matching
+ record combination for each record combination of outer tables.
+
+ then the inner side of the outer join can be removed from the query, as it
+ will always produce only one record combination (either real or
+ null-complemented one) and we don't care about what that record combination
+ is.
+
+
+ MODULE INTERFACE
+ ================
+
+ The module has one entry point - the eliminate_tables() function, which one
+ needs to call (once) at some point before join optimization.
+ eliminate_tables() operates over the JOIN structures. Logically, it
+ removes the inner tables of an outer join operation together with the
+ operation itself. Physically, it changes the following members:
+
+ * Eliminated tables are marked as constant and moved to the front of the
+ join order.
+
+ * In addition to this, they are recorded in JOIN::eliminated_tables bitmap.
+
+ * Items that became disused because they were in the ON expression of an
+ eliminated outer join are notified by means of the Item tree walk which
+ calls Item::mark_as_eliminated_processor for every item
+ - At the moment the only Item that cares whether it was eliminated is
+ Item_subselect with its Item_subselect::eliminated flag which is used
+ by EXPLAIN code to check if the subquery should be shown in EXPLAIN.
+
+ Table elimination is redone on every PS re-execution.
+
+
+ TABLE ELIMINATION ALGORITHM FOR ONE OUTER JOIN
+ ==============================================
+
+ As described above, we can remove inner side of an outer join if it is
+
+ 1. not referred to from any other parts of the query
+ 2. always produces one matching record combination.
+
+ We check #1 by doing a recursive descent down the join->join_list while
+ maintaining a union of used_tables() attribute of all Item expressions in
+ other parts of the query. When we encounter an outer join, we check if the
+ bitmap of tables on its inner side has intersection with tables that are used
+ elsewhere. No intersection means that inner side of the outer join could
+ potentially be eliminated.
+
+ In order to check #2, one needs to prove that inner side of an outer join
+ is functionally dependent on the outside. The proof is constructed from
+ functional dependencies of intermediate objects:
+
+ - Inner side of outer join is functionally dependent when each of its tables
+ are functionally dependent. (We assume a table is functionally dependent
+ when its dependencies allow to uniquely identify one table record, or no
+ records).
+
+ - Table is functionally dependent when it has got a unique key whose columns
+ are functionally dependent.
+
+ - A column is functionally dependent when we could locate an AND-part of a
+ certain ON clause in form
+
+ tblX.columnY= expr
+
+ where expr is functionally depdendent. expr is functionally dependent when
+ all columns that it refers to are functionally dependent.
+
+ These relationships are modeled as a bipartite directed graph that has
+ dependencies as edges and two kinds of nodes:
+
+ Value nodes:
+ - Table column values (each is a value of tblX.columnY)
+ - Table values (each node represents a table inside the join nest we're
+ trying to eliminate).
+ A value has one attribute, it is either bound (i.e. functionally dependent)
+ or not.
+
+ Module nodes:
+ - Modules representing tblX.colY=expr equalities. Equality module has
+ = incoming edges from columns used in expr
+ = outgoing edge to tblX.colY column.
+ - Nodes representing unique keys. Unique key has
+ = incoming edges from key component value modules
+ = outgoing edge to key's table module
+ - Inner side of outer join module. Outer join module has
+ = incoming edges from table value modules
+ = No outgoing edges. Once we reach it, we know we can eliminate the
+ outer join.
+ A module may depend on multiple values, and hence its primary attribute is
+ the number of its arguments that are not bound.
+
+ The algorithm starts with equality nodes that don't have any incoming edges
+ (their expressions are either constant or depend only on tables that are
+ outside of the outer join in question) and performns a breadth-first
+ traversal. If we reach the outer join nest node, it means outer join is
+ functionally dependent and can be eliminated. Otherwise it cannot be
+ eliminated.
+
+ HANDLING MULTIPLE NESTED OUTER JOINS
+ ====================================
+
+ Outer joins that are not nested one within another are eliminated
+ independently. For nested outer joins we have the following considerations:
+
+ 1. ON expressions from children outer joins must be taken into account
+
+ Consider this example:
+
+ SELECT t0.*
+ FROM
+ t0
+ LEFT JOIN
+ (t1 LEFT JOIN t2 ON t2.primary_key=t1.col1)
+ ON
+ t1.primary_key=t0.col AND t2.col1=t1.col2
+
+ Here we cannot eliminate the "... LEFT JOIN t2 ON ..." part alone because the
+ ON clause of top level outer join has references to table t2.
+ We can eliminate the entire "... LEFT JOIN (t1 LEFT JOIN t2) ON .." part,
+ but in order to do that, we must look at both ON expressions.
+
+ 2. ON expressions of parent outer joins are useless.
+ Consider an example:
+
+ SELECT t0.*
+ FROM
+ t0
+ LEFT JOIN
+ (t1 LEFT JOIN t2 ON some_expr)
+ ON
+ t2.primary_key=t1.col -- (*)
+
+ Here the uppermost ON expression has a clause that gives us functional
+ dependency of table t2 on t1 and hence could be used to eliminate the
+ "... LEFT JOIN t2 ON..." part.
+ However, we would not actually encounter this situation, because before the
+ table elimination we run simplify_joins(), which, among other things, upon
+ seeing a functional dependency condition like (*) will convert the outer join
+ of
+
+ "... LEFT JOIN t2 ON ..."
+
+ into inner join and thus make table elimination not to consider eliminating
+ table t2.
+*/
+
+class Dep_value;
+ class Dep_value_field;
+ class Dep_value_table;
+
+
+class Dep_module;
+ class Dep_module_expr;
+ class Dep_module_goal;
+ class Dep_module_key;
+
+class Dep_analysis_context;
+
+
+/*
+ A value, something that can be bound or not bound. One can also iterate over
+ unbound modules that depend on this value
+*/
+
+class Dep_value : public Sql_alloc
+{
+public:
+ Dep_value(): bound(FALSE) {}
+ virtual ~Dep_value(){} /* purecov: inspected */ /* stop compiler warnings */
+
+ bool is_bound() { return bound; }
+ void make_bound() { bound= TRUE; }
+
+ /* Iteration over unbound modules that depend on this value */
+ typedef char *Iterator;
+ virtual Iterator init_unbound_modules_iter(char *buf)=0;
+ virtual Dep_module* get_next_unbound_module(Dep_analysis_context *dac,
+ Iterator iter) = 0;
+ static const size_t iterator_size;
+protected:
+ bool bound;
+};
+
+
+/*
+ A table field value. There is exactly only one such object for any tblX.fieldY
+ - the field depends on its table and equalities
+ - expressions that use the field are its dependencies
+*/
+
+class Dep_value_field : public Dep_value
+{
+public:
+ Dep_value_field(Dep_value_table *table_arg, Field *field_arg) :
+ table(table_arg), field(field_arg)
+ {}
+
+ Dep_value_table *table; /* Table this field is from */
+ Field *field; /* Field this object is representing */
+
+ /* Iteration over unbound modules that are our dependencies */
+ Iterator init_unbound_modules_iter(char *buf);
+ Dep_module* get_next_unbound_module(Dep_analysis_context *dac,
+ Iterator iter);
+
+ void make_unbound_modules_iter_skip_keys(Iterator iter);
+
+ static const size_t iterator_size;
+private:
+ /*
+ Field_deps that belong to one table form a linked list, ordered by
+ field_index
+ */
+ Dep_value_field *next_table_field;
+
+ /*
+ Offset to bits in Dep_analysis_context::expr_deps (see comment to that
+ member for semantics of the bits).
+ */
+ uint bitmap_offset;
+
+ class Module_iter
+ {
+ public:
+ /* if not null, return this and advance */
+ Dep_module_key *key_dep;
+ /* Otherwise, this and advance */
+ uint equality_no;
+ };
+ friend class Dep_analysis_context;
+ friend class Field_dependency_recorder;
+ friend class Dep_value_table;
+};
+
+const size_t Dep_value_field::iterator_size=
+ ALIGN_SIZE(sizeof(Dep_value_field::Module_iter));
+
+
+/*
+ A table value. There is one Dep_value_table object for every table that can
+ potentially be eliminated.
+
+ Table becomes bound as soon as some of its unique keys becomes bound
+ Once the table is bound:
+ - all of its fields are bound
+ - its embedding outer join has one less unknown argument
+*/
+
+class Dep_value_table : public Dep_value
+{
+public:
+ Dep_value_table(TABLE *table_arg) :
+ table(table_arg), fields(NULL), keys(NULL)
+ {}
+ TABLE *table; /* Table this object is representing */
+ /* Ordered list of fields that belong to this table */
+ Dep_value_field *fields;
+ Dep_module_key *keys; /* Ordered list of Unique keys in this table */
+
+ /* Iteration over unbound modules that are our dependencies */
+ Iterator init_unbound_modules_iter(char *buf);
+ Dep_module* get_next_unbound_module(Dep_analysis_context *dac,
+ Iterator iter);
+ static const size_t iterator_size;
+private:
+ class Module_iter
+ {
+ public:
+ /* Space for field iterator */
+ char buf[Dep_value_field::iterator_size];
+ /* !NULL <=> iterating over depdenent modules of this field */
+ Dep_value_field *field_dep;
+ bool returned_goal;
+ };
+};
+
+
+const size_t Dep_value_table::iterator_size=
+ ALIGN_SIZE(sizeof(Dep_value_table::Module_iter));
+
+const size_t Dep_value::iterator_size=
+ max(Dep_value_table::iterator_size, Dep_value_field::iterator_size);
+
+
+/*
+ A 'module'. Module has unsatisfied dependencies, number of whose is stored in
+ unbound_args. Modules also can be linked together in a list.
+*/
+
+class Dep_module : public Sql_alloc
+{
+public:
+ virtual ~Dep_module(){} /* purecov: inspected */ /* stop compiler warnings */
+
+ /* Mark as bound. Currently is non-virtual and does nothing */
+ void make_bound() {};
+
+ /*
+ The final module will return TRUE here. When we see that TRUE was returned,
+ that will mean that functional dependency check succeeded.
+ */
+ virtual bool is_final () { return FALSE; }
+
+ /*
+ Increment number of bound arguments. this is expected to change
+ is_applicable() from false to true after sufficient set of arguments is
+ bound.
+ */
+ void touch() { unbound_args--; }
+ bool is_applicable() { return !test(unbound_args); }
+
+ /* Iteration over values that */
+ typedef char *Iterator;
+ virtual Iterator init_unbound_values_iter(char *buf)=0;
+ virtual Dep_value* get_next_unbound_value(Dep_analysis_context *dac,
+ Iterator iter)=0;
+ static const size_t iterator_size;
+protected:
+ uint unbound_args;
+
+ Dep_module() : unbound_args(0) {}
+ /* to bump unbound_args when constructing depedendencies */
+ friend class Field_dependency_recorder;
+ friend class Dep_analysis_context;
+};
+
+
+/*
+ This represents either
+ - "tbl.column= expr" equality dependency, i.e. tbl.column depends on fields
+ used in the expression, or
+ - tbl1.col1=tbl2.col2=... multi-equality.
+*/
+
+class Dep_module_expr : public Dep_module
+{
+public:
+ Dep_value_field *field;
+ Item *expr;
+
+ List<Dep_value_field> *mult_equal_fields;
+ /* Used during condition analysis only, similar to KEYUSE::level */
+ uint level;
+
+ Iterator init_unbound_values_iter(char *buf);
+ Dep_value* get_next_unbound_value(Dep_analysis_context *dac, Iterator iter);
+ static const size_t iterator_size;
+private:
+ class Value_iter
+ {
+ public:
+ Dep_value_field *field;
+ List_iterator<Dep_value_field> it;
+ };
+};
+
+const size_t Dep_module_expr::iterator_size=
+ ALIGN_SIZE(sizeof(Dep_module_expr::Value_iter));
+
+
+/*
+ A Unique key module
+ - Unique key has all of its components as arguments
+ - Once unique key is bound, its table value is known
+*/
+
+class Dep_module_key: public Dep_module
+{
+public:
+ Dep_module_key(Dep_value_table *table_arg, uint keyno_arg, uint n_parts_arg) :
+ table(table_arg), keyno(keyno_arg), next_table_key(NULL)
+ {
+ unbound_args= n_parts_arg;
+ }
+ Dep_value_table *table; /* Table this key is from */
+ uint keyno; /* The index we're representing */
+ /* Unique keys form a linked list, ordered by keyno */
+ Dep_module_key *next_table_key;
+
+ Iterator init_unbound_values_iter(char *buf);
+ Dep_value* get_next_unbound_value(Dep_analysis_context *dac, Iterator iter);
+ static const size_t iterator_size;
+private:
+ class Value_iter
+ {
+ public:
+ Dep_value_table *table;
+ };
+};
+
+const size_t Dep_module_key::iterator_size=
+ ALIGN_SIZE(sizeof(Dep_module_key::Value_iter));
+
+const size_t Dep_module::iterator_size=
+ max(Dep_module_expr::iterator_size, Dep_module_key::iterator_size);
+
+
+/*
+ A module that represents outer join that we're trying to eliminate. If we
+ manage to declare this module to be bound, then outer join can be eliminated.
+*/
+
+class Dep_module_goal: public Dep_module
+{
+public:
+ Dep_module_goal(uint n_children)
+ {
+ unbound_args= n_children;
+ }
+ bool is_final() { return TRUE; }
+ /*
+ This is the goal module, so the running wave algorithm should terminate
+ once it sees that this module is applicable and should never try to apply
+ it, hence no use for unbound value iterator implementation.
+ */
+ Iterator init_unbound_values_iter(char *buf)
+ {
+ DBUG_ASSERT(0);
+ return NULL;
+ }
+ Dep_value* get_next_unbound_value(Dep_analysis_context *dac, Iterator iter)
+ {
+ DBUG_ASSERT(0);
+ return NULL;
+ }
+};
+
+
+/*
+ Functional dependency analyzer context
+*/
+class Dep_analysis_context
+{
+public:
+ bool setup_equality_modules_deps(List<Dep_module> *bound_modules);
+ bool run_wave(List<Dep_module> *new_bound_modules);
+
+ /* Tables that we're looking at eliminating */
+ table_map usable_tables;
+
+ /* Array of equality dependencies */
+ Dep_module_expr *equality_mods;
+ uint n_equality_mods; /* Number of elements in the array */
+ uint n_equality_mods_alloced;
+
+ /* tablenr -> Dep_value_table* mapping. */
+ Dep_value_table *table_deps[MAX_KEY];
+
+ /* Element for the outer join we're attempting to eliminate */
+ Dep_module_goal *outer_join_dep;
+
+ /*
+ Bitmap of how expressions depend on bits. Given a Dep_value_field object,
+ one can check bitmap_is_set(expr_deps, field_val->bitmap_offset + expr_no)
+ to see if expression equality_mods[expr_no] depends on the given field.
+ */
+ MY_BITMAP expr_deps;
+
+ Dep_value_table *create_table_value(TABLE *table);
+ Dep_value_field *get_field_value(Field *field);
+
+#ifndef DBUG_OFF
+ void dbug_print_deps();
+#endif
+};
+
+
+void eliminate_tables(JOIN *join);
+
+static bool
+eliminate_tables_for_list(JOIN *join,
+ List<TABLE_LIST> *join_list,
+ table_map tables_in_list,
+ Item *on_expr,
+ table_map tables_used_elsewhere);
+static
+bool check_func_dependency(JOIN *join,
+ table_map dep_tables,
+ List_iterator<TABLE_LIST> *it,
+ TABLE_LIST *oj_tbl,
+ Item* cond);
+static
+void build_eq_mods_for_cond(Dep_analysis_context *dac,
+ Dep_module_expr **eq_mod, uint *and_level,
+ Item *cond);
+static
+void check_equality(Dep_analysis_context *dac, Dep_module_expr **eq_mod,
+ uint and_level, Item_func *cond, Item *left, Item *right);
+static
+Dep_module_expr *merge_eq_mods(Dep_module_expr *start,
+ Dep_module_expr *new_fields,
+ Dep_module_expr *end, uint and_level);
+static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl);
+static
+void add_module_expr(Dep_analysis_context *dac, Dep_module_expr **eq_mod,
+ uint and_level, Dep_value_field *field_val, Item *right,
+ List<Dep_value_field>* mult_equal_fields);
+
+
+/*****************************************************************************/
+
+/*
+ Perform table elimination
+
+ SYNOPSIS
+ eliminate_tables()
+ join Join to work on
+
+ DESCRIPTION
+ This is the entry point for table elimination. Grep for MODULE INTERFACE
+ section in this file for calling convention.
+
+ The idea behind table elimination is that if we have an outer join:
+
+ SELECT * FROM t1 LEFT JOIN
+ (t2 JOIN t3) ON t2.primary_key=t1.col AND
+ t3.primary_key=t2.col
+ such that
+
+ 1. columns of the inner tables are not used anywhere ouside the outer
+ join (not in WHERE, not in GROUP/ORDER BY clause, not in select list
+ etc etc), and
+ 2. inner side of the outer join is guaranteed to produce at most one
+ record combination for each record combination of outer tables.
+
+ then the inner side of the outer join can be removed from the query.
+ This is because it will always produce one matching record (either a
+ real match or a NULL-complemented record combination), and since there
+ are no references to columns of the inner tables anywhere, it doesn't
+ matter which record combination it was.
+
+ This function primary handles checking #1. It collects a bitmap of
+ tables that are not used in select list/GROUP BY/ORDER BY/HAVING/etc and
+ thus can possibly be eliminated.
+
+ After this, if #1 is met, the function calls eliminate_tables_for_list()
+ that checks #2.
+
+ SIDE EFFECTS
+ See the OVERVIEW section at the top of this file.
+
+*/
+
+void eliminate_tables(JOIN *join)
+{
+ THD* thd= join->thd;
+ Item *item;
+ table_map used_tables;
+ DBUG_ENTER("eliminate_tables");
+
+ DBUG_ASSERT(join->eliminated_tables == 0);
+
+ /* If there are no outer joins, we have nothing to eliminate: */
+ if (!join->outer_join)
+ DBUG_VOID_RETURN;
+
+#ifndef DBUG_OFF
+ if (!optimizer_flag(thd, OPTIMIZER_SWITCH_TABLE_ELIMINATION))
+ DBUG_VOID_RETURN; /* purecov: inspected */
+#endif
+
+ /* Find the tables that are referred to from WHERE/HAVING */
+ used_tables= (join->conds? join->conds->used_tables() : 0) |
+ (join->having? join->having->used_tables() : 0);
+
+ /* Add tables referred to from the select list */
+ List_iterator<Item> it(join->fields_list);
+ while ((item= it++))
+ used_tables |= item->used_tables();
+
+ /* Add tables referred to from ORDER BY and GROUP BY lists */
+ ORDER *all_lists[]= { join->order, join->group_list};
+ for (int i=0; i < 2; i++)
+ {
+ for (ORDER *cur_list= all_lists[i]; cur_list; cur_list= cur_list->next)
+ used_tables |= (*(cur_list->item))->used_tables();
+ }
+
+ if (join->select_lex == &thd->lex->select_lex)
+ {
+
+ /* Multi-table UPDATE: don't eliminate tables referred from SET statement */
+ if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI)
+ {
+ /* Multi-table UPDATE and DELETE: don't eliminate the tables we modify: */
+ used_tables |= thd->table_map_for_update;
+ List_iterator<Item> it2(thd->lex->value_list);
+ while ((item= it2++))
+ used_tables |= item->used_tables();
+ }
+
+ if (thd->lex->sql_command == SQLCOM_DELETE_MULTI)
+ {
+ TABLE_LIST *tbl;
+ for (tbl= (TABLE_LIST*)thd->lex->auxiliary_table_list.first;
+ tbl; tbl= tbl->next_local)
+ {
+ used_tables |= tbl->table->map;
+ }
+ }
+ }
+
+ table_map all_tables= join->all_tables_map();
+ if (all_tables & ~used_tables)
+ {
+ /* There are some tables that we probably could eliminate. Try it. */
+ eliminate_tables_for_list(join, join->join_list, all_tables, NULL,
+ used_tables);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Perform table elimination in a given join list
+
+ SYNOPSIS
+ eliminate_tables_for_list()
+ join The join we're working on
+ join_list Join list to eliminate tables from (and if
+ on_expr !=NULL, then try eliminating join_list
+ itself)
+ list_tables Bitmap of tables embedded in the join_list.
+ on_expr ON expression, if the join list is the inner side
+ of an outer join.
+ NULL means it's not an outer join but rather a
+ top-level join list.
+ tables_used_elsewhere Bitmap of tables that are referred to from
+ somewhere outside of the join list (e.g.
+ select list, HAVING, other ON expressions, etc).
+
+ DESCRIPTION
+ Perform table elimination in a given join list:
+ - First, walk through join list members and try doing table elimination for
+ them.
+ - Then, if the join list itself is an inner side of outer join
+ (on_expr!=NULL), then try to eliminate the entire join list.
+
+ See "HANDLING MULTIPLE NESTED OUTER JOINS" section at the top of this file
+ for more detailed description and justification.
+
+ RETURN
+ TRUE The entire join list eliminated
+ FALSE Join list wasn't eliminated (but some of its child outer joins
+ possibly were)
+*/
+
+static bool
+eliminate_tables_for_list(JOIN *join, List<TABLE_LIST> *join_list,
+ table_map list_tables, Item *on_expr,
+ table_map tables_used_elsewhere)
+{
+ TABLE_LIST *tbl;
+ List_iterator<TABLE_LIST> it(*join_list);
+ table_map tables_used_on_left= 0;
+ bool all_eliminated= TRUE;
+
+ while ((tbl= it++))
+ {
+ if (tbl->on_expr)
+ {
+ table_map outside_used_tables= tables_used_elsewhere |
+ tables_used_on_left;
+ if (tbl->nested_join)
+ {
+ /* This is "... LEFT JOIN (join_nest) ON cond" */
+ if (eliminate_tables_for_list(join,
+ &tbl->nested_join->join_list,
+ tbl->nested_join->used_tables,
+ tbl->on_expr,
+ outside_used_tables))
+ {
+ mark_as_eliminated(join, tbl);
+ }
+ else
+ all_eliminated= FALSE;
+ }
+ else
+ {
+ /* This is "... LEFT JOIN tbl ON cond" */
+ if (!(tbl->table->map & outside_used_tables) &&
+ check_func_dependency(join, tbl->table->map, NULL, tbl,
+ tbl->on_expr))
+ {
+ mark_as_eliminated(join, tbl);
+ }
+ else
+ all_eliminated= FALSE;
+ }
+ tables_used_on_left |= tbl->on_expr->used_tables();
+ }
+ else
+ {
+ DBUG_ASSERT(!tbl->nested_join);
+ }
+ }
+
+ /* Try eliminating the nest we're called for */
+ if (all_eliminated && on_expr && !(list_tables & tables_used_elsewhere))
+ {
+ it.rewind();
+ return check_func_dependency(join, list_tables & ~join->eliminated_tables,
+ &it, NULL, on_expr);
+ }
+ return FALSE; /* not eliminated */
+}
+
+
+/*
+ Check if given condition makes given set of tables functionally dependent
+
+ SYNOPSIS
+ check_func_dependency()
+ join Join we're procesing
+ dep_tables Tables that we check to be functionally dependent (on
+ everything else)
+ it Iterator that enumerates these tables, or NULL if we're
+ checking one single table and it is specified in oj_tbl
+ parameter.
+ oj_tbl NULL, or one single table that we're checking
+ cond Condition to use to prove functional dependency
+
+ DESCRIPTION
+ Check if we can use given condition to infer that the set of given tables
+ is functionally dependent on everything else.
+
+ RETURN
+ TRUE - Yes, functionally dependent
+ FALSE - No, or error
+*/
+
+static
+bool check_func_dependency(JOIN *join,
+ table_map dep_tables,
+ List_iterator<TABLE_LIST> *it,
+ TABLE_LIST *oj_tbl,
+ Item* cond)
+{
+ Dep_analysis_context dac;
+
+ /*
+ Pre-alloc some Dep_module_expr structures. We don't need this to be
+ guaranteed upper bound.
+ */
+ dac.n_equality_mods_alloced=
+ join->thd->lex->current_select->max_equal_elems +
+ (join->thd->lex->current_select->cond_count+1)*2 +
+ join->thd->lex->current_select->between_count;
+
+ bzero(dac.table_deps, sizeof(dac.table_deps));
+ if (!(dac.equality_mods= new Dep_module_expr[dac.n_equality_mods_alloced]))
+ return FALSE; /* purecov: inspected */
+
+ Dep_module_expr* last_eq_mod= dac.equality_mods;
+
+ /* Create Dep_value_table objects for all tables we're trying to eliminate */
+ if (oj_tbl)
+ {
+ if (!dac.create_table_value(oj_tbl->table))
+ return FALSE; /* purecov: inspected */
+ }
+ else
+ {
+ TABLE_LIST *tbl;
+ while ((tbl= (*it)++))
+ {
+ if (tbl->table && (tbl->table->map & dep_tables))
+ {
+ if (!dac.create_table_value(tbl->table))
+ return FALSE; /* purecov: inspected */
+ }
+ }
+ }
+ dac.usable_tables= dep_tables;
+
+ /*
+ Analyze the the ON expression and create Dep_module_expr objects and
+ Dep_value_field objects for the used fields.
+ */
+ uint and_level=0;
+ build_eq_mods_for_cond(&dac, &last_eq_mod, &and_level, cond);
+ if (!(dac.n_equality_mods= last_eq_mod - dac.equality_mods))
+ return FALSE; /* No useful conditions */
+
+ List<Dep_module> bound_modules;
+
+ if (!(dac.outer_join_dep= new Dep_module_goal(my_count_bits(dep_tables))) ||
+ dac.setup_equality_modules_deps(&bound_modules))
+ {
+ return FALSE; /* OOM, default to non-dependent */ /* purecov: inspected */
+ }
+
+ DBUG_EXECUTE("test", dac.dbug_print_deps(); );
+
+ return dac.run_wave(&bound_modules);
+}
+
+
+/*
+ Running wave functional dependency check algorithm
+
+ SYNOPSIS
+ Dep_analysis_context::run_wave()
+ new_bound_modules List of bound modules to start the running wave from.
+ The list is destroyed during execution
+
+ DESCRIPTION
+ This function uses running wave algorithm to check if the join nest is
+ functionally-dependent.
+ We start from provided list of bound modules, and then run the wave across
+ dependency edges, trying the reach the Dep_module_goal module. If we manage
+ to reach it, then the join nest is functionally-dependent, otherwise it is
+ not.
+
+ RETURN
+ TRUE Yes, functionally dependent
+ FALSE No.
+*/
+
+bool Dep_analysis_context::run_wave(List<Dep_module> *new_bound_modules)
+{
+ List<Dep_value> new_bound_values;
+
+ Dep_value *value;
+ Dep_module *module;
+
+ while (!new_bound_modules->is_empty())
+ {
+ /*
+ The "wave" is in new_bound_modules list. Iterate over values that can be
+ reached from these modules but are not yet bound, and collect the next
+ wave generation in new_bound_values list.
+ */
+ List_iterator<Dep_module> modules_it(*new_bound_modules);
+ while ((module= modules_it++))
+ {
+ char iter_buf[Dep_module::iterator_size + ALIGN_MAX_UNIT];
+ Dep_module::Iterator iter;
+ iter= module->init_unbound_values_iter(iter_buf);
+ while ((value= module->get_next_unbound_value(this, iter)))
+ {
+ value->make_bound();
+ new_bound_values.push_back(value);
+ }
+ }
+ new_bound_modules->empty();
+
+ /*
+ Now walk over list of values we've just found to be bound and check which
+ unbound modules can be reached from them. If there are some modules that
+ became bound, collect them in new_bound_modules list.
+ */
+ List_iterator<Dep_value> value_it(new_bound_values);
+ while ((value= value_it++))
+ {
+ char iter_buf[Dep_value::iterator_size + ALIGN_MAX_UNIT];
+ Dep_value::Iterator iter;
+ iter= value->init_unbound_modules_iter(iter_buf);
+ while ((module= value->get_next_unbound_module(this, iter)))
+ {
+ module->touch();
+ if (!module->is_applicable())
+ continue;
+ if (module->is_final())
+ return TRUE; /* Functionally dependent */
+ module->make_bound();
+ new_bound_modules->push_back(module);
+ }
+ }
+ new_bound_values.empty();
+ }
+ return FALSE;
+}
+
+
+/*
+ This is used to analyze expressions in "tbl.col=expr" dependencies so
+ that we can figure out which fields the expression depends on.
+*/
+
+class Field_dependency_recorder : public Field_enumerator
+{
+public:
+ Field_dependency_recorder(Dep_analysis_context *ctx_arg): ctx(ctx_arg)
+ {}
+
+ void visit_field(Field *field)
+ {
+ Dep_value_table *tbl_dep;
+ if ((tbl_dep= ctx->table_deps[field->table->tablenr]))
+ {
+ for (Dep_value_field *field_dep= tbl_dep->fields; field_dep;
+ field_dep= field_dep->next_table_field)
+ {
+ if (field->field_index == field_dep->field->field_index)
+ {
+ uint offs= field_dep->bitmap_offset + expr_offset;
+ if (!bitmap_is_set(&ctx->expr_deps, offs))
+ ctx->equality_mods[expr_offset].unbound_args++;
+ bitmap_set_bit(&ctx->expr_deps, offs);
+ return;
+ }
+ }
+ /*
+ We got here if didn't find this field. It's not a part of
+ a unique key, and/or there is no field=expr element for it.
+ Bump the dependency anyway, this will signal that this dependency
+ cannot be satisfied.
+ */
+ ctx->equality_mods[expr_offset].unbound_args++;
+ }
+ else
+ visited_other_tables= TRUE;
+ }
+
+ Dep_analysis_context *ctx;
+ /* Offset of the expression we're processing in the dependency bitmap */
+ uint expr_offset;
+
+ bool visited_other_tables;
+};
+
+
+
+
+/*
+ Setup inbound dependency relationships for tbl.col=expr equalities
+
+ SYNOPSIS
+ setup_equality_modules_deps()
+ bound_deps_list Put here modules that were found not to depend on
+ any non-bound columns.
+
+ DESCRIPTION
+ Setup inbound dependency relationships for tbl.col=expr equalities:
+ - allocate a bitmap where we store such dependencies
+ - for each "tbl.col=expr" equality, analyze the expr part and find out
+ which fields it refers to and set appropriate dependencies.
+
+ RETURN
+ FALSE OK
+ TRUE Out of memory
+*/
+
+bool Dep_analysis_context::setup_equality_modules_deps(List<Dep_module>
+ *bound_modules)
+{
+ DBUG_ENTER("setup_equality_modules_deps");
+
+ /*
+ Count Dep_value_field objects and assign each of them a unique
+ bitmap_offset value.
+ */
+ uint offset= 0;
+ for (Dep_value_table **tbl_dep= table_deps;
+ tbl_dep < table_deps + MAX_TABLES;
+ tbl_dep++)
+ {
+ if (*tbl_dep)
+ {
+ for (Dep_value_field *field_dep= (*tbl_dep)->fields;
+ field_dep;
+ field_dep= field_dep->next_table_field)
+ {
+ field_dep->bitmap_offset= offset;
+ offset += n_equality_mods;
+ }
+ }
+ }
+
+ void *buf;
+ if (!(buf= current_thd->alloc(bitmap_buffer_size(offset))) ||
+ bitmap_init(&expr_deps, (my_bitmap_map*)buf, offset, FALSE))
+ {
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+ }
+ bitmap_clear_all(&expr_deps);
+
+ /*
+ Analyze all "field=expr" dependencies, and have expr_deps encode
+ dependencies of expressions from fields.
+
+ Also collect a linked list of equalities that are bound.
+ */
+ Field_dependency_recorder deps_recorder(this);
+ for (Dep_module_expr *eq_mod= equality_mods;
+ eq_mod < equality_mods + n_equality_mods;
+ eq_mod++)
+ {
+ deps_recorder.expr_offset= eq_mod - equality_mods;
+ deps_recorder.visited_other_tables= FALSE;
+ eq_mod->unbound_args= 0;
+
+ if (eq_mod->field)
+ {
+ /* Regular tbl.col=expr(tblX1.col1, tblY1.col2, ...) */
+ eq_mod->expr->walk(&Item::enumerate_field_refs_processor, FALSE,
+ (uchar*)&deps_recorder);
+ }
+ else
+ {
+ /* It's a multi-equality */
+ eq_mod->unbound_args= !test(eq_mod->expr);
+ List_iterator<Dep_value_field> it(*eq_mod->mult_equal_fields);
+ Dep_value_field* field_val;
+ while ((field_val= it++))
+ {
+ uint offs= field_val->bitmap_offset + eq_mod - equality_mods;
+ bitmap_set_bit(&expr_deps, offs);
+ }
+ }
+
+ if (!eq_mod->unbound_args)
+ bound_modules->push_back(eq_mod);
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ Ordering that we're using whenever we need to maintain a no-duplicates list
+ of field value objects.
+*/
+
+static
+int compare_field_values(Dep_value_field *a, Dep_value_field *b, void *unused)
+{
+ uint a_ratio= a->field->table->tablenr*MAX_FIELDS +
+ a->field->field_index;
+
+ uint b_ratio= b->field->table->tablenr*MAX_FIELDS +
+ b->field->field_index;
+ return (a_ratio < b_ratio)? -1 : ((a_ratio == b_ratio)? 0 : 1);
+}
+
+
+/*
+ Produce Dep_module_expr elements for given condition.
+
+ SYNOPSIS
+ build_eq_mods_for_cond()
+ ctx Table elimination context
+ eq_mod INOUT Put produced equality conditions here
+ and_level INOUT AND-level (like in add_key_fields)
+ cond Condition to process
+
+ DESCRIPTION
+ Analyze the given condition and produce an array of Dep_module_expr
+ dependencies from it. The idea of analysis is as follows:
+ There are useful equalities that have form
+
+ eliminable_tbl.field = expr (denote as useful_equality)
+
+ The condition is composed of useful equalities and other conditions that
+ are combined together with AND and OR operators. We process the condition
+ in recursive fashion according to these basic rules:
+
+ useful_equality1 AND useful_equality2 -> make array of two
+ Dep_module_expr objects
+
+ useful_equality AND other_cond -> discard other_cond
+
+ useful_equality OR other_cond -> discard everything
+
+ useful_equality1 OR useful_equality2 -> check if both sides of OR are the
+ same equality. If yes, that's the
+ result, otherwise discard
+ everything.
+
+ The rules are used to map the condition into an array Dep_module_expr
+ elements. The array will specify functional dependencies that logically
+ follow from the condition.
+
+ SEE ALSO
+ This function is modeled after add_key_fields()
+*/
+
+static
+void build_eq_mods_for_cond(Dep_analysis_context *ctx,
+ Dep_module_expr **eq_mod,
+ uint *and_level, Item *cond)
+{
+ if (cond->type() == Item_func::COND_ITEM)
+ {
+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
+ uint orig_offset= *eq_mod - ctx->equality_mods;
+
+ /* AND/OR */
+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
+ {
+ Item *item;
+ while ((item=li++))
+ build_eq_mods_for_cond(ctx, eq_mod, and_level, item);
+
+ for (Dep_module_expr *mod_exp= ctx->equality_mods + orig_offset;
+ mod_exp != *eq_mod ; mod_exp++)
+ {
+ mod_exp->level= *and_level;
+ }
+ }
+ else
+ {
+ Item *item;
+ (*and_level)++;
+ build_eq_mods_for_cond(ctx, eq_mod, and_level, li++);
+ while ((item=li++))
+ {
+ Dep_module_expr *start_key_fields= *eq_mod;
+ (*and_level)++;
+ build_eq_mods_for_cond(ctx, eq_mod, and_level, item);
+ *eq_mod= merge_eq_mods(ctx->equality_mods + orig_offset,
+ start_key_fields, *eq_mod,
+ ++(*and_level));
+ }
+ }
+ return;
+ }
+
+ if (cond->type() != Item::FUNC_ITEM)
+ return;
+
+ Item_func *cond_func= (Item_func*) cond;
+ Item **args= cond_func->arguments();
+
+ switch (cond_func->functype()) {
+ case Item_func::BETWEEN:
+ {
+ Item *fld;
+ if (!((Item_func_between*)cond)->negated &&
+ (fld= args[0]->real_item())->type() == Item::FIELD_ITEM &&
+ args[1]->eq(args[2], ((Item_field*)fld)->field->binary()))
+ {
+ check_equality(ctx, eq_mod, *and_level, cond_func, args[0], args[1]);
+ check_equality(ctx, eq_mod, *and_level, cond_func, args[1], args[0]);
+ }
+ break;
+ }
+ case Item_func::EQ_FUNC:
+ case Item_func::EQUAL_FUNC:
+ {
+ check_equality(ctx, eq_mod, *and_level, cond_func, args[0], args[1]);
+ check_equality(ctx, eq_mod, *and_level, cond_func, args[1], args[0]);
+ break;
+ }
+ case Item_func::ISNULL_FUNC:
+ {
+ Item *tmp=new Item_null;
+ if (tmp)
+ check_equality(ctx, eq_mod, *and_level, cond_func, args[0], tmp);
+ break;
+ }
+ case Item_func::MULT_EQUAL_FUNC:
+ {
+ /*
+ The condition is a
+
+ tbl1.field1 = tbl2.field2 = tbl3.field3 [= const_expr]
+
+ multiple-equality. Do two things:
+ - Collect List<Dep_value_field> of tblX.colY where tblX is one of the
+ tables we're trying to eliminate.
+ - rembember if there was a bound value, either const_expr or tblY.colZ
+ swher tblY is not a table that we're trying to eliminate.
+ Store all collected information in a Dep_module_expr object.
+ */
+ Item_equal *item_equal= (Item_equal*)cond;
+ List<Dep_value_field> *fvl;
+ if (!(fvl= new List<Dep_value_field>))
+ break; /* purecov: inspected */
+
+ Item_equal_iterator it(*item_equal);
+ Item_field *item;
+ Item *bound_item= item_equal->get_const();
+ while ((item= it++))
+ {
+ if ((item->used_tables() & ctx->usable_tables))
+ {
+ Dep_value_field *field_val;
+ if ((field_val= ctx->get_field_value(item->field)))
+ fvl->push_back(field_val);
+ }
+ else
+ {
+ if (!bound_item)
+ bound_item= item;
+ }
+ }
+ /*
+ Multiple equality is only useful if it includes at least one field from
+ the table that we could potentially eliminate:
+ */
+ if (fvl->elements)
+ {
+
+ exchange_sort<Dep_value_field>(fvl, compare_field_values, NULL);
+ add_module_expr(ctx, eq_mod, *and_level, NULL, bound_item, fvl);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+
+/*
+ Perform an OR operation on two (adjacent) Dep_module_expr arrays.
+
+ SYNOPSIS
+ merge_eq_mods()
+ start Start of left OR-part
+ new_fields Start of right OR-part
+ end End of right OR-part
+ and_level AND-level (like in add_key_fields)
+
+ DESCRIPTION
+ This function is invoked for two adjacent arrays of Dep_module_expr elements:
+
+ $LEFT_PART $RIGHT_PART
+ +-----------------------+-----------------------+
+ start new_fields end
+
+ The goal is to produce an array which would correspond to the combined
+
+ $LEFT_PART OR $RIGHT_PART
+
+ condition. This is achieved as follows: First, we apply distrubutive law:
+
+ (fdep_A_1 AND fdep_A_2 AND ...) OR (fdep_B_1 AND fdep_B_2 AND ...) =
+
+ = AND_ij (fdep_A_[i] OR fdep_B_[j])
+
+ Then we walk over the obtained "fdep_A_[i] OR fdep_B_[j]" pairs, and
+ - Discard those that that have left and right part referring to different
+ columns. We can't infer anything useful from "col1=expr1 OR col2=expr2".
+ - When left and right parts refer to the same column, we check if they are
+ essentially the same.
+ = If they are the same, we keep one copy
+ "t.col=expr OR t.col=expr" -> "t.col=expr
+ = if they are different , then we discard both
+ "t.col=expr1 OR t.col=expr2" -> (nothing useful)
+
+ (no per-table or for-index FUNC_DEPS exist yet at this phase).
+
+ See also merge_key_fields().
+
+ RETURN
+ End of the result array
+*/
+
+static
+Dep_module_expr *merge_eq_mods(Dep_module_expr *start,
+ Dep_module_expr *new_fields,
+ Dep_module_expr *end, uint and_level)
+{
+ if (start == new_fields)
+ return start; /* (nothing) OR (...) -> (nothing) */
+ if (new_fields == end)
+ return start; /* (...) OR (nothing) -> (nothing) */
+
+ Dep_module_expr *first_free= new_fields;
+
+ for (; new_fields != end ; new_fields++)
+ {
+ for (Dep_module_expr *old=start ; old != first_free ; old++)
+ {
+ if (old->field == new_fields->field)
+ {
+ if (!old->field)
+ {
+ /*
+ OR-ing two multiple equalities. We must compute an intersection of
+ used fields, and check the constants according to these rules:
+
+ a=b=c=d OR a=c=e=f -> a=c (compute intersection)
+ a=const1 OR a=b -> (nothing)
+ a=const1 OR a=const1 -> a=const1
+ a=const1 OR a=const2 -> (nothing)
+
+ If we're performing an OR operation over multiple equalities, e.g.
+
+ (a=b=c AND p=q) OR (a=b AND v=z)
+
+ then we'll need to try combining each equality with each. ANDed
+ equalities are guaranteed to be disjoint, so we'll only get one
+ hit.
+ */
+ Field *eq_field= old->mult_equal_fields->head()->field;
+ if (old->expr && new_fields->expr &&
+ old->expr->eq_by_collation(new_fields->expr, eq_field->binary(),
+ eq_field->charset()))
+ {
+ /* Ok, keep */
+ }
+ else
+ {
+ /* no single constant/bound item. */
+ old->expr= NULL;
+ }
+
+ List <Dep_value_field> *fv;
+ if (!(fv= new List<Dep_value_field>))
+ break; /* purecov: inspected */
+
+ List_iterator<Dep_value_field> it1(*old->mult_equal_fields);
+ List_iterator<Dep_value_field> it2(*new_fields->mult_equal_fields);
+ Dep_value_field *lfield= it1++;
+ Dep_value_field *rfield= it2++;
+ /* Intersect two ordered lists */
+ while (lfield && rfield)
+ {
+ if (lfield == rfield)
+ {
+ fv->push_back(lfield);
+ lfield=it1++;
+ rfield=it2++;
+ }
+ else
+ {
+ if (compare_field_values(lfield, rfield, NULL) < 0)
+ lfield= it1++;
+ else
+ rfield= it2++;
+ }
+ }
+
+ if (fv->elements + test(old->expr) > 1)
+ {
+ old->mult_equal_fields= fv;
+ old->level= and_level;
+ }
+ }
+ else if (!new_fields->expr->const_item())
+ {
+ /*
+ If the value matches, we can use the key reference.
+ If not, we keep it until we have examined all new values
+ */
+ if (old->expr->eq(new_fields->expr,
+ old->field->field->binary()))
+ {
+ old->level= and_level;
+ }
+ }
+ else if (old->expr->eq_by_collation(new_fields->expr,
+ old->field->field->binary(),
+ old->field->field->charset()))
+ {
+ old->level= and_level;
+ }
+ else
+ {
+ /* The expressions are different. */
+ if (old == --first_free) // If last item
+ break;
+ *old= *first_free; // Remove old value
+ old--; // Retry this value
+ }
+ }
+ }
+ }
+
+ /*
+ Ok, the results are within the [start, first_free) range, and the useful
+ elements have level==and_level. Now, remove all unusable elements:
+ */
+ for (Dep_module_expr *old=start ; old != first_free ;)
+ {
+ if (old->level != and_level)
+ { // Not used in all levels
+ if (old == --first_free)
+ break;
+ *old= *first_free; // Remove old value
+ continue;
+ }
+ old++;
+ }
+ return first_free;
+}
+
+
+/*
+ Add an Dep_module_expr element for left=right condition
+
+ SYNOPSIS
+ check_equality()
+ fda Table elimination context
+ eq_mod INOUT Store created Dep_module_expr here and increment ptr if
+ you do so
+ and_level AND-level (like in add_key_fields)
+ cond Condition we've inferred the left=right equality from.
+ left Left expression
+ right Right expression
+ usable_tables Create Dep_module_expr only if Left_expression's table
+ belongs to this set.
+
+ DESCRIPTION
+ Check if the passed left=right equality is such that
+ - 'left' is an Item_field referring to a field in a table we're checking
+ to be functionally depdendent,
+ - the equality allows to conclude that 'left' expression is functionally
+ dependent on the 'right',
+ and if so, create an Dep_module_expr object.
+*/
+
+static
+void check_equality(Dep_analysis_context *ctx, Dep_module_expr **eq_mod,
+ uint and_level, Item_func *cond, Item *left, Item *right)
+{
+ if ((left->used_tables() & ctx->usable_tables) &&
+ !(right->used_tables() & RAND_TABLE_BIT) &&
+ left->real_item()->type() == Item::FIELD_ITEM)
+ {
+ Field *field= ((Item_field*)left->real_item())->field;
+ if (field->result_type() == STRING_RESULT)
+ {
+ if (right->result_type() != STRING_RESULT)
+ {
+ if (field->cmp_type() != right->result_type())
+ return;
+ }
+ else
+ {
+ /*
+ We can't assume there's a functional dependency if the effective
+ collation of the operation differ from the field collation.
+ */
+ if (field->cmp_type() == STRING_RESULT &&
+ ((Field_str*)field)->charset() != cond->compare_collation())
+ return;
+ }
+ }
+ Dep_value_field *field_val;
+ if ((field_val= ctx->get_field_value(field)))
+ add_module_expr(ctx, eq_mod, and_level, field_val, right, NULL);
+ }
+}
+
+
+/*
+ Add a Dep_module_expr object with the specified parameters.
+
+ DESCRIPTION
+ Add a Dep_module_expr object with the specified parameters. Re-allocate
+ the ctx->equality_mods array if it has no space left.
+*/
+
+static
+void add_module_expr(Dep_analysis_context *ctx, Dep_module_expr **eq_mod,
+ uint and_level, Dep_value_field *field_val,
+ Item *right, List<Dep_value_field>* mult_equal_fields)
+{
+ if (*eq_mod == ctx->equality_mods + ctx->n_equality_mods_alloced)
+ {
+ /*
+ We've filled the entire equality_mods array. Replace it with a bigger
+ one. We do it somewhat inefficiently but it doesn't matter.
+ */
+ /* purecov: begin inspected */
+ Dep_module_expr *new_arr;
+ if (!(new_arr= new Dep_module_expr[ctx->n_equality_mods_alloced *2]))
+ return;
+ ctx->n_equality_mods_alloced *= 2;
+ for (int i= 0; i < *eq_mod - ctx->equality_mods; i++)
+ new_arr[i]= ctx->equality_mods[i];
+
+ ctx->equality_mods= new_arr;
+ *eq_mod= new_arr + (*eq_mod - ctx->equality_mods);
+ /* purecov: end */
+ }
+
+ (*eq_mod)->field= field_val;
+ (*eq_mod)->expr= right;
+ (*eq_mod)->level= and_level;
+ (*eq_mod)->mult_equal_fields= mult_equal_fields;
+ (*eq_mod)++;
+}
+
+
+/*
+ Create a Dep_value_table object for the given table
+
+ SYNOPSIS
+ Dep_analysis_context::create_table_value()
+ table Table to create object for
+
+ DESCRIPTION
+ Create a Dep_value_table object for the given table. Also create
+ Dep_module_key objects for all unique keys in the table.
+
+ RETURN
+ Created table value object
+ NULL if out of memory
+*/
+
+Dep_value_table *Dep_analysis_context::create_table_value(TABLE *table)
+{
+ Dep_value_table *tbl_dep;
+ if (!(tbl_dep= new Dep_value_table(table)))
+ return NULL; /* purecov: inspected */
+
+ Dep_module_key **key_list= &(tbl_dep->keys);
+ /* Add dependencies for unique keys */
+ for (uint i=0; i < table->s->keys; i++)
+ {
+ KEY *key= table->key_info + i;
+ if ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME)
+ {
+ Dep_module_key *key_dep;
+ if (!(key_dep= new Dep_module_key(tbl_dep, i, key->key_parts)))
+ return NULL;
+ *key_list= key_dep;
+ key_list= &(key_dep->next_table_key);
+ }
+ }
+ return table_deps[table->tablenr]= tbl_dep;
+}
+
+
+/*
+ Get a Dep_value_field object for the given field, creating it if necessary
+
+ SYNOPSIS
+ Dep_analysis_context::get_field_value()
+ field Field to create object for
+
+ DESCRIPTION
+ Get a Dep_value_field object for the given field. First, we search for it
+ in the list of Dep_value_field objects we have already created. If we don't
+ find it, we create a new Dep_value_field and put it into the list of field
+ objects we have for the table.
+
+ RETURN
+ Created field value object
+ NULL if out of memory
+*/
+
+Dep_value_field *Dep_analysis_context::get_field_value(Field *field)
+{
+ TABLE *table= field->table;
+ Dep_value_table *tbl_dep= table_deps[table->tablenr];
+
+ /* Try finding the field in field list */
+ Dep_value_field **pfield= &(tbl_dep->fields);
+ while (*pfield && (*pfield)->field->field_index < field->field_index)
+ {
+ pfield= &((*pfield)->next_table_field);
+ }
+ if (*pfield && (*pfield)->field->field_index == field->field_index)
+ return *pfield;
+
+ /* Create the field and insert it in the list */
+ Dep_value_field *new_field= new Dep_value_field(tbl_dep, field);
+ new_field->next_table_field= *pfield;
+ *pfield= new_field;
+
+ return new_field;
+}
+
+
+/*
+ Iteration over unbound modules that are our dependencies.
+ for those we have:
+ - dependendencies of our fields
+ - outer join we're in
+*/
+char *Dep_value_table::init_unbound_modules_iter(char *buf)
+{
+ Module_iter *iter= ALIGN_PTR(my_ptrdiff_t(buf), Module_iter);
+ iter->field_dep= fields;
+ if (fields)
+ {
+ fields->init_unbound_modules_iter(iter->buf);
+ fields->make_unbound_modules_iter_skip_keys(iter->buf);
+ }
+ iter->returned_goal= FALSE;
+ return (char*)iter;
+}
+
+
+Dep_module*
+Dep_value_table::get_next_unbound_module(Dep_analysis_context *dac,
+ char *iter)
+{
+ Module_iter *di= (Module_iter*)iter;
+ while (di->field_dep)
+ {
+ Dep_module *res;
+ if ((res= di->field_dep->get_next_unbound_module(dac, di->buf)))
+ return res;
+ if ((di->field_dep= di->field_dep->next_table_field))
+ {
+ char *field_iter= ((Module_iter*)iter)->buf;
+ di->field_dep->init_unbound_modules_iter(field_iter);
+ di->field_dep->make_unbound_modules_iter_skip_keys(field_iter);
+ }
+ }
+
+ if (!di->returned_goal)
+ {
+ di->returned_goal= TRUE;
+ return dac->outer_join_dep;
+ }
+ return NULL;
+}
+
+
+char *Dep_module_expr::init_unbound_values_iter(char *buf)
+{
+ Value_iter *iter= ALIGN_PTR(my_ptrdiff_t(buf), Value_iter);
+ iter->field= field;
+ if (!field)
+ {
+ new (&iter->it) List_iterator<Dep_value_field>(*mult_equal_fields);
+ }
+ return (char*)iter;
+}
+
+
+Dep_value* Dep_module_expr::get_next_unbound_value(Dep_analysis_context *dac,
+ char *buf)
+{
+ Dep_value *res;
+ if (field)
+ {
+ res= ((Value_iter*)buf)->field;
+ ((Value_iter*)buf)->field= NULL;
+ return (!res || res->is_bound())? NULL : res;
+ }
+ else
+ {
+ while ((res= ((Value_iter*)buf)->it++))
+ {
+ if (!res->is_bound())
+ return res;
+ }
+ return NULL;
+ }
+}
+
+
+char *Dep_module_key::init_unbound_values_iter(char *buf)
+{
+ Value_iter *iter= ALIGN_PTR(my_ptrdiff_t(buf), Value_iter);
+ iter->table= table;
+ return (char*)iter;
+}
+
+
+Dep_value* Dep_module_key::get_next_unbound_value(Dep_analysis_context *dac,
+ Dep_module::Iterator iter)
+{
+ Dep_value* res= ((Value_iter*)iter)->table;
+ ((Value_iter*)iter)->table= NULL;
+ return res;
+}
+
+
+Dep_value::Iterator Dep_value_field::init_unbound_modules_iter(char *buf)
+{
+ Module_iter *iter= ALIGN_PTR(my_ptrdiff_t(buf), Module_iter);
+ iter->key_dep= table->keys;
+ iter->equality_no= 0;
+ return (char*)iter;
+}
+
+
+void
+Dep_value_field::make_unbound_modules_iter_skip_keys(Dep_value::Iterator iter)
+{
+ ((Module_iter*)iter)->key_dep= NULL;
+}
+
+
+Dep_module* Dep_value_field::get_next_unbound_module(Dep_analysis_context *dac,
+ Dep_value::Iterator iter)
+{
+ Module_iter *di= (Module_iter*)iter;
+ Dep_module_key *key_dep= di->key_dep;
+
+ /*
+ First, enumerate all unique keys that are
+ - not yet applicable
+ - have this field as a part of them
+ */
+ while (key_dep && (key_dep->is_applicable() ||
+ !field->part_of_key.is_set(key_dep->keyno)))
+ {
+ key_dep= key_dep->next_table_key;
+ }
+
+ if (key_dep)
+ {
+ di->key_dep= key_dep->next_table_key;
+ return key_dep;
+ }
+ else
+ di->key_dep= NULL;
+
+ /*
+ Then walk through [multi]equalities and find those that
+ - depend on this field
+ - and are not bound yet.
+ */
+ uint eq_no= di->equality_no;
+ while (eq_no < dac->n_equality_mods &&
+ (!bitmap_is_set(&dac->expr_deps, bitmap_offset + eq_no) ||
+ dac->equality_mods[eq_no].is_applicable()))
+ {
+ eq_no++;
+ }
+
+ if (eq_no < dac->n_equality_mods)
+ {
+ di->equality_no= eq_no+1;
+ return &dac->equality_mods[eq_no];
+ }
+ return NULL;
+}
+
+
+/*
+ Mark one table or the whole join nest as eliminated.
+*/
+
+static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl)
+{
+ TABLE *table;
+ /*
+ NOTE: there are TABLE_LIST object that have
+ tbl->table!= NULL && tbl->nested_join!=NULL and
+ tbl->table == tbl->nested_join->join_list->element(..)->table
+ */
+ if (tbl->nested_join)
+ {
+ TABLE_LIST *child;
+ List_iterator<TABLE_LIST> it(tbl->nested_join->join_list);
+ while ((child= it++))
+ mark_as_eliminated(join, child);
+ }
+ else if ((table= tbl->table))
+ {
+ JOIN_TAB *tab= tbl->table->reginfo.join_tab;
+ if (!(join->const_table_map & tab->table->map))
+ {
+ DBUG_PRINT("info", ("Eliminated table %s", table->alias));
+ tab->type= JT_CONST;
+ join->eliminated_tables |= table->map;
+ join->const_table_map|= table->map;
+ set_position(join, join->const_tables++, tab, (KEYUSE*)0);
+ }
+ }
+
+ if (tbl->on_expr)
+ tbl->on_expr->walk(&Item::mark_as_eliminated_processor, FALSE, NULL);
+}
+
+
+#ifndef DBUG_OFF
+/* purecov: begin inspected */
+void Dep_analysis_context::dbug_print_deps()
+{
+ DBUG_ENTER("dbug_print_deps");
+ DBUG_LOCK_FILE;
+
+ fprintf(DBUG_FILE,"deps {\n");
+
+ /* Start with printing equalities */
+ for (Dep_module_expr *eq_mod= equality_mods;
+ eq_mod != equality_mods + n_equality_mods; eq_mod++)
+ {
+ char buf[128];
+ String str(buf, sizeof(buf), &my_charset_bin);
+ str.length(0);
+ eq_mod->expr->print(&str, QT_ORDINARY);
+ if (eq_mod->field)
+ {
+ fprintf(DBUG_FILE, " equality%ld: %s -> %s.%s\n",
+ (long)(eq_mod - equality_mods),
+ str.c_ptr(),
+ eq_mod->field->table->table->alias,
+ eq_mod->field->field->field_name);
+ }
+ else
+ {
+ fprintf(DBUG_FILE, " equality%ld: multi-equality",
+ (long)(eq_mod - equality_mods));
+ }
+ }
+ fprintf(DBUG_FILE,"\n");
+
+ /* Then tables and their fields */
+ for (uint i=0; i < MAX_TABLES; i++)
+ {
+ Dep_value_table *table_dep;
+ if ((table_dep= table_deps[i]))
+ {
+ /* Print table */
+ fprintf(DBUG_FILE, " table %s\n", table_dep->table->alias);
+ /* Print fields */
+ for (Dep_value_field *field_dep= table_dep->fields; field_dep;
+ field_dep= field_dep->next_table_field)
+ {
+ fprintf(DBUG_FILE, " field %s.%s ->", table_dep->table->alias,
+ field_dep->field->field_name);
+ uint ofs= field_dep->bitmap_offset;
+ for (uint bit= ofs; bit < ofs + n_equality_mods; bit++)
+ {
+ if (bitmap_is_set(&expr_deps, bit))
+ fprintf(DBUG_FILE, " equality%d ", bit - ofs);
+ }
+ fprintf(DBUG_FILE, "\n");
+ }
+ }
+ }
+ fprintf(DBUG_FILE,"\n}\n");
+ DBUG_UNLOCK_FILE;
+ DBUG_VOID_RETURN;
+}
+/* purecov: end */
+
+#endif
+/**
+ @} (end of group Table_Elimination)
+*/
+
diff --git a/sql/parse_file.cc b/sql/parse_file.cc
index 91a9a31efb6..e5b2953e969 100644
--- a/sql/parse_file.cc
+++ b/sql/parse_file.cc
@@ -219,7 +219,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
File_option *param;
DBUG_ENTER("sql_create_definition_file");
DBUG_PRINT("enter", ("Dir: %s, file: %s, base 0x%lx",
- dir ? dir->str : "(null)",
+ dir ? dir->str : "",
file_name->str, (ulong) base));
if (dir)
diff --git a/sql/partition_element.h b/sql/partition_element.h
index 905bc38165b..a0e74a6830f 100644
--- a/sql/partition_element.h
+++ b/sql/partition_element.h
@@ -65,6 +65,7 @@ public:
char* data_file_name;
char* index_file_name;
handlerton *engine_type;
+ LEX_STRING connect_string;
enum partition_state part_state;
uint16 nodegroup_id;
bool has_null_value;
@@ -80,6 +81,8 @@ public:
nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE),
signed_flag(FALSE), max_value(FALSE)
{
+ connect_string.str= 0;
+ connect_string.length= 0;
}
partition_element(partition_element *part_elem)
: part_max_rows(part_elem->part_max_rows),
@@ -90,10 +93,13 @@ public:
data_file_name(part_elem->data_file_name),
index_file_name(part_elem->index_file_name),
engine_type(part_elem->engine_type),
+ connect_string(part_elem->connect_string),
part_state(part_elem->part_state),
nodegroup_id(part_elem->nodegroup_id),
has_null_value(FALSE)
{
+ connect_string.str= 0;
+ connect_string.length= 0;
}
~partition_element() {}
};
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 6f1f7adcaf9..f51d3fdf641 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/password.c b/sql/password.c
index e9e81fb7bf3..c8aa90aa56d 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -71,41 +71,12 @@
/*
New (MySQL 3.21+) random generation structure initialization
SYNOPSIS
- randominit()
+ my_rnd_init()
rand_st OUT Structure to initialize
seed1 IN First initialization parameter
seed2 IN Second initialization parameter
*/
-void randominit(struct rand_struct *rand_st, ulong seed1, ulong seed2)
-{ /* For mysql 3.21.# */
-#ifdef HAVE_purify
- bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
-#endif
- rand_st->max_value= 0x3FFFFFFFL;
- rand_st->max_value_dbl=(double) rand_st->max_value;
- rand_st->seed1=seed1%rand_st->max_value ;
- rand_st->seed2=seed2%rand_st->max_value;
-}
-
-
-/*
- Generate random number.
- SYNOPSIS
- my_rnd()
- rand_st INOUT Structure used for number generation
- RETURN VALUE
- generated pseudo random number
-*/
-
-double my_rnd(struct rand_struct *rand_st)
-{
- rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
- rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
- return (((double) rand_st->seed1)/rand_st->max_value_dbl);
-}
-
-
/*
Generate binary hash from raw text string
Used for Pre-4.1 password handling
@@ -185,7 +156,7 @@ void make_scrambled_password_323(char *to, const char *password)
void scramble_323(char *to, const char *message, const char *password)
{
- struct rand_struct rand_st;
+ struct my_rnd_struct rand_st;
ulong hash_pass[2], hash_message[2];
if (password && password[0])
@@ -194,7 +165,7 @@ void scramble_323(char *to, const char *message, const char *password)
const char *message_end= message + SCRAMBLE_LENGTH_323;
hash_password(hash_pass,password, (uint) strlen(password));
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
- randominit(&rand_st,hash_pass[0] ^ hash_message[0],
+ my_rnd_init(&rand_st,hash_pass[0] ^ hash_message[0],
hash_pass[1] ^ hash_message[1]);
for (; message < message_end; message++)
*to++= (char) (floor(my_rnd(&rand_st)*31)+64);
@@ -222,7 +193,7 @@ my_bool
check_scramble_323(const char *scrambled, const char *message,
ulong *hash_pass)
{
- struct rand_struct rand_st;
+ struct my_rnd_struct rand_st;
ulong hash_message[2];
/* Big enough for checks. */
char buff[16], scrambled_buff[SCRAMBLE_LENGTH_323 + 1];
@@ -235,7 +206,7 @@ check_scramble_323(const char *scrambled, const char *message,
scrambled= scrambled_buff;
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
- randominit(&rand_st,hash_pass[0] ^ hash_message[0],
+ my_rnd_init(&rand_st,hash_pass[0] ^ hash_message[0],
hash_pass[1] ^ hash_message[1]);
to=buff;
DBUG_ASSERT(sizeof(buff) > SCRAMBLE_LENGTH_323);
@@ -316,7 +287,8 @@ void make_password_from_salt_323(char *to, const ulong *salt)
rand_st INOUT structure used for number generation
*/
-void create_random_string(char *to, uint length, struct rand_struct *rand_st)
+void create_random_string(char *to, uint length,
+ struct my_rnd_struct *rand_st)
{
char *end= to + length;
/* Use pointer arithmetics as it is faster way to do so. */
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 8b652fe855a..055c166f5a5 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -59,6 +60,65 @@ bool Protocol_binary::net_store_data(const uchar *from, size_t length)
}
+/*
+ net_store_data() - extended version with character set conversion.
+
+ It is optimized for short strings whose length after
+ conversion is garanteed to be less than 251, which accupies
+ exactly one byte to store length. It allows not to use
+ the "convert" member as a temporary buffer, conversion
+ is done directly to the "packet" member.
+ The limit 251 is good enough to optimize send_fields()
+ because column, table, database names fit into this limit.
+*/
+
+#ifndef EMBEDDED_LIBRARY
+bool Protocol::net_store_data(const uchar *from, size_t length,
+ CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
+{
+ uint dummy_errors;
+ /* Calculate maxumum possible result length */
+ size_t conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
+ ulong packet_length, new_length;
+ char *length_pos, *to;
+
+ if (conv_length > 250)
+ {
+ /*
+ For strings with conv_length greater than 250 bytes
+ we don't know how many bytes we will need to store length: one or two,
+ because we don't know result length until conversion is done.
+ For example, when converting from utf8 (mbmaxlen=3) to latin1,
+ conv_length=300 means that the result length can vary between 100 to 300.
+ length=100 needs one byte, length=300 needs to bytes.
+
+ Thus conversion directly to "packet" is not worthy.
+ Let's use "convert" as a temporary buffer.
+ */
+ return (convert->copy((const char*) from, length, from_cs, to_cs,
+ &dummy_errors) ||
+ net_store_data((const uchar*) convert->ptr(), convert->length()));
+ }
+
+ packet_length= packet->length();
+ new_length= packet_length + conv_length + 1;
+
+ if (new_length > packet->alloced_length() && packet->realloc(new_length))
+ return 1;
+
+ length_pos= (char*) packet->ptr() + packet_length;
+ to= length_pos + 1;
+
+ to+= copy_and_convert(to, conv_length, to_cs,
+ (const char*) from, length, from_cs, &dummy_errors);
+
+ net_store_length((uchar*) length_pos, to - length_pos - 1);
+ packet->length((uint) (to - packet->ptr()));
+ return 0;
+}
+#endif
+
+
/**
Send a error string to client.
@@ -145,7 +205,7 @@ net_send_ok(THD *thd,
NET *net= &thd->net;
uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
bool error= FALSE;
- DBUG_ENTER("my_ok");
+ DBUG_ENTER("net_send_ok");
if (! net->vio) // hack for re-parsing queries
{
@@ -431,6 +491,7 @@ static uchar *net_store_length_fast(uchar *packet, uint length)
void net_end_statement(THD *thd)
{
+ DBUG_ENTER("net_end_statement");
DBUG_ASSERT(! thd->main_da.is_sent);
/* Can not be true, but do not take chances in production. */
@@ -470,6 +531,7 @@ void net_end_statement(THD *thd)
}
if (!error)
thd->main_da.is_sent= TRUE;
+ DBUG_VOID_RETURN;
}
@@ -528,7 +590,8 @@ void Protocol::init(THD *thd_arg)
void Protocol::end_partial_result_set(THD *thd_arg)
{
- net_send_eof(thd_arg, thd_arg->server_status, 0 /* no warnings, we're inside SP */);
+ net_send_eof(thd_arg, thd_arg->server_status,
+ 0 /* no warnings, we're inside SP */);
}
@@ -828,10 +891,10 @@ bool Protocol::store_string_aux(const char *from, size_t length,
fromcs != &my_charset_bin &&
tocs != &my_charset_bin)
{
- uint dummy_errors;
- return (convert->copy(from, length, fromcs, tocs, &dummy_errors) ||
- net_store_data((uchar*) convert->ptr(), convert->length()));
+ /* Store with conversion */
+ return net_store_data((uchar*) from, length, fromcs, tocs);
}
+ /* Store without conversion */
return net_store_data((uchar*) from, length);
}
@@ -1011,12 +1074,16 @@ bool Protocol_text::store(MYSQL_TIME *tm)
#endif
char buff[40];
uint length;
- length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
- (int) tm->year, (int) tm->month,
- (int) tm->day, (int) tm->hour,
- (int) tm->minute, (int) tm->second);
+ length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d",
+ (int) tm->year,
+ (int) tm->month,
+ (int) tm->day,
+ (int) tm->hour,
+ (int) tm->minute,
+ (int) tm->second));
if (tm->second_part)
- length+= sprintf(buff+length, ".%06d", (int) tm->second_part);
+ length+= my_sprintf(buff+length,(buff+length, ".%06d",
+ (int)tm->second_part));
return net_store_data((uchar*) buff, length);
}
@@ -1050,11 +1117,13 @@ bool Protocol_text::store_time(MYSQL_TIME *tm)
char buff[40];
uint length;
uint day= (tm->year || tm->month) ? 0 : tm->day;
- length= sprintf(buff, "%s%02ld:%02d:%02d", tm->neg ? "-" : "",
- (long) day*24L+(long) tm->hour, (int) tm->minute,
- (int) tm->second);
+ length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d",
+ tm->neg ? "-" : "",
+ (long) day*24L+(long) tm->hour,
+ (int) tm->minute,
+ (int) tm->second));
if (tm->second_part)
- length+= sprintf(buff+length, ".%06d", (int) tm->second_part);
+ length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part));
return net_store_data((uchar*) buff, length);
}
diff --git a/sql/protocol.h b/sql/protocol.h
index 1a649a252e5..5d49aa28112 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -45,6 +45,8 @@ protected:
MYSQL_FIELD *next_mysql_field;
MEM_ROOT *alloc;
#endif
+ bool net_store_data(const uchar *from, size_t length,
+ CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
bool store_string_aux(const char *from, size_t length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs);
public:
diff --git a/sql/records.cc b/sql/records.cc
index e275db83c93..181afbad400 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -196,18 +196,10 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
if (select && my_b_inited(&select->file))
tempfile= &select->file;
- else if (select && select->quick && select->quick->clustered_pk_range())
- {
- /*
- In case of QUICK_INDEX_MERGE_SELECT with clustered pk range we have to
- use its own access method(i.e QUICK_INDEX_MERGE_SELECT::get_next()) as
- sort file does not contain rowids which satisfy clustered pk range.
- */
- tempfile= 0;
- }
else
tempfile= table->sort.io_cache;
- if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
+ if (tempfile && my_b_inited(tempfile) &&
+ !(select && select->quick))
{
DBUG_PRINT("info",("using rr_from_tempfile"));
info->read_record= (table->sort.addon_field ?
@@ -530,7 +522,7 @@ static int init_rr_cache(THD *thd, READ_RECORD *info)
info->struct_length+1,
MYF(0))))
DBUG_RETURN(1);
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
// Avoid warnings in qsort
bzero(info->cache,rec_cache_size+info->cache_records* info->struct_length+1);
#endif
@@ -631,7 +623,7 @@ static int rr_cmp(uchar *a,uchar *b)
if (a[4] != b[4])
return (int) a[4] - (int) b[4];
if (a[5] != b[5])
- return (int) a[1] - (int) b[5];
+ return (int) a[5] - (int) b[5];
if (a[6] != b[6])
return (int) a[6] - (int) b[6];
return (int) a[7] - (int) b[7];
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 71bb2d9c9ac..374ef77c297 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2001, 2010, Oracle and/or its affiliates.
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
@@ -1038,5 +1038,10 @@ err:
return error;
}
+#elif defined(__WIN__)
+
+// Remove linker warning 4221 about empty file
+namespace { char dummy; };
+
#endif /* HAVE_REPLICATION */
diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc
index 3d38c243a0a..585334433df 100644
--- a/sql/rpl_filter.cc
+++ b/sql/rpl_filter.cc
@@ -94,7 +94,7 @@ Rpl_filter::tables_ok(const char* db, TABLE_LIST* tables)
for (; tables; tables= tables->next_global)
{
- char hash_key[2*NAME_LEN+2];
+ char hash_key[SAFE_NAME_LEN*2+2];
char *end;
uint len;
@@ -158,8 +158,10 @@ Rpl_filter::db_ok(const char* db)
and db was not selected, do not replicate.
*/
if (!db)
+ {
+ DBUG_PRINT("exit", ("Don't replicate"));
DBUG_RETURN(0);
-
+ }
if (!do_db.is_empty()) // if the do's are not empty
{
I_List_iterator<i_string> it(do_db);
@@ -170,6 +172,7 @@ Rpl_filter::db_ok(const char* db)
if (!strcmp(tmp->ptr, db))
DBUG_RETURN(1); // match
}
+ DBUG_PRINT("exit", ("Don't replicate"));
DBUG_RETURN(0);
}
else // there are some elements in the don't, otherwise we cannot get here
@@ -180,7 +183,10 @@ Rpl_filter::db_ok(const char* db)
while ((tmp=it++))
{
if (!strcmp(tmp->ptr, db))
+ {
+ DBUG_PRINT("exit", ("Don't replicate"));
DBUG_RETURN(0); // match
+ }
}
DBUG_RETURN(1);
}
@@ -222,7 +228,7 @@ Rpl_filter::db_ok_with_wild_table(const char *db)
{
DBUG_ENTER("Rpl_filter::db_ok_with_wild_table");
- char hash_key[NAME_LEN+2];
+ char hash_key[SAFE_NAME_LEN+2];
char *end;
int len;
end= strmov(hash_key, db);
diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc
index 060975c90f3..b84cfe413a6 100644
--- a/sql/rpl_injector.cc
+++ b/sql/rpl_injector.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
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
@@ -37,6 +37,7 @@ injector::transaction::transaction(MYSQL_BIN_LOG *log, THD *thd)
m_start_pos.m_file_name= my_strdup(log_info.log_file_name, MYF(0));
m_start_pos.m_file_pos= log_info.pos;
+ m_thd->lex->start_transaction_opt= 0; /* for begin_trans() */
begin_trans(m_thd);
thd->set_current_stmt_binlog_row_based();
diff --git a/sql/rpl_injector.h b/sql/rpl_injector.h
index 4ece092c5b8..a31ff31a44f 100644
--- a/sql/rpl_injector.h
+++ b/sql/rpl_injector.h
@@ -290,7 +290,7 @@ public:
"START_STATE", "TABLE_STATE", "ROW_STATE", "STATE_COUNT"
};
- DBUG_ASSERT(0 <= target_state && target_state <= STATE_COUNT);
+ DBUG_ASSERT(target_state <= STATE_COUNT);
DBUG_PRINT("info", ("In state %s", state_name[m_state]));
#endif
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index b4c974aed3a..7011f59adf0 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
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
@@ -24,11 +24,6 @@
#ifdef HAVE_REPLICATION
-// Defined in slave.cc
-int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
-int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
- const char *default_val);
-
Master_info::Master_info()
:Slave_reporting_capability("I/O"),
ssl(0), ssl_verify_server_cert(0), fd(-1), io_thd(0), inited(0),
@@ -40,11 +35,26 @@ Master_info::Master_info()
ssl_cipher[0]= 0; ssl_key[0]= 0;
bzero((char*) &file, sizeof(file));
- pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
+ /*
+ We have to use MYF_NO_DEADLOCK_DETECTION because mysqld doesn't
+ lock run_lock and data_lock consistently.
+ Should be fixed as this can easily lead to deadlocks
+ */
+ my_pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST,
+ "Master_info::run_lock", MYF_NO_DEADLOCK_DETECTION);
+ my_pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST,
+ "Master_info::data_lock", MYF_NO_DEADLOCK_DETECTION);
pthread_cond_init(&data_cond, NULL);
pthread_cond_init(&start_cond, NULL);
pthread_cond_init(&stop_cond, NULL);
+
+#ifdef SAFE_MUTEX
+ /* Define mutex order for locks to find wrong lock usage */
+ pthread_mutex_lock(&data_lock);
+ pthread_mutex_lock(&run_lock);
+ pthread_mutex_unlock(&run_lock);
+ pthread_mutex_unlock(&data_lock);
+#endif
}
Master_info::~Master_info()
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 5e356589b3d..47b528001dc 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index f9390007bd9..5a33b62538b 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -79,7 +80,7 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
unsigned int null_mask= 1U;
for ( ; (field= *p_field) ; p_field++)
{
- DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d",
+ DBUG_PRINT("debug", ("null_mask: %d null_ptr: %p row_data: %p null_byte_count: %d",
null_mask, null_ptr, row_data, null_byte_count));
if (bitmap_is_set(cols, p_field - table->field))
{
diff --git a/sql/rpl_record.h b/sql/rpl_record.h
index 189f389411f..6005d57daf3 100644
--- a/sql/rpl_record.h
+++ b/sql/rpl_record.h
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_record_old.h b/sql/rpl_record_old.h
index bdaedd56741..300c9d9a1a6 100644
--- a/sql/rpl_record_old.h
+++ b/sql/rpl_record_old.h
@@ -1,4 +1,4 @@
-/* Copyright 2007 MySQL AB. All rights reserved.
+/* Copyright 2007 MySQL AB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 6fe4cbd4ea6..b56cef3913f 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
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
@@ -25,18 +25,13 @@
static int count_relay_log_space(Relay_log_info* rli);
-// Defined in slave.cc
-int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
-int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
- const char *default_val);
-
Relay_log_info::Relay_log_info()
:Slave_reporting_capability("SQL"),
no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id),
info_fd(-1), cur_log_fd(-1), save_temporary_tables(0),
cur_log_old_open_count(0), group_relay_log_pos(0), event_relay_log_pos(0),
-#if HAVE_purify
+#if HAVE_valgrind
is_fake(FALSE),
#endif
group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0),
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index ae8639c69ac..0fd07901fdf 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
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
@@ -166,7 +166,7 @@ public:
ulonglong event_relay_log_pos;
ulonglong future_event_relay_log_pos;
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
bool is_fake; /* Mark that this is a fake relay log info structure */
#endif
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index 46c93f7cd20..d304d5fbd6a 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h
index 4036a41bc60..701b9f3c5de 100644
--- a/sql/rpl_utility.h
+++ b/sql/rpl_utility.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/scheduler.cc b/sql/scheduler.cc
index b05bdf4756f..5b8f834aecc 100644
--- a/sql/scheduler.cc
+++ b/sql/scheduler.cc
@@ -22,6 +22,9 @@
#endif
#include <mysql_priv.h>
+#if MYSQL_VERSION_ID >= 60000
+#include "sql_audit.h"
+#endif
/*
'Dummy' functions to be used when we don't need any handling for a scheduler
@@ -29,7 +32,7 @@
*/
static bool init_dummy(void) {return 0;}
-static void post_kill_dummy(THD* thd) {}
+static void post_kill_dummy(THD *thd) {}
static void end_dummy(void) {}
static bool end_thread_dummy(THD *thd, bool cache_thread) { return 0; }
@@ -63,9 +66,12 @@ static bool no_threads_end(THD *thd, bool put_in_cache)
Initailize scheduler for --thread-handling=no-threads
*/
-void one_thread_scheduler(scheduler_functions* func)
+void one_thread_scheduler(scheduler_functions *func)
{
func->max_threads= 1;
+ max_connections= 1;
+ func->max_connections= &max_connections;
+ func->connection_count= &connection_count;
#ifndef EMBEDDED_LIBRARY
func->add_connection= handle_connection_in_main_thread;
#endif
@@ -79,10 +85,672 @@ void one_thread_scheduler(scheduler_functions* func)
*/
#ifndef EMBEDDED_LIBRARY
-void one_thread_per_connection_scheduler(scheduler_functions* func)
+void one_thread_per_connection_scheduler(scheduler_functions *func,
+ ulong *arg_max_connections,
+ uint *arg_connection_count)
{
- func->max_threads= max_connections;
+ func->max_threads= *arg_max_connections + 1;
+ func->max_connections= arg_max_connections;
+ func->connection_count= arg_connection_count;
func->add_connection= create_thread_to_handle_connection;
func->end_thread= one_thread_per_connection_end;
}
#endif /* EMBEDDED_LIBRARY */
+
+
+#if defined(HAVE_LIBEVENT) && HAVE_POOL_OF_THREADS == 1
+
+#include "event.h"
+
+static struct event_base *base;
+
+static uint created_threads, killed_threads;
+static bool kill_pool_threads;
+
+static struct event thd_add_event;
+static struct event thd_kill_event;
+
+static pthread_mutex_t LOCK_thd_add; /* protects thds_need_adding */
+static LIST *thds_need_adding; /* list of thds to add to libevent queue */
+
+static int thd_add_pair[2]; /* pipe to signal add a connection to libevent*/
+static int thd_kill_pair[2]; /* pipe to signal kill a connection in libevent */
+
+/*
+ LOCK_event_loop protects the non-thread safe libevent calls (event_add and
+ event_del) and thds_need_processing and thds_waiting_for_io.
+*/
+static pthread_mutex_t LOCK_event_loop;
+static LIST *thds_need_processing; /* list of thds that needs some processing */
+static LIST *thds_waiting_for_io; /* list of thds with added events */
+
+pthread_handler_t libevent_thread_proc(void *arg);
+static void libevent_end();
+static bool libevent_needs_immediate_processing(THD *thd);
+static void libevent_connection_close(THD *thd);
+static bool libevent_should_close_connection(THD* thd);
+static void libevent_thd_add(THD* thd);
+void libevent_io_callback(int Fd, short Operation, void *ctx);
+void libevent_add_thd_callback(int Fd, short Operation, void *ctx);
+void libevent_kill_thd_callback(int Fd, short Operation, void *ctx);
+
+
+/*
+ Create a pipe and set to non-blocking.
+ Returns TRUE if there is an error.
+*/
+
+static bool init_socketpair(int sock_pair[])
+{
+ sock_pair[0]= sock_pair[1]= -1;
+ return (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, sock_pair) < 0 ||
+ evutil_make_socket_nonblocking(sock_pair[0]) == -1 ||
+ evutil_make_socket_nonblocking(sock_pair[1]) == -1);
+}
+
+static void close_socketpair(int sock_pair[])
+{
+ if (sock_pair[0] != -1)
+ EVUTIL_CLOSESOCKET(sock_pair[0]);
+ if (sock_pair[1] != -1)
+ EVUTIL_CLOSESOCKET(sock_pair[1]);
+}
+
+/*
+ thd_scheduler keeps the link between THD and events.
+ It's embedded in the THD class.
+*/
+
+thd_scheduler::thd_scheduler()
+ : logged_in(FALSE), io_event(NULL), thread_attached(FALSE)
+{
+#ifndef DBUG_OFF
+ dbug_explain[0]= '\0';
+ set_explain= FALSE;
+#endif
+}
+
+
+thd_scheduler::~thd_scheduler()
+{
+ my_free(io_event, MYF(MY_ALLOW_ZERO_PTR));
+}
+
+
+bool thd_scheduler::init(THD *parent_thd)
+{
+ io_event=
+ (struct event*)my_malloc(sizeof(*io_event),MYF(MY_ZEROFILL|MY_WME));
+
+ if (!io_event)
+ {
+ sql_print_error("Memory allocation error in thd_scheduler::init\n");
+ return TRUE;
+ }
+
+ event_set(io_event, (int)parent_thd->net.vio->sd, EV_READ,
+ libevent_io_callback, (void*)parent_thd);
+
+ list.data= parent_thd;
+
+ return FALSE;
+}
+
+
+/*
+ Attach/associate the connection with the OS thread, for command processing.
+*/
+
+bool thd_scheduler::thread_attach()
+{
+ DBUG_ASSERT(!thread_attached);
+ THD* thd = (THD*)list.data;
+ if (libevent_should_close_connection(thd) ||
+ setup_connection_thread_globals(thd))
+ {
+ return TRUE;
+ }
+ my_errno= 0;
+ thd->mysys_var->abort= 0;
+ thread_attached= TRUE;
+#ifndef DBUG_OFF
+ /*
+ When we attach the thread for a connection for the first time,
+ we know that there is no session value set yet. Thus
+ the initial setting of set_explain to FALSE is OK.
+ */
+ if (set_explain)
+ DBUG_SET(dbug_explain);
+#endif
+ return FALSE;
+}
+
+
+/*
+ Detach/disassociate the connection with the OS thread.
+*/
+
+void thd_scheduler::thread_detach()
+{
+ if (thread_attached)
+ {
+ THD* thd = (THD*)list.data;
+ thd->reset_globals();
+ thread_attached= FALSE;
+#ifndef DBUG_OFF
+ /*
+ If during the session @@session.dbug was assigned, the
+ dbug options/state has been pushed. Check if this is the
+ case, to be able to restore the state when we attach this
+ logical connection to a physical thread.
+ */
+ if (_db_is_pushed_())
+ {
+ set_explain= TRUE;
+ if (DBUG_EXPLAIN(dbug_explain, sizeof(dbug_explain)))
+ sql_print_error("thd_scheduler: DBUG_EXPLAIN buffer is too small");
+ }
+ /* DBUG_POP() is a no-op in case there is no session state */
+ DBUG_POP();
+#endif
+ }
+}
+
+/**
+ Create all threads for the thread pool
+
+ NOTES
+ After threads are created we wait until all threads has signaled that
+ they have started before we return
+
+ RETURN
+ 0 ok
+ 1 We got an error creating the thread pool
+ In this case we will abort all created threads
+*/
+
+static bool libevent_init(void)
+{
+ uint i;
+ DBUG_ENTER("libevent_init");
+
+ base= (struct event_base *) event_init();
+
+ created_threads= 0;
+ killed_threads= 0;
+ kill_pool_threads= FALSE;
+
+ pthread_mutex_init(&LOCK_event_loop, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&LOCK_thd_add, MY_MUTEX_INIT_FAST);
+
+ /* set up sockets used to add new thds to the event pool */
+ if (init_socketpair(thd_add_pair))
+ {
+ sql_print_error("init_socketpair(thd_add_spair) error in libevent_init");
+ DBUG_RETURN(1);
+ }
+ /* set up sockets used to kill thds in the event queue */
+ if (init_socketpair(thd_kill_pair))
+ {
+ sql_print_error("init_socketpair(thd_kill_pair) error in libevent_init");
+ close_socketpair(thd_add_pair);
+ DBUG_RETURN(1);
+ }
+ event_set(&thd_add_event, thd_add_pair[0], EV_READ|EV_PERSIST,
+ libevent_add_thd_callback, NULL);
+ event_set(&thd_kill_event, thd_kill_pair[0], EV_READ|EV_PERSIST,
+ libevent_kill_thd_callback, NULL);
+
+ if (event_add(&thd_add_event, NULL) || event_add(&thd_kill_event, NULL))
+ {
+ sql_print_error("thd_add_event event_add error in libevent_init");
+ libevent_end();
+ DBUG_RETURN(1);
+ }
+ /* Set up the thread pool */
+ created_threads= killed_threads= 0;
+ pthread_mutex_lock(&LOCK_thread_count);
+
+ for (i= 0; i < thread_pool_size; i++)
+ {
+ pthread_t thread;
+ int error;
+ if ((error= pthread_create(&thread, &connection_attrib,
+ libevent_thread_proc, 0)))
+ {
+ sql_print_error("Can't create completion port thread (error %d)",
+ error);
+ pthread_mutex_unlock(&LOCK_thread_count);
+ libevent_end(); // Cleanup
+ DBUG_RETURN(TRUE);
+ }
+ }
+
+ /* Wait until all threads are created */
+ while (created_threads != thread_pool_size)
+ pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
+ pthread_mutex_unlock(&LOCK_thread_count);
+
+ DBUG_PRINT("info", ("%u threads created", (uint) thread_pool_size));
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ This is called when data is ready on the socket.
+
+ NOTES
+ This is only called by the thread that owns LOCK_event_loop.
+
+ We add the thd that got the data to thds_need_processing, and
+ cause the libevent event_loop() to terminate. Then this same thread will
+ return from event_loop and pick the thd value back up for processing.
+*/
+
+void libevent_io_callback(int, short, void *ctx)
+{
+ safe_mutex_assert_owner(&LOCK_event_loop);
+ THD *thd= (THD*)ctx;
+ thds_waiting_for_io= list_delete(thds_waiting_for_io, &thd->event_scheduler.list);
+ thds_need_processing= list_add(thds_need_processing, &thd->event_scheduler.list);
+}
+
+/*
+ This is called when we have a thread we want to be killed.
+
+ NOTES
+ This is only called by the thread that owns LOCK_event_loop.
+*/
+
+void libevent_kill_thd_callback(int Fd, short, void*)
+{
+ safe_mutex_assert_owner(&LOCK_event_loop);
+
+ /* clear the pending events */
+ char c;
+ while (recv(Fd, &c, sizeof(c), 0) == sizeof(c))
+ {}
+
+ LIST* list= thds_waiting_for_io;
+ while (list)
+ {
+ THD *thd= (THD*)list->data;
+ list= list_rest(list);
+ if (thd->killed == THD::KILL_CONNECTION)
+ {
+ /*
+ Delete from libevent and add to the processing queue.
+ */
+ event_del(thd->event_scheduler.io_event);
+ thds_waiting_for_io= list_delete(thds_waiting_for_io,
+ &thd->event_scheduler.list);
+ thds_need_processing= list_add(thds_need_processing,
+ &thd->event_scheduler.list);
+ }
+ }
+}
+
+
+/*
+ This is used to add connections to the pool. This callback is invoked from
+ the libevent event_loop() call whenever the thd_add_pair[1] has a byte
+ written to it.
+
+ NOTES
+ This is only called by the thread that owns LOCK_event_loop.
+*/
+
+void libevent_add_thd_callback(int Fd, short, void *)
+{
+ safe_mutex_assert_owner(&LOCK_event_loop);
+
+ /* clear the pending events */
+ char c;
+ while (recv(Fd, &c, sizeof(c), 0) == sizeof(c))
+ {}
+
+ pthread_mutex_lock(&LOCK_thd_add);
+ while (thds_need_adding)
+ {
+ /* pop the first thd off the list */
+ THD* thd= (THD*)thds_need_adding->data;
+ thds_need_adding= list_delete(thds_need_adding, thds_need_adding);
+
+ pthread_mutex_unlock(&LOCK_thd_add);
+
+ if (!thd->event_scheduler.logged_in || libevent_should_close_connection(thd))
+ {
+ /*
+ Add thd to thds_need_processing list. If it needs closing we'll close
+ it outside of event_loop().
+ */
+ thds_need_processing= list_add(thds_need_processing,
+ &thd->event_scheduler.list);
+ }
+ else
+ {
+ /* Add to libevent */
+ if (event_add(thd->event_scheduler.io_event, NULL))
+ {
+ sql_print_error("event_add error in libevent_add_thd_callback");
+ libevent_connection_close(thd);
+ }
+ else
+ {
+ thds_waiting_for_io= list_add(thds_waiting_for_io,
+ &thd->event_scheduler.list);
+ }
+ }
+ pthread_mutex_lock(&LOCK_thd_add);
+ }
+ pthread_mutex_unlock(&LOCK_thd_add);
+}
+
+
+/**
+ Notify the thread pool about a new connection
+
+ NOTES
+ LOCK_thread_count is locked on entry. This function MUST unlock it!
+*/
+
+static void libevent_add_connection(THD *thd)
+{
+ DBUG_ENTER("libevent_add_connection");
+ DBUG_PRINT("enter", ("thd: %p thread_id: %lu",
+ thd, thd->thread_id));
+
+ if (thd->event_scheduler.init(thd))
+ {
+ sql_print_error("Scheduler init error in libevent_add_new_connection");
+ pthread_mutex_unlock(&LOCK_thread_count);
+ libevent_connection_close(thd);
+ DBUG_VOID_RETURN;
+ }
+ threads.append(thd);
+ libevent_thd_add(thd);
+
+ pthread_mutex_unlock(&LOCK_thread_count);
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ @brief Signal a waiting connection it's time to die.
+
+ @details This function will signal libevent the THD should be killed.
+ Either the global LOCK_thd_count or the THD's LOCK_thd_data must be locked
+ upon entry.
+
+ @param[in] thd The connection to kill
+*/
+
+static void libevent_post_kill_notification(THD *)
+{
+ /*
+ Note, we just wake up libevent with an event that a THD should be killed,
+ It will search its list of thds for thd->killed == KILL_CONNECTION to
+ find the THDs it should kill.
+
+ So we don't actually tell it which one and we don't actually use the
+ THD being passed to us, but that's just a design detail that could change
+ later.
+ */
+ char c= 0;
+ send(thd_kill_pair[1], &c, sizeof(c), 0);
+}
+
+
+/*
+ Close and delete a connection.
+*/
+
+static void libevent_connection_close(THD *thd)
+{
+ DBUG_ENTER("libevent_connection_close");
+ DBUG_PRINT("enter", ("thd: %p", thd));
+
+ thd->killed= THD::KILL_CONNECTION; // Avoid error messages
+
+ if (thd->net.vio->sd >= 0) // not already closed
+ {
+ end_connection(thd);
+ close_connection(thd, 0, 1);
+ }
+ thd->event_scheduler.thread_detach();
+ unlink_thd(thd); /* locks LOCK_thread_count and deletes thd */
+ pthread_mutex_unlock(&LOCK_thread_count);
+
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Returns true if we should close and delete a THD connection.
+*/
+
+static bool libevent_should_close_connection(THD* thd)
+{
+ return thd->net.error ||
+ thd->net.vio == 0 ||
+ thd->killed == THD::KILL_CONNECTION;
+}
+
+
+/*
+ libevent_thread_proc is the outer loop of each thread in the thread pool.
+ These procs only return/terminate on shutdown (kill_pool_threads == true).
+*/
+
+pthread_handler_t libevent_thread_proc(void *arg)
+{
+ if (init_new_connection_handler_thread())
+ {
+ my_thread_global_end();
+ sql_print_error("libevent_thread_proc: my_thread_init() failed");
+ exit(1);
+ }
+ DBUG_ENTER("libevent_thread_proc");
+
+ /*
+ Signal libevent_init() when all threads has been created and are ready to
+ receive events.
+ */
+ (void) pthread_mutex_lock(&LOCK_thread_count);
+ created_threads++;
+ thread_created++;
+ if (created_threads == thread_pool_size)
+ (void) pthread_cond_signal(&COND_thread_count);
+ (void) pthread_mutex_unlock(&LOCK_thread_count);
+
+ for (;;)
+ {
+ THD *thd= NULL;
+ (void) pthread_mutex_lock(&LOCK_event_loop);
+
+ /* get thd(s) to process */
+ while (!thds_need_processing)
+ {
+ if (kill_pool_threads)
+ {
+ /* the flag that we should die has been set */
+ (void) pthread_mutex_unlock(&LOCK_event_loop);
+ goto thread_exit;
+ }
+ event_loop(EVLOOP_ONCE);
+ }
+
+ /* pop the first thd off the list */
+ thd= (THD*)thds_need_processing->data;
+ thds_need_processing= list_delete(thds_need_processing,
+ thds_need_processing);
+
+ (void) pthread_mutex_unlock(&LOCK_event_loop);
+
+ /* now we process the connection (thd) */
+
+ /* set up the thd<->thread links. */
+ thd->thread_stack= (char*) &thd;
+
+ if (thd->event_scheduler.thread_attach())
+ {
+ libevent_connection_close(thd);
+ continue;
+ }
+
+ /* is the connection logged in yet? */
+ if (!thd->event_scheduler.logged_in)
+ {
+ DBUG_PRINT("info", ("init new connection. sd: %d",
+ thd->net.vio->sd));
+ lex_start(thd);
+ if (login_connection(thd))
+ {
+ /* Failed to log in */
+ libevent_connection_close(thd);
+ continue;
+ }
+ else
+ {
+ /* login successful */
+#if MYSQL_VERSION_ID >= 60000
+ MYSQL_CONNECTION_START(thd->thread_id, thd->security_ctx->priv_user,
+ (char *) thd->security_ctx->host_or_ip);
+#endif
+ thd->event_scheduler.logged_in= TRUE;
+ prepare_new_connection_state(thd);
+ if (!libevent_needs_immediate_processing(thd))
+ continue; /* New connection is now waiting for data in libevent*/
+ }
+ }
+
+ do
+ {
+ /* Process a query */
+ if (do_command(thd))
+ {
+ libevent_connection_close(thd);
+ break;
+ }
+ } while (libevent_needs_immediate_processing(thd));
+ }
+
+thread_exit:
+ DBUG_PRINT("exit", ("ending thread"));
+ (void) pthread_mutex_lock(&LOCK_thread_count);
+ killed_threads++;
+ pthread_cond_broadcast(&COND_thread_count);
+ (void) pthread_mutex_unlock(&LOCK_thread_count);
+ my_thread_end();
+ pthread_exit(0);
+ DBUG_RETURN(0); /* purify: deadcode */
+}
+
+
+/*
+ Returns TRUE if the connection needs immediate processing and FALSE if
+ instead it's queued for libevent processing or closed,
+*/
+
+static bool libevent_needs_immediate_processing(THD *thd)
+{
+ if (libevent_should_close_connection(thd))
+ {
+ libevent_connection_close(thd);
+ return FALSE;
+ }
+ /*
+ If more data in the socket buffer, return TRUE to process another command.
+
+ Note: we cannot add for event processing because the whole request might
+ already be buffered and we wouldn't receive an event.
+ */
+ if (vio_pending(thd->net.vio) > 0)
+ return TRUE;
+
+ thd->event_scheduler.thread_detach();
+ libevent_thd_add(thd);
+ return FALSE;
+}
+
+
+/*
+ Adds a THD to queued for libevent processing.
+
+ This call does not actually register the event with libevent.
+ Instead, it places the THD onto a queue and signals libevent by writing
+ a byte into thd_add_pair, which will cause our libevent_add_thd_callback to
+ be invoked which will find the THD on the queue and add it to libevent.
+*/
+
+static void libevent_thd_add(THD* thd)
+{
+ char c= 0;
+ /* release any audit resources, this thd is going to sleep */
+#if MYSQL_VERSION_ID >= 60000
+ mysql_audit_release(thd);
+#endif
+ pthread_mutex_lock(&LOCK_thd_add);
+ /* queue for libevent */
+ thds_need_adding= list_add(thds_need_adding, &thd->event_scheduler.list);
+ /* notify libevent */
+ send(thd_add_pair[1], &c, sizeof(c), 0);
+ pthread_mutex_unlock(&LOCK_thd_add);
+}
+
+
+/**
+ Wait until all pool threads have been deleted for clean shutdown
+*/
+
+static void libevent_end()
+{
+ DBUG_ENTER("libevent_end");
+ DBUG_PRINT("enter", ("created_threads: %d killed_threads: %u",
+ created_threads, killed_threads));
+
+ /*
+ check if initialized. This may not be the case if get an error at
+ startup
+ */
+ if (!base)
+ DBUG_VOID_RETURN;
+
+ (void) pthread_mutex_lock(&LOCK_thread_count);
+
+
+ kill_pool_threads= TRUE;
+ while (killed_threads != created_threads)
+ {
+ /* wake up the event loop */
+ char c= 0;
+ send(thd_add_pair[1], &c, sizeof(c), 0);
+ pthread_cond_wait(&COND_thread_count, &LOCK_thread_count);
+ }
+ (void) pthread_mutex_unlock(&LOCK_thread_count);
+
+ event_del(&thd_add_event);
+ close_socketpair(thd_add_pair);
+ event_del(&thd_kill_event);
+ close_socketpair(thd_kill_pair);
+ event_base_free(base);
+ base= 0;
+
+ (void) pthread_mutex_destroy(&LOCK_event_loop);
+ (void) pthread_mutex_destroy(&LOCK_thd_add);
+ DBUG_VOID_RETURN;
+}
+
+
+void pool_of_threads_scheduler(scheduler_functions* func)
+{
+ func->max_threads= thread_pool_size;
+ func->max_connections= &max_connections;
+ func->connection_count= &connection_count;
+ func->init= libevent_init;
+ func->end= libevent_end;
+ func->post_kill_notification= libevent_post_kill_notification;
+ func->add_connection= libevent_add_connection;
+}
+
+#endif
diff --git a/sql/scheduler.h b/sql/scheduler.h
index 46bbd300cbb..501fdd87bbf 100644
--- a/sql/scheduler.h
+++ b/sql/scheduler.h
@@ -28,7 +28,8 @@ class THD;
class scheduler_functions
{
public:
- uint max_threads;
+ uint max_threads, *connection_count;
+ ulong *max_connections;
bool (*init)(void);
bool (*init_new_connection_thread)(void);
void (*add_connection)(THD *thd);
@@ -45,16 +46,47 @@ enum scheduler_types
SCHEDULER_POOL_OF_THREADS
};
-void one_thread_per_connection_scheduler(scheduler_functions* func);
+void one_thread_per_connection_scheduler(scheduler_functions *func,
+ ulong *arg_max_connections,
+ uint *arg_connection_count);
void one_thread_scheduler(scheduler_functions* func);
-enum pool_command_op
+#if defined(HAVE_LIBEVENT) && !defined(EMBEDDED_LIBRARY)
+
+#define HAVE_POOL_OF_THREADS 1
+
+struct event;
+
+class thd_scheduler
{
- NOT_IN_USE_OP= 0, NORMAL_OP= 1, CONNECT_OP, KILL_OP, DIE_OP
+public:
+ bool logged_in;
+ struct event* io_event;
+ LIST list;
+ bool thread_attached; /* Indicates if THD is attached to the OS thread */
+
+#ifndef DBUG_OFF
+ char dbug_explain[256];
+ bool set_explain;
+#endif
+
+ thd_scheduler();
+ ~thd_scheduler();
+ bool init(THD* parent_thd);
+ bool thread_attach();
+ void thread_detach();
};
+void pool_of_threads_scheduler(scheduler_functions* func);
+
+#else
+
#define HAVE_POOL_OF_THREADS 0 /* For easyer tests */
-#define pool_of_threads_scheduler(A) one_thread_per_connection_scheduler(A)
+#define pool_of_threads_scheduler(A) \
+ one_thread_per_connection_scheduler(A, &max_connections, \
+ &connection_count)
class thd_scheduler
{};
+
+#endif
diff --git a/sql/set_var.cc b/sql/set_var.cc
index d9133a25d98..40e26ea4930 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -60,8 +61,11 @@
#include <my_getopt.h>
#include <thr_alarm.h>
#include <myisam.h>
+#ifdef WITH_MARIA_STORAGE_ENGINE
+#include <maria.h>
+#endif
#include <my_dir.h>
-
+#include <waiting_threads.h>
#include "events.h"
/* WITH_NDBCLUSTER_STORAGE_ENGINE */
@@ -127,7 +131,9 @@ static void fix_net_write_timeout(THD *thd, enum_var_type type);
static void fix_net_retry_count(THD *thd, enum_var_type type);
static void fix_max_join_size(THD *thd, enum_var_type type);
static void fix_query_cache_size(THD *thd, enum_var_type type);
+#ifdef HAVE_QUERY_CACHE
static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type);
+#endif
static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
static void fix_max_binlog_size(THD *thd, enum_var_type type);
static void fix_max_relay_log_size(THD *thd, enum_var_type type);
@@ -148,6 +154,7 @@ static bool sys_update_general_log_path(THD *thd, set_var * var);
static void sys_default_general_log_path(THD *thd, enum_var_type type);
static bool sys_update_slow_log_path(THD *thd, set_var * var);
static void sys_default_slow_log_path(THD *thd, enum_var_type type);
+static void fix_sys_log_slow_filter(THD *thd, enum_var_type);
static uchar *get_myisam_mmap_size(THD *thd);
static int check_max_allowed_packet(THD *thd, set_var *var);
static int check_net_buffer_length(THD *thd, set_var *var);
@@ -239,6 +246,19 @@ static sys_var_long_ptr sys_concurrent_insert(&vars, "concurrent_insert",
static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
&connect_timeout);
static sys_var_const_os_str sys_datadir(&vars, "datadir", mysql_real_data_home);
+
+static sys_var_thd_ulong sys_deadlock_search_depth_short(&vars,
+ "deadlock_search_depth_short",
+ &SV::wt_deadlock_search_depth_short);
+static sys_var_thd_ulong sys_deadlock_search_depth_long(&vars,
+ "deadlock_search_depth_long",
+ &SV::wt_deadlock_search_depth_long);
+static sys_var_thd_ulong sys_deadlock_timeout_short(&vars,
+ "deadlock_timeout_short",
+ &SV::wt_timeout_short);
+static sys_var_thd_ulong sys_deadlock_timeout_long(&vars,
+ "deadlock_timeout_long",
+ &SV::wt_timeout_long);
#ifndef DBUG_OFF
static sys_var_thd_dbug sys_dbug(&vars, "debug");
#endif
@@ -257,6 +277,13 @@ static sys_var_long_ptr sys_delayed_queue_size(&vars, "delayed_queue_size",
static sys_var_event_scheduler sys_event_scheduler(&vars, "event_scheduler");
#endif
+static sys_var_const sys_extra_port(&vars, "extra_port",
+ OPT_GLOBAL, SHOW_INT,
+ (uchar*) &mysqld_extra_port);
+static sys_var_long_ptr sys_extra_max_connections(&vars,
+ "extra_max_connections",
+ &extra_max_connections,
+ fix_max_connections);
static sys_var_long_ptr sys_expire_logs_days(&vars, "expire_logs_days",
&expire_logs_days);
static sys_var_bool_ptr sys_flush(&vars, "flush", &myisam_flush);
@@ -333,7 +360,7 @@ static sys_var_const sys_log_bin(&vars, "log_bin",
static sys_var_trust_routine_creators
sys_trust_routine_creators(&vars, "log_bin_trust_routine_creators",
&trust_function_creators);
-static sys_var_bool_ptr
+static sys_var_bool_ptr
sys_trust_function_creators(&vars, "log_bin_trust_function_creators",
&trust_function_creators);
static sys_var_const sys_log_error(&vars, "log_error",
@@ -345,6 +372,9 @@ static sys_var_bool_ptr
static sys_var_thd_ulong sys_log_warnings(&vars, "log_warnings", &SV::log_warnings);
static sys_var_microseconds sys_var_long_query_time(&vars, "long_query_time",
&SV::long_query_time);
+static sys_var_microseconds sys_var_long_query_time2(&vars,
+ "log_slow_time",
+ &SV::long_query_time);
static sys_var_thd_bool sys_low_priority_updates(&vars, "low_priority_updates",
&SV::low_priority_updates,
fix_low_priority_updates);
@@ -569,10 +599,10 @@ static sys_var_thd_ulong sys_trans_alloc_block_size(&vars, "transaction_alloc_bl
static sys_var_thd_ulong sys_trans_prealloc_size(&vars, "transaction_prealloc_size",
&SV::trans_prealloc_size,
0, fix_trans_mem_root);
-sys_var_enum_const sys_thread_handling(&vars, "thread_handling",
- &SV::thread_handling,
- &thread_handling_typelib,
- NULL);
+sys_var_enum_const sys_thread_handling(&vars, "thread_handling",
+ &SV::thread_handling,
+ &thread_handling_typelib,
+ NULL);
#ifdef HAVE_QUERY_CACHE
static sys_var_long_ptr sys_query_cache_limit(&vars, "query_cache_limit",
@@ -652,8 +682,8 @@ static sys_var_debug_sync sys_debug_sync(&vars, "debug_sync");
static sys_var_long_ptr sys_thread_cache_size(&vars, "thread_cache_size",
&thread_cache_size);
#if HAVE_POOL_OF_THREADS == 1
-sys_var_long_ptr sys_thread_pool_size(&vars, "thread_pool_size",
- &thread_pool_size);
+static sys_var_long_ptr sys_thread_pool_size(&vars, "thread_pool_size",
+ &thread_pool_size);
#endif
static sys_var_thd_enum sys_tx_isolation(&vars, "tx_isolation",
&SV::tx_isolation,
@@ -856,6 +886,20 @@ sys_var_thd_ulong sys_group_concat_max_len(&vars, "group_concat_ma
sys_var_thd_time_zone sys_time_zone(&vars, "time_zone",
sys_var::SESSION_VARIABLE_IN_BINLOG);
+/* Unique variables for MariaDB */
+static sys_var_thd_ulong sys_log_slow_rate_limit(&vars,
+ "log_slow_rate_limit",
+ &SV::log_slow_rate_limit);
+static sys_var_thd_set sys_log_slow_filter(&vars, "log_slow_filter",
+ &SV::log_slow_filter,
+ &log_slow_filter_typelib,
+ QPLAN_VISIBLE_MASK,
+ fix_sys_log_slow_filter);
+static sys_var_thd_set sys_log_slow_verbosity(&vars,
+ "log_slow_verbosity",
+ &SV::log_slow_verbosity,
+ &log_slow_verbosity_typelib);
+
/* Global read-only variable containing hostname */
static sys_var_const_str sys_hostname(&vars, "hostname", glob_hostname);
@@ -1183,12 +1227,23 @@ extern void fix_delay_key_write(THD *thd, enum_var_type type)
switch ((enum_delay_key_write) delay_key_write_options) {
case DELAY_KEY_WRITE_NONE:
myisam_delay_key_write=0;
+#ifdef WITH_MARIA_STORAGE_ENGINE
+ maria_delay_key_write= 0;
+#endif
+ ha_open_options&= ~HA_OPEN_DELAY_KEY_WRITE;
break;
case DELAY_KEY_WRITE_ON:
myisam_delay_key_write=1;
+#ifdef WITH_MARIA_STORAGE_ENGINE
+ maria_delay_key_write= 1;
+#endif
+ ha_open_options&= ~HA_OPEN_DELAY_KEY_WRITE;
break;
case DELAY_KEY_WRITE_ALL:
myisam_delay_key_write=1;
+#ifdef WITH_MARIA_STORAGE_ENGINE
+ maria_delay_key_write= 1;
+#endif
ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
break;
}
@@ -1232,8 +1287,9 @@ void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
{
bool rc= sys_var_set::check(thd, var);
- if (!rc && (var->save_result.ulong_value & SLAVE_EXEC_MODE_STRICT) &&
- (var->save_result.ulong_value & SLAVE_EXEC_MODE_IDEMPOTENT))
+ if (!rc &&
+ test_all_bits(var->save_result.ulong_value,
+ SLAVE_EXEC_MODE_STRICT | SLAVE_EXEC_MODE_IDEMPOTENT))
{
rc= true;
my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
@@ -1254,8 +1310,8 @@ void fix_slave_exec_mode(void)
{
DBUG_ENTER("fix_slave_exec_mode");
- if ((slave_exec_mode_options & SLAVE_EXEC_MODE_STRICT) &&
- (slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT))
+ if (test_all_bits(slave_exec_mode_options,
+ SLAVE_EXEC_MODE_STRICT | SLAVE_EXEC_MODE_IDEMPOTENT))
{
sql_print_error("Ambiguous slave modes combination. STRICT will be used");
slave_exec_mode_options&= ~SLAVE_EXEC_MODE_IDEMPOTENT;
@@ -1309,7 +1365,7 @@ bool sys_var_thd_binlog_format::is_readonly() const
if (thd->in_sub_stmt)
{
my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
- return 1;
+ return 1;
}
return sys_var_thd_enum::is_readonly();
}
@@ -1363,7 +1419,7 @@ static int check_max_delayed_threads(THD *thd, set_var *var)
static void fix_max_connections(THD *thd, enum_var_type type)
{
#ifndef EMBEDDED_LIBRARY
- resize_thr_alarm(max_connections +
+ resize_thr_alarm(max_connections + extra_max_connections +
global_system_variables.max_insert_delayed_threads + 10);
#endif
}
@@ -1604,7 +1660,6 @@ uchar *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
return (uchar*) enum_names->type_names[*value];
}
-
uchar *sys_var_enum_const::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
@@ -1785,7 +1840,7 @@ bool sys_var::check_enum(THD *thd, set_var *var, const TYPELIB *enum_names)
{
char buff[STRING_BUFFER_USUAL_SIZE];
const char *value;
- String str(buff, sizeof(buff), system_charset_info), *res;
+ String str(buff, sizeof(buff) - 1, system_charset_info), *res;
if (var->value->result_type() == STRING_RESULT)
{
@@ -1816,13 +1871,19 @@ err:
return 1;
}
+/**
+ Check vality of set
+
+ Note that this sets 'save_result.ulong_value' for the update function,
+ which means that we don't need a separate sys_var::update() function
+*/
bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
{
bool not_used;
- char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
+ char buff[256], *error= 0;
uint error_len= 0;
- String str(buff, sizeof(buff), system_charset_info), *res;
+ String str(buff, sizeof(buff) - 1, system_charset_info), *res;
if (var->value->result_type() == STRING_RESULT)
{
@@ -1832,8 +1893,7 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
goto err;
}
- if (!m_allow_empty_value &&
- res->length() == 0)
+ if (!m_allow_empty_value && res->length() == 0)
{
buff[0]= 0;
goto err;
@@ -1855,8 +1915,7 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
{
ulonglong tmp= var->value->val_int();
- if (!m_allow_empty_value &&
- tmp == 0)
+ if (!m_allow_empty_value && tmp == 0)
{
buff[0]= '0';
buff[1]= 0;
@@ -1883,6 +1942,49 @@ err:
}
+/**
+ Make string representation of set
+
+ @param[in] thd thread handler
+ @param[in] val sql_mode value
+ @param[in] names names for the different bits
+ @param[out] rep Result string
+
+ @return
+ 0 ok
+ 1 end of memory
+*/
+
+bool sys_var::make_set(THD *thd, ulonglong val, TYPELIB *names,
+ LEX_STRING *rep)
+{
+ /* Strings for typelib may be big; This is reallocated on demand */
+ char buff[256];
+ String tmp(buff, sizeof(buff) - 1, &my_charset_latin1);
+ bool error= 0;
+
+ tmp.length(0);
+ for (uint i= 0; val; val>>= 1, i++)
+ {
+ if (val & 1)
+ {
+ error|= tmp.append(names->type_names[i],
+ names->type_lengths[i]);
+ error|= tmp.append(',');
+ }
+ }
+
+ if (tmp.length())
+ tmp.length(tmp.length() - 1); /* trim the trailing comma */
+
+ /* Allocate temporary copy of string */
+ if (!(rep->str= thd->strmake(tmp.ptr(), tmp.length())))
+ error= 1;
+ rep->length= tmp.length();
+ return error; /* Error in case of out of memory */
+}
+
+
CHARSET_INFO *sys_var::charset(THD *thd)
{
return is_os_charset ? thd->variables.character_set_filesystem :
@@ -1918,6 +2020,16 @@ uchar *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type,
return (uchar*) enum_names->type_names[tmp];
}
+uchar *sys_var_thd_set::value_ptr(THD *thd, enum_var_type type,
+ LEX_STRING *base)
+{
+ LEX_STRING sql_mode;
+ ulong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
+ thd->variables.*offset);
+ (void) make_set(thd, val & visible_value_mask, enum_names, &sql_mode);
+ return (uchar *) sql_mode.str;
+}
+
bool sys_var_thd_bit::check(THD *thd, set_var *var)
{
return (check_enum(thd, var, &bool_typelib) ||
@@ -1987,7 +2099,7 @@ bool sys_var_thd_date_time_format::update(THD *thd, set_var *var)
bool sys_var_thd_date_time_format::check(THD *thd, set_var *var)
{
char buff[STRING_BUFFER_USUAL_SIZE];
- String str(buff,sizeof(buff), system_charset_info), *res;
+ String str(buff,sizeof(buff) - 1, system_charset_info), *res;
DATE_TIME_FORMAT *format;
if (!(res=var->value->val_str(&str)))
@@ -2092,7 +2204,7 @@ bool sys_var_collation::check(THD *thd, set_var *var)
if (var->value->result_type() == STRING_RESULT)
{
char buff[STRING_BUFFER_USUAL_SIZE];
- String str(buff,sizeof(buff), system_charset_info), *res;
+ String str(buff,sizeof(buff) - 1, system_charset_info), *res;
if (!(res=var->value->val_str(&str)))
{
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
@@ -2127,7 +2239,7 @@ bool sys_var_character_set::check(THD *thd, set_var *var)
if (var->value->result_type() == STRING_RESULT)
{
char buff[STRING_BUFFER_USUAL_SIZE];
- String str(buff,sizeof(buff), system_charset_info), *res;
+ String str(buff,sizeof(buff) - 1, system_charset_info), *res;
if (!(res=var->value->val_str(&str)))
{
if (!nullable)
@@ -2275,10 +2387,9 @@ KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
if (!cache_name || ! cache_name->length)
cache_name= &default_key_cache_base;
return ((KEY_CACHE*) find_named(&key_caches,
- cache_name->str, cache_name->length, 0));
+ cache_name->str, cache_name->length, 0));
}
-
uchar *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
@@ -2446,13 +2557,11 @@ end:
bool sys_var_log_state::update(THD *thd, set_var *var)
{
bool res;
-
if (this == &sys_var_log)
WARN_DEPRECATED(thd, "7.0", "@@log", "'@@general_log'");
else if (this == &sys_var_log_slow)
WARN_DEPRECATED(thd, "7.0", "@@log_slow_queries", "'@@slow_query_log'");
- pthread_mutex_lock(&LOCK_global_system_variables);
if (!var->save_result.ulong_value)
{
logger.deactivate_log_handler(thd, log_type);
@@ -2460,7 +2569,6 @@ bool sys_var_log_state::update(THD *thd, set_var *var)
}
else
res= logger.activate_log_handler(thd, log_type);
- pthread_mutex_unlock(&LOCK_global_system_variables);
return res;
}
@@ -2471,9 +2579,7 @@ void sys_var_log_state::set_default(THD *thd, enum_var_type type)
else if (this == &sys_var_log_slow)
WARN_DEPRECATED(thd, "7.0", "@@log_slow_queries", "'@@slow_query_log'");
- pthread_mutex_lock(&LOCK_global_system_variables);
logger.deactivate_log_handler(thd, log_type);
- pthread_mutex_unlock(&LOCK_global_system_variables);
}
@@ -2482,7 +2588,7 @@ static int sys_check_log_path(THD *thd, set_var *var)
char path[FN_REFLEN], buff[FN_REFLEN];
MY_STAT f_stat;
String str(buff, sizeof(buff), system_charset_info), *res;
- const char *log_file_str;
+ const char *log_file_str= 0;
size_t path_length;
if (!(res= var->value->val_str(&str)))
@@ -2532,7 +2638,7 @@ static int sys_check_log_path(THD *thd, set_var *var)
err:
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name,
- res ? log_file_str : "NULL");
+ log_file_str ? log_file_str : "NULL");
return 1;
}
@@ -2541,7 +2647,7 @@ bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
set_var *var, const char *log_ext,
bool log_state, uint log_type)
{
- MYSQL_QUERY_LOG *file_log;
+ MYSQL_QUERY_LOG *file_log= 0;
char buff[FN_REFLEN];
char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
bool result= 0;
@@ -2569,23 +2675,18 @@ bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
goto err;
}
- pthread_mutex_lock(&LOCK_global_system_variables);
logger.lock_exclusive();
if (file_log && log_state)
file_log->close(0);
- old_value= var_str->value;
- var_str->value= res;
- var_str->value_length= str_length;
- my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
if (file_log && log_state)
{
switch (log_type) {
case QUERY_LOG_SLOW:
- file_log->open_slow_log(sys_var_slow_log_path.value);
+ file_log->open_slow_log(res);
break;
case QUERY_LOG_GENERAL:
- file_log->open_query_log(sys_var_general_log_path.value);
+ file_log->open_query_log(res);
break;
default:
DBUG_ASSERT(0);
@@ -2593,6 +2694,13 @@ bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
}
logger.unlock();
+
+ /* update global variable */
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ old_value= var_str->value;
+ var_str->value= res;
+ var_str->value_length= str_length;
+ my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
pthread_mutex_unlock(&LOCK_global_system_variables);
err:
@@ -2632,26 +2740,22 @@ static void sys_default_slow_log_path(THD *thd, enum_var_type type)
bool sys_var_log_output::update(THD *thd, set_var *var)
{
- pthread_mutex_lock(&LOCK_global_system_variables);
logger.lock_exclusive();
logger.init_slow_log(var->save_result.ulong_value);
logger.init_general_log(var->save_result.ulong_value);
*value= var->save_result.ulong_value;
logger.unlock();
- pthread_mutex_unlock(&LOCK_global_system_variables);
return 0;
}
void sys_var_log_output::set_default(THD *thd, enum_var_type type)
{
- pthread_mutex_lock(&LOCK_global_system_variables);
logger.lock_exclusive();
logger.init_slow_log(LOG_FILE);
logger.init_general_log(LOG_FILE);
*value= LOG_FILE;
logger.unlock();
- pthread_mutex_unlock(&LOCK_global_system_variables);
}
@@ -3714,6 +3818,24 @@ int set_var_password::update(THD *thd)
}
/****************************************************************************
+ Functions to handle log_slow_filter
+****************************************************************************/
+
+/* Ensure that the proper bits are set for easy test of logging */
+static void fix_sys_log_slow_filter(THD *thd, enum_var_type type)
+{
+ /* Maintain everything with filters */
+ opt_log_slow_admin_statements= 1;
+ if (type == OPT_GLOBAL)
+ global_system_variables.log_slow_filter=
+ fix_log_slow_filter(global_system_variables.log_slow_filter);
+ else
+ thd->variables.log_slow_filter=
+ fix_log_slow_filter(thd->variables.log_slow_filter);
+}
+
+
+/****************************************************************************
Functions to handle table_type
****************************************************************************/
@@ -3723,7 +3845,7 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
{
char buff[STRING_BUFFER_USUAL_SIZE];
const char *value;
- String str(buff, sizeof(buff), &my_charset_latin1), *res;
+ String str(buff, sizeof(buff) - 1, &my_charset_latin1), *res;
var->save_result.plugin= NULL;
if (var->value->result_type() == STRING_RESULT)
@@ -3758,9 +3880,9 @@ uchar *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *engine_name;
plugin_ref plugin= thd->variables.*offset;
if (type == OPT_GLOBAL)
- plugin= my_plugin_lock(thd, &(global_system_variables.*offset));
+ plugin= my_plugin_lock(thd, global_system_variables.*offset);
hton= plugin_data(plugin, handlerton*);
- engine_name= &hton2plugin[hton->slot]->name;
+ engine_name= hton_name(hton);
result= (uchar *) thd->strmake(engine_name->str, engine_name->length);
if (type == OPT_GLOBAL)
plugin_unlock(thd, plugin);
@@ -3779,7 +3901,7 @@ void sys_var_thd_storage_engine::set_default(THD *thd, enum_var_type type)
else
{
value= &(thd->variables.*offset);
- new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
+ new_value= my_plugin_lock(NULL, global_system_variables.*offset);
}
DBUG_ASSERT(new_value);
old_value= *value;
@@ -3796,7 +3918,7 @@ bool sys_var_thd_storage_engine::update(THD *thd, set_var *var)
old_value= *value;
if (old_value != var->save_result.plugin)
{
- *value= my_plugin_lock(NULL, &var->save_result.plugin);
+ *value= my_plugin_lock(NULL, var->save_result.plugin);
plugin_unlock(NULL, old_value);
}
return 0;
@@ -3824,67 +3946,6 @@ bool sys_var_thd_table_type::update(THD *thd, set_var *var)
Functions to handle sql_mode
****************************************************************************/
-/**
- Make string representation of mode.
-
- @param[in] thd thread handler
- @param[in] val sql_mode value
- @param[out] len pointer on length of string
-
- @return
- pointer to string with sql_mode representation
-*/
-
-bool
-sys_var_thd_sql_mode::
-symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
-{
- char buff[STRING_BUFFER_USUAL_SIZE*8];
- String tmp(buff, sizeof(buff), &my_charset_latin1);
-
- tmp.length(0);
-
- for (uint i= 0; val; val>>= 1, i++)
- {
- if (val & 1)
- {
- tmp.append(sql_mode_typelib.type_names[i],
- sql_mode_typelib.type_lengths[i]);
- tmp.append(',');
- }
- }
-
- if (tmp.length())
- tmp.length(tmp.length() - 1); /* trim the trailing comma */
-
- rep->str= thd->strmake(tmp.ptr(), tmp.length());
-
- rep->length= rep->str ? tmp.length() : 0;
-
- return rep->length != tmp.length();
-}
-
-
-uchar *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type,
- LEX_STRING *base)
-{
- LEX_STRING sql_mode;
- ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
- thd->variables.*offset);
- (void) symbolic_mode_representation(thd, val, &sql_mode);
- return (uchar *) sql_mode.str;
-}
-
-
-void sys_var_thd_sql_mode::set_default(THD *thd, enum_var_type type)
-{
- if (type == OPT_GLOBAL)
- global_system_variables.*offset= 0;
- else
- thd->variables.*offset= global_system_variables.*offset;
-}
-
-
void fix_sql_mode_var(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
@@ -4248,25 +4309,46 @@ bool sys_var_thd_dbug::update(THD *thd, set_var *var)
{
char buf[256];
String str(buf, sizeof(buf), system_charset_info), *res;
-
+ const char *command;
+
res= var->value->val_str(&str);
+ command= res ? res->c_ptr(): 0;
+ if (!command)
+ command= "";
if (var->type == OPT_GLOBAL)
- DBUG_SET_INITIAL(res ? res->c_ptr() : "");
+ DBUG_SET_INITIAL(command);
else
- DBUG_SET(res ? res->c_ptr() : "");
-
+ {
+ if (_db_is_pushed_())
+ {
+ /* We have already a local state done with DBUG_PUSH; Modify the state */
+ DBUG_SET(command);
+ }
+ else
+ {
+ /*
+ We are sharing the state with the global state;
+ Create a local state for this thread.
+ */
+ DBUG_PUSH(command);
+ }
+ }
return 0;
}
uchar *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
{
- char buf[256];
+ char buf[1024];
if (type == OPT_GLOBAL)
+ {
DBUG_EXPLAIN_INITIAL(buf, sizeof(buf));
+ }
else
+ {
DBUG_EXPLAIN(buf, sizeof(buf));
+ }
return (uchar*) thd->strdup(buf);
}
#endif /* DBUG_OFF */
diff --git a/sql/set_var.h b/sql/set_var.h
index 97e3c74593b..2e9812eca3b 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2010, Oracle and/or its affiliates.
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
@@ -98,6 +98,8 @@ public:
virtual bool check(THD *thd, set_var *var);
bool check_enum(THD *thd, set_var *var, const TYPELIB *enum_names);
bool check_set(THD *thd, set_var *var, TYPELIB *enum_names);
+ static bool make_set(THD *thd, ulonglong sql_mode, TYPELIB *names,
+ LEX_STRING *rep);
bool is_written_to_binlog(enum_var_type type)
{
return (type == OPT_SESSION || type == OPT_DEFAULT) &&
@@ -534,6 +536,25 @@ public:
};
+class sys_var_thd_set :public sys_var_thd_enum
+{
+ ulong visible_value_mask; /* Mask away internal bits */
+public:
+ sys_var_thd_set(sys_var_chain *chain, const char *name_arg,
+ ulong SV::*offset_arg, TYPELIB *typelib,
+ ulong value_mask= ~ (ulong) 0,
+ sys_after_update_func func= NULL)
+ :sys_var_thd_enum(chain, name_arg, offset_arg, typelib,
+ func), visible_value_mask(value_mask)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return check_set(thd, var, enum_names);
+ }
+ uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+};
+
+
class sys_var_thd_optimizer_switch :public sys_var_thd_enum
{
public:
@@ -550,22 +571,14 @@ public:
extern void fix_sql_mode_var(THD *thd, enum_var_type type);
-class sys_var_thd_sql_mode :public sys_var_thd_enum
+class sys_var_thd_sql_mode :public sys_var_thd_set
{
public:
sys_var_thd_sql_mode(sys_var_chain *chain, const char *name_arg,
ulong SV::*offset_arg)
- :sys_var_thd_enum(chain, name_arg, offset_arg, &sql_mode_typelib,
- fix_sql_mode_var)
+ :sys_var_thd_set(chain, name_arg, offset_arg, &sql_mode_typelib,
+ ~(ulong) 0, fix_sql_mode_var)
{}
- bool check(THD *thd, set_var *var)
- {
- return check_set(thd, var, enum_names);
- }
- void set_default(THD *thd, enum_var_type type);
- uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
- static bool symbolic_mode_representation(THD *thd, ulonglong sql_mode,
- LEX_STRING *rep);
};
@@ -1205,7 +1218,6 @@ public:
bool update(THD *thd, set_var *var);
};
-
/**
Handler for setting the system variable --read-only.
*/
diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am
index 805f4d4d935..4a9123d6d25 100644
--- a/sql/share/Makefile.am
+++ b/sql/share/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2010, Oracle and/or its affiliates
#
# 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
@@ -57,6 +57,3 @@ distclean-local:
# Do nothing
link_sources:
-
-# Don't update the files from bitkeeper
-%::SCCS/s.%
diff --git a/sql/share/charsets/languages.html b/sql/share/charsets/languages.html
index 76af973113e..6d1a8aafc5c 100644
--- a/sql/share/charsets/languages.html
+++ b/sql/share/charsets/languages.html
@@ -1,20 +1,4 @@
#!/bin/sh
-
-# Copyright (C) 2003 MySQL AB
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
#<pre>
(
echo "DROP TABLE lang;"
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index bbae17c4327..0f9e2a24a93 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -2044,7 +2044,7 @@ ER_BLOBS_AND_NO_TERMINATED 42000 S1009
ukr "îÅ ÍÏÖÎÁ ×ÉËÏÒÉÓÔÏ×Õ×ÁÔÉ ÓÔÁÌÕ ÄÏ×ÖÉÎÕ ÓÔÒÏËÉ Ú BLOB. úËÏÒÉÓÔÁÊÔÅÓÑ 'fields terminated by'"
ER_TEXTFILE_NOT_READABLE
cze "Soubor '%-.128s' mus-Bí být v adresáøi databáze nebo èitelný pro v¹echny"
- dan "Filen '%-.128s' skal være i database-folderen og kunne læses af alle"
+ dan "Filen '%-.128s' skal være i database-folderen, eller kunne læses af alle"
nla "Het bestand '%-.128s' dient in de database directory voor the komen of leesbaar voor iedereen te zijn."
eng "The file '%-.128s' must be in the database directory or be readable by all"
jps "ƒtƒ@ƒCƒ‹ '%-.128s' ‚Í databse ‚Ì directory ‚É‚ ‚é‚©‘S‚Ẵ†[ƒU[‚ª“Ç‚ß‚é‚悤‚É‹–‰Â‚³‚ê‚Ä‚¢‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ.",
@@ -3173,22 +3173,22 @@ ER_CANT_CREATE_THREAD
swe "Kan inte skapa en ny tråd (errno %d)"
ukr "îÅ ÍÏÖÕ ÓÔ×ÏÒÉÔÉ ÎÏ×Õ Ç¦ÌËÕ (ÐÏÍÉÌËÁ %d). ñËÝÏ ×É ÎÅ ×ÉËÏÒÉÓÔÁÌÉ ÕÓÀ ÐÁÍ'ÑÔØ, ÔÏ ÐÒÏÞÉÔÁÊÔÅ ÄÏËÕÍÅÎÔÁæÀ ÄÏ ×ÁÛϧ ïó - ÍÏÖÌÉ×Ï ÃÅ ÐÏÍÉÌËÁ ïó"
ER_WRONG_VALUE_COUNT_ON_ROW 21S01
- cze "Po-Bèet sloupcù neodpovídá poètu hodnot na øádku %ld"
- dan "Kolonne antallet stemmer ikke overens med antallet af værdier i post %ld"
- nla "Kolom aantal komt niet overeen met waarde aantal in rij %ld"
- eng "Column count doesn't match value count at row %ld"
- est "Tulpade hulk erineb väärtuste hulgast real %ld"
- ger "Anzahl der Felder stimmt nicht mit der Anzahl der Werte in Zeile %ld überein"
- hun "Az oszlopban talalhato ertek nem egyezik meg a %ld sorban szamitott ertekkel"
- ita "Il numero delle colonne non corrisponde al conteggio alla riga %ld"
- kor "Row %ld¿¡¼­ Ä®·³ Ä«¿îÆ®¿Í value Ä«¿îÅÍ¿Í ÀÏÄ¡ÇÏÁö ¾Ê½À´Ï´Ù."
- por "Contagem de colunas não confere com a contagem de valores na linha %ld"
- rum "Numarul de coloane nu corespunde cu numarul de valori la linia %ld"
- rus "ëÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ× ÎÅ ÓÏ×ÐÁÄÁÅÔ Ó ËÏÌÉÞÅÓÔ×ÏÍ ÚÎÁÞÅÎÉÊ × ÚÁÐÉÓÉ %ld"
- serbian "Broj kolona ne odgovara broju vrednosti u slogu %ld"
- spa "El número de columnas no corresponde al número en la línea %ld"
- swe "Antalet kolumner motsvarar inte antalet värden på rad: %ld"
- ukr "ë¦ÌØ˦ÓÔØ ÓÔÏ×ÂÃ¦× ÎÅ ÓЦ×ÐÁÄÁ¤ Ú Ë¦ÌØ˦ÓÔÀ ÚÎÁÞÅÎØ Õ ÓÔÒÏæ %ld"
+ cze "Po-Bèet sloupcù neodpovídá poètu hodnot na øádku %lu"
+ dan "Kolonne antallet stemmer ikke overens med antallet af værdier i post %lu"
+ nla "Kolom aantal komt niet overeen met waarde aantal in rij %lu"
+ eng "Column count doesn't match value count at row %lu"
+ est "Tulpade hulk erineb väärtuste hulgast real %lu"
+ ger "Anzahl der Felder stimmt nicht mit der Anzahl der Werte in Zeile %lu überein"
+ hun "Az oszlopban talalhato ertek nem egyezik meg a %lu sorban szamitott ertekkel"
+ ita "Il numero delle colonne non corrisponde al conteggio alla riga %lu"
+ kor "Row %lu¿¡¼­ Ä®·³ Ä«¿îÆ®¿Í value Ä«¿îÅÍ¿Í ÀÏÄ¡ÇÏÁö ¾Ê½À´Ï´Ù."
+ por "Contagem de colunas não confere com a contagem de valores na linha %lu"
+ rum "Numarul de coloane nu corespunde cu numarul de valori la linia %lu"
+ rus "ëÏÌÉÞÅÓÔ×Ï ÓÔÏÌÂÃÏ× ÎÅ ÓÏ×ÐÁÄÁÅÔ Ó ËÏÌÉÞÅÓÔ×ÏÍ ÚÎÁÞÅÎÉÊ × ÚÁÐÉÓÉ %lu"
+ serbian "Broj kolona ne odgovara broju vrednosti u slogu %lu"
+ spa "El número de columnas no corresponde al número en la línea %lu"
+ swe "Antalet kolumner motsvarar inte antalet värden på rad: %lu"
+ ukr "ë¦ÌØ˦ÓÔØ ÓÔÏ×ÂÃ¦× ÎÅ ÓЦ×ÐÁÄÁ¤ Ú Ë¦ÌØ˦ÓÔÀ ÚÎÁÞÅÎØ Õ ÓÔÒÏæ %lu"
ER_CANT_REOPEN_TABLE
cze "Nemohu znovuotev-Bøít tabulku: '%-.192s"
dan "Kan ikke genåbne tabel '%-.192s"
@@ -4887,29 +4887,29 @@ ER_CUT_VALUE_GROUP_CONCAT
swe "%d rad(er) kapades av group_concat()"
ukr "%d line(s) was(were) cut by group_concat()"
ER_WARN_TOO_FEW_RECORDS 01000
- eng "Row %ld doesn't contain data for all columns"
- ger "Zeile %ld enthält nicht für alle Felder Daten"
- nla "Rij %ld bevat niet de data voor alle kolommen"
- por "Conta de registro é menor que a conta de coluna na linha %ld"
- spa "Línea %ld no contiene datos para todas las columnas"
+ eng "Row %lu doesn't contain data for all columns"
+ ger "Zeile %lu enthält nicht für alle Felder Daten"
+ nla "Rij %lu bevat niet de data voor alle kolommen"
+ por "Conta de registro é menor que a conta de coluna na linha %lu"
+ spa "Línea %lu no contiene datos para todas las columnas"
ER_WARN_TOO_MANY_RECORDS 01000
- eng "Row %ld was truncated; it contained more data than there were input columns"
- ger "Zeile %ld gekürzt, die Zeile enthielt mehr Daten, als es Eingabefelder gibt"
- nla "Regel %ld ingekort, bevatte meer data dan invoer kolommen"
- por "Conta de registro é maior que a conta de coluna na linha %ld"
- spa "Línea %ld fué truncada; La misma contine mas datos que las que existen en las columnas de entrada"
+ eng "Row %lu was truncated; it contained more data than there were input columns"
+ ger "Zeile %lu gekürzt, die Zeile enthielt mehr Daten, als es Eingabefelder gibt"
+ nla "Regel %lu ingekort, bevatte meer data dan invoer kolommen"
+ por "Conta de registro é maior que a conta de coluna na linha %lu"
+ spa "Línea %lu fué truncada; La misma contine mas datos que las que existen en las columnas de entrada"
ER_WARN_NULL_TO_NOTNULL 22004
- eng "Column set to default value; NULL supplied to NOT NULL column '%s' at row %ld"
- ger "Feld auf Vorgabewert gesetzt, da NULL für NOT-NULL-Feld '%s' in Zeile %ld angegeben"
- por "Dado truncado, NULL fornecido para NOT NULL coluna '%s' na linha %ld"
- spa "Datos truncado, NULL suministrado para NOT NULL columna '%s' en la línea %ld"
+ eng "Column set to default value; NULL supplied to NOT NULL column '%s' at row %lu"
+ ger "Feld auf Vorgabewert gesetzt, da NULL für NOT-NULL-Feld '%s' in Zeile %lu angegeben"
+ por "Dado truncado, NULL fornecido para NOT NULL coluna '%s' na linha %lu"
+ spa "Datos truncado, NULL suministrado para NOT NULL columna '%s' en la línea %lu"
ER_WARN_DATA_OUT_OF_RANGE 22003
- eng "Out of range value for column '%s' at row %ld"
+ eng "Out of range value for column '%s' at row %lu"
WARN_DATA_TRUNCATED 01000
- eng "Data truncated for column '%s' at row %ld"
- ger "Daten abgeschnitten für Feld '%s' in Zeile %ld"
- por "Dado truncado para coluna '%s' na linha %ld"
- spa "Datos truncados para columna '%s' en la línea %ld"
+ eng "Data truncated for column '%s' at row %lu"
+ ger "Daten abgeschnitten für Feld '%s' in Zeile %lu"
+ por "Dado truncado para coluna '%s' na linha %lu"
+ spa "Datos truncados para columna '%s' en la línea %lu"
ER_WARN_USING_OTHER_HANDLER
eng "Using storage engine %s for table '%s'"
ger "Für Tabelle '%s' wird Speicher-Engine %s benutzt"
@@ -5090,8 +5090,8 @@ ER_UNKNOWN_TIME_ZONE
eng "Unknown or incorrect time zone: '%-.64s'"
ger "Unbekannte oder falsche Zeitzone: '%-.64s'"
ER_WARN_INVALID_TIMESTAMP
- eng "Invalid TIMESTAMP value in column '%s' at row %ld"
- ger "Ungültiger TIMESTAMP-Wert in Feld '%s', Zeile %ld"
+ eng "Invalid TIMESTAMP value in column '%s' at row %lu"
+ ger "Ungültiger TIMESTAMP-Wert in Feld '%s', Zeile %lu"
ER_INVALID_CHARACTER_STRING
eng "Invalid %s character string: '%.64s'"
ger "Ungültiger %s-Zeichen-String: '%.64s'"
@@ -5322,8 +5322,8 @@ ER_DIVISION_BY_ZERO 22012
eng "Division by 0"
ger "Division durch 0"
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
- eng "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %ld"
- ger "Falscher %-.32s-Wert: '%-.128s' für Feld '%.192s' in Zeile %ld"
+ eng "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %lu"
+ ger "Falscher %-.32s-Wert: '%-.128s' für Feld '%.192s' in Zeile %lu"
ER_ILLEGAL_VALUE_FOR_TYPE 22007
eng "Illegal %s '%-.192s' value found during parsing"
ger "Nicht zulässiger %s-Wert '%-.192s' beim Parsen gefunden"
@@ -5456,8 +5456,8 @@ ER_PROC_AUTO_REVOKE_FAIL
eng "Failed to revoke all privileges to dropped routine"
ger "Rücknahme aller Rechte für die gelöschte Routine fehlgeschlagen"
ER_DATA_TOO_LONG 22001
- eng "Data too long for column '%s' at row %ld"
- ger "Daten zu lang für Feld '%s' in Zeile %ld"
+ eng "Data too long for column '%s' at row %lu"
+ ger "Daten zu lang für Feld '%s' in Zeile %lu"
ER_SP_BAD_SQLSTATE 42000
eng "Bad SQLSTATE: '%s'"
ger "Ungültiger SQLSTATE: '%s'"
diff --git a/sql/slave.cc b/sql/slave.cc
index 02d8cc2c199..d779d8cdc9e 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -826,56 +827,6 @@ const char *print_slave_db_safe(const char* db)
DBUG_RETURN((db ? db : ""));
}
-int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
- const char *default_val)
-{
- uint length;
- DBUG_ENTER("init_strvar_from_file");
-
- if ((length=my_b_gets(f,var, max_size)))
- {
- char* last_p = var + length -1;
- if (*last_p == '\n')
- *last_p = 0; // if we stopped on newline, kill it
- else
- {
- /*
- If we truncated a line or stopped on last char, remove all chars
- up to and including newline.
- */
- int c;
- while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)) ;
- }
- DBUG_RETURN(0);
- }
- else if (default_val)
- {
- strmake(var, default_val, max_size-1);
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
-
-
-int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
-{
- char buf[32];
- DBUG_ENTER("init_intvar_from_file");
-
-
- if (my_b_gets(f, buf, sizeof(buf)))
- {
- *var = atoi(buf);
- DBUG_RETURN(0);
- }
- else if (default_val)
- {
- *var = default_val;
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
-
/*
Check if the error is caused by network.
@@ -1200,18 +1151,27 @@ be equal for the Statement-format replication to work";
goto err;
}
}
- else if (is_network_error(mysql_errno(mysql)))
+ else if (is_network_error(err_code= mysql_errno(mysql)))
{
- mi->report(WARNING_LEVEL, mysql_errno(mysql),
- "Get master TIME_ZONE failed with error: %s", mysql_error(mysql));
+ mi->report(ERROR_LEVEL, err_code,
+ "Get master TIME_ZONE failed with error: %s",
+ mysql_error(mysql));
goto network_err;
- }
+ }
+ else if (err_code == ER_UNKNOWN_SYSTEM_VARIABLE)
+ {
+ /* We use ERROR_LEVEL to get the error logged to file */
+ mi->report(ERROR_LEVEL, err_code,
+
+ "MySQL master doesn't have a TIME_ZONE variable. Note that"
+ "if your timezone is not same between master and slave, your "
+ "slave may get wrong data into timestamp columns");
+ }
else
{
/* Fatal error */
errmsg= "The slave I/O thread stops because a fatal error is encountered \
when it try to get the value of TIME_ZONE global variable from master.";
- err_code= mysql_errno(mysql);
sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
goto err;
}
@@ -1840,6 +1800,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
+ MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
thd->slave_thread = 1;
thd->enable_slow_log= opt_log_slow_slave_statements;
+ thd->variables.log_slow_filter= global_system_variables.log_slow_filter;
set_slave_thread_options(thd);
thd->client_capabilities = CLIENT_LOCAL_FILES;
pthread_mutex_lock(&LOCK_thread_count);
@@ -2193,7 +2154,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
if (exec_res == 0)
{
int error= ev->update_pos(rli);
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
if (!rli->is_fake)
#endif
{
@@ -2327,7 +2288,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
if (slave_trans_retries)
{
- int UNINIT_VAR(temp_err);
+ int temp_err;
+ LINT_INIT(temp_err);
if (exec_res && (temp_err= has_temporary_error(thd)))
{
const char *errmsg;
@@ -2904,7 +2866,6 @@ pthread_handler_t handle_slave_sql(void *arg)
my_off_t UNINIT_VAR(saved_log_pos);
my_off_t UNINIT_VAR(saved_master_log_pos);
my_off_t saved_skip= 0;
-
Relay_log_info* rli = &((Master_info*)arg)->rli;
const char *errmsg;
@@ -2912,6 +2873,8 @@ pthread_handler_t handle_slave_sql(void *arg)
my_thread_init();
DBUG_ENTER("handle_slave_sql");
+ LINT_INIT(saved_master_log_pos);
+ LINT_INIT(saved_log_pos);
DBUG_ASSERT(rli->inited);
pthread_mutex_lock(&rli->run_lock);
DBUG_ASSERT(!rli->slave_running);
@@ -3913,10 +3876,11 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
suppress_warnings= 0;
mi->report(ERROR_LEVEL, last_errno,
"error %s to master '%s@%s:%d'"
- " - retry-time: %d retries: %lu",
+ " - retry-time: %d retries: %lu message: %s",
(reconnect ? "reconnecting" : "connecting"),
mi->user, mi->host, mi->port,
- mi->connect_retry, master_retry_count);
+ mi->connect_retry, master_retry_count,
+ mysql_error(mysql));
}
/*
By default we try forever. The reason is that failure will trigger
@@ -4493,6 +4457,7 @@ int rotate_relay_log(Master_info* mi)
DBUG_ENTER("rotate_relay_log");
Relay_log_info* rli= &mi->rli;
int error= 0;
+ safe_mutex_assert_owner(&mi->data_lock);
/*
We need to test inited because otherwise, new_file() will attempt to lock
diff --git a/sql/slave.h b/sql/slave.h
index b5156f2ce5d..f174b40c108 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -103,7 +103,8 @@ extern MY_BITMAP slave_error_mask;
extern char slave_skip_error_names[];
extern bool use_slave_mask;
extern char *slave_load_tmpdir;
-extern char *master_info_file, *relay_log_info_file;
+extern char *master_info_file;
+extern MYSQL_PLUGIN_IMPORT char *relay_log_info_file;
extern char *opt_relay_logname, *opt_relaylog_index_name;
extern my_bool opt_skip_slave_start, opt_reckless_slave;
extern my_bool opt_log_slave_updates;
@@ -206,7 +207,7 @@ extern int disconnect_slave_event_count, abort_slave_event_count ;
/* the master variables are defaults read from my.cnf or command line */
extern uint master_port, master_connect_retry, report_port;
extern char * master_user, *master_password, *master_host;
-extern char *master_info_file, *relay_log_info_file, *report_user;
+extern char *master_info_file, *report_user;
extern char *report_host, *report_password;
extern my_bool master_ssl;
diff --git a/sql/sp.cc b/sql/sp.cc
index 472d311908a..6f8c351f637 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
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
@@ -750,7 +750,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
{
LEX *old_lex= thd->lex, newlex;
String defstr;
- char saved_cur_db_name_buf[NAME_LEN+1];
+ char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed;
@@ -825,7 +825,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
{
Parser_state parser_state;
- if (parser_state.init(thd, defstr.c_ptr(), defstr.length()))
+ if (parser_state.init(thd, defstr.c_ptr_safe(), defstr.length()))
{
ret= SP_INTERNAL_ERROR;
goto end;
@@ -1970,7 +1970,7 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
Hence, the overrun happens only if the name is in length > 32 and
uses multibyte (cyrillic, greek, etc.)
*/
- char n[NAME_LEN*2+2];
+ char n[SAFE_NAME_LEN*2+2];
/* m_qname.str is not always \0 terminated */
memcpy(n, name.m_qname.str, name.m_qname.length);
diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc
index 93fb70f07ed..7e98480cffa 100644
--- a/sql/sp_cache.cc
+++ b/sql/sp_cache.cc
@@ -115,6 +115,12 @@ void sp_cache_clear(sp_cache **cp)
}
+void sp_cache_end()
+{
+ pthread_mutex_destroy(&Cversion_lock);
+}
+
+
/*
Insert a routine into the cache.
diff --git a/sql/sp_cache.h b/sql/sp_cache.h
index f4d44a1f29f..efb61d76719 100644
--- a/sql/sp_cache.h
+++ b/sql/sp_cache.h
@@ -53,6 +53,7 @@ class sp_cache;
*/
void sp_cache_init();
+void sp_cache_end();
void sp_cache_clear(sp_cache **cp);
void sp_cache_insert(sp_cache **cp, sp_head *sp);
sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 95a7eda0540..7d3bd52ffe2 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
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
@@ -1087,7 +1087,7 @@ bool
sp_head::execute(THD *thd)
{
DBUG_ENTER("sp_head::execute");
- char saved_cur_db_name_buf[NAME_LEN+1];
+ char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed= FALSE;
@@ -1877,7 +1877,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
uint params = m_pcont->context_var_count();
sp_rcontext *save_spcont, *octx;
sp_rcontext *nctx = NULL;
- bool save_enable_slow_log= false;
+ bool save_enable_slow_log;
bool save_log_general= false;
DBUG_ENTER("sp_head::execute_procedure");
DBUG_PRINT("info", ("procedure %s", m_name.str));
@@ -1955,9 +1955,10 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (spvar->mode == sp_param_out)
{
Item_null *null_item= new Item_null();
+ Item *tmp_item= null_item;
if (!null_item ||
- nctx->set_variable(thd, i, (Item **)&null_item))
+ nctx->set_variable(thd, i, &tmp_item))
{
err_status= TRUE;
break;
@@ -1988,10 +1989,10 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length,
m_name.str));
}
- if (!(m_flags & LOG_SLOW_STATEMENTS) && thd->enable_slow_log)
+ save_enable_slow_log= thd->enable_slow_log;
+ if (!(m_flags & LOG_SLOW_STATEMENTS) && save_enable_slow_log)
{
DBUG_PRINT("info", ("Disabling slow log for the execution"));
- save_enable_slow_log= true;
thd->enable_slow_log= FALSE;
}
if (!(m_flags & LOG_GENERAL_LOG) && !(thd->options & OPTION_LOG_OFF))
@@ -2014,8 +2015,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (save_log_general)
thd->options &= ~OPTION_LOG_OFF;
- if (save_enable_slow_log)
- thd->enable_slow_log= true;
+ thd->enable_slow_log= save_enable_slow_log;
/*
In the case when we weren't able to employ reuse mechanism for
OUT/INOUT paranmeters, we should reallocate memory. This
@@ -2455,8 +2455,7 @@ sp_head::show_create_routine(THD *thd, int type)
if (check_show_routine_access(thd, this, &full_access))
DBUG_RETURN(TRUE);
- sys_var_thd_sql_mode::symbolic_mode_representation(
- thd, m_sql_mode, &sql_mode);
+ sys_var::make_set(thd, m_sql_mode, &sql_mode_typelib, &sql_mode);
/* Send header. */
@@ -3870,7 +3869,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
for (; table ; table= table->next_global)
if (!table->derived && !table->schema_table)
{
- char tname[(NAME_LEN + 1) * 3]; // db\0table\0alias\0
+ char tname[(SAFE_NAME_LEN + 1) * 3]; // db\0table\0alias\0
uint tlen, alen;
tlen= table->db_length;
diff --git a/sql/sp_head.h b/sql/sp_head.h
index da490527f42..cdf1786f2d5 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -1,6 +1,6 @@
/* -*- C++ -*- */
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 8c23b9b49a9..ee33b6f5325 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -654,7 +654,7 @@ int Select_fetch_into_spvars::prepare(List<Item> &fields, SELECT_LEX_UNIT *u)
}
-bool Select_fetch_into_spvars::send_data(List<Item> &items)
+int Select_fetch_into_spvars::send_data(List<Item> &items)
{
List_iterator_fast<struct sp_variable> spvar_iter(*spvar_list);
List_iterator_fast<Item> item_iter(items);
@@ -671,7 +671,7 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items)
for (; spvar= spvar_iter++, item= item_iter++; )
{
if (thd->spcont->set_variable(thd, spvar->offset, &item))
- return TRUE;
+ return 1;
}
- return FALSE;
+ return 0;
}
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index 368a017da21..8da0a4bee82 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -254,7 +254,7 @@ public:
void set_spvar_list(List<struct sp_variable> *vars) { spvar_list= vars; }
virtual bool send_eof() { return FALSE; }
- virtual bool send_data(List<Item> &items);
+ virtual int send_data(List<Item> &items);
virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
};
diff --git a/sql/spatial.cc b/sql/spatial.cc
index ed3d72b91ec..6e2e03bf5bb 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/spatial.h b/sql/spatial.h
index 4159d93c7a7..662c377dc1d 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 6d5d34d0602..89b70032642 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2009-2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -313,7 +314,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
READ_RECORD read_record_info;
my_bool return_val= TRUE;
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
- char tmp_name[NAME_LEN+1];
+ char tmp_name[SAFE_NAME_LEN+1];
int password_length;
ulong old_sql_mode= thd->variables.sql_mode;
DBUG_ENTER("acl_load");
@@ -1203,7 +1204,7 @@ static void acl_update_user(const char *user, const char *host,
{
if ((!acl_user->host.hostname && !host[0]) ||
(acl_user->host.hostname &&
- !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)))
+ !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)))
{
acl_user->access=privileges;
if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
@@ -1287,10 +1288,11 @@ static void acl_update_db(const char *user, const char *host, const char *db,
{
if ((!acl_db->host.hostname && !host[0]) ||
(acl_db->host.hostname &&
- !strcmp(host, acl_db->host.hostname)))
+ !strcmp(host, acl_db->host.hostname)))
{
if ((!acl_db->db && !db[0]) ||
(acl_db->db && !strcmp(db,acl_db->db)))
+
{
if (privileges)
acl_db->access=privileges;
@@ -1662,10 +1664,12 @@ bool change_password(THD *thd, const char *host, const char *user,
result= 0;
if (mysql_bin_log.is_open())
{
- query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'",
- acl_user->user ? acl_user->user : "",
- acl_user->host.hostname ? acl_user->host.hostname : "",
- new_password);
+ query_length=
+ my_sprintf(buff,
+ (buff,"SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'",
+ acl_user->user ? acl_user->user : "",
+ acl_user->host.hostname ? acl_user->host.hostname : "",
+ new_password));
thd->clear_error();
result= thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length,
FALSE, FALSE, 0);
@@ -2464,7 +2468,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
const char *user, const char *tname,
bool exact, bool name_tolower)
{
- char helping [NAME_LEN*2+USERNAME_LENGTH+3], *name_ptr;
+ char helping [SAFE_NAME_LEN*2+USERNAME_LENGTH+3], *name_ptr;
uint len;
GRANT_NAME *grant_name,*found=0;
HASH_SEARCH_STATE state;
@@ -3442,7 +3446,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
{
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str, *tmp_Str;
- char tmp_db[NAME_LEN+1];
+ char tmp_db[SAFE_NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
bool save_binlog_row_based;
@@ -4327,7 +4331,7 @@ static bool check_grant_db_routine(THD *thd, const char *db, HASH *hash)
bool check_grant_db(THD *thd,const char *db)
{
Security_context *sctx= thd->security_ctx;
- char helping [NAME_LEN+USERNAME_LENGTH+2];
+ char helping [SAFE_NAME_LEN + USERNAME_LENGTH+2];
uint len;
bool error= TRUE;
@@ -4464,8 +4468,10 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name,
ulong get_table_grant(THD *thd, TABLE_LIST *table)
{
ulong privilege;
+#ifndef EMBEDDED_LIBRARY
Security_context *sctx= thd->security_ctx;
const char *db = table->db ? table->db : thd->db;
+#endif
GRANT_TABLE *grant_table;
rw_rdlock(&LOCK_grant);
@@ -5432,16 +5438,16 @@ static int handle_grant_struct(uint struct_no, bool drop,
elements= acl_dbs.elements;
break;
case 2:
- elements= column_priv_hash.records;
grant_name_hash= &column_priv_hash;
+ elements= grant_name_hash->records;
break;
case 3:
- elements= proc_priv_hash.records;
grant_name_hash= &proc_priv_hash;
+ elements= grant_name_hash->records;
break;
case 4:
- elements= func_priv_hash.records;
grant_name_hash= &func_priv_hash;
+ elements= grant_name_hash->records;
break;
default:
return -1;
@@ -5634,8 +5640,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
else
{
/* Handle user array. */
- if ((handle_grant_struct(0, drop, user_from, user_to) && ! result) ||
- found)
+ if ((handle_grant_struct(0, drop, user_from, user_to)) || found)
{
result= 1; /* At least one record/element found. */
/* If search is requested, we do not need to search further. */
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 24169fddb97..91b7e2a8636 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -248,7 +248,8 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
}
DBUG_RETURN(0);
}
- for (str++; *(end - 1) == '0'; end--) ; // jump over zeros at the end
+ for (str++; *(end - 1) == '0'; end--) // jump over zeros at the end
+ ;
if (str == end) // number was something like '123.000'
{
char *endpos= (char*) str;
@@ -410,7 +411,7 @@ void field_real::add()
if ((decs = decimals()) == NOT_FIXED_DEC)
{
- length= sprintf(buff, "%g", num);
+ length= my_sprintf(buff, (buff, "%g", num));
if (rint(num) != num)
max_notzero_dec_len = 1;
}
@@ -421,7 +422,7 @@ void field_real::add()
snprintf(buff, sizeof(buff)-1, "%-.*f", (int) decs, num);
length = (uint) strlen(buff);
#else
- length= sprintf(buff, "%-.*f", (int) decs, num);
+ length= my_sprintf(buff, (buff, "%-.*f", (int) decs, num));
#endif
// We never need to check further than this
@@ -754,7 +755,7 @@ int analyse::end_of_records()
tmp_str.append(STRING_WITH_LEN(" NOT NULL"));
output_str_length = tmp_str.length();
func_items[9]->set(tmp_str.ptr(), tmp_str.length(), tmp_str.charset());
- if (result->send_data(result_fields))
+ if (result->send_data(result_fields) > 0)
return -1;
continue;
}
@@ -799,7 +800,7 @@ int analyse::end_of_records()
if (!(*f)->nulls)
ans.append(STRING_WITH_LEN(" NOT NULL"));
func_items[9]->set(ans.ptr(), ans.length(), ans.charset());
- if (result->send_data(result_fields))
+ if (result->send_data(result_fields) > 0)
return -1;
}
return 0;
@@ -1008,9 +1009,9 @@ void field_decimal::get_opt_type(String *answer,
my_decimal_set_zero(&zero);
my_bool is_unsigned= (my_decimal_cmp(&zero, &min_arg) >= 0);
- length= my_snprintf(buff, sizeof(buff), "DECIMAL(%d, %d)",
- (int) (max_length - (item->decimals ? 1 : 0)),
- item->decimals);
+ length= my_sprintf(buff, (buff, "DECIMAL(%d, %d)",
+ (int) (max_length - (item->decimals ? 1 : 0)),
+ item->decimals));
if (is_unsigned)
length= (uint) (strmov(buff+length, " UNSIGNED")- buff);
answer->append(buff, length);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ace78947054..54921500e93 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -240,8 +240,12 @@ static void check_unused(void)
uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list,
bool tmp_table)
{
- uint key_length= (uint) (strmov(strmov(key, table_list->db)+1,
- table_list->table_name)-key)+1;
+ char *db_end= strnmov(key, table_list->db, MAX_DBKEY_LENGTH - 2);
+ *db_end++= '\0';
+ char *table_end= strnmov(db_end, table_list->table_name,
+ key + MAX_DBKEY_LENGTH - 1 - db_end);
+ *table_end++= '\0';
+ uint key_length= (uint) (table_end-key);
if (tmp_table)
{
int4store(key + key_length, thd->server_id);
@@ -482,8 +486,8 @@ static TABLE_SHARE
@todo Rework alternative ways to deal with ER_NO_SUCH TABLE.
*/
- if (share || (thd->is_error() && thd->main_da.sql_errno() != ER_NO_SUCH_TABLE))
-
+ if (share ||
+ (thd->is_error() && thd->main_da.sql_errno() != ER_NO_SUCH_TABLE))
DBUG_RETURN(share);
/* Table didn't exist. Check if some engine can provide it */
@@ -616,7 +620,7 @@ void release_table_share(TABLE_SHARE *share, enum release_type type)
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
{
- char key[NAME_LEN*2+2];
+ char key[SAFE_NAME_LEN*2+2];
TABLE_LIST table_list;
uint key_length;
safe_mutex_assert_owner(&LOCK_open);
@@ -937,7 +941,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
for (TABLE_LIST *table= tables; table; table= table->next_local)
{
if (remove_table_from_cache(thd, table->db, table->table_name,
- RTFC_OWNED_BY_THD_FLAG))
+ RTFC_OWNED_BY_THD_FLAG, table->deleting))
found=1;
}
if (!found)
@@ -2035,6 +2039,8 @@ static void unlink_open_merge(THD *thd, TABLE *table, TABLE ***prev_pp)
Remove parent from open_tables list and close it.
This includes detaching and hence clearing parent references.
*/
+ DBUG_PRINT("info", ("Closing parent to '%s'.'%s'",
+ table->s->db.str, table->s->table_name.str));
close_thread_table(thd, prv_p);
}
}
@@ -2148,6 +2154,7 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock)
void drop_open_table(THD *thd, TABLE *table, const char *db_name,
const char *table_name)
{
+ DBUG_ENTER("drop_open_table");
if (table->s->tmp_table)
close_temporary_table(thd, table, 1, 1);
else
@@ -2158,10 +2165,12 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name,
unlink_open_table() also tells threads waiting for refresh or close
that something has happened.
*/
+ table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
unlink_open_table(thd, table, FALSE);
quick_rm_table(table_type, db_name, table_name, 0);
VOID(pthread_mutex_unlock(&LOCK_open));
}
+ DBUG_VOID_RETURN;
}
@@ -3013,6 +3022,13 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->pos_in_table_list= table_list;
table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
table->clear_column_bitmaps();
+#if !defined(DBUG_OFF) && !defined(HAVE_valgrind)
+ /*
+ Fill record with random values to find bugs where we access fields
+ without first reading them.
+ */
+ bfill(table->record[0], table->s->reclength, 254);
+#endif
DBUG_ASSERT(table->key_read == 0);
DBUG_RETURN(table);
}
@@ -3058,8 +3074,9 @@ bool reopen_table(TABLE *table)
TABLE_LIST table_list;
THD *thd= table->in_use;
DBUG_ENTER("reopen_table");
- DBUG_PRINT("tcache", ("table: '%s'.'%s' 0x%lx", table->s->db.str,
- table->s->table_name.str, (long) table));
+ DBUG_PRINT("tcache", ("table: '%s'.'%s' table: 0x%lx share: 0x%lx",
+ table->s->db.str, table->s->table_name.str,
+ (long) table, (long) table->s));
DBUG_ASSERT(table->s->ref_count == 0);
DBUG_ASSERT(!table->sort.io_cache);
@@ -3324,7 +3341,6 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
const uint flags= MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN |
MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK |
MYSQL_LOCK_IGNORE_FLUSH;
-
DBUG_ENTER("reopen_tables");
if (!thd->open_tables)
@@ -3432,9 +3448,13 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
}
continue;
}
- my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
- VOID(hash_delete(&open_cache, (uchar *) table));
- error= 1;
+ my_error(ER_CANT_REOPEN_TABLE, MYF(0),
+ table->alias ? table->alias : table->s->table_name.str);
+ unlink_open_table(thd, table, 0);
+ /* Restart loop, as one of the used tables may now be closed */
+ prev= &thd->open_tables;
+ next= *prev;
+ error=1;
}
*prev=0;
/*
@@ -3483,7 +3503,7 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old)
}
DBUG_PRINT("tcache", ("open tables to lock: %u",
(uint) (tables_ptr - tables)));
- if (tables != tables_ptr) // Should we get back old locks
+ if (tables != tables_ptr) // Should we get back old locks
{
MYSQL_LOCK *lock;
/*
@@ -3562,6 +3582,11 @@ static void close_old_data_files(THD *thd, TABLE *table, bool morph_locks,
if (ulcktbl->lock_count)
{
/*
+ Inform handler that we will do a close even if the table may be
+ locked or part of a transaction
+ */
+ table->file->extra(HA_EXTRA_PREPARE_FOR_FORCED_CLOSE);
+ /*
Wake up threads waiting for table-level lock on this table
so they won't sneak in when we will temporarily remove our
lock on it. This will also give them a chance to close their
@@ -3627,7 +3652,7 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock)
char *key= table->s->table_cache_key.str;
uint key_length= table->s->table_cache_key.length;
- DBUG_PRINT("loop", ("table_name: %s", table->alias));
+ DBUG_PRINT("loop", ("table_name: %s", table->alias ? table->alias : ""));
HASH_SEARCH_STATE state;
for (TABLE *search= (TABLE*) hash_first(&open_cache, (uchar*) key,
key_length, &state);
@@ -3736,6 +3761,9 @@ TABLE *drop_locked_tables(THD *thd,const char *db, const char *table_name)
if (!strcmp(table->s->table_name.str, table_name) &&
!strcmp(table->s->db.str, db))
{
+ /* Inform handler that table will be dropped after close */
+ table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
+
/* If MERGE child, forward lock handling to parent. */
mysql_lock_remove(thd, thd->locked_tables,
table->parent ? table->parent : table, TRUE);
@@ -3962,6 +3990,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list,
int error;
TABLE_SHARE *share;
uint discover_retry_count= 0;
+ bool locked_table;
DBUG_ENTER("open_unireg_entry");
safe_mutex_assert_owner(&LOCK_open);
@@ -4082,8 +4111,10 @@ retry:
}
if (!entry->s || !entry->s->crashed)
goto err;
- // Code below is for repairing a crashed file
- if ((error= lock_table_name(thd, table_list, TRUE)))
+
+ // Code below is for repairing a crashed file
+ locked_table= table_list->table != 0;
+ if (! locked_table && (error= lock_table_name(thd, table_list, TRUE)))
{
if (error < 0)
goto err;
@@ -4117,12 +4148,13 @@ retry:
else
thd->clear_error(); // Clear error message
pthread_mutex_lock(&LOCK_open);
- unlock_table_name(thd, table_list);
+ if (!locked_table)
+ unlock_table_name(thd, table_list);
if (error)
goto err;
break;
- }
+ }
if (Table_triggers_list::check_n_load(thd, share->db.str,
share->table_name.str, entry, 0))
@@ -4350,7 +4382,6 @@ void detach_merge_children(TABLE *table, bool clear_refs)
{
TABLE_LIST *child_l;
TABLE *parent= table->child_l ? table : table->parent;
- bool first_detach;
DBUG_ENTER("detach_merge_children");
/*
Either table->child_l or table->parent must be set. Parent must have
@@ -4368,7 +4399,7 @@ void detach_merge_children(TABLE *table, bool clear_refs)
children attached yet. Also this is called for every child and the
parent from close_thread_tables().
*/
- if ((first_detach= parent->children_attached))
+ if (parent->children_attached)
{
VOID(parent->file->extra(HA_EXTRA_DETACH_CHILDREN));
parent->children_attached= FALSE;
@@ -4380,38 +4411,50 @@ void detach_merge_children(TABLE *table, bool clear_refs)
if (clear_refs)
{
- /* In any case clear the own parent reference. (***) */
- table->parent= NULL;
+ if (table->parent)
+ {
+ /* In any case clear the own parent reference. (***) */
+ table->parent= NULL;
+ table->file->extra(HA_EXTRA_DETACH_CHILD);
+ }
/*
- On the first detach, clear all references. If this table is the
- parent, we still may need to clear the child references. The first
- detach might not have done this.
+ Clear all references. If this table is the parent, we still may
+ need to clear the child references. The first detach might not
+ have done this.
*/
- if (first_detach || (table == parent))
+ for (child_l= parent->child_l; ; child_l= child_l->next_global)
{
- /* Clear TABLE references to force new assignment at next open. */
- for (child_l= parent->child_l; ; child_l= child_l->next_global)
+ /*
+ Do not DBUG_ASSERT(child_l->table); open_tables might be
+ incomplete or we may have been called twice.
+
+ Clear the parent reference of the children only on the first
+ detach. The children might already be closed. They will clear
+ it themselves when this function is called for them with
+ 'clear_refs' true. See above "(***)".
+ */
+ if (child_l->table)
{
+ if (child_l->table->parent)
+ {
+ child_l->table->parent= NULL;
+ if (child_l->table->db_stat)
+ child_l->table->file->extra(HA_EXTRA_DETACH_CHILD);
+ }
/*
- Do not DBUG_ASSERT(child_l->table); open_tables might be
- incomplete.
-
- Clear the parent reference of the children only on the first
- detach. The children might already be closed. They will clear
- it themseves when this function is called for them with
- 'clear_refs' true. See above "(***)".
+ Set alias to "" to ensure that table is not used if we are in
+ LOCK TABLES
*/
- if (first_detach && child_l->table)
- child_l->table->parent= NULL;
+ ((char*) child_l->table->alias)[0]= 0;
/* Clear the table reference to force new assignment at next open. */
child_l->table= NULL;
-
- /* Break when this was the last child. */
- if (&child_l->next_global == parent->child_last_l)
- break;
}
+
+ /* Break when this was the last child. */
+ if (&child_l->next_global == parent->child_last_l)
+ break;
}
}
@@ -4603,8 +4646,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
/* Also used for indicating that prelocking is need */
TABLE_LIST **query_tables_last_own;
bool safe_to_ignore_table;
-
DBUG_ENTER("open_tables");
+
/*
temporary mem_root for new .frm parsing.
TODO: variables for size
@@ -5208,9 +5251,11 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags)
static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
{
+ DBUG_ENTER("mark_real_tables_as_free_for_reuse");
for (; table; table= table->next_global)
if (!table->placeholder())
table->table->query_id= 0;
+ DBUG_VOID_RETURN;
}
@@ -6012,6 +6057,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
{
/* This is a base table. */
DBUG_ASSERT(nj_col->view_field == NULL);
+ Item *ref= 0;
/*
This fix_fields is not necessary (initially this item is fixed by
the Item_field constructor; after reopen_tables the Item_func_eq
@@ -6019,12 +6065,13 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
reopening for columns that was dropped by the concurrent connection.
*/
if (!nj_col->table_field->fixed &&
- nj_col->table_field->fix_fields(thd, (Item **)&nj_col->table_field))
+ nj_col->table_field->fix_fields(thd, &ref))
{
DBUG_PRINT("info", ("column '%s' was dropped by the concurrent connection",
nj_col->table_field->name));
DBUG_RETURN(NULL);
}
+ DBUG_ASSERT(ref == 0); // Should not have changed
DBUG_ASSERT(nj_col->table_ref->table == nj_col->table_field->field->table);
found_field= nj_col->table_field->field;
update_field_dependencies(thd, found_field, nj_col->table_ref->table);
@@ -6392,7 +6439,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
const char *table_name= item->table_name;
const char *name= item->field_name;
uint length=(uint) strlen(name);
- char name_buff[NAME_LEN+1];
+ char name_buff[SAFE_NAME_LEN+1];
TABLE_LIST *cur_table= first_table;
TABLE_LIST *actual_table;
bool allow_rowid;
@@ -6557,7 +6604,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
(report_error == REPORT_ALL_ERRORS ||
report_error == REPORT_EXCEPT_NON_UNIQUE))
{
- char buff[NAME_LEN*2 + 2];
+ char buff[SAFE_NAME_LEN*2 + 2];
if (db && db[0])
{
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
@@ -7591,6 +7638,9 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
/* make * substituting permanent */
SELECT_LEX *select_lex= thd->lex->current_select;
select_lex->with_wild= 0;
+#ifdef HAVE_valgrind
+ if (&select_lex->item_list != &fields) // Avoid warning
+#endif
/*
The assignment below is translated to memcpy() call (at least on some
platforms). memcpy() expects that source and destination areas do not
@@ -7940,7 +7990,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
{
Field_iterator_table_ref field_iterator;
bool found;
- char name_buff[NAME_LEN+1];
+ char name_buff[SAFE_NAME_LEN+1];
DBUG_ENTER("insert_fields");
DBUG_PRINT("arena", ("stmt arena: 0x%lx", (ulong)thd->stmt_arena));
@@ -7976,7 +8026,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
DBUG_ASSERT(tables->is_leaf_for_name_resolution());
if ((table_name && my_strcasecmp(table_alias_charset, table_name,
- tables->alias)) ||
+ tables->alias)) ||
(db_name && strcmp(tables->db,db_name)))
continue;
@@ -8222,7 +8272,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
/* Make a join an a expression */
thd->where="on clause";
if ((!embedded->on_expr->fixed &&
- embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
+ embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
embedded->on_expr->check_cols(1))
goto err_no_arena;
select_lex->cond_count++;
@@ -8378,7 +8428,7 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
{
return (fill_record(thd, fields, values, ignore_errors) ||
(triggers && triggers->process_triggers(thd, event,
- TRG_ACTION_BEFORE, TRUE)));
+ TRG_ACTION_BEFORE, TRUE)));
}
@@ -8473,7 +8523,7 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
{
return (fill_record(thd, ptr, values, ignore_errors) ||
(triggers && triggers->process_triggers(thd, event,
- TRG_ACTION_BEFORE, TRUE)));
+ TRG_ACTION_BEFORE, TRUE)));
}
@@ -8518,7 +8568,7 @@ my_bool mysql_rm_tmp_tables(void)
uint filePath_len= my_snprintf(filePath, sizeof(filePath),
"%s%c%s", tmpdir, FN_LIBCHAR,
file->name);
- if (!memcmp(reg_ext, ext, ext_len))
+ if (!strcmp(reg_ext, ext))
{
handler *handler_file= 0;
/* We should cut file extention before deleting of table */
@@ -8576,6 +8626,11 @@ void remove_db_from_cache(const char *db)
if (!strcmp(table->s->db.str, db))
{
table->s->version= 0L; /* Free when thread is ready */
+ /*
+ This functions only called from DROP DATABASE code, so we are going
+ to drop all tables so we mark them as deleting
+ */
+ table->s->deleting= TRUE;
if (!table->in_use)
relink_unused(table);
}
@@ -8618,7 +8673,7 @@ void flush_tables()
*/
bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
- uint flags)
+ uint flags, my_bool deleting)
{
char key[MAX_DBKEY_LENGTH];
uint key_length;
@@ -8665,19 +8720,26 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
result=1;
}
/* Kill delayed insert threads */
- if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
- ! in_use->killed)
+ if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT))
{
- in_use->killed= THD::KILL_CONNECTION;
- pthread_mutex_lock(&in_use->mysys_var->mutex);
- if (in_use->mysys_var->current_cond)
- {
- pthread_mutex_lock(in_use->mysys_var->current_mutex);
- signalled= 1;
- pthread_cond_broadcast(in_use->mysys_var->current_cond);
- pthread_mutex_unlock(in_use->mysys_var->current_mutex);
- }
- pthread_mutex_unlock(&in_use->mysys_var->mutex);
+ if (!in_use->killed)
+ {
+ in_use->killed= THD::KILL_CONNECTION;
+ pthread_mutex_lock(&in_use->mysys_var->mutex);
+ if (in_use->mysys_var->current_cond)
+ {
+ pthread_mutex_lock(in_use->mysys_var->current_mutex);
+ signalled= 1;
+ pthread_cond_broadcast(in_use->mysys_var->current_cond);
+ pthread_mutex_unlock(in_use->mysys_var->current_mutex);
+ }
+ pthread_mutex_unlock(&in_use->mysys_var->mutex);
+ }
+ /*
+ Don't abort locks. Instead give the delayed insert thread
+ time to finish it's inserts and die gracefully.
+ */
+ continue;
}
/*
Now we must abort all tables locks used by this thread
@@ -8705,7 +8767,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
}
}
while (unused_tables && !unused_tables->s->version)
+ {
+ unused_tables->s->deleting= deleting;
VOID(hash_delete(&open_cache,(uchar*) unused_tables));
+ }
DBUG_PRINT("info", ("Removing table from table_def_cache"));
/* Remove table from table definition cache if it's not in use */
@@ -8903,7 +8968,7 @@ int abort_and_upgrade_lock_and_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
/* If MERGE child, forward lock handling to parent. */
mysql_lock_abort(thd, lpt->table->parent ? lpt->table->parent : lpt->table,
TRUE);
- if (remove_table_from_cache(thd, db, table_name, flags))
+ if (remove_table_from_cache(thd, db, table_name, flags, FALSE))
{
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(1);
@@ -8933,7 +8998,7 @@ void close_open_tables_and_downgrade(ALTER_PARTITION_PARAM_TYPE *lpt)
{
VOID(pthread_mutex_lock(&LOCK_open));
remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name,
- RTFC_WAIT_OTHER_THREAD_FLAG);
+ RTFC_WAIT_OTHER_THREAD_FLAG, FALSE);
VOID(pthread_mutex_unlock(&LOCK_open));
/* If MERGE child, forward lock handling to parent. */
mysql_lock_downgrade_write(lpt->thd, lpt->table->parent ? lpt->table->parent :
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 1d95876c73c..1624a9639a1 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
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
@@ -75,7 +75,7 @@ void mysql_client_binlog_statement(THD* thd)
if (!rli)
{
rli= thd->rli_fake= new Relay_log_info;
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
rli->is_fake= TRUE;
#endif
have_fd_event= FALSE;
@@ -111,7 +111,7 @@ void mysql_client_binlog_statement(THD* thd)
char const *endptr= 0;
int bytes_decoded= base64_decode(strptr, coded_len, buf, &endptr);
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
/*
This debug printout should not be used for valgrind builds
since it will read from unassigned memory.
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h
index 97accefe8aa..e07806a56ab 100644
--- a/sql/sql_bitmap.h
+++ b/sql/sql_bitmap.h
@@ -93,6 +93,34 @@ public:
}
};
+/* An iterator to quickly walk over bits in unlonglong bitmap. */
+class Table_map_iterator
+{
+ ulonglong bmp;
+ uint no;
+public:
+ Table_map_iterator(ulonglong t) : bmp(t), no(0) {}
+ int next_bit()
+ {
+ static const char last_bit[16]= {32, 0, 1, 0,
+ 2, 0, 1, 0,
+ 3, 0, 1, 0,
+ 2, 0, 1, 0};
+ uint bit;
+ while ((bit= last_bit[bmp & 0xF]) == 32)
+ {
+ no += 4;
+ bmp= bmp >> 4;
+ if (!bmp)
+ return BITMAP_END;
+ }
+ bmp &= ~(1LL << bit);
+ return no + bit;
+ }
+ int operator++(int) { return next_bit(); }
+ enum { BITMAP_END= 64 };
+};
+
template <> class Bitmap<64>
{
ulonglong map;
@@ -136,5 +164,10 @@ public:
my_bool operator==(const Bitmap<64>& map2) const { return map == map2.map; }
char *print(char *buf) const { longlong2str(map,buf,16); return buf; }
ulonglong to_ulonglong() const { return map; }
+ class Iterator : public Table_map_iterator
+ {
+ public:
+ Iterator(Bitmap<64> &bmp) : Table_map_iterator(bmp.map) {}
+ };
};
diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in
index 3becdbaccfe..7ecd4918d7b 100644
--- a/sql/sql_builtin.cc.in
+++ b/sql/sql_builtin.cc.in
@@ -13,6 +13,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+#include <my_global.h>
#include <mysql/plugin.h>
typedef struct st_mysql_plugin builtin_plugin[];
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index b791428eef0..1fa21d271c7 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -379,9 +379,11 @@ TODO list:
static void debug_wait_for_kill(const char *info)
{
- DBUG_ENTER("debug_wait_for_kill");
const char *prev_info;
THD *thd;
+ char buff[1024];
+ DBUG_ENTER("debug_wait_for_kill");
+
thd= current_thd;
prev_info= thd->proc_info;
thd->proc_info= info;
@@ -389,8 +391,16 @@ static void debug_wait_for_kill(const char *info)
while(!thd->killed)
my_sleep(1000);
thd->killed= THD::NOT_KILLED;
+ /*
+ Remove the set debug variable, to ensure we don't get stuck on it again
+ This is needed as for MyISAM, invalidate_table() may be called twice
+ (Once from mysql_delete() and once from mi_update_status())
+ */
+ sprintf(buff, "-d,%s", info);
+ DBUG_SET(buff);
sql_print_information("Exit debug_wait_for_kill");
thd->proc_info= prev_info;
+
DBUG_VOID_RETURN;
}
@@ -916,15 +926,18 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
void query_cache_abort(NET *net)
{
+ THD *thd;
DBUG_ENTER("query_cache_abort");
- THD *thd= current_thd;
/* See the comment on double-check locking usage above. */
if (net->query_cache_query == 0)
DBUG_VOID_RETURN;
if (query_cache.try_lock())
+ {
+ net->query_cache_query = 0;
DBUG_VOID_RETURN;
+ }
/*
While we were waiting another thread might have changed the status
@@ -934,6 +947,7 @@ void query_cache_abort(NET *net)
net->query_cache_query);
if (query_block)
{
+ thd= current_thd;
thd_proc_info(thd, "storing result in query cache");
DUMP(&query_cache);
BLOCK_LOCK_WR(query_block);
@@ -943,6 +957,7 @@ void query_cache_abort(NET *net)
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
}
+ DBUG_ASSERT(!net->query_cache_query);
query_cache.unlock();
DBUG_VOID_RETURN;
}
@@ -972,8 +987,12 @@ void query_cache_end_of_result(THD *thd)
#endif
if (query_cache.try_lock())
+ {
+ thd->net.query_cache_query= 0;
DBUG_VOID_RETURN;
+ }
+ /* thd->net.query_cache_query may have changed during resize */
query_block= ((Query_cache_block*) thd->net.query_cache_query);
if (query_block)
{
@@ -999,8 +1018,8 @@ void query_cache_end_of_result(THD *thd)
to this function. In the release version that query should be ignored
and removed from QC.
*/
- DBUG_ASSERT(0);
query_cache.free_query(query_block);
+ thd->net.query_cache_query= 0;
query_cache.unlock();
DBUG_VOID_RETURN;
}
@@ -1388,8 +1407,8 @@ send_data_in_chunks(NET *net, const uchar *packet, ulong len)
to the user.
RESULTS
- 1 Query was not cached.
- 0 The query was cached and user was sent the result.
+ 0 Query was not cached.
+ 1 The query was cached and user was sent the result.
-1 The query was cached but we didn't have rights to use it.
No error is sent to the client yet.
@@ -1403,7 +1422,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
{
ulonglong engine_data;
Query_cache_query *query;
- Query_cache_block *first_result_block, *result_block;
+#ifndef EMBEDDED_LIBRARY
+ Query_cache_block *first_result_block;
+#endif
+ Query_cache_block *result_block;
Query_cache_block_table *block_table, *block_table_end;
ulong tot_length;
Query_cache_query_flags flags;
@@ -1563,7 +1585,10 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
BLOCK_LOCK_RD(query_block);
query = query_block->query();
- result_block= first_result_block= query->result();
+ result_block= query->result();
+#ifndef EMBEDDED_LIBRARY
+ first_result_block= result_block;
+#endif
if (result_block == 0 || result_block->type != Query_cache_block::RESULT)
{
@@ -1706,6 +1731,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
thd->limit_found_rows = query->found_rows();
thd->status_var.last_query_cost= 0.0;
+ thd->query_plan_flags= (thd->query_plan_flags & ~QPLAN_QC_NO) | QPLAN_QC;
if (!thd->main_da.is_set())
thd->main_da.disable_status();
@@ -1715,6 +1741,10 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
err_unlock:
unlock();
err:
+ /*
+ query_plan_flags doesn't have to be changed here as it contains
+ QPLAN_QC_NO by default
+ */
DBUG_RETURN(0); // Query was not cached
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7fb1d2ade5f..49710d5dbcc 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -266,14 +267,17 @@ int thd_tablespace_op(const THD *thd)
extern "C"
-const char *set_thd_proc_info(THD *thd, const char *info,
- const char *calling_function,
- const char *calling_file,
+const char *set_thd_proc_info(THD *thd, const char *info,
+ const char *calling_function,
+ const char *calling_file,
const unsigned int calling_line)
{
+ if (!thd)
+ thd= current_thd;
+
const char *old_info= thd->proc_info;
- DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line,
- (info != NULL) ? info : "(null)"));
+ DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line,
+ (info != NULL) ? info : ""));
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.status_change(info, calling_function, calling_file, calling_line);
#endif
@@ -473,6 +477,7 @@ bool Drop_table_error_handler::handle_error(uint sql_errno,
void
Diagnostics_area::reset_diagnostics_area()
{
+ DBUG_ENTER("reset_diagnostics_area");
#ifdef DBUG_OFF
can_overwrite_status= FALSE;
/** Don't take chances in production */
@@ -486,6 +491,7 @@ Diagnostics_area::reset_diagnostics_area()
is_sent= FALSE;
/** Tiny reset in debug mode to see garbage right away */
m_status= DA_EMPTY;
+ DBUG_VOID_RETURN;
}
@@ -499,16 +505,14 @@ Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
ulonglong last_insert_id_arg,
const char *message_arg)
{
+ DBUG_ENTER("set_ok_status");
DBUG_ASSERT(! is_set());
-#ifdef DBUG_OFF
/*
In production, refuse to overwrite an error or a custom response
with an OK packet.
*/
if (is_error() || is_disabled())
return;
-#endif
- /** Only allowed to report success if has not yet reported an error */
m_server_status= thd->server_status;
m_total_warn_count= thd->total_warn_count;
@@ -519,6 +523,7 @@ Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
else
m_message[0]= '\0';
m_status= DA_OK;
+ DBUG_VOID_RETURN;
}
@@ -529,17 +534,15 @@ Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
void
Diagnostics_area::set_eof_status(THD *thd)
{
- /** Only allowed to report eof if has not yet reported an error */
-
+ DBUG_ENTER("set_eof_status");
+ /* Only allowed to report eof if has not yet reported an error */
DBUG_ASSERT(! is_set());
-#ifdef DBUG_OFF
/*
In production, refuse to overwrite an error or a custom response
with an EOF packet.
*/
if (is_error() || is_disabled())
return;
-#endif
m_server_status= thd->server_status;
/*
@@ -550,6 +553,7 @@ Diagnostics_area::set_eof_status(THD *thd)
m_total_warn_count= thd->spcont ? 0 : thd->total_warn_count;
m_status= DA_EOF;
+ DBUG_VOID_RETURN;
}
/**
@@ -560,6 +564,7 @@ void
Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
const char *message_arg)
{
+ DBUG_ENTER("set_error_status");
/*
Only allowed to report error if has not yet reported a success
The only exception is when we flush the message to the client,
@@ -576,9 +581,10 @@ Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
#endif
m_sql_errno= sql_errno_arg;
- strmake(m_message, message_arg, sizeof(m_message) - 1);
+ strmake(m_message, message_arg, sizeof(m_message)-1);
m_status= DA_ERROR;
+ DBUG_VOID_RETURN;
}
@@ -638,6 +644,8 @@ THD::THD()
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
stmt_arena= this;
thread_stack= 0;
+ scheduler= &thread_scheduler; // Will be fixed later
+ extra_port= 0;
catalog= (char*)"std"; // the only catalog we have for now
main_security_ctx.init();
security_ctx= &main_security_ctx;
@@ -691,6 +699,10 @@ THD::THD()
peer_port= 0; // For SHOW PROCESSLIST
transaction.m_pending_rows_event= 0;
transaction.on= 1;
+ wt_thd_lazy_init(&transaction.wt, &variables.wt_deadlock_search_depth_short,
+ &variables.wt_timeout_short,
+ &variables.wt_deadlock_search_depth_long,
+ &variables.wt_timeout_long);
#ifdef SIGNAL_WITH_VIO_CLOSE
active_vio = 0;
#endif
@@ -732,7 +744,7 @@ THD::THD()
tablespace_op=FALSE;
tmp= sql_rnd_with_mutex();
- randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
+ my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
substitute_null_with_insert_id = FALSE;
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
thr_lock_owner_init(&main_lock_id, &lock_info);
@@ -768,7 +780,6 @@ bool THD::handle_error(uint sql_errno, const char *message,
if (error_handler->handle_error(sql_errno, message, level, this))
return TRUE;
}
-
return FALSE;
}
@@ -960,6 +971,7 @@ void THD::cleanup(void)
lock=locked_tables; locked_tables=0;
close_thread_tables(this);
}
+ wt_thd_destroy(&transaction.wt);
#if defined(ENABLED_DEBUG_SYNC)
/* End the Debug Sync Facility. See debug_sync.cc. */
@@ -973,7 +985,7 @@ void THD::cleanup(void)
my_free((char*) variables.time_format, MYF(MY_ALLOW_ZERO_PTR));
my_free((char*) variables.date_format, MYF(MY_ALLOW_ZERO_PTR));
my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
-
+
sp_cache_clear(&sp_proc_cache);
sp_cache_clear(&sp_func_cache);
@@ -1011,6 +1023,7 @@ THD::~THD()
#endif
stmt_map.reset(); /* close all prepared statements */
DBUG_ASSERT(lock_info.n_cursors == 0);
+
if (!cleanup_done)
cleanup();
@@ -1098,6 +1111,14 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent;
}
+#define SECONDS_TO_WAIT_FOR_KILL 2
+#if !defined(__WIN__) && defined(HAVE_SELECT)
+/* my_sleep() can wait for sub second times */
+#define WAIT_FOR_KILL_TRY_TIMES 20
+#else
+#define WAIT_FOR_KILL_TRY_TIMES 2
+#endif
+
void THD::awake(THD::killed_state state_to_set)
{
@@ -1152,12 +1173,35 @@ void THD::awake(THD::killed_state state_to_set)
we issue a second KILL or the status it's waiting for happens).
It's true that we have set its thd->killed but it may not
see it immediately and so may have time to reach the cond_wait().
+
+ We have to do the loop with trylock, because if we would use
+ pthread_mutex_lock(), we can cause a deadlock as we are here locking
+ the mysys_var->mutex and mysys_var->current_mutex in a different order
+ than in the thread we are trying to kill.
+ We only sleep for 2 seconds as we don't want to have LOCK_thd_data
+ locked too long time.
+
+ There is a small change we may not succeed in aborting a thread that
+ is not yet waiting for a mutex, but as this happens only for a
+ thread that was doing something else when the kill was issued and
+ which should detect the kill flag before it starts to wait, this
+ should be good enough.
*/
if (mysys_var->current_cond && mysys_var->current_mutex)
{
- pthread_mutex_lock(mysys_var->current_mutex);
- pthread_cond_broadcast(mysys_var->current_cond);
- pthread_mutex_unlock(mysys_var->current_mutex);
+ uint i;
+ for (i= 0; i < WAIT_FOR_KILL_TRY_TIMES * SECONDS_TO_WAIT_FOR_KILL; i++)
+ {
+ int ret= pthread_mutex_trylock(mysys_var->current_mutex);
+ pthread_cond_broadcast(mysys_var->current_cond);
+ if (!ret)
+ {
+ /* Signal is sure to get through */
+ pthread_mutex_unlock(mysys_var->current_mutex);
+ break;
+ }
+ }
+ my_sleep(1000000L / WAIT_FOR_KILL_TRY_TIMES);
}
pthread_mutex_unlock(&mysys_var->mutex);
}
@@ -1187,12 +1231,23 @@ bool THD::store_globals()
*/
mysys_var->id= thread_id;
real_id= pthread_self(); // For debugging
+ mysys_var->stack_ends_here= thread_stack + // for consistency, see libevent_thread_proc
+ STACK_DIRECTION * (long)my_thread_stack_size;
/*
We have to call thr_lock_info_init() again here as THD may have been
created in another thread
*/
thr_lock_info_init(&lock_info);
+
+#ifdef SAFE_MUTEX
+ /* Register order of mutex for wrong mutex deadlock detector */
+ pthread_mutex_lock(&LOCK_thd_data);
+ pthread_mutex_lock(&mysys_var->mutex);
+
+ pthread_mutex_unlock(&mysys_var->mutex);
+ pthread_mutex_unlock(&LOCK_thd_data);
+#endif
return 0;
}
@@ -1216,6 +1271,19 @@ bool THD::restore_globals()
}
+/**
+ Untie THD from current thread
+
+ Used when using --thread-handling=pool-of-threads
+*/
+
+void THD::reset_globals()
+{
+ pthread_mutex_lock(&LOCK_thd_data);
+ mysys_var= 0;
+ pthread_mutex_unlock(&LOCK_thd_data);
+}
+
/*
Cleanup after query.
@@ -1575,6 +1643,36 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
change_list.append(change);
}
+/**
+ Check and register item change if needed
+
+ @param place place where we should assign new value
+ @param new_value place of the new value
+
+ @details
+ Let C be a reference to an item that changed the reference A
+ at the location (occurrence) L1 and this change has been registered.
+ If C is substituted for reference A another location (occurrence) L2
+ that is to be registered as well than this change has to be
+ consistent with the first change in order the procedure that rollback
+ changes to substitute the same reference at both locations L1 and L2.
+*/
+
+void THD::check_and_register_item_tree_change(Item **place, Item **new_value,
+ MEM_ROOT *runtime_memroot)
+{
+ Item_change_record *change;
+ I_List_iterator<Item_change_record> it(change_list);
+ while ((change= it++))
+ {
+ if (change->place == new_value)
+ break; // we need only very first value
+ }
+ if (change)
+ nocheck_register_item_tree_change(place, change->old_value,
+ runtime_memroot);
+}
+
void THD::rollback_item_tree_changes()
{
@@ -1597,7 +1695,7 @@ void THD::rollback_item_tree_changes()
select_result::select_result()
{
thd=current_thd;
- nest_level= -1;
+ nest_level= (uint) -1;
}
void select_result::send_error(uint errcode,const char *err)
@@ -1682,7 +1780,7 @@ void select_send::cleanup()
/* Send data to client. Returns 0 if ok */
-bool select_send::send_data(List<Item> &items)
+int select_send::send_data(List<Item> &items)
{
if (unit->offset_limit_cnt)
{ // using limit offset,count
@@ -1991,7 +2089,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
(int) (uchar) (x) == line_sep_char || \
!(x))
-bool select_export::send_data(List<Item> &items)
+int select_export::send_data(List<Item> &items)
{
DBUG_ENTER("select_export::send_data");
@@ -2059,7 +2157,7 @@ bool select_export::send_data(List<Item> &items)
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
"string", printable_buff,
- item->name, static_cast<long>(row_count));
+ item->name, (ulong) row_count);
}
else if (from_end_pos < res->ptr() + res->length())
{
@@ -2249,7 +2347,7 @@ select_dump::prepare(List<Item> &list __attribute__((unused)),
}
-bool select_dump::send_data(List<Item> &items)
+int select_dump::send_data(List<Item> &items)
{
List_iterator_fast<Item> li(items);
char buff[MAX_FIELD_WIDTH];
@@ -2294,7 +2392,7 @@ select_subselect::select_subselect(Item_subselect *item_arg)
}
-bool select_singlerow_subselect::send_data(List<Item> &items)
+int select_singlerow_subselect::send_data(List<Item> &items)
{
DBUG_ENTER("select_singlerow_subselect::send_data");
Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
@@ -2325,7 +2423,7 @@ void select_max_min_finder_subselect::cleanup()
}
-bool select_max_min_finder_subselect::send_data(List<Item> &items)
+int select_max_min_finder_subselect::send_data(List<Item> &items)
{
DBUG_ENTER("select_max_min_finder_subselect::send_data");
Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
@@ -2343,8 +2441,7 @@ bool select_max_min_finder_subselect::send_data(List<Item> &items)
if (!cache)
{
cache= Item_cache::get_cache(val_item);
- switch (val_item->result_type())
- {
+ switch (val_item->result_type()) {
case REAL_RESULT:
op= &select_max_min_finder_subselect::cmp_real;
break;
@@ -2358,6 +2455,7 @@ bool select_max_min_finder_subselect::send_data(List<Item> &items)
op= &select_max_min_finder_subselect::cmp_decimal;
break;
case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
op= 0;
@@ -2429,7 +2527,7 @@ bool select_max_min_finder_subselect::cmp_str()
sortcmp(val1, val2, cache->collation.collation) < 0);
}
-bool select_exists_subselect::send_data(List<Item> &items)
+int select_exists_subselect::send_data(List<Item> &items)
{
DBUG_ENTER("select_exists_subselect::send_data");
Item_exists_subselect *it= (Item_exists_subselect *)item;
@@ -2781,7 +2879,7 @@ Statement_map::~Statement_map()
hash_free(&st_hash);
}
-bool select_dumpvar::send_data(List<Item> &items)
+int select_dumpvar::send_data(List<Item> &items)
{
List_iterator_fast<my_var> var_li(var_list);
List_iterator<Item> it(items);
@@ -3186,6 +3284,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
backup->options= options;
backup->in_sub_stmt= in_sub_stmt;
backup->enable_slow_log= enable_slow_log;
+ backup->query_plan_flags= query_plan_flags;
backup->limit_found_rows= limit_found_rows;
backup->examined_row_count= examined_row_count;
backup->sent_row_count= sent_row_count;
@@ -3252,6 +3351,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
options= backup->options;
in_sub_stmt= backup->in_sub_stmt;
enable_slow_log= backup->enable_slow_log;
+ query_plan_flags= backup->query_plan_flags;
first_successful_insert_id_in_prev_stmt=
backup->first_successful_insert_id_in_prev_stmt;
first_successful_insert_id_in_cur_stmt=
@@ -3549,70 +3649,6 @@ THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
Update_rows_log_event *);
#endif
-#ifdef NOT_USED
-static char const*
-field_type_name(enum_field_types type)
-{
- switch (type) {
- case MYSQL_TYPE_DECIMAL:
- return "MYSQL_TYPE_DECIMAL";
- case MYSQL_TYPE_TINY:
- return "MYSQL_TYPE_TINY";
- case MYSQL_TYPE_SHORT:
- return "MYSQL_TYPE_SHORT";
- case MYSQL_TYPE_LONG:
- return "MYSQL_TYPE_LONG";
- case MYSQL_TYPE_FLOAT:
- return "MYSQL_TYPE_FLOAT";
- case MYSQL_TYPE_DOUBLE:
- return "MYSQL_TYPE_DOUBLE";
- case MYSQL_TYPE_NULL:
- return "MYSQL_TYPE_NULL";
- case MYSQL_TYPE_TIMESTAMP:
- return "MYSQL_TYPE_TIMESTAMP";
- case MYSQL_TYPE_LONGLONG:
- return "MYSQL_TYPE_LONGLONG";
- case MYSQL_TYPE_INT24:
- return "MYSQL_TYPE_INT24";
- case MYSQL_TYPE_DATE:
- return "MYSQL_TYPE_DATE";
- case MYSQL_TYPE_TIME:
- return "MYSQL_TYPE_TIME";
- case MYSQL_TYPE_DATETIME:
- return "MYSQL_TYPE_DATETIME";
- case MYSQL_TYPE_YEAR:
- return "MYSQL_TYPE_YEAR";
- case MYSQL_TYPE_NEWDATE:
- return "MYSQL_TYPE_NEWDATE";
- case MYSQL_TYPE_VARCHAR:
- return "MYSQL_TYPE_VARCHAR";
- case MYSQL_TYPE_BIT:
- return "MYSQL_TYPE_BIT";
- case MYSQL_TYPE_NEWDECIMAL:
- return "MYSQL_TYPE_NEWDECIMAL";
- case MYSQL_TYPE_ENUM:
- return "MYSQL_TYPE_ENUM";
- case MYSQL_TYPE_SET:
- return "MYSQL_TYPE_SET";
- case MYSQL_TYPE_TINY_BLOB:
- return "MYSQL_TYPE_TINY_BLOB";
- case MYSQL_TYPE_MEDIUM_BLOB:
- return "MYSQL_TYPE_MEDIUM_BLOB";
- case MYSQL_TYPE_LONG_BLOB:
- return "MYSQL_TYPE_LONG_BLOB";
- case MYSQL_TYPE_BLOB:
- return "MYSQL_TYPE_BLOB";
- case MYSQL_TYPE_VAR_STRING:
- return "MYSQL_TYPE_VAR_STRING";
- case MYSQL_TYPE_STRING:
- return "MYSQL_TYPE_STRING";
- case MYSQL_TYPE_GEOMETRY:
- return "MYSQL_TYPE_GEOMETRY";
- }
- return "Unknown";
-}
-#endif
-
namespace {
/**
@@ -3791,7 +3827,7 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
Don't print debug messages when running valgrind since they can
trigger false warnings.
*/
-#ifndef HAVE_purify
+#ifndef HAVE_valgrind
DBUG_DUMP("before_record", before_record, table->s->reclength);
DBUG_DUMP("after_record", after_record, table->s->reclength);
DBUG_DUMP("before_row", before_row, before_size);
@@ -4014,11 +4050,10 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
binlog_table_maps= 0;
DBUG_RETURN(error);
}
- break;
case THD::QUERY_TYPE_COUNT:
default:
- DBUG_ASSERT(0 <= qtype && qtype < QUERY_TYPE_COUNT);
+ DBUG_ASSERT(qtype < QUERY_TYPE_COUNT);
}
DBUG_RETURN(0);
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3c1b2c1330f..40a5d61e433 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -65,10 +66,12 @@ public:
bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; }
+ Reprepare_observer() {} /* Remove gcc warning */
private:
bool m_invalidated;
};
+#include <waiting_threads.h>
class Relay_log_info;
@@ -77,6 +80,7 @@ class Load_log_event;
class Slave_log_event;
class sp_rcontext;
class sp_cache;
+class Lex_input_stream;
class Parser_state;
class Rows_log_event;
@@ -285,18 +289,18 @@ struct system_variables
{
/*
How dynamically allocated system variables are handled:
-
+
The global_system_variables and max_system_variables are "authoritative"
They both should have the same 'version' and 'size'.
When attempting to access a dynamic variable, if the session version
is out of date, then the session version is updated and realloced if
neccessary and bytes copied from global to make up for missing data.
- */
+ */
ulong dynamic_variables_version;
char* dynamic_variables_ptr;
uint dynamic_variables_head; /* largest valid variable offset */
uint dynamic_variables_size; /* how many bytes are in use */
-
+
ulonglong myisam_max_extra_sort_file_size;
ulonglong myisam_max_sort_file_size;
ulonglong max_heap_table_size;
@@ -352,6 +356,10 @@ struct system_variables
ulong trans_prealloc_size;
ulong log_warnings;
ulong group_concat_max_len;
+ /* Flags for slow log filtering */
+ ulong log_slow_rate_limit;
+ ulong log_slow_filter;
+ ulong log_slow_verbosity;
ulong ndb_autoincrement_prefetch_sz;
ulong ndb_index_stat_cache_entries;
ulong ndb_index_stat_update_freq;
@@ -365,9 +373,9 @@ struct system_variables
my_bool low_priority_updates;
my_bool new_mode;
- /*
+ /*
compatibility option:
- - index usage hints (USE INDEX without a FOR clause) behave as in 5.0
+ - index usage hints (USE INDEX without a FOR clause) behave as in 5.0
*/
my_bool old_mode;
my_bool query_cache_wlock_invalidate;
@@ -404,6 +412,10 @@ struct system_variables
DATE_TIME_FORMAT *datetime_format;
DATE_TIME_FORMAT *time_format;
my_bool sysdate_is_now;
+
+ /* deadlock detection */
+ ulong wt_timeout_short, wt_deadlock_search_depth_short;
+ ulong wt_timeout_long, wt_deadlock_search_depth_long;
};
@@ -604,7 +616,7 @@ class Server_side_cursor;
- prepared, that is, contain placeholders,
- opened as cursors. We maintain 1 to 1 relationship between
statement and cursor - if user wants to create another cursor for his
- query, we create another statement for it.
+ query, we create another statement for it.
To perform some action with statement we reset THD part to the state of
that statement, do the action, and then save back modified state from THD
to the statement. It will be changed in near future, and Statement will
@@ -807,7 +819,7 @@ public:
{
return (*priv_host ? priv_host : (char *)"%");
}
-
+
bool set_user(char *user_arg);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -997,6 +1009,7 @@ public:
ulonglong limit_found_rows;
ha_rows cuted_fields, sent_row_count, examined_row_count;
ulong client_capabilities;
+ ulong query_plan_flags;
uint in_sub_stmt;
bool enable_slow_log;
bool last_insert_id_used;
@@ -1103,6 +1116,7 @@ public:
/* Ignore error */
return TRUE;
}
+ Dummy_error_handler() {} /* Remove gcc warning */
};
@@ -1200,6 +1214,13 @@ public:
return m_total_warn_count;
}
+ /* Used to count any warnings pushed after calling set_ok_status(). */
+ void increment_warning()
+ {
+ if (m_status != DA_EMPTY)
+ m_total_warn_count++;
+ }
+
Diagnostics_area() { reset_diagnostics_area(); }
private:
@@ -1320,6 +1341,7 @@ public:
struct st_mysql_stmt *current_stmt;
#endif
NET net; // client connection descriptor
+ scheduler_functions *scheduler; // Scheduler for this connection
MEM_ROOT warn_root; // For warnings and errors
Protocol *protocol; // Current protocol
Protocol_text protocol_text; // Normal protocol
@@ -1328,7 +1350,7 @@ public:
String packet; // dynamic buffer for network I/O
String convert_buffer; // buffer for charset conversions
struct sockaddr_in remote; // client socket address
- struct rand_struct rand; // used for authentication
+ struct my_rnd_struct rand; // used for authentication
struct system_variables variables; // Changeable local variables
struct system_status_var status_var; // Per thread statistic vars
struct system_status_var *initial_status_var; /* used by show status */
@@ -1403,7 +1425,7 @@ public:
/*
One thread can hold up to one named user-level lock. This variable
points to a lock object if the lock is present. See item_func.cc and
- chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
+ chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK.
*/
User_level_lock *ull;
#ifndef DBUG_OFF
@@ -1418,12 +1440,12 @@ public:
uint32 server_id;
uint32 file_id; // for LOAD DATA INFILE
/* remote (peer) port */
- uint16 peer_port;
+ uint16 peer_port;
time_t start_time, user_time;
// track down slow pthread_create
ulonglong prior_thr_create_utime, thr_create_utime;
ulonglong start_utime, utime_after_lock;
-
+
thr_lock_type update_lock_default;
Delayed_insert *di;
@@ -1502,6 +1524,7 @@ public:
THD_TRANS stmt; // Trans for current statement
bool on; // see ha_enable_transaction()
XID_STATE xid_state;
+ WT_THD wt; ///< for deadlock detection
Rows_log_event *m_pending_rows_event;
/*
@@ -1548,7 +1571,7 @@ public:
/*
This is to track items changed during execution of a prepared
statement/stored procedure. It's created by
- register_item_tree_change() in memory root of THD, and freed in
+ nocheck_register_item_tree_change() in memory root of THD, and freed in
rollback_item_tree_changes(). For conventional execution it's always
empty.
*/
@@ -1772,6 +1795,8 @@ public:
create_sort_index(); may differ from examined_row_count.
*/
ulong row_count;
+ ulong query_plan_flags;
+ ulong query_plan_fsort_passes;
pthread_t real_id; /* For debugging */
my_thread_id thread_id;
uint tmp_table, global_read_lock;
@@ -1804,6 +1829,8 @@ public:
bool locked, some_tables_deleted;
bool last_cuted_field;
bool no_errors, password;
+ bool extra_port; /* If extra connection */
+
/**
Set to TRUE if execution of the current compound statement
can not continue. In particular, disables activation of
@@ -1842,7 +1869,7 @@ public:
*/
bool is_slave_error;
bool bootstrap, cleanup_done;
-
+
/** is set if some thread specific value(s) used in a statement. */
bool thread_specific_used;
bool charset_is_system_charset, charset_is_collation_connection;
@@ -1877,10 +1904,10 @@ public:
ulong ulong_value;
ulonglong ulonglong_value;
} sys_var_tmp;
-
+
struct {
- /*
- If true, mysql_bin_log::write(Log_event) call will not write events to
+ /*
+ If true, mysql_bin_log::write(Log_event) call will not write events to
binlog, and maintain 2 below variables instead (use
mysql_bin_log.start_union_events to turn this on)
*/
@@ -1891,13 +1918,13 @@ public:
*/
bool unioned_events;
/*
- If TRUE, at least one mysql_bin_log::write(Log_event e), where
- e.cache_stmt == TRUE call has been made after last
+ If TRUE, at least one mysql_bin_log::write(Log_event e), where
+ e.cache_stmt == TRUE call has been made after last
mysql_bin_log.start_union_events() call.
*/
bool unioned_events_trans;
-
- /*
+
+ /*
'queries' (actually SP statements) that run under inside this binlog
union have thd->query_id >= first_query_id.
*/
@@ -1931,13 +1958,14 @@ public:
killing mysqld) where it's vital to not allocate excessive and not used
memory. Note, that we still don't return error from init_for_queries():
if preallocation fails, we should notice that at the first call to
- alloc_root.
+ alloc_root.
*/
void init_for_queries();
void change_user(void);
void cleanup(void);
void cleanup_after_query();
bool store_globals();
+ void reset_globals();
bool restore_globals();
#ifdef SIGNAL_WITH_VIO_CLOSE
inline void set_active_vio(Vio* vio)
@@ -1962,12 +1990,12 @@ public:
The query can be logged row-based or statement-based
*/
ROW_QUERY_TYPE,
-
+
/*
The query has to be logged statement-based
*/
STMT_QUERY_TYPE,
-
+
/*
The query represents a change to a table in the "mysql"
database and is currently mapped to ROW_QUERY_TYPE.
@@ -1975,7 +2003,7 @@ public:
MYSQL_QUERY_TYPE,
QUERY_TYPE_COUNT
};
-
+
int binlog_query(enum_binlog_query_type qtype,
char const *query, ulong query_len,
bool is_trans, bool suppress_use,
@@ -2144,8 +2172,26 @@ public:
nocheck_register_item_tree_change(place, *place, mem_root);
*place= new_value;
}
+ /**
+ Make change in item tree after checking whether it needs registering
+
+
+ @param place place where we should assign new value
+ @param new_value place of the new value
+
+ @details
+ see check_and_register_item_tree_change details
+ */
+ void check_and_register_item_tree(Item **place, Item **new_value)
+ {
+ if (!stmt_arena->is_conventional())
+ check_and_register_item_tree_change(place, new_value, mem_root);
+ *place= *new_value;
+ }
void nocheck_register_item_tree_change(Item **place, Item *old_value,
MEM_ROOT *runtime_memroot);
+ void check_and_register_item_tree_change(Item **place, Item **new_value,
+ MEM_ROOT *runtime_memroot);
void rollback_item_tree_changes();
/*
@@ -2232,7 +2278,7 @@ public:
if ((temporary_tables == NULL) && (in_sub_stmt == 0) &&
(system_thread != SYSTEM_THREAD_NDBCLUSTER_BINLOG))
{
- current_stmt_binlog_row_based=
+ current_stmt_binlog_row_based=
test(variables.binlog_format == BINLOG_FORMAT_ROW);
}
}
@@ -2304,7 +2350,7 @@ public:
*p_db_length= db_length;
return FALSE;
}
- thd_scheduler scheduler;
+ thd_scheduler event_scheduler;
public:
inline Internal_error_handler *get_internal_handler()
@@ -2374,7 +2420,7 @@ private:
statements or default definer is set in CREATE/ALTER SP, SF, Event,
TRIGGER or VIEW statements.
- Current user will be binlogged into Query_log_event if current_user_used
+ Current user will be binlogged into Query_log_event if m_binlog_invoker
is TRUE; It will be stored into invoker_host and invoker_user by SQL thread.
*/
bool m_binlog_invoker;
@@ -2464,7 +2510,11 @@ public:
virtual uint field_count(List<Item> &fields) const
{ return fields.elements; }
virtual bool send_fields(List<Item> &list, uint flags)=0;
- virtual bool send_data(List<Item> &items)=0;
+ /*
+ send_data returns 0 on ok, 1 on error and -1 if data was ignored, for
+ example for a duplicate row entry written to a temp table.
+ */
+ virtual int send_data(List<Item> &items)=0;
virtual bool initialize_tables (JOIN *join=0) { return 0; }
virtual void send_error(uint errcode,const char *err);
virtual bool send_eof()=0;
@@ -2488,7 +2538,7 @@ public:
@return
-1 if nest level is undefined, otherwise a positive integer.
*/
- int get_nest_level() { return nest_level; }
+ int get_nest_level() { return (int) nest_level; }
#ifdef EMBEDDED_LIBRARY
virtual void begin_dataset() {}
#else
@@ -2522,7 +2572,7 @@ class select_send :public select_result {
public:
select_send() :is_result_set_started(FALSE) {}
bool send_fields(List<Item> &list, uint flags);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool send_eof();
virtual bool check_simple_select() const { return FALSE; }
void abort();
@@ -2593,7 +2643,7 @@ public:
}
~select_export();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
};
@@ -2610,7 +2660,7 @@ public:
nest_level= nest_level_arg;
}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
};
@@ -2631,7 +2681,7 @@ public:
~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
virtual int prepare2(void);
- bool send_data(List<Item> &items);
+ virtual int send_data(List<Item> &items);
virtual void store_values(List<Item> &values);
virtual bool can_rollback_data() { return 0; }
void send_error(uint errcode,const char *err);
@@ -2683,10 +2733,17 @@ public:
int prepare2(void) { return 0; }
};
+
+#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
+#include <maria.h>
+#define ENGINE_COLUMNDEF MARIA_COLUMNDEF
+#else
#include <myisam.h>
+#define ENGINE_COLUMNDEF MI_COLUMNDEF
+#endif
-/*
- Param to create temporary tables when doing SELECT:s
+/*
+ Param to create temporary tables when doing SELECT:s
NOTE
This structure is copied using memcpy as a part of JOIN.
*/
@@ -2705,7 +2762,7 @@ public:
Copy_field *save_copy_field, *save_copy_field_end;
uchar *group_buff;
Item **items_to_copy; /* Fields in tmp table */
- MI_COLUMNDEF *recinfo,*start_recinfo;
+ ENGINE_COLUMNDEF *recinfo, *start_recinfo;
KEY *keyinfo;
ha_rows end_write_records;
/**
@@ -2739,8 +2796,8 @@ public:
uint quick_group;
bool using_indirect_summary_function;
/* If >0 convert all blob fields to varchar(convert_blob_length) */
- uint convert_blob_length;
- CHARSET_INFO *table_charset;
+ uint convert_blob_length;
+ CHARSET_INFO *table_charset;
bool schema_table;
/*
True if GROUP BY and its aggregate functions are already computed
@@ -2779,7 +2836,7 @@ public:
select_union() :table(0) {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool send_eof();
bool flush();
@@ -2795,7 +2852,7 @@ protected:
Item_subselect *item;
public:
select_subselect(Item_subselect *item);
- bool send_data(List<Item> &items)=0;
+ int send_data(List<Item> &items)=0;
bool send_eof() { return 0; };
};
@@ -2806,7 +2863,7 @@ public:
select_singlerow_subselect(Item_subselect *item_arg)
:select_subselect(item_arg)
{}
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
};
/* used in independent ALL/ANY optimisation */
@@ -2820,7 +2877,7 @@ public:
:select_subselect(item_arg), cache(0), fmax(mx)
{}
void cleanup();
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool cmp_real();
bool cmp_int();
bool cmp_decimal();
@@ -2833,7 +2890,7 @@ class select_exists_subselect :public select_subselect
public:
select_exists_subselect(Item_subselect *item_arg)
:select_subselect(item_arg){}
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
};
/* Structs used when sorting */
@@ -2874,7 +2931,7 @@ public:
else
db= db_arg;
}
- inline Table_ident(LEX_STRING table_arg)
+ inline Table_ident(LEX_STRING table_arg)
:table(table_arg), sel((SELECT_LEX_UNIT *)0)
{
db.str=0;
@@ -2920,7 +2977,7 @@ class user_var_entry
};
/*
- Unique -- class for unique (removing of duplicates).
+ Unique -- class for unique (removing of duplicates).
Puts all values to the TREE. If the tree becomes too big,
it's dumped to the file. User can request sorted values, or
just iterate through them. In the last case tree merging is performed in
@@ -2954,13 +3011,13 @@ public:
}
bool get(TABLE *table);
- static double get_use_cost(uint *buffer, uint nkeys, uint key_size,
+ static double get_use_cost(uint *buffer, uint nkeys, uint key_size,
ulonglong max_in_memory_size);
- inline static int get_cost_calc_buff_size(ulong nkeys, uint key_size,
+ inline static int get_cost_calc_buff_size(ulong nkeys, uint key_size,
ulonglong max_in_memory_size)
{
register ulonglong max_elems_in_tree=
- (1 + max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size));
+ max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size);
return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree));
}
@@ -2998,7 +3055,7 @@ public:
multi_delete(TABLE_LIST *dt, uint num_of_tables);
~multi_delete();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err);
int do_deletes();
@@ -3021,7 +3078,7 @@ class multi_update :public select_result_interceptor
uint table_count;
/*
List of tables referenced in the CHECK OPTION condition of
- the updated view excluding the updated table.
+ the updated view excluding the updated table.
*/
List <TABLE> unupdated_check_opt_tables;
Copy_field *copy_field;
@@ -3042,7 +3099,7 @@ public:
enum_duplicates handle_duplicates, bool ignore);
~multi_update();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err);
int do_updates();
@@ -3086,7 +3143,7 @@ public:
}
~select_dumpvar() {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- bool send_data(List<Item> &items);
+ int send_data(List<Item> &items);
bool send_eof();
virtual bool check_simple_select() const;
void cleanup();
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 44b4af74ef1..7dd15ea731f 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,10 +22,23 @@
#include "mysql_priv.h"
-/** Size of the header fields of an authentication packet. */
-#define AUTH_PACKET_HEADER_SIZE_PROTO_41 32
-#define AUTH_PACKET_HEADER_SIZE_PROTO_40 5
-#define AUTH_PACKET_HEADER_SIZE_CONNJ_SSL 4
+#ifdef HAVE_OPENSSL
+/*
+ Without SSL the handshake consists of one packet. This packet
+ has both client capabilites and scrambled password.
+ With SSL the handshake might consist of two packets. If the first
+ packet (client capabilities) has CLIENT_SSL flag set, we have to
+ switch to SSL and read the second packet. The scrambled password
+ is in the second packet and client_capabilites field will be ignored.
+ Maybe it is better to accept flags other than CLIENT_SSL from the
+ second packet?
+*/
+#define SSL_HANDSHAKE_SIZE 2
+#define NORMAL_HANDSHAKE_SIZE 6
+#define MIN_HANDSHAKE_SIZE 2
+#else
+#define MIN_HANDSHAKE_SIZE 6
+#endif /* HAVE_OPENSSL */
#ifdef __WIN__
extern void win_install_sigabrt_handler();
@@ -390,11 +404,15 @@ check_user(THD *thd, enum enum_server_command command,
if (check_count)
{
- pthread_mutex_lock(&LOCK_connection_count);
- bool count_ok= connection_count <= max_connections ||
- (thd->main_security_ctx.master_access & SUPER_ACL);
- VOID(pthread_mutex_unlock(&LOCK_connection_count));
-
+ bool count_ok= 1;
+
+ if (!(thd->main_security_ctx.master_access & SUPER_ACL))
+ {
+ pthread_mutex_lock(&LOCK_connection_count);
+ count_ok= (*thd->scheduler->connection_count <=
+ *thd->scheduler->max_connections);
+ VOID(pthread_mutex_unlock(&LOCK_connection_count));
+ }
if (!count_ok)
{ // too many connections
my_error(ER_CON_COUNT_ERROR, MYF(0));
@@ -458,16 +476,14 @@ check_user(THD *thd, enum enum_server_command command,
}
}
my_ok(thd);
- thd->password= test(passwd_len); // remember for error messages
-#ifndef EMBEDDED_LIBRARY
/*
Allow the network layer to skip big packets. Although a malicious
authenticated session might use this to trick the server to read
big packets indefinitely, this is a previously established behavior
that needs to be preserved as to not break backwards compatibility.
*/
- thd->net.skip_big_packet= TRUE;
-#endif
+ thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size
+ thd->password= test(passwd_len); // remember for error messages
/* Ready to handle queries */
DBUG_RETURN(0);
}
@@ -641,154 +657,6 @@ bool init_new_connection_handler_thread()
return 0;
}
-#ifndef EMBEDDED_LIBRARY
-
-/** Get a string according to the protocol of the underlying buffer. */
-typedef char * (*get_proto_string_func_t) (char **, size_t *, size_t *);
-
-/**
- Get a string formatted according to the 4.1 version of the MySQL protocol.
-
- @param buffer[in, out] Pointer to the user-supplied buffer to be scanned.
- @param max_bytes_available[in, out] Limit the bytes to scan.
- @param string_length[out] The number of characters scanned not including
- the null character.
-
- @remark Strings are always null character terminated in this version of the
- protocol.
-
- @remark The string_length does not include the terminating null character.
- However, after the call, the buffer is increased by string_length+1
- bytes, beyond the null character if there still available bytes to
- scan.
-
- @return pointer to beginning of the string scanned.
- @retval NULL The buffer content is malformed
-*/
-
-static
-char *get_41_protocol_string(char **buffer,
- size_t *max_bytes_available,
- size_t *string_length)
-{
- char *str= (char *)memchr(*buffer, '\0', *max_bytes_available);
-
- if (str == NULL)
- return NULL;
-
- *string_length= (size_t)(str - *buffer);
- *max_bytes_available-= *string_length + 1;
- str= *buffer;
- *buffer += *string_length + 1;
-
- return str;
-}
-
-
-/**
- Get a string formatted according to the 4.0 version of the MySQL protocol.
-
- @param buffer[in, out] Pointer to the user-supplied buffer to be scanned.
- @param max_bytes_available[in, out] Limit the bytes to scan.
- @param string_length[out] The number of characters scanned not including
- the null character.
-
- @remark If there are not enough bytes left after the current position of
- the buffer to satisfy the current string, the string is considered
- to be empty and a pointer to empty_c_string is returned.
-
- @remark A string at the end of the packet is not null terminated.
-
- @return Pointer to beginning of the string scanned, or a pointer to a empty
- string.
-*/
-static
-char *get_40_protocol_string(char **buffer,
- size_t *max_bytes_available,
- size_t *string_length)
-{
- char *str;
- size_t len;
-
- /* No bytes to scan left, treat string as empty. */
- if ((*max_bytes_available) == 0)
- {
- *string_length= 0;
- return empty_c_string;
- }
-
- str= (char *) memchr(*buffer, '\0', *max_bytes_available);
-
- /*
- If the string was not null terminated by the client,
- the remainder of the packet is the string. Otherwise,
- advance the buffer past the end of the null terminated
- string.
- */
- if (str == NULL)
- len= *string_length= *max_bytes_available;
- else
- len= (*string_length= (size_t)(str - *buffer)) + 1;
-
- str= *buffer;
- *buffer+= len;
- *max_bytes_available-= len;
-
- return str;
-}
-
-
-/**
- Get a length encoded string from a user-supplied buffer.
-
- @param buffer[in, out] The buffer to scan; updates position after scan.
- @param max_bytes_available[in, out] Limit the number of bytes to scan
- @param string_length[out] Number of characters scanned
-
- @remark In case the length is zero, then the total size of the string is
- considered to be 1 byte; the size byte.
-
- @return pointer to first byte after the header in buffer.
- @retval NULL The buffer content is malformed
-*/
-
-static
-char *get_length_encoded_string(char **buffer,
- size_t *max_bytes_available,
- size_t *string_length)
-{
- if (*max_bytes_available == 0)
- return NULL;
-
- /* Do double cast to prevent overflow from signed / unsigned conversion */
- size_t str_len= (size_t)(unsigned char)**buffer;
-
- /*
- If the length encoded string has the length 0
- the total size of the string is only one byte long (the size byte)
- */
- if (str_len == 0)
- {
- ++*buffer;
- *string_length= 0;
- /*
- Return a pointer to the 0 character so the return value will be
- an empty string.
- */
- return *buffer-1;
- }
-
- if (str_len >= *max_bytes_available)
- return NULL;
-
- char *str= *buffer+1;
- *string_length= str_len;
- *max_bytes_available-= *string_length + 1;
- *buffer+= *string_length + 1;
- return str;
-}
-
-
/*
Perform handshake, authorize client and update thd ACL variables.
@@ -802,20 +670,16 @@ char *get_length_encoded_string(char **buffer,
> 0 error code (not sent to user)
*/
+#ifndef EMBEDDED_LIBRARY
static int check_connection(THD *thd)
{
uint connect_errors= 0;
NET *net= &thd->net;
ulong pkt_len= 0;
- char *end;
-
- bool packet_has_required_size= false;
- char *db;
- size_t db_len;
- char *passwd;
- size_t passwd_len;
- char *user;
- size_t user_len;
+ char *end, *user, *passwd, *db;
+ uint user_len, dummy_errors, passwd_len, db_len;
+ char db_buff[SAFE_NAME_LEN*2 + 1]; // buffer to store db in utf8
+ char user_buff[USERNAME_LENGTH*2 + 1]; // buffer to store user in utf8
DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio)));
@@ -911,7 +775,7 @@ static int check_connection(THD *thd)
part at the end of packet.
*/
end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1;
-
+
int2store(end, server_capabilites);
/* write server characteristics: up to 16 bytes allowed */
end[2]=(char) default_charset_info->number;
@@ -925,12 +789,9 @@ static int check_connection(THD *thd)
/* At this point we write connection message and read reply */
if (net_write_command(net, (uchar) protocol_version, (uchar*) "", 0,
(uchar*) buff, (size_t) (end-buff)) ||
- (pkt_len= my_net_read(net)) == packet_error)
- {
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0));
- return 1;
- }
+ (pkt_len= my_net_read(net)) == packet_error ||
+ pkt_len < MIN_HANDSHAKE_SIZE)
+ goto error;
}
#ifdef _CUSTOMCONFIG_
#include "_cust_sql_parse.h"
@@ -940,82 +801,34 @@ static int check_connection(THD *thd)
if (thd->packet.alloc(thd->variables.net_buffer_length))
return 1; /* The error is set by alloc(). */
- uint charset_code= 0;
- end= (char *)net->read_pos;
- /*
- In order to safely scan a head for '\0' string terminators
- we must keep track of how many bytes remain in the allocated
- buffer or we might read past the end of the buffer.
- */
- size_t bytes_remaining_in_packet= pkt_len;
-
/*
- Peek ahead on the client capability packet and determine which version of
- the protocol should be used.
+ Protocol buffer is guaranteed to always end with \0. (see my_net_read())
+ As the code below depends on this, lets check that.
*/
- if (bytes_remaining_in_packet < 2)
- goto error;
-
- thd->client_capabilities= uint2korr(end);
-
- /*
- Connector/J only sends client capabilities (4 bytes) before starting SSL
- negotiation so we don't have char_set and other information for client in
- packet read. In that case, skip reading those information. The below code
- is patch for this.
- */
- if(bytes_remaining_in_packet == AUTH_PACKET_HEADER_SIZE_CONNJ_SSL &&
- (thd->client_capabilities & CLIENT_SSL))
- {
- thd->client_capabilities= uint4korr(end);
- thd->max_client_packet_length= global_system_variables.max_allowed_packet;
- charset_code= default_charset_info->number;
- end+= AUTH_PACKET_HEADER_SIZE_CONNJ_SSL;
- bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_CONNJ_SSL;
- goto skip_to_ssl;
- }
+ DBUG_ASSERT(net->read_pos[pkt_len] == 0);
- if (thd->client_capabilities & CLIENT_PROTOCOL_41)
- packet_has_required_size= bytes_remaining_in_packet >=
- AUTH_PACKET_HEADER_SIZE_PROTO_41;
- else
- packet_has_required_size= bytes_remaining_in_packet >=
- AUTH_PACKET_HEADER_SIZE_PROTO_40;
-
- if (!packet_has_required_size)
- goto error;
-
+ thd->client_capabilities= uint2korr(net->read_pos);
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
- thd->client_capabilities= uint4korr(end);
- thd->max_client_packet_length= uint4korr(end + 4);
- charset_code= (uint)(uchar)*(end + 8);
- /*
- Skip 23 remaining filler bytes which have no particular meaning.
- */
- end+= AUTH_PACKET_HEADER_SIZE_PROTO_41;
- bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_PROTO_41;
+ if (pkt_len < 32)
+ goto error;
+
+ thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
+ thd->max_client_packet_length= uint4korr(net->read_pos+4);
+ DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
+ if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
+ return 1;
+ thd->update_charset();
+ end= (char*) net->read_pos+32;
}
else
{
- thd->client_capabilities= uint2korr(end);
- thd->max_client_packet_length= uint3korr(end + 2);
- end+= AUTH_PACKET_HEADER_SIZE_PROTO_40;
- bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_PROTO_40;
- /**
- Old clients didn't have their own charset. Instead the assumption
- was that they used what ever the server used.
- */
- charset_code= default_charset_info->number;
- }
-
-skip_to_ssl:
-
- DBUG_PRINT("info", ("client_character_set: %u", charset_code));
- if (thd_init_client_charset(thd, charset_code))
- goto error;
- thd->update_charset();
+ if (pkt_len < 5)
+ goto error;
+ thd->max_client_packet_length= uint3korr(net->read_pos+2);
+ end= (char*) net->read_pos+5;
+ }
/*
Disable those bits which are not supported by the server.
This is a precautionary measure, if the client lies. See Bug#27944.
@@ -1026,146 +839,79 @@ skip_to_ssl:
thd->variables.sql_mode|= MODE_IGNORE_SPACE;
#ifdef HAVE_OPENSSL
DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
-
- /*
- If client requested SSL then we must stop parsing, try to switch to SSL,
- and wait for the client to send a new handshake packet.
- The client isn't expected to send any more bytes until SSL is initialized.
- */
if (thd->client_capabilities & CLIENT_SSL)
{
+ char error_string[1024];
/* Do the SSL layering. */
if (!ssl_acceptor_fd)
goto error;
-
DBUG_PRINT("info", ("IO layer change in progress..."));
- if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
+ if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, error_string))
{
DBUG_PRINT("error", ("Failed to accept new SSL connection"));
goto error;
}
-
DBUG_PRINT("info", ("Reading user information over SSL layer"));
- if ((pkt_len= my_net_read(net)) == packet_error)
+ if ((pkt_len= my_net_read(net)) == packet_error ||
+ pkt_len < NORMAL_HANDSHAKE_SIZE)
{
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
pkt_len));
goto error;
}
- /*
- A new packet was read and the statistics reflecting the remaining bytes
- in the packet must be updated.
- */
- bytes_remaining_in_packet= pkt_len;
-
- /*
- After the SSL handshake is performed the client resends the handshake
- packet but because of legacy reasons we chose not to parse the packet
- fields a second time and instead only assert the length of the packet.
- */
- if (thd->client_capabilities & CLIENT_PROTOCOL_41)
- {
-
- packet_has_required_size= bytes_remaining_in_packet >=
- AUTH_PACKET_HEADER_SIZE_PROTO_41;
- end= (char *)net->read_pos + AUTH_PACKET_HEADER_SIZE_PROTO_41;
- bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_41;
- }
- else
- {
- packet_has_required_size= bytes_remaining_in_packet >=
- AUTH_PACKET_HEADER_SIZE_PROTO_40;
- end= (char *)net->read_pos + AUTH_PACKET_HEADER_SIZE_PROTO_40;
- bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_40;
- }
-
- if (!packet_has_required_size)
- goto error;
}
#endif /* HAVE_OPENSSL */
+ if (end >= (char*) net->read_pos+ pkt_len +2)
+ goto error;
+
if (thd->client_capabilities & CLIENT_INTERACTIVE)
thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions)
net->return_status= &thd->server_status;
- /*
- The 4.0 and 4.1 versions of the protocol differ on how strings
- are terminated. In the 4.0 version, if a string is at the end
- of the packet, the string is not null terminated. Do not assume
- that the returned string is always null terminated.
- */
- get_proto_string_func_t get_string;
-
- if (thd->client_capabilities & CLIENT_PROTOCOL_41)
- get_string= get_41_protocol_string;
- else
- get_string= get_40_protocol_string;
-
- user= get_string(&end, &bytes_remaining_in_packet, &user_len);
- if (user == NULL)
- goto error;
+ user= end;
+ passwd= strend(user)+1;
+ user_len= passwd - user - 1;
+ db= passwd;
/*
- Old clients send a null-terminated string as password; new clients send
+ Old clients send null-terminated string as password; new clients send
the size (1 byte) + string (not null-terminated). Hence in case of empty
password both send '\0'.
- */
- passwd_len= 0;
- passwd= NULL;
- if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
- {
- /*
- 4.1+ password. First byte is password length.
- */
- passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet,
- &passwd_len);
- }
- else
- {
- /*
- Old passwords are zero terminated strings.
- */
- passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len);
- }
+ This strlen() can't be easily deleted without changing protocol.
- if (passwd == NULL)
- goto error;
+ Cast *passwd to an unsigned char, so that it doesn't extend the sign for
+ *passwd > 127 and become 2**32-127+ after casting to uint.
- db_len= 0;
- db= NULL;
+ strlen() is safe as packet[pkt_len] is guranteed to be 0
+ */
+ passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ (uchar)(*passwd++) : strlen(passwd);
+ db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
+ db + passwd_len + 1 : 0;
- if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
- {
- db= get_string(&end, &bytes_remaining_in_packet, &db_len);
- if (db == NULL)
- goto error;
- }
+ if (passwd + passwd_len + test(db) > (char *)net->read_pos + pkt_len)
+ goto error;
- char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
- char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
- uint dummy_errors;
+ /* strlen() can't be easily deleted without changing protocol */
+ db_len= db ? strlen(db) : 0;
- /*
- Copy and convert the user and database names to the character set used
- by the server. Since 4.1 all database names are stored in UTF-8. Also,
- ensure that the names are properly null-terminated as this is relied
- upon later.
- */
+ /* Since 4.1 all database names are stored in utf8 */
if (db)
{
- db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info,
- db, db_len, thd->charset(), &dummy_errors);
- db_buff[db_len]= '\0';
+ db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
+ system_charset_info,
+ db, db_len,
+ thd->charset(), &dummy_errors)]= 0;
db= db_buff;
}
- user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
- system_charset_info, user, user_len,
- thd->charset(), &dummy_errors);
- user_buff[user_len]= '\0';
+ user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
+ system_charset_info, user, user_len,
+ thd->charset(), &dummy_errors)]= '\0';
user= user_buff;
/* If username starts and ends in "'", chop them off */
@@ -1189,10 +935,12 @@ skip_to_ssl:
user[user_len]= '\0';
}
+ if (thd->main_security_ctx.user)
+ x_free(thd->main_security_ctx.user);
if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
return 1; /* The error is set by my_strdup(). */
return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
-
+
error:
inc_host_errors(&thd->remote.sin_addr);
my_error(ER_HANDSHAKE_ERROR, MYF(0));
@@ -1219,7 +967,7 @@ bool setup_connection_thread_globals(THD *thd)
{
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
statistic_increment(aborted_connects,&LOCK_status);
- thread_scheduler.end_thread(thd, 0);
+ thd->scheduler->end_thread(thd, 0);
return 1; // Error
}
return 0;
@@ -1241,8 +989,7 @@ bool setup_connection_thread_globals(THD *thd)
1 error
*/
-
-static bool login_connection(THD *thd)
+bool login_connection(THD *thd)
{
NET *net= &thd->net;
int error;
@@ -1280,7 +1027,7 @@ static bool login_connection(THD *thd)
This mainly updates status variables
*/
-static void end_connection(THD *thd)
+void end_connection(THD *thd)
{
NET *net= &thd->net;
plugin_thdvar_cleanup(thd);
@@ -1313,7 +1060,7 @@ static void end_connection(THD *thd)
Initialize THD to handle queries
*/
-static void prepare_new_connection_state(THD* thd)
+void prepare_new_connection_state(THD* thd)
{
Security_context *sctx= thd->security_ctx;
@@ -1383,7 +1130,7 @@ pthread_handler_t handle_one_connection(void *arg)
{
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
statistic_increment(aborted_connects,&LOCK_status);
- thread_scheduler.end_thread(thd,0);
+ thd->scheduler->end_thread(thd,0);
return 0;
}
@@ -1433,7 +1180,7 @@ pthread_handler_t handle_one_connection(void *arg)
end_thread:
close_connection(thd, 0, 1);
- if (thread_scheduler.end_thread(thd,1))
+ if (thd->scheduler->end_thread(thd,1))
return 0; // Probably no-threads
/*
@@ -1446,4 +1193,3 @@ end_thread:
}
}
#endif /* EMBEDDED_LIBRARY */
-
diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc
index d8fcdcfcb9f..3ebc28ebbd2 100644
--- a/sql/sql_crypt.cc
+++ b/sql/sql_crypt.cc
@@ -34,7 +34,7 @@
void SQL_CRYPT::init(ulong *rand_nr)
{
uint i;
- randominit(&rand,rand_nr[0],rand_nr[1]);
+ my_rnd_init(&rand,rand_nr[0],rand_nr[1]);
for (i=0 ; i<=255; i++)
decode_buff[i]= (char) i;
diff --git a/sql/sql_crypt.h b/sql/sql_crypt.h
index 46243b7645b..2c06b0e4ac5 100644
--- a/sql/sql_crypt.h
+++ b/sql/sql_crypt.h
@@ -23,7 +23,7 @@
class SQL_CRYPT :public Sql_alloc
{
- struct rand_struct rand,org_rand;
+ struct my_rnd_struct rand,org_rand;
char decode_buff[256],encode_buff[256];
uint shift;
public:
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 3521e54e02f..eca507a5d50 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
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
@@ -664,7 +664,7 @@ void Materialized_cursor::fetch(ulong num_rows)
If network write failed (i.e. due to a closed socked),
the error has already been set. Just return.
*/
- if (result->send_data(item_list))
+ if (result->send_data(item_list) > 0)
return;
}
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 39c33da23ef..460b41349b3 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -1524,13 +1524,9 @@ static inline bool
cmp_db_names(const char *db1_name,
const char *db2_name)
{
- return
- /* db1 is NULL and db2 is NULL */
- (!db1_name && !db2_name) ||
-
- /* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
- (db1_name && db2_name &&
- my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
+ return ((!db1_name && !db2_name) ||
+ (db1_name && db2_name &&
+ my_strcasecmp(system_charset_info, db1_name, db2_name) == 0));
}
@@ -1603,12 +1599,9 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
Security_context *sctx= thd->security_ctx;
ulong db_access= sctx->db_access;
CHARSET_INFO *db_default_cl;
-
DBUG_ENTER("mysql_change_db");
- DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
- if (new_db_name == NULL ||
- new_db_name->length == 0)
+ if (new_db_name->length == 0)
{
if (force_switch)
{
@@ -1617,8 +1610,7 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
after loading stored program. The thing is that loading of stored
program can happen when there is no current database.
- TODO: actually, new_db_name and new_db_name->str seem to be always
- non-NULL. In case of stored program, new_db_name->str == "" and
+ In case of stored program, new_db_name->str == "" and
new_db_name->length == 0.
*/
@@ -1633,6 +1625,7 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
DBUG_RETURN(TRUE);
}
}
+ DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
if (is_schema_db(new_db_name->str, new_db_name->length))
{
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index e2eccff7ef1..f6a1654ec74 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -53,7 +53,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
THD::killed_state killed_status= THD::NOT_KILLED;
DBUG_ENTER("mysql_delete");
bool save_binlog_row_based;
- bool skip_record;
THD::enum_binlog_query_type query_type=
thd->lex->sql_command == SQLCOM_TRUNCATE ?
@@ -310,9 +309,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
{
thd->examined_row_count++;
// thd->is_error() is tested to disallow delete row on error
- if (!select || (!select->skip_record(thd, &skip_record) && !skip_record))
+ if (!select || select->skip_record(thd) > 0)
{
-
if (triggers_applicable &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
@@ -348,8 +346,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
InnoDB it can fail in a FOREIGN KEY error or an
out-of-tablespace error.
*/
- error= 1;
- break;
+ if (!select_lex->no_error)
+ {
+ error= 1;
+ break;
+ }
}
}
else
@@ -751,7 +752,7 @@ multi_delete::~multi_delete()
}
-bool multi_delete::send_data(List<Item> &values)
+int multi_delete::send_data(List<Item> &values)
{
int secure_counter= delete_while_scanning ? -1 : 0;
TABLE_LIST *del_table;
@@ -1104,6 +1105,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
HA_CREATE_INFO create_info;
char path[FN_REFLEN + 1];
TABLE *table;
+ TABLE_LIST *tbl;
bool error;
uint path_length;
bool is_temporary_table= false;
@@ -1117,14 +1119,19 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
/* If it is a temporary table, close and regenerate it */
if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
{
- is_temporary_table= true;
- handlerton *table_type= table->s->db_type();
TABLE_SHARE *share= table->s;
+ handlerton *table_type= share->db_type();
+ is_temporary_table= true;
+
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
goto trunc_by_del;
+ for (tbl= table_list; tbl; tbl= tbl->next_local)
+ tbl->deleting= TRUE; /* to trigger HA_PREPARE_FOR_DROP */
+
table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
-
+
+ create_info.options|= HA_LEX_CREATE_TMP_TABLE;
close_temporary_table(thd, table, 0, 0); // Don't free share
ha_create_table(thd, share->normalized_path.str,
share->db.str, share->table_name.str, &create_info, 1);
@@ -1132,7 +1139,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
if ((error= (int) !(open_temporary_table(thd, share->path.str,
share->db.str,
share->table_name.str, 1))))
- (void) rm_temporary_table(table_type, path);
+ (void) rm_temporary_table(table_type, share->path.str);
else
thd->thread_specific_used= TRUE;
@@ -1158,7 +1165,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
table_list->db, table_list->table_name);
DBUG_RETURN(TRUE);
}
- if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd, table_type),
+ if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd,
+ table_type),
HTON_CAN_RECREATE))
goto trunc_by_del;
@@ -1166,9 +1174,11 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
DBUG_RETURN(TRUE);
}
- // Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
- // crashes, replacement works. *(path + path_length - reg_ext_length)=
- // '\0';
+ /*
+ Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
+ crashes, replacement works. *(path + path_length - reg_ext_length)=
+ '\0';
+ */
path[path_length - reg_ext_length] = 0;
VOID(pthread_mutex_lock(&LOCK_open));
error= ha_create_table(thd, path, table_list->db, table_list->table_name,
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 01e2fd10be9..3eb89f65f40 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 1718bcb3e09..55d85625eae 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -162,6 +162,8 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
}
thd->warn_count[(uint) level]++;
thd->total_warn_count++;
+ /* Make sure we also count warnings pushed after calling set_ok_status(). */
+ thd->main_da.increment_warning();
DBUG_RETURN(err);
}
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 1de7f47f915..15a2a1298f0 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2001, 2010, Oracle and/or its affiliates.
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.
@@ -550,6 +550,12 @@ retry:
mode= RLAST;
}
}
+ else if (table->file->inited != handler::RND)
+ {
+ /* Convert RNEXT to RFIRST if we haven't started row scan */
+ if (mode == RNEXT)
+ mode= RFIRST;
+ }
if (insert_fields(thd, &thd->lex->select_lex.context,
tables->db, tables->alias, &it, 0))
@@ -571,6 +577,8 @@ retry:
case RNEXT:
if (table->file->inited != handler::NONE)
{
+ if ((error= table->file->can_continue_handler_scan()))
+ break;
if (keyname)
{
/* Check if we read from the same index. */
@@ -605,6 +613,8 @@ retry:
DBUG_ASSERT((uint) keyno == table->file->get_index());
if (table->file->inited != handler::NONE)
{
+ if ((error= table->file->can_continue_handler_scan()))
+ break;
error=table->file->index_prev(table->record[0]);
break;
}
@@ -675,8 +685,11 @@ retry:
continue;
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
{
- sql_print_error("mysql_ha_read: Got error %d when reading table '%s'",
- error, tables->table_name);
+ /* Don't give error in the log file for some expected problems */
+ if (error != HA_ERR_RECORD_CHANGED && error != HA_ERR_WRONG_COMMAND)
+ sql_print_error("mysql_ha_read: Got error %d when reading "
+ "table '%s'",
+ error, tables->table_name);
table->file->print_error(error,MYF(0));
goto err;
}
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index e6f30747fa0..a00fc1003c2 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
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
@@ -528,7 +528,8 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
String **end= pointers + names->elements;
List_iterator<String> it(*names);
- for (pos= pointers; pos!=end; (*pos++= it++)) ;
+ for (pos= pointers; pos!=end; (*pos++= it++))
+ ;
my_qsort(pointers,names->elements,sizeof(String*),string_ptr_cmp);
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index e176e5c9b6d..07cf499f134 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -89,6 +89,7 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view);
SYNOPSIS
check_view_single_update()
fields The insert/update fields to be checked.
+ values Values to use for update
view The view for insert.
map [in/out] The insert table map.
@@ -108,8 +109,8 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view);
1 Error
*/
-bool check_view_single_update(List<Item> &fields, TABLE_LIST *view,
- table_map *map)
+bool check_view_single_update(List<Item> &fields, List<Item> *values,
+ TABLE_LIST *view, table_map *map)
{
/* it is join view => we need to find the table for update */
List_iterator_fast<Item> it(fields);
@@ -120,6 +121,15 @@ bool check_view_single_update(List<Item> &fields, TABLE_LIST *view,
while ((item= it++))
tables|= item->used_tables();
+ if (values)
+ {
+ it.init(*values);
+ while ((item= it++))
+ tables|= item->used_tables();
+ }
+
+ /* Convert to real table bits */
+ tables&= ~PSEUDO_TABLE_BITS;
/* Check found map against provided map */
if (*map)
{
@@ -153,6 +163,10 @@ error:
fields The insert fields.
values The insert values.
check_unique If duplicate values should be rejected.
+ fields_and_values_from_different_maps
+ Set to 1 if fields and values are using
+ different table maps, like on select ... insert
+ map Store here table map for used fields
NOTE
Clears TIMESTAMP_AUTO_SET_ON_INSERT from table->timestamp_field_type
@@ -166,7 +180,9 @@ error:
static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
List<Item> &fields, List<Item> &values,
- bool check_unique, table_map *map)
+ bool check_unique,
+ bool fields_and_values_from_different_maps,
+ table_map *map)
{
TABLE *table= table_list->table;
@@ -239,7 +255,10 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE)
{
- if (check_view_single_update(fields, table_list, map))
+ if (check_view_single_update(fields,
+ fields_and_values_from_different_maps ?
+ (List<Item>*) 0 : &values,
+ table_list, map))
return -1;
table= table_list->table;
}
@@ -299,10 +318,12 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
*/
static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
- List<Item> &update_fields, table_map *map)
+ List<Item> &update_fields,
+ List<Item> &update_values, table_map *map)
{
TABLE *table= insert_table_list->table;
- my_bool timestamp_mark= 0;
+ my_bool timestamp_mark;
+ LINT_INIT(timestamp_mark);
if (table->timestamp_field)
{
@@ -319,7 +340,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
return -1;
if (insert_table_list->effective_algorithm == VIEW_ALGORITHM_MERGE &&
- check_view_single_update(update_fields, insert_table_list, map))
+ check_view_single_update(update_fields, &update_values,
+ insert_table_list, map))
return -1;
if (table->timestamp_field)
@@ -386,10 +408,9 @@ void prepare_triggers_for_insert_stmt(TABLE *table)
downgrade the lock in handler::store_lock() method.
*/
-static
-void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
- enum_duplicates duplic,
- bool is_multi_insert)
+void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type,
+ enum_duplicates duplic,
+ bool is_multi_insert)
{
if (duplic == DUP_UPDATE ||
(duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT))
@@ -574,6 +595,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
bool transactional_table, joins_freed= FALSE;
bool changed;
bool was_insert_delayed= (table_list->lock_type == TL_WRITE_DELAYED);
+ bool using_bulk_insert= 0;
uint value_count;
ulong counter = 1;
ulonglong id;
@@ -601,8 +623,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
Upgrade lock type if the requested lock is incompatible with
the current connection mode or table operation.
*/
- upgrade_lock_type(thd, &table_list->lock_type, duplic,
- values_list.elements > 1);
+ upgrade_lock_type_for_insert(thd, &table_list->lock_type, duplic,
+ values_list.elements > 1);
/*
We can't write-delayed into a table locked with LOCK TABLES:
@@ -739,8 +761,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
{
if (duplic != DUP_ERROR || ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- if (!thd->prelocked_mode)
+ if (!thd->prelocked_mode && values_list.elements > 1)
+ {
+ using_bulk_insert= 1;
table->file->ha_start_bulk_insert(values_list.elements);
+ }
}
thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
@@ -863,7 +888,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
auto_inc values from the delayed_insert thread as they share TABLE.
*/
table->file->ha_release_auto_increment();
- if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error)
+ if (using_bulk_insert && table->file->ha_end_bulk_insert() && !error)
{
table->file->print_error(my_errno,MYF(0));
error=1;
@@ -884,7 +909,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
}
if (error <= 0 ||
thd->transaction.stmt.modified_non_trans_table ||
- was_insert_delayed)
+ was_insert_delayed)
{
if (mysql_bin_log.is_open())
{
@@ -1213,7 +1238,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
bool res= 0;
table_map map= 0;
DBUG_ENTER("mysql_prepare_insert");
- DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d",
+ DBUG_PRINT("enter", ("table_list: 0x%lx table: 0x%lx view: %d",
(ulong)table_list, (ulong)table,
(int)insert_into_view));
/* INSERT should have a SELECT or VALUES clause */
@@ -1266,9 +1291,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
table_list->next_local= 0;
context->resolve_in_table_list_only(table_list);
- res= check_insert_fields(thd, context->table_list, fields, *values,
- !insert_into_view, &map) ||
- setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0);
+ res= (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0) ||
+ check_insert_fields(thd, context->table_list, fields, *values,
+ !insert_into_view, 0, &map));
if (!res && check_fields)
{
@@ -1281,18 +1306,19 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
thd->abort_on_warning= saved_abort_on_warning;
}
+ if (!res)
+ res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0);
+
if (!res && duplic == DUP_UPDATE)
{
select_lex->no_wrap_view_item= TRUE;
- res= check_update_fields(thd, context->table_list, update_fields, &map);
+ res= check_update_fields(thd, context->table_list, update_fields,
+ update_values, &map);
select_lex->no_wrap_view_item= FALSE;
}
/* Restore the current context. */
ctx_state.restore_state(context, table_list);
-
- if (!res)
- res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0);
}
if (res)
@@ -1484,7 +1510,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->file->adjust_next_insert_id_after_explicit_value(
table->next_number_field->val_int());
info->touched++;
- if (!records_are_comparable(table) || compare_records(table))
+ if (!records_are_comparable(table) || compare_record(table))
{
if ((error=table->file->ha_update_row(table->record[1],
table->record[0])) &&
@@ -1766,7 +1792,8 @@ public:
thd.system_thread= SYSTEM_THREAD_DELAYED_INSERT;
thd.security_ctx->host_or_ip= "";
bzero((char*) &info,sizeof(info));
- pthread_mutex_init(&mutex,MY_MUTEX_INIT_FAST);
+ my_pthread_mutex_init(&mutex, MY_MUTEX_INIT_FAST, "Delayed_insert::mutex",
+ 0);
pthread_cond_init(&cond,NULL);
pthread_cond_init(&cond_client,NULL);
VOID(pthread_mutex_lock(&LOCK_thread_count));
@@ -2276,6 +2303,7 @@ void kill_delayed_threads(void)
while ((di= it++))
{
di->thd.killed= THD::KILL_CONNECTION;
+ pthread_mutex_lock(&di->thd.LOCK_thd_data);
if (di->thd.mysys_var)
{
pthread_mutex_lock(&di->thd.mysys_var->mutex);
@@ -2286,13 +2314,15 @@ void kill_delayed_threads(void)
in handle_delayed_insert()
*/
if (&di->mutex != di->thd.mysys_var->current_mutex)
- pthread_mutex_lock(di->thd.mysys_var->current_mutex);
+ my_pthread_mutex_lock(di->thd.mysys_var->current_mutex,
+ MYF_NO_DEADLOCK_DETECTION);
pthread_cond_broadcast(di->thd.mysys_var->current_cond);
if (&di->mutex != di->thd.mysys_var->current_mutex)
pthread_mutex_unlock(di->thd.mysys_var->current_mutex);
}
pthread_mutex_unlock(&di->thd.mysys_var->mutex);
}
+ pthread_mutex_unlock(&di->thd.LOCK_thd_data);
}
VOID(pthread_mutex_unlock(&LOCK_delayed_insert)); // For unlink from list
}
@@ -2540,13 +2570,14 @@ end:
clients
*/
- close_thread_tables(thd); // Free the table
di->table=0;
di->dead= 1; // If error
thd->killed= THD::KILL_CONNECTION; // If error
- pthread_cond_broadcast(&di->cond_client); // Safety
pthread_mutex_unlock(&di->mutex);
+ close_thread_tables(thd); // Free the table
+ pthread_cond_broadcast(&di->cond_client); // Safety
+
pthread_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table
pthread_mutex_lock(&LOCK_delayed_insert);
delete di;
@@ -2611,7 +2642,7 @@ bool Delayed_insert::handle_inserts(void)
or if another thread is removing the current table definition
from the table cache.
*/
- my_error(ER_DELAYED_CANT_CHANGE_LOCK,MYF(ME_FATALERROR),
+ my_error(ER_DELAYED_CANT_CHANGE_LOCK, MYF(ME_FATALERROR | ME_NOREFRESH),
table->s->table_name.str);
goto err;
}
@@ -2785,10 +2816,11 @@ bool Delayed_insert::handle_inserts(void)
query_cache_invalidate3(&thd, table, 1);
if (thr_reschedule_write_lock(*thd.lock->locks))
{
- /* This is not known to happen. */
- my_error(ER_DELAYED_CANT_CHANGE_LOCK,MYF(ME_FATALERROR),
- table->s->table_name.str);
- goto err;
+ /* This is not known to happen. */
+ my_error(ER_DELAYED_CANT_CHANGE_LOCK,
+ MYF(ME_FATALERROR | ME_NOREFRESH),
+ table->s->table_name.str);
+ goto err;
}
if (!using_bin_log)
table->file->extra(HA_EXTRA_WRITE_CACHE);
@@ -2963,10 +2995,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
/* Errors during check_insert_fields() should not be ignored. */
lex->current_select->no_error= FALSE;
- res= check_insert_fields(thd, table_list, *fields, values,
- !insert_into_view, &map) ||
- setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0);
-
+ res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) ||
+ check_insert_fields(thd, table_list, *fields, values,
+ !insert_into_view, 1, &map));
if (!res && fields->elements)
{
bool saved_abort_on_warning= thd->abort_on_warning;
@@ -2992,7 +3023,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
lex->select_lex.no_wrap_view_item= TRUE;
res= res || check_update_fields(thd, context->table_list,
- *info.update_fields, &map);
+ *info.update_fields, *info.update_values,
+ &map);
lex->select_lex.no_wrap_view_item= FALSE;
/*
When we are not using GROUP BY and there are no ungrouped aggregate functions
@@ -3147,7 +3179,7 @@ select_insert::~select_insert()
}
-bool select_insert::send_data(List<Item> &values)
+int select_insert::send_data(List<Item> &values)
{
DBUG_ENTER("select_insert::send_data");
bool error=0;
@@ -3247,12 +3279,11 @@ bool select_insert::send_eof()
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
trans_table, table->file->table_type()));
- error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert():0;
+ error= (!thd->prelocked_mode) ? table->file->ha_end_bulk_insert() : 0;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
- changed= (info.copied || info.deleted || info.updated);
- if (changed)
+ if ((changed= (info.copied || info.deleted || info.updated)))
{
/*
We must invalidate the table in the query cache before binlog writing
@@ -3548,10 +3579,12 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
Create_field *cr_field;
Field *field, *def_field;
if (item->type() == Item::FUNC_ITEM)
+ {
if (item->result_type() != STRING_RESULT)
field= item->tmp_table_field(&tmp_table);
else
field= item->tmp_table_field_from_field_type(&tmp_table, 0);
+ }
else
field= create_tmp_field(thd, &tmp_table, item, item->type(),
(Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
@@ -3646,6 +3679,12 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
MYSQL_LOCK_IGNORE_FLUSH, &not_used)) ||
hooks->postlock(&table, 1))
{
+ /* purecov: begin tested */
+ /*
+ This can happen in innodb when you get a deadlock when using same table
+ in insert and select
+ */
+ my_error(ER_CANT_LOCK, MYF(0), my_errno);
if (*lock)
{
mysql_unlock_tables(thd, *lock);
@@ -3655,6 +3694,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
if (!create_info->table_existed)
drop_open_table(thd, table, create_table->db, create_table->table_name);
DBUG_RETURN(0);
+ /* purecov: end */
}
DBUG_RETURN(table);
}
@@ -3785,7 +3825,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_RETURN(-1);
}
- /* First field to copy */
+ /* First field to copy */
field= table->field+table->s->fields - values.elements;
/* Mark all fields that are given values */
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 6e40f9b9614..82c375fe045 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -775,7 +775,7 @@ bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted)
int MYSQLlex(void *arg, void *yythd)
{
- reg1 uchar c= 0;
+ reg1 uchar c;
bool comment_closed;
int tokval, result_state;
uint length;
@@ -788,6 +788,7 @@ int MYSQLlex(void *arg, void *yythd)
uchar *state_map= cs->state_map;
uchar *ident_map= cs->ident_map;
+ LINT_INIT(c);
lip->yylval=yylval; // The global state
lip->start_token();
@@ -853,7 +854,8 @@ int MYSQLlex(void *arg, void *yythd)
its value in a query for the binlog, the query must stay
grammatically correct.
*/
- if (c == '?' && lip->stmt_prepare_mode && !ident_map[lip->yyPeek()])
+ if (c == '?' && lip->stmt_prepare_mode &&
+ !ident_map[(uchar) lip->yyPeek()])
return(PARAM_MARKER);
}
@@ -921,7 +923,10 @@ int MYSQLlex(void *arg, void *yythd)
else
#endif
{
- for (result_state= c; ident_map[c= lip->yyGet()]; result_state|= c) ;
+ for (result_state= c;
+ ident_map[(uchar) (c= lip->yyGet())];
+ result_state|= c)
+ ;
/* If there were non-ASCII characters, mark that we must convert */
result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
}
@@ -933,9 +938,11 @@ int MYSQLlex(void *arg, void *yythd)
If we find a space then this can't be an identifier. We notice this
below by checking start != lex->ptr.
*/
- for (; state_map[c] == MY_LEX_SKIP ; c= lip->yyGet()) ;
+ for (; state_map[(uchar) c] == MY_LEX_SKIP ; c= lip->yyGet())
+ ;
}
- if (start == lip->get_ptr() && c == '.' && ident_map[lip->yyPeek()])
+ if (start == lip->get_ptr() && c == '.' &&
+ ident_map[(uchar) lip->yyPeek()])
lip->next_state=MY_LEX_IDENT_SEP;
else
{ // '(' must follow directly if function
@@ -978,12 +985,12 @@ int MYSQLlex(void *arg, void *yythd)
return(result_state); // IDENT or IDENT_QUOTED
- case MY_LEX_IDENT_SEP: // Found ident and now '.'
+ case MY_LEX_IDENT_SEP: // Found ident and now '.'
yylval->lex_str.str= (char*) lip->get_ptr();
yylval->lex_str.length= 1;
- c= lip->yyGet(); // should be '.'
- lip->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword)
- if (!ident_map[lip->yyPeek()]) // Probably ` or "
+ c= lip->yyGet(); // should be '.'
+ lip->next_state= MY_LEX_IDENT_START; // Next is ident (not keyword)
+ if (!ident_map[(uchar) lip->yyPeek()]) // Probably ` or "
lip->next_state= MY_LEX_START;
return((int) c);
@@ -1006,7 +1013,8 @@ int MYSQLlex(void *arg, void *yythd)
}
else if (c == 'b')
{
- while ((c= lip->yyGet()) == '0' || c == '1') ;
+ while ((c= lip->yyGet()) == '0' || c == '1')
+ ;
if ((lip->yyLength() >= 3) && !ident_map[c])
{
/* Skip '0b' */
@@ -1065,11 +1073,12 @@ int MYSQLlex(void *arg, void *yythd)
else
#endif
{
- for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c) ;
+ for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c)
+ ;
/* If there were non-ASCII characters, mark that we must convert */
result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
}
- if (c == '.' && ident_map[lip->yyPeek()])
+ if (c == '.' && ident_map[(uchar) lip->yyPeek()])
lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
yylval->lex_str= get_token(lip, 0, lip->yyLength());
@@ -1168,7 +1177,8 @@ int MYSQLlex(void *arg, void *yythd)
case MY_LEX_BIN_NUMBER: // Found b'bin-string'
lip->yySkip(); // Accept opening '
- while ((c= lip->yyGet()) == '0' || c == '1') ;
+ while ((c= lip->yyGet()) == '0' || c == '1')
+ ;
if (c != '\'')
return(ABORT_SYM); // Illegal hex constant
lip->yySkip(); // Accept closing '
@@ -1179,8 +1189,8 @@ int MYSQLlex(void *arg, void *yythd)
return (BIN_NUM);
case MY_LEX_CMP_OP: // Incomplete comparison operator
- if (state_map[lip->yyPeek()] == MY_LEX_CMP_OP ||
- state_map[lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
+ if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP ||
+ state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
lip->yySkip();
if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
{
@@ -1191,11 +1201,11 @@ int MYSQLlex(void *arg, void *yythd)
break;
case MY_LEX_LONG_CMP_OP: // Incomplete comparison operator
- if (state_map[lip->yyPeek()] == MY_LEX_CMP_OP ||
- state_map[lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
+ if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP ||
+ state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
{
lip->yySkip();
- if (state_map[lip->yyPeek()] == MY_LEX_CMP_OP)
+ if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP)
lip->yySkip();
}
if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
@@ -1414,7 +1424,7 @@ int MYSQLlex(void *arg, void *yythd)
}
break;
case MY_LEX_USER_END: // end '@' of user@hostname
- switch (state_map[lip->yyPeek()]) {
+ switch (state_map[(uchar) lip->yyPeek()]) {
case MY_LEX_STRING:
case MY_LEX_USER_VARIABLE_DELIMITER:
case MY_LEX_STRING_OR_DELIMITER:
@@ -1439,7 +1449,7 @@ int MYSQLlex(void *arg, void *yythd)
yylval->lex_str.str=(char*) lip->get_ptr();
yylval->lex_str.length=1;
lip->yySkip(); // Skip '@'
- lip->next_state= (state_map[lip->yyPeek()] ==
+ lip->next_state= (state_map[(uchar) lip->yyPeek()] ==
MY_LEX_USER_VARIABLE_DELIMITER ?
MY_LEX_OPERATOR_OR_IDENT :
MY_LEX_IDENT_OR_KEYWORD);
@@ -1451,7 +1461,8 @@ int MYSQLlex(void *arg, void *yythd)
[(global | local | session) .]variable_name
*/
- for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c) ;
+ for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c)
+ ;
/* If there were non-ASCII characters, mark that we must convert */
result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
@@ -1595,7 +1606,6 @@ void st_select_lex::init_query()
having= prep_having= where= prep_where= 0;
olap= UNSPECIFIED_OLAP_TYPE;
having_fix_field= 0;
- group_fix_field= 0;
context.select_lex= this;
context.init();
/*
@@ -1835,15 +1845,19 @@ void st_select_lex_unit::exclude_tree()
'last' should be reachable from this st_select_lex_node
*/
-void st_select_lex::mark_as_dependent(st_select_lex *last)
+void st_select_lex::mark_as_dependent(st_select_lex *last, Item *dependency)
{
+ SELECT_LEX *next_to_last;
+
+ DBUG_ASSERT(this != last);
+
/*
Mark all selects from resolved to 1 before select where was
found table as depended (of select where was found table)
*/
- for (SELECT_LEX *s= this;
- s && s != last;
- s= s->outer_select())
+ SELECT_LEX *s= this;
+ do
+ {
if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
{
// Select is dependent of outer select
@@ -1859,8 +1873,13 @@ void st_select_lex::mark_as_dependent(st_select_lex *last)
sl->uncacheable|= UNCACHEABLE_UNITED;
}
}
+ next_to_last= s;
+ } while ((s= s->outer_select()) != last && s != 0);
+
is_correlated= TRUE;
this->master_unit()->item->is_correlated= TRUE;
+ if (dependency)
+ next_to_last->master_unit()->item->refers_to.push_back(dependency);
}
bool st_select_lex_node::set_braces(bool value) { return 1; }
@@ -2877,7 +2896,7 @@ static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
{
if (tbl->on_expr)
{
- tbl->prep_on_expr= tbl->on_expr;
+ thd->check_and_register_item_tree(&tbl->prep_on_expr, &tbl->on_expr);
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
}
fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list);
@@ -2911,12 +2930,12 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
first_execution= 0;
if (*conds)
{
- prep_where= *conds;
+ thd->check_and_register_item_tree(&prep_where, conds);
*conds= where= prep_where->copy_andor_structure(thd);
}
if (*having_conds)
{
- prep_having= *having_conds;
+ thd->check_and_register_item_tree(&prep_having, having_conds);
*having_conds= having= prep_having->copy_andor_structure(thd);
}
fix_prepare_info_in_table_list(thd, table_list.first);
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 035fa1fde91..3706d4c30ae 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -649,8 +649,6 @@ public:
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
/* TRUE when having fix field called in processing of this SELECT */
bool having_fix_field;
- /* TRUE when GROUP BY fix field called in processing of this SELECT */
- bool group_fix_field;
/* List of references to fields referenced from inner selects */
List<Item_outer_ref> inner_refs_list;
/* Number of Item_sum-derived objects in this SELECT */
@@ -737,8 +735,9 @@ public:
{
return master_unit()->return_after_parsing();
}
+ inline bool is_subquery_function() { return master_unit()->item != 0; }
- void mark_as_dependent(st_select_lex *last);
+ void mark_as_dependent(st_select_lex *last, Item *dependency);
bool set_braces(bool value);
bool inc_in_sum_expr();
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 81283a6ae53..27882d057b8 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -1,7 +1,7 @@
#ifndef INCLUDES_MYSQL_SQL_LIST_H
#define INCLUDES_MYSQL_SQL_LIST_H
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -45,7 +45,7 @@ public:
static void operator delete[](void *ptr, MEM_ROOT *mem_root)
{ /* never called */ }
static void operator delete[](void *ptr, size_t size) { TRASH(ptr, size); }
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
bool dummy;
inline Sql_alloc() :dummy(0) {}
inline ~Sql_alloc() {}
@@ -512,6 +512,43 @@ public:
/*
+ Exchange sort algorithm for List<T>.
+*/
+template <class T>
+inline void exchange_sort(List<T> *list_to_sort,
+ int (*sort_func)(T *a, T *b, void *arg), void *arg)
+{
+ bool swap;
+ List_iterator<T> it(*list_to_sort);
+ do
+ {
+ T *item1= it++;
+ T **ref1= it.ref();
+ T *item2;
+
+ swap= FALSE;
+ while ((item2= it++))
+ {
+ T **ref2= it.ref();
+ if (sort_func(item1, item2, arg) < 0)
+ {
+ T *item= *ref1;
+ *ref1= *ref2;
+ *ref2= item;
+ swap= TRUE;
+ }
+ else
+ {
+ item1= item2;
+ ref1= ref2;
+ }
+ }
+ it.rewind();
+ } while (swap);
+}
+
+
+/*
A simple intrusive list which automaticly removes element from list
on delete (for THD element)
*/
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 6a0e5fd9133..23105d84a9d 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -753,7 +753,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
it.rewind();
uchar *pos=read_info.row_start;
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
read_info.row_end[0]=0;
#endif
@@ -892,11 +892,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
real_item= item->real_item();
if ((!read_info.enclosed &&
- (enclosed_length && length == 4 &&
- !memcmp(pos, STRING_WITH_LEN("NULL")))) ||
+ (enclosed_length && length == 4 &&
+ !memcmp(pos, STRING_WITH_LEN("NULL")))) ||
(length == 1 && read_info.found_null))
{
-
if (real_item->type() == Item::FIELD_ITEM)
{
Field *field= ((Item_field *)real_item)->field;
@@ -1108,7 +1107,6 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
field_term_char= field_term_length ? (uchar) field_term_ptr[0] : INT_MAX;
line_term_char= line_term_length ? (uchar) line_term_ptr[0] : INT_MAX;
-
/* Set of a stack for unget if long terminators */
uint length= max(cs->mbmaxlen, max(field_term_length, line_term_length)) + 1;
set_if_bigger(length,line_start.length());
@@ -1125,7 +1123,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
MYF(MY_WME)))
{
my_free((uchar*) buffer,MYF(0)); /* purecov: inspected */
- buffer= NULL;
+ buffer= 0;
error=1;
}
else
@@ -1154,7 +1152,6 @@ READ_INFO::~READ_INFO()
{
if (need_end_io_cache)
::end_io_cache(&cache);
-
my_free(buffer, MYF(MY_ALLOW_ZERO_PTR));
}
@@ -1271,8 +1268,9 @@ int READ_INFO::read_field()
// End of enclosed field if followed by field_term or line_term
if (chr == my_b_EOF ||
(chr == line_term_char && terminator(line_term_ptr,
- line_term_length)))
- { // Maybe unexpected linefeed
+ line_term_length)))
+ {
+ /* Maybe unexpected linefeed */
enclosed=1;
found_end_of_line=1;
row_start=buffer+1;
diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc
index 4edd51d47c3..ddc287c1b6d 100644
--- a/sql/sql_olap.cc
+++ b/sql/sql_olap.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 14ad77d29fd..28723713fe7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +31,11 @@
#include "events.h"
#include "sql_trigger.h"
#include "debug_sync.h"
+#include <rpl_mi.h>
+
+#ifdef WITH_MARIA_STORAGE_ENGINE
+#include "../storage/maria/ha_maria.h"
+#endif
/**
@defgroup Runtime_Environment Runtime Environment
@@ -47,6 +53,9 @@
"FUNCTION" : "PROCEDURE")
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
+static bool execute_show_status(THD *thd, TABLE_LIST *all_tables);
+static bool execute_rename_table(THD *thd, TABLE_LIST *first_table,
+ TABLE_LIST *all_tables);
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
const char *any_db="*any*"; // Special symbol for check_access
@@ -180,6 +189,9 @@ bool end_active_trans(THD *thd)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_commit(thd))
error=1;
+#ifdef WITH_MARIA_STORAGE_ENGINE
+ ha_maria::implicit_commit(thd, TRUE);
+#endif
}
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
thd->transaction.all.modified_non_trans_table= FALSE;
@@ -363,7 +375,7 @@ void init_update_queries(void)
bool is_update_query(enum enum_sql_command command)
{
- DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
+ DBUG_ASSERT(command <= SQLCOM_END);
return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
}
@@ -374,7 +386,7 @@ bool is_update_query(enum enum_sql_command command)
*/
bool is_log_table_write_query(enum enum_sql_command command)
{
- DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
+ DBUG_ASSERT(command <= SQLCOM_END);
return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
}
@@ -450,7 +462,7 @@ static void handle_bootstrap_impl(THD *thd)
thd->init_for_queries();
while (fgets(buff, thd->net.max_packet, file))
{
- char *query, *res;
+ char *query;
/* strlen() can't be deleted because fgets() doesn't return length */
ulong length= (ulong) strlen(buff);
while (buff[length-1] != '\n' && !feof(file))
@@ -467,8 +479,7 @@ static void handle_bootstrap_impl(THD *thd)
break;
}
buff= (char*) thd->net.buff;
- res= fgets(buff + length, thd->net.max_packet - length, file);
- if (!res && !feof(file))
+ if (!fgets(buff + length, thd->net.max_packet - length, file))
{
net_end_statement(thd);
bootstrap_error= 1;
@@ -737,6 +748,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
xa_state_names[thd->transaction.xid_state.xa_state]);
DBUG_RETURN(1);
}
+ thd->lex->start_transaction_opt= 0; /* for begin_trans() */
switch (completion) {
case COMMIT:
/*
@@ -993,7 +1005,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
NET *net= &thd->net;
bool error= 0;
DBUG_ENTER("dispatch_command");
- DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
+ DBUG_PRINT("info", ("command: %d", command));
thd->command=command;
/*
@@ -1001,6 +1013,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
the slow log only if opt_log_slow_admin_statements is set.
*/
thd->enable_slow_log= TRUE;
+ thd->query_plan_flags= QPLAN_INIT;
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
thd->set_time();
if (!thd->is_valid_time())
@@ -1087,6 +1100,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
status_var_increment(thd->status_var.com_other);
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
db.str= (char*) thd->alloc(db_len + tbl_len + 2);
if (!db.str)
{
@@ -1119,7 +1133,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
Cast *passwd to an unsigned char, so that it doesn't extend the sign
for *passwd > 127 and become 2**32-127 after casting to uint.
*/
- char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char db_buff[SAFE_NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd;
char *save_db;
/*
@@ -1280,12 +1294,18 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
char *beginning_of_next_stmt= (char*) end_of_stmt;
- net_end_statement(thd);
- query_cache_end_of_result(thd);
+#ifdef WITH_MARIA_STORAGE_ENGINE
+ ha_maria::implicit_commit(thd, FALSE);
+#endif
+
/*
Multiple queries exits, execute them individually
*/
close_thread_tables(thd);
+
+ net_end_statement(thd);
+ query_cache_end_of_result(thd);
+
ulong length= (ulong)(packet_end - beginning_of_next_stmt);
log_slow_statement(thd);
@@ -1328,10 +1348,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
#else
{
- char *fields, *packet_end= packet + packet_length, *arg_end;
+ char *fields, *packet_end= packet + packet_length, *wildcard;
/* Locked closure of all tables */
TABLE_LIST table_list;
- LEX_STRING conv_name;
+ char db_buff[SAFE_NAME_LEN+1];
+ uint32 db_length;
+ uint dummy_errors, query_length;
/* used as fields initializator */
lex_start(thd);
@@ -1342,27 +1364,29 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break;
/*
We have name + wildcard in packet, separated by endzero
+ (The packet is guaranteed to end with an end zero)
*/
- arg_end= strend(packet);
- uint arg_length= arg_end - packet;
-
- /* Check given table name length. */
- if (arg_length >= packet_length || arg_length > NAME_LEN)
+ wildcard= strend(packet);
+ db_length= wildcard - packet;
+ wildcard++;
+ query_length= (uint) (packet_end - wildcard); // Don't count end \0
+ if (db_length > SAFE_NAME_LEN || query_length > NAME_LEN)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
}
- thd->convert_string(&conv_name, system_charset_info,
- packet, arg_length, thd->charset());
- if (check_table_name(conv_name.str, conv_name.length, FALSE))
+ db_length= copy_and_convert(db_buff, sizeof(db_buff)-1,
+ system_charset_info, packet, db_length,
+ thd->charset(), &dummy_errors);
+ db_buff[db_length]= '\0';
+ if (check_table_name(db_buff, db_length, FALSE))
{
- /* this is OK due to convert_string() null-terminating the string */
- my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
+ my_error(ER_WRONG_TABLE_NAME, MYF(0), db_buff);
break;
}
-
- table_list.alias= table_list.table_name= conv_name.str;
- packet= arg_end + 1;
+ table_list.alias= table_list.table_name= db_buff;
+ if (!(fields= (char *) thd->memdup(wildcard, query_length + 1)))
+ break;
if (is_schema_db(table_list.db, table_list.db_length))
{
@@ -1371,9 +1395,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
table_list.schema_table= schema_table;
}
- uint query_length= (uint) (packet_end - packet); // Don't count end \0
- if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
- break;
thd->set_query(fields, query_length);
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
if (lower_case_table_names)
@@ -1468,6 +1489,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
status_var_increment(thd->status_var.com_other);
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
if (check_global_access(thd, REPL_SLAVE_ACL))
break;
@@ -1556,33 +1578,41 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
case COM_STATISTICS:
{
- STATUS_VAR current_global_status_var;
+ STATUS_VAR *current_global_status_var; // Big; Don't allocate on stack
ulong uptime;
- uint length __attribute__((unused));
+#if defined(SAFEMALLOC) || !defined(EMBEDDED_LIBRARY)
+ uint length;
+#endif
ulonglong queries_per_second1000;
char buff[250];
uint buff_len= sizeof(buff);
+ if (!(current_global_status_var= (STATUS_VAR*)
+ thd->alloc(sizeof(STATUS_VAR))))
+ break;
general_log_print(thd, command, NullS);
status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
- calc_sum_of_all_status(&current_global_status_var);
+ calc_sum_of_all_status(current_global_status_var);
if (!(uptime= (ulong) (thd->start_time - server_start_time)))
queries_per_second1000= 0;
else
queries_per_second1000= thd->query_id * LL(1000) / uptime;
- length= my_snprintf(buff, buff_len - 1,
- "Uptime: %lu Threads: %d Questions: %lu "
- "Slow queries: %lu Opens: %lu Flush tables: %lu "
- "Open tables: %u Queries per second avg: %u.%u",
- uptime,
- (int) thread_count, (ulong) thd->query_id,
- current_global_status_var.long_query_count,
- current_global_status_var.opened_tables,
- refresh_version,
- cached_open_tables(),
- (uint) (queries_per_second1000 / 1000),
- (uint) (queries_per_second1000 % 1000));
+#if defined(SAFEMALLOC) || !defined(EMBEDDED_LIBRARY)
+ length=
+#endif
+ my_snprintf((char*) buff, buff_len - 1,
+ "Uptime: %lu Threads: %d Questions: %lu "
+ "Slow queries: %lu Opens: %lu Flush tables: %lu "
+ "Open tables: %u Queries per second avg: %u.%u",
+ uptime,
+ (int) thread_count, (ulong) thd->query_id,
+ current_global_status_var->long_query_count,
+ current_global_status_var->opened_tables,
+ refresh_version,
+ cached_open_tables(),
+ (uint) (queries_per_second1000 / 1000),
+ (uint) (queries_per_second1000 % 1000));
#ifdef SAFEMALLOC
if (sf_malloc_cur_memory) // Using SAFEMALLOC
{
@@ -1681,13 +1711,26 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->transaction.stmt.reset();
- net_end_statement(thd);
- query_cache_end_of_result(thd);
+#ifdef WITH_MARIA_STORAGE_ENGINE
+ ha_maria::implicit_commit(thd, FALSE);
+#endif
+ if (!(sql_command_flags[thd->lex->sql_command] & CF_CHANGES_DATA))
+ {
+ /* No changes in data; We can send ok at once to the client */
+ net_end_statement(thd);
+ query_cache_end_of_result(thd);
+ }
thd->proc_info= "closing tables";
/* Free tables */
close_thread_tables(thd);
+ if (sql_command_flags[thd->lex->sql_command] & CF_CHANGES_DATA)
+ {
+ net_end_statement(thd);
+ query_cache_end_of_result(thd);
+ }
+
log_slow_statement(thd);
thd_proc_info(thd, "cleaning up");
@@ -1715,6 +1758,19 @@ void log_slow_statement(THD *thd)
if (unlikely(thd->in_sub_stmt))
DBUG_VOID_RETURN; // Don't set time for sub stmt
+ /* Follow the slow log filter configuration. */
+ DBUG_ASSERT(thd->variables.log_slow_filter != 0);
+ if (!(thd->variables.log_slow_filter & thd->query_plan_flags))
+ DBUG_VOID_RETURN;
+
+ /*
+ If rate limiting of slow log writes is enabled, decide whether to log
+ this query to the log or not.
+ */
+ if (thd->variables.log_slow_rate_limit > 1 &&
+ (global_query_id % thd->variables.log_slow_rate_limit) != 0)
+ DBUG_VOID_RETURN;
+
/*
Do not log administrative statements unless the appropriate option is
set.
@@ -2254,22 +2310,7 @@ mysql_execute_command(THD *thd)
break;
case SQLCOM_SHOW_STATUS:
{
- system_status_var old_status_var= thd->status_var;
- thd->initial_status_var= &old_status_var;
- if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
- res= execute_sqlcom_select(thd, all_tables);
- /* Don't log SHOW STATUS commands to slow query log */
- thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
- SERVER_QUERY_NO_GOOD_INDEX_USED);
- /*
- restore status variables, as we don't want 'show status' to cause
- changes
- */
- pthread_mutex_lock(&LOCK_status);
- add_diff_to_status(&global_status_var, &thd->status_var,
- &old_status_var);
- thd->status_var= old_status_var;
- pthread_mutex_unlock(&LOCK_status);
+ execute_show_status(thd, all_tables);
break;
}
case SQLCOM_SHOW_DATABASES:
@@ -2398,8 +2439,8 @@ mysql_execute_command(THD *thd)
my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
goto error;
#endif
- break;
}
+ break;
case SQLCOM_SHOW_NEW_MASTER:
{
if (check_global_access(thd, REPL_SLAVE_ACL))
@@ -2438,6 +2479,7 @@ mysql_execute_command(THD *thd)
check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
res = mysql_backup_table(thd, first_table);
select_lex->table_list.first= first_table;
lex->query_tables=all_tables;
@@ -2450,6 +2492,7 @@ mysql_execute_command(THD *thd)
check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
res = mysql_restore_table(thd, first_table);
select_lex->table_list.first= first_table;
lex->query_tables=all_tables;
@@ -2866,6 +2909,7 @@ end_with_restore_list:
ALTER TABLE.
*/
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
bzero((char*) &create_info, sizeof(create_info));
create_info.db_type= 0;
@@ -2914,10 +2958,12 @@ end_with_restore_list:
#endif /* HAVE_REPLICATION */
case SQLCOM_ALTER_TABLE:
- DBUG_ASSERT(first_table == all_tables && first_table != 0);
{
ulong priv=0;
ulong priv_needed= ALTER_ACL;
+
+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
+
/*
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
so we have to use a copy of this structure to make execution
@@ -2927,7 +2973,7 @@ end_with_restore_list:
HA_CREATE_INFO create_info(lex->create_info);
Alter_info alter_info(lex->alter_info, thd->mem_root);
- if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
+ if (thd->is_fatal_error) /* OOM creating a copy of alter_info */
goto error;
/*
We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well
@@ -2982,6 +3028,7 @@ end_with_restore_list:
}
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
res= mysql_alter_table(thd, select_lex->db, lex->name.str,
&create_info,
first_table,
@@ -2993,31 +3040,7 @@ end_with_restore_list:
}
case SQLCOM_RENAME_TABLE:
{
- DBUG_ASSERT(first_table == all_tables && first_table != 0);
- TABLE_LIST *table;
- for (table= first_table; table; table= table->next_local->next_local)
- {
- if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
- &table->grant.privilege,0,0, test(table->schema_table)) ||
- check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
- &table->next_local->grant.privilege, 0, 0,
- test(table->next_local->schema_table)))
- goto error;
- TABLE_LIST old_list, new_list;
- /*
- we do not need initialize old_list and new_list because we will
- come table[0] and table->next[0] there
- */
- old_list= table[0];
- new_list= table->next_local[0];
- if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
- (!test_all_bits(table->next_local->grant.privilege,
- INSERT_ACL | CREATE_ACL) &&
- check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
- goto error;
- }
-
- if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
+ if (execute_rename_table(thd, first_table, all_tables))
goto error;
break;
}
@@ -3069,6 +3092,7 @@ end_with_restore_list:
UINT_MAX, FALSE))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
res= mysql_repair_table(thd, first_table, &lex->check_opt);
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
@@ -3089,6 +3113,7 @@ end_with_restore_list:
UINT_MAX, FALSE))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
res = mysql_check_table(thd, first_table, &lex->check_opt);
select_lex->table_list.first= first_table;
lex->query_tables=all_tables;
@@ -3101,6 +3126,7 @@ end_with_restore_list:
UINT_MAX, FALSE))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
@@ -3122,6 +3148,7 @@ end_with_restore_list:
UINT_MAX, FALSE))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
+ thd->query_plan_flags|= QPLAN_ADMIN;
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
mysql_recreate_table(thd, first_table) :
mysql_optimize_table(thd, first_table, &lex->check_opt);
@@ -3287,12 +3314,17 @@ end_with_restore_list:
DBUG_EXECUTE_IF("after_mysql_insert",
{
- const char act[]=
+ const char act1[]=
"now "
"wait_for signal.continue";
+ const char act2[]=
+ "now "
+ "signal signal.continued";
DBUG_ASSERT(opt_debug_sync_timeout > 0);
- DBUG_ASSERT(!debug_sync_set_action(current_thd,
- STRING_WITH_LEN(act)));
+ DBUG_ASSERT(!debug_sync_set_action(thd,
+ STRING_WITH_LEN(act1)));
+ DBUG_ASSERT(!debug_sync_set_action(thd,
+ STRING_WITH_LEN(act2)));
};);
break;
}
@@ -5111,11 +5143,6 @@ create_sp_error:
if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
thd->row_count_func= -1;
- goto finish;
-
-error:
- res= TRUE;
-
finish:
if (need_start_waiting)
{
@@ -5126,6 +5153,11 @@ finish:
start_waiting_global_read_lock(thd);
}
DBUG_RETURN(res || thd->is_error());
+
+error:
+ thd_proc_info(thd, "query end");
+ res= TRUE;
+ goto finish;
}
@@ -5185,6 +5217,62 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
}
+static bool execute_show_status(THD *thd, TABLE_LIST *all_tables)
+{
+ bool res;
+ system_status_var old_status_var= thd->status_var;
+ thd->initial_status_var= &old_status_var;
+ if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
+ res= execute_sqlcom_select(thd, all_tables);
+ /* Don't log SHOW STATUS commands to slow query log */
+ thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
+ SERVER_QUERY_NO_GOOD_INDEX_USED);
+ /*
+ restore status variables, as we don't want 'show status' to cause
+ changes
+ */
+ pthread_mutex_lock(&LOCK_status);
+ add_diff_to_status(&global_status_var, &thd->status_var,
+ &old_status_var);
+ thd->status_var= old_status_var;
+ pthread_mutex_unlock(&LOCK_status);
+ return res;
+}
+
+
+static bool execute_rename_table(THD *thd, TABLE_LIST *first_table,
+ TABLE_LIST *all_tables)
+{
+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
+ TABLE_LIST *table;
+ for (table= first_table; table; table= table->next_local->next_local)
+ {
+ if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
+ &table->grant.privilege,0,0, test(table->schema_table)) ||
+ check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
+ &table->next_local->grant.privilege, 0, 0,
+ test(table->next_local->schema_table)))
+ return 1;
+ TABLE_LIST old_list, new_list;
+ /*
+ we do not need initialize old_list and new_list because we will
+ come table[0] and table->next[0] there
+ */
+ old_list= table[0];
+ new_list= table->next_local[0];
+ if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
+ (!test_all_bits(table->next_local->grant.privilege,
+ INSERT_ACL | CREATE_ACL) &&
+ check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
+ return 1;
+ }
+
+ if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
+ return 1;
+ return 0;
+}
+
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/**
Check grants for commands which work only with one table.
@@ -5312,8 +5400,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
(see SQLCOM_GRANT case, mysql_execute_command() function) and
set db_is_pattern according to 'dont_check_global_grants' value.
*/
- bool db_is_pattern= (test(want_access & GRANT_ACL) &&
- dont_check_global_grants);
+ bool db_is_pattern= ((want_access & GRANT_ACL) && dont_check_global_grants);
ulong dummy;
DBUG_ENTER("check_access");
DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
@@ -5792,6 +5879,7 @@ void mysql_reset_thd_for_next_command(THD *thd)
DBUG_ENTER("mysql_reset_thd_for_next_command");
DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
DBUG_ASSERT(! thd->in_sub_stmt);
+ DBUG_ASSERT(thd->transaction.on);
thd->free_list= 0;
thd->select_number= 1;
/*
@@ -5831,6 +5919,8 @@ void mysql_reset_thd_for_next_command(THD *thd)
thd->total_warn_count=0; // Warnings for this query
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
+ thd->query_plan_flags= QPLAN_INIT;
+ thd->query_plan_fsort_passes= 0;
/*
Because we come here only for start of top-statements, binlog format is
@@ -6810,6 +6900,28 @@ push_new_name_resolution_context(THD *thd,
/**
+ Fix condition which contains only field (f turns to f <> 0 )
+
+ @param cond The condition to fix
+
+ @return fixed condition
+*/
+
+Item *normalize_cond(Item *cond)
+{
+ if (cond)
+ {
+ Item::Type type= cond->type();
+ if (type == Item::FIELD_ITEM || type == Item::REF_ITEM)
+ {
+ cond= new Item_func_ne(cond, new Item_int(0));
+ }
+ }
+ return cond;
+}
+
+
+/**
Add an ON condition to the second operand of a JOIN ... ON.
Add an ON condition to the right operand of a JOIN ... ON clause.
@@ -6827,6 +6939,7 @@ void add_join_on(TABLE_LIST *b, Item *expr)
{
if (expr)
{
+ expr= normalize_cond(expr);
if (!b->on_expr)
b->on_expr= expr;
else
@@ -6943,7 +7056,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
When an error is returned, my_message may have not been called and
the client will hang waiting for a response.
*/
- my_error(ER_UNKNOWN_ERROR, MYF(0));
+ my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed");
}
}
@@ -6979,9 +7092,9 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
}
#ifdef HAVE_REPLICATION
int rotate_error= 0;
- pthread_mutex_lock(&LOCK_active_mi);
+ pthread_mutex_lock(&active_mi->data_lock);
rotate_error= rotate_relay_log(active_mi);
- pthread_mutex_unlock(&LOCK_active_mi);
+ pthread_mutex_unlock(&active_mi->data_lock);
if (rotate_error)
*write_to_binlog= -1;
#endif
@@ -7862,15 +7975,14 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
/*
Check if path does not contain mysql data home directory
+
SYNOPSIS
test_if_data_home_dir()
dir directory
- conv_home_dir converted data home directory
- home_dir_len converted data home directory length
RETURN VALUES
0 ok
- 1 error
+ 1 error ; Given path contains data directory
*/
C_MODE_START
@@ -7898,11 +8010,17 @@ int test_if_data_home_dir(const char *dir)
mysql_unpacked_real_data_home_len,
(const uchar*) mysql_unpacked_real_data_home,
mysql_unpacked_real_data_home_len))
+ {
+ DBUG_PRINT("error", ("Path is part of mysql_real_data_home"));
DBUG_RETURN(1);
+ }
}
else if (!memcmp(path, mysql_unpacked_real_data_home,
mysql_unpacked_real_data_home_len))
+ {
+ DBUG_PRINT("error", ("Path is part of mysql_real_data_home"));
DBUG_RETURN(1);
+ }
}
DBUG_RETURN(0);
}
@@ -7963,6 +8081,9 @@ bool parse_sql(THD *thd,
Parser_state *parser_state,
Object_creation_ctx *creation_ctx)
{
+ bool mysql_parse_status;
+ DBUG_ENTER("parse_sql");
+
DBUG_ASSERT(thd->m_parser_state == NULL);
/* Backup creation context. */
@@ -7978,7 +8099,7 @@ bool parse_sql(THD *thd,
/* Parse the query. */
- bool mysql_parse_status= MYSQLparse(thd) != 0;
+ mysql_parse_status= MYSQLparse(thd) != 0;
/*
Check that if MYSQLparse() failed, thd->is_error() is set (unless
@@ -7986,8 +8107,8 @@ bool parse_sql(THD *thd,
*/
DBUG_ASSERT(!mysql_parse_status ||
- (mysql_parse_status && thd->is_error()) ||
- (mysql_parse_status && thd->get_internal_handler()));
+ thd->is_error() ||
+ thd->get_internal_handler());
/* Reset parser state. */
@@ -8000,7 +8121,7 @@ bool parse_sql(THD *thd,
/* That's it. */
- return mysql_parse_status || thd->is_fatal_error;
+ DBUG_RETURN(mysql_parse_status || thd->is_fatal_error);
}
/**
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 0b103dcbda9..c810963b701 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2005, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2009-2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2005,6 +2006,9 @@ static int add_partition_options(File fptr, partition_element *p_elem)
}
if (p_elem->part_comment)
err+= add_keyword_string(fptr, "COMMENT", TRUE, p_elem->part_comment);
+ if (p_elem->connect_string.length)
+ err+= add_keyword_string(fptr, "CONNECTION", TRUE,
+ p_elem->connect_string.str);
return err + add_engine(fptr,p_elem->engine_type);
}
@@ -7160,8 +7164,8 @@ static uint32 get_next_partition_via_walking(PARTITION_ITERATOR *part_iter)
field->store(part_iter->field_vals.cur++,
((Field_num*)field)->unsigned_flag);
if ((part_iter->part_info->is_sub_partitioned() &&
- !part_iter->part_info->get_part_partition_id(part_iter->part_info,
- &part_id, &dummy)) ||
+ !part_iter->part_info->get_part_partition_id(part_iter->part_info,
+ &part_id, &dummy)) ||
!part_iter->part_info->get_partition_id(part_iter->part_info,
&part_id, &dummy))
return part_id;
@@ -7270,4 +7274,3 @@ void create_subpartition_name(char *out, const char *in1,
"#SP#", transl_subpart_name, "#REN#", NullS);
}
#endif
-
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index 091d3095827..2f741c76594 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index bd1da080089..f44813f3224 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
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
@@ -21,14 +21,6 @@
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
-#ifdef DBUG_OFF
-#define plugin_ref_to_int(A) A
-#define plugin_int_to_ref(A) A
-#else
-#define plugin_ref_to_int(A) (A ? A[0] : NULL)
-#define plugin_int_to_ref(A) &(A)
-#endif
-
extern struct st_mysql_plugin *mysqld_builtins[];
/**
@@ -363,7 +355,7 @@ static inline void free_plugin_mem(struct st_plugin_dl *p)
dlclose(p->handle);
#endif
my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR));
- if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION)
+ if (p->allocated)
my_free((uchar*)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
}
@@ -391,7 +383,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{
if (report & REPORT_TO_USER)
my_error(ER_UDF_NO_PATHS, MYF(0));
- if (report & REPORT_TO_LOG)
+ if ((report & (REPORT_TO_LOG | REPORT_TO_USER)) == REPORT_TO_LOG)
sql_print_error("%s", ER(ER_UDF_NO_PATHS));
DBUG_RETURN(0);
}
@@ -486,35 +478,37 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
#endif
}
- for (i= 0;
- ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- /* no op */;
-
- cur= (struct st_mysql_plugin*)
- my_malloc(i*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
- if (!cur)
+ if (sizeof_st_plugin != sizeof(st_mysql_plugin))
{
- free_plugin_mem(&plugin_dl);
- if (report & REPORT_TO_USER)
- my_error(ER_OUTOFMEMORY, MYF(0),
- static_cast<int>(plugin_dl.dl.length));
- if (report & REPORT_TO_LOG)
- sql_print_error(ER(ER_OUTOFMEMORY),
- static_cast<int>(plugin_dl.dl.length));
- DBUG_RETURN(0);
- }
- /*
- All st_plugin fields not initialized in the plugin explicitly, are
- set to 0. It matches C standard behaviour for struct initializers that
- have less values than the struct definition.
- */
- for (i=0;
- (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
- i++)
- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
+ for (i= 0;
+ ((struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ /* no op */;
+
+ cur= (struct st_mysql_plugin*)
+ my_malloc((i+1)*sizeof(struct st_mysql_plugin), MYF(MY_ZEROFILL|MY_WME));
+ if (!cur)
+ {
+ free_plugin_mem(&plugin_dl);
+ if (report & REPORT_TO_USER)
+ my_error(ER_OUTOFMEMORY, MYF(0), (int) plugin_dl.dl.length);
+ if (report & REPORT_TO_LOG)
+ sql_print_error(ER(ER_OUTOFMEMORY), (int) plugin_dl.dl.length);
+ DBUG_RETURN(0);
+ }
+ /*
+ All st_plugin fields not initialized in the plugin explicitly, are
+ set to 0. It matches C standard behaviour for struct initializers that
+ have less values than the struct definition.
+ */
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+ memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
- sym= cur;
+ sym= cur;
+ plugin_dl.allocated= true;
+ }
}
plugin_dl.plugins= (struct st_mysql_plugin *)sym;
@@ -659,7 +653,10 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
{
plugin_ref plugin;
#ifdef DBUG_OFF
- /* built-in plugins don't need ref counting */
+ /*
+ In optimized builds we don't do reference counting for built-in
+ (plugin->plugin_dl == 0) plugins.
+ */
if (!pi->plugin_dl)
DBUG_RETURN(pi);
@@ -676,7 +673,7 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
*plugin= pi;
#endif
pi->ref_count++;
- DBUG_PRINT("info",("thd: 0x%lx, plugin: \"%s\", ref_count: %d",
+ DBUG_PRINT("info",("thd: 0x%lx plugin: \"%s\" ref_count: %d",
(long) current_thd, pi->name.str, pi->ref_count));
if (lex)
@@ -687,13 +684,33 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO)
}
-plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO)
+plugin_ref plugin_lock(THD *thd, plugin_ref ptr CALLER_INFO_PROTO)
{
LEX *lex= thd ? thd->lex : 0;
plugin_ref rc;
DBUG_ENTER("plugin_lock");
+
+#ifdef DBUG_OFF
+ /*
+ In optimized builds we don't do reference counting for built-in
+ (plugin->plugin_dl == 0) plugins.
+
+ Note that we access plugin->plugin_dl outside of LOCK_plugin, and for
+ dynamic plugins a 'plugin' could correspond to plugin that was unloaded
+ meanwhile! But because st_plugin_int is always allocated on
+ plugin_mem_root, the pointer can never be invalid - the memory is never
+ freed.
+ Of course, the memory that 'plugin' points to can be overwritten by
+ another plugin being loaded, but plugin->plugin_dl can never change
+ from zero to non-zero or vice versa.
+ That is, it's always safe to check for plugin->plugin_dl==0 even
+ without a mutex.
+ */
+ if (! plugin_dlib(ptr))
+ DBUG_RETURN(ptr);
+#endif
pthread_mutex_lock(&LOCK_plugin);
- rc= my_intern_plugin_lock_ci(lex, *ptr);
+ rc= my_intern_plugin_lock_ci(lex, ptr);
pthread_mutex_unlock(&LOCK_plugin);
DBUG_RETURN(rc);
}
@@ -1036,10 +1053,11 @@ void plugin_unlock_list(THD *thd, plugin_ref *list, uint count)
static int plugin_initialize(struct st_plugin_int *plugin)
{
int ret= 1;
+ uint state;
DBUG_ENTER("plugin_initialize");
safe_mutex_assert_owner(&LOCK_plugin);
- uint state= plugin->state;
+ state= plugin->state;
DBUG_ASSERT(state == PLUGIN_IS_UNINITIALIZED);
pthread_mutex_unlock(&LOCK_plugin);
@@ -1205,6 +1223,7 @@ int plugin_init(int *argc, char **argv, int flags)
!my_strnncoll(&my_charset_latin1, (const uchar*) plugin->name,
6, (const uchar*) "InnoDB", 6))
continue;
+
bzero(&tmp, sizeof(tmp));
tmp.plugin= plugin;
tmp.name.str= (char *)plugin->name;
@@ -1218,15 +1237,23 @@ int plugin_init(int *argc, char **argv, int flags)
if (register_builtin(plugin, &tmp, &plugin_ptr))
goto err_unlock;
- /* only initialize MyISAM and CSV at this stage */
- if (!(is_myisam=
- !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM")) &&
- my_strcasecmp(&my_charset_latin1, plugin->name, "CSV"))
- continue;
+ is_myisam= !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM");
- if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED &&
- plugin_initialize(plugin_ptr))
- goto err_unlock;
+ /*
+ strictly speaking, we should to initialize all plugins,
+ even for mysqld --help, because important subsystems
+ may be disabled otherwise, and the help will be incomplete.
+ For example, if the mysql.plugin table is not MyISAM.
+ But for now it's an unlikely corner case, and to optimize
+ mysqld --help for all other users, we will only initialize
+ MyISAM here.
+ */
+ if (!(flags & PLUGIN_INIT_SKIP_INITIALIZATION) || is_myisam)
+ {
+ if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED &&
+ plugin_initialize(plugin_ptr))
+ goto err_unlock;
+ }
/*
initialize the global default storage engine so that it may
@@ -1431,13 +1458,6 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
table= tables.table;
init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE);
table->use_all_columns();
- /*
- there're no other threads running yet, so we don't need a mutex.
- but plugin_add() before is designed to work in multi-threaded
- environment, and it uses safe_mutex_assert_owner(), so we lock
- the mutex here to satisfy the assert
- */
- pthread_mutex_lock(&LOCK_plugin);
while (!(error= read_record_info.read_record(&read_record_info)))
{
DBUG_PRINT("info", ("init plugin record"));
@@ -1448,12 +1468,19 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
LEX_STRING name= {(char *)str_name.ptr(), str_name.length()};
LEX_STRING dl= {(char *)str_dl.ptr(), str_dl.length()};
+ /*
+ there're no other threads running yet, so we don't need a mutex.
+ but plugin_add() before is designed to work in multi-threaded
+ environment, and it uses safe_mutex_assert_owner(), so we lock
+ the mutex here to satisfy the assert
+ */
+ pthread_mutex_lock(&LOCK_plugin);
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.",
str_name.c_ptr(), str_dl.c_ptr());
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
+ pthread_mutex_unlock(&LOCK_plugin);
}
- pthread_mutex_unlock(&LOCK_plugin);
if (error > 0)
sql_print_error(ER(ER_GET_ERRNO), my_errno);
end_read_record(&read_record_info);
@@ -1724,9 +1751,10 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
if (tmp->state == PLUGIN_IS_DISABLED)
{
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_CANT_INITIALIZE_UDF, ER(ER_CANT_INITIALIZE_UDF),
- name->str, "Plugin is disabled");
+ if (global_system_variables.log_warnings)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_CANT_INITIALIZE_UDF, ER(ER_CANT_INITIALIZE_UDF),
+ name->str, "Plugin is disabled");
}
else
{
@@ -2724,7 +2752,7 @@ TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
default:
return NULL;
}
- return NULL;
+ return NULL; /* Keep compiler happy */
}
@@ -3059,10 +3087,10 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
Allocate temporary space for the value of the tristate.
This option will have a limited lifetime and is not used beyond
server initialization.
- GET_ENUM value is a unsigned long integer.
+ GET_ENUM value is an ulong.
*/
options[0].value= options[1].value= (uchar **)alloc_root(mem_root,
- sizeof(ulong));
+ sizeof(ulong));
*((ulong*) options[0].value)= *((ulong*) options[1].value)=
(ulong) options[0].def_value;
@@ -3153,6 +3181,19 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
opt->name, plugin_name);
}
}
+ /*
+ PLUGIN_VAR_STR command-line options without PLUGIN_VAR_MEMALLOC, point
+ directly to values in the argv[] array. For plugins started at the
+ server startup, argv[] array is allocated with load_defaults(), and
+ freed when the server is shut down. But for plugins loaded with
+ INSTALL PLUGIN, the memory allocated with load_defaults() is freed with
+ freed() at the end of mysql_install_plugin(). Which means we cannot
+ allow any pointers into that area.
+ Thus, for all plugins loaded after the server was started,
+ we force all command-line options to be PLUGIN_VAR_MEMALLOC
+ */
+ if (mysqld_server_started && !(opt->flags & PLUGIN_VAR_NOCMDOPT))
+ opt->flags|= PLUGIN_VAR_MEMALLOC;
break;
case PLUGIN_VAR_ENUM:
if (!opt->check)
@@ -3289,7 +3330,6 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
my_bool can_disable;
bool disable_plugin;
enum_plugin_load_policy plugin_load_policy= PLUGIN_ON;
-
MEM_ROOT *mem_root= alloc_root_inited(&tmp->mem_root) ?
&tmp->mem_root : &plugin_mem_root;
st_mysql_sys_var **opt;
@@ -3303,13 +3343,17 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
DBUG_ENTER("test_plugin_options");
DBUG_ASSERT(tmp->plugin && tmp->name.str);
+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
/*
- The 'federated' and 'ndbcluster' storage engines are always disabled by
- default.
+ The 'ndbcluster' storage engines is always disabled by default.
*/
- if (!(my_strcasecmp(&my_charset_latin1, tmp->name.str, "federated") &&
- my_strcasecmp(&my_charset_latin1, tmp->name.str, "ndbcluster")))
+ if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "ndbcluster"))
+ plugin_load_policy= PLUGIN_OFF;
+#endif
+#ifdef WITH_FEEDBACK_PLUGIN
+ if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "feedback"))
plugin_load_policy= PLUGIN_OFF;
+#endif
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
@@ -3358,6 +3402,11 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
can_disable=
my_strcasecmp(&my_charset_latin1, tmp->name.str, "MyISAM") &&
my_strcasecmp(&my_charset_latin1, tmp->name.str, "MEMORY");
+#ifdef USE_MARIA_FOR_TMP_TABLES
+ if (!can_disable)
+ can_disable= (my_strcasecmp(&my_charset_latin1, tmp->name.str, "Maria")
+ != 0);
+#endif
tmp->is_mandatory= (plugin_load_policy == PLUGIN_FORCE) || !can_disable;
@@ -3449,8 +3498,7 @@ void my_print_help_inc_plugins(my_option *main_options, uint size)
{
p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
- if (!p->plugin->system_vars ||
- !(opt= construct_help_options(&mem_root, p)))
+ if (!(opt= construct_help_options(&mem_root, p)))
continue;
/* Only options with a non-NULL comment are displayed in help text */
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index 6a0107d07bb..c63e1d4acff 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
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
@@ -65,7 +65,8 @@ struct st_plugin_dl
LEX_STRING dl;
void *handle;
struct st_mysql_plugin *plugins;
- int version;
+ int version;
+ bool allocated;
uint ref_count; /* number of plugins loaded from the library */
};
@@ -91,6 +92,8 @@ struct st_plugin_int
*/
#ifdef DBUG_OFF
typedef struct st_plugin_int *plugin_ref;
+#define plugin_ref_to_int(A) A
+#define plugin_int_to_ref(A) A
#define plugin_decl(pi) ((pi)->plugin)
#define plugin_dlib(pi) ((pi)->plugin_dl)
#define plugin_data(pi,cast) ((cast)((pi)->data))
@@ -99,6 +102,8 @@ typedef struct st_plugin_int *plugin_ref;
#define plugin_equals(p1,p2) ((p1) == (p2))
#else
typedef struct st_plugin_int **plugin_ref;
+#define plugin_ref_to_int(A) (A ? A[0] : NULL)
+#define plugin_int_to_ref(A) &(A)
#define plugin_decl(pi) ((pi)[0]->plugin)
#define plugin_dlib(pi) ((pi)[0]->plugin_dl)
#define plugin_data(pi,cast) ((cast)((pi)[0]->data))
@@ -122,7 +127,7 @@ extern bool plugin_is_ready(const LEX_STRING *name, int type);
#define my_plugin_lock_by_name_ci(A,B,C) plugin_lock_by_name(A,B,C ORIG_CALLER_INFO)
#define my_plugin_lock(A,B) plugin_lock(A,B CALLER_INFO)
#define my_plugin_lock_ci(A,B) plugin_lock(A,B ORIG_CALLER_INFO)
-extern plugin_ref plugin_lock(THD *thd, plugin_ref *ptr CALLER_INFO_PROTO);
+extern plugin_ref plugin_lock(THD *thd, plugin_ref ptr CALLER_INFO_PROTO);
extern plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name,
int type CALLER_INFO_PROTO);
extern void plugin_unlock(THD *thd, plugin_ref plugin);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index ec7a7fb73b8..1c0ee55b79d 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -106,7 +107,7 @@ class Select_fetch_protocol_binary: public select_send
public:
Select_fetch_protocol_binary(THD *thd);
virtual bool send_fields(List<Item> &list, uint flags);
- virtual bool send_data(List<Item> &items);
+ virtual int send_data(List<Item> &items);
virtual bool send_eof();
#ifdef EMBEDDED_LIBRARY
void begin_dataset()
@@ -1155,6 +1156,8 @@ static bool mysql_test_insert(Prepared_statement *stmt,
if (insert_precheck(thd, table_list))
goto error;
+ upgrade_lock_type_for_insert(thd, &table_list->lock_type, duplic,
+ values_list.elements > 1);
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
@@ -1467,8 +1470,9 @@ static bool mysql_test_set_fields(Prepared_statement *stmt,
THD *thd= stmt->thd;
set_var_base *var;
- if ((tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
- || open_normal_and_derived_tables(thd, tables, 0))
+ if ((tables &&
+ check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
+ open_normal_and_derived_tables(thd, tables, 0))
goto error;
while ((var= it++))
@@ -1503,7 +1507,8 @@ static bool mysql_test_call_fields(Prepared_statement *stmt,
THD *thd= stmt->thd;
Item *item;
- if ((tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
+ if ((tables &&
+ check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
open_normal_and_derived_tables(thd, tables, 0))
goto err;
@@ -2502,7 +2507,6 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
DBUG_EXECUTE_IF("close_conn_after_stmt_execute", vio_close(thd->net.vio););
DBUG_VOID_RETURN;
-
}
@@ -2746,7 +2750,7 @@ public:
{
stmt->state= Query_arena::ERROR;
stmt->last_errno= sql_errno;
- strncpy(stmt->last_error, message, MYSQL_ERRMSG_SIZE);
+ strnmov(stmt->last_error, message, MYSQL_ERRMSG_SIZE);
return TRUE;
}
@@ -2865,11 +2869,11 @@ bool Select_fetch_protocol_binary::send_eof()
}
-bool
+int
Select_fetch_protocol_binary::send_data(List<Item> &fields)
{
Protocol *save_protocol= thd->protocol;
- bool rc;
+ int rc;
thd->protocol= &protocol;
rc= select_send::send_data(fields);
@@ -3363,7 +3367,7 @@ reexecute:
bool
Prepared_statement::reprepare()
{
- char saved_cur_db_name_buf[NAME_LEN+1];
+ char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
LEX_STRING stmt_db_name= { db, db_length };
@@ -3524,7 +3528,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
Query_arena *old_stmt_arena;
bool error= TRUE;
- char saved_cur_db_name_buf[NAME_LEN+1];
+ char saved_cur_db_name_buf[SAFE_NAME_LEN+1];
LEX_STRING saved_cur_db_name=
{ saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) };
bool cur_db_changed;
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 1a6477e4c4d..116cdb91ef3 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,14 +36,11 @@
#include "my_sys.h"
#define TIME_FLOAT_DIGITS 9
-/** two vals encoded: (dec*100)+len */
+/** two vals encoded: (len*100)+dec */
#define TIME_I_S_DECIMAL_SIZE (TIME_FLOAT_DIGITS*100)+(TIME_FLOAT_DIGITS-3)
#define MAX_QUERY_LENGTH 300
-/* Reserved for systems that can't record the function name in source. */
-const char * const _unknown_func_ = "<unknown>";
-
/**
Connects Information_Schema and Profiling.
*/
@@ -136,6 +134,23 @@ int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table)
#define RUSAGE_USEC(tv) ((tv).tv_sec*1000*1000 + (tv).tv_usec)
#define RUSAGE_DIFF_USEC(tv1, tv2) (RUSAGE_USEC((tv1))-RUSAGE_USEC((tv2)))
+#ifdef __WIN__
+inline ULONGLONG FileTimeToQuadWord(FILETIME *ft)
+{
+ ULONGLONG nrv = 0;
+ nrv |= ft->dwHighDateTime;
+ nrv <<= 32;
+ nrv |= ft->dwLowDateTime;
+ return nrv;
+}
+
+
+// Get time difference between to FILETIME objects in seconds.
+inline double GetTimeDiffInSeconds(FILETIME *a, FILETIME *b)
+{
+ return ((FileTimeToQuadWord(a) - FileTimeToQuadWord(b)) / 1e7);
+}
+#endif /* __WIN__ */
PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char
*status_arg)
@@ -226,6 +241,11 @@ void PROF_MEASUREMENT::collect()
time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */
#ifdef HAVE_GETRUSAGE
getrusage(RUSAGE_SELF, &rusage);
+#elif defined(__WIN__)
+ FILETIME ftDummy;
+ GetProcessTimes(GetCurrentProcess(), &ftDummy, &ftDummy, &ftKernel, &ftUser);
+ GetProcessIoCounters(GetCurrentProcess(), &io_count);
+ GetProcessMemoryInfo(GetCurrentProcess(), &mem_count, sizeof(mem_count));
#endif
}
@@ -595,6 +615,23 @@ int PROFILING::fill_statistics_info(THD *thd_arg, TABLE_LIST *tables, Item *cond
table->field[5]->store_decimal(&cpu_stime_decimal);
table->field[4]->set_notnull();
table->field[5]->set_notnull();
+#elif defined(__WIN__)
+ my_decimal cpu_utime_decimal, cpu_stime_decimal;
+
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ GetTimeDiffInSeconds(&entry->ftUser,
+ &previous->ftUser),
+ &cpu_utime_decimal);
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ GetTimeDiffInSeconds(&entry->ftKernel,
+ &previous->ftKernel),
+ &cpu_stime_decimal);
+
+ // Store the result.
+ table->field[4]->store_decimal(&cpu_utime_decimal);
+ table->field[5]->store_decimal(&cpu_stime_decimal);
+ table->field[4]->set_notnull();
+ table->field[5]->set_notnull();
#else
/* TODO: Add CPU-usage info for non-BSD systems */
#endif
@@ -617,6 +654,17 @@ int PROFILING::fill_statistics_info(THD *thd_arg, TABLE_LIST *tables, Item *cond
table->field[9]->store((uint32)(entry->rusage.ru_oublock -
previous->rusage.ru_oublock));
table->field[9]->set_notnull();
+#elif defined(__WIN__)
+ ULONGLONG reads_delta = entry->io_count.ReadOperationCount -
+ previous->io_count.ReadOperationCount;
+ ULONGLONG writes_delta = entry->io_count.WriteOperationCount -
+ previous->io_count.WriteOperationCount;
+
+ table->field[8]->store((uint32)reads_delta);
+ table->field[8]->set_notnull();
+
+ table->field[9]->store((uint32)writes_delta);
+ table->field[9]->set_notnull();
#else
/* TODO: Add block IO info for non-BSD systems */
#endif
@@ -639,6 +687,13 @@ int PROFILING::fill_statistics_info(THD *thd_arg, TABLE_LIST *tables, Item *cond
table->field[13]->store((uint32)(entry->rusage.ru_minflt -
previous->rusage.ru_minflt), true);
table->field[13]->set_notnull();
+#elif defined(__WIN__)
+ /* Windows APIs don't easily distinguish between hard and soft page
+ faults, so we just fill the 'major' column and leave the second NULL.
+ */
+ table->field[12]->store((uint32)(entry->mem_count.PageFaultCount -
+ previous->mem_count.PageFaultCount), true);
+ table->field[12]->set_notnull();
#else
/* TODO: Add page fault info for non-BSD systems */
#endif
diff --git a/sql/sql_profile.h b/sql/sql_profile.h
index b21216f290f..297130962d8 100644
--- a/sql/sql_profile.h
+++ b/sql/sql_profile.h
@@ -19,14 +19,6 @@
#ifndef _SQL_PROFILE_H
#define _SQL_PROFILE_H
-#ifndef __func__
-#ifdef __FUNCTION__
-#define __func__ __FUNCTION__
-#else
-#define __func__ "unknown function"
-#endif
-#endif
-
extern ST_FIELD_INFO query_profile_statistics_info[];
int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table);
@@ -47,6 +39,10 @@ int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table);
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
#include "mysql_priv.h"
+#ifdef __WIN__
+#include <psapi.h>
+#endif
+
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
@@ -176,6 +172,10 @@ private:
char *status;
#ifdef HAVE_GETRUSAGE
struct rusage rusage;
+#elif defined(__WIN__)
+ FILETIME ftKernel, ftUser;
+ IO_COUNTERS io_count;
+ PROCESS_MEMORY_COUNTERS mem_count;
#endif
char *function;
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 33ce54a7024..cab41b1df07 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -247,7 +247,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
char *new_table_alias, bool skip_error)
{
int rc= 1;
- char name[FN_REFLEN + 1];
+ char new_name[FN_REFLEN + 1], old_name[FN_REFLEN + 1];
const char *new_alias, *old_alias;
frm_type_enum frm_type;
enum legacy_db_type table_type;
@@ -266,17 +266,17 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
}
DBUG_ASSERT(new_alias);
- build_table_filename(name, sizeof(name) - 1,
+ build_table_filename(new_name, sizeof(new_name) - 1,
new_db, new_alias, reg_ext, 0);
- if (!access(name,F_OK))
+ build_table_filename(old_name, sizeof(old_name) - 1,
+ ren_table->db, old_alias, reg_ext, 0);
+ if (check_table_file_presence(old_name,
+ new_name, new_db, new_alias, new_alias, TRUE))
{
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
DBUG_RETURN(1); // This can't be skipped
}
- build_table_filename(name, sizeof(name) - 1,
- ren_table->db, old_alias, reg_ext, 0);
- frm_type= mysql_frm_type(thd, name, &table_type);
+ frm_type= mysql_frm_type(thd, old_name, &table_type);
switch (frm_type)
{
case FRMTYPE_TABLE:
@@ -321,7 +321,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
default:
DBUG_ASSERT(0); // should never happen
case FRMTYPE_ERROR:
- my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
+ my_error(ER_FILE_NOT_FOUND, MYF(0), old_name, my_errno);
break;
}
if (rc && !skip_error)
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index a2c388ba388..7a09074f554 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -572,6 +573,11 @@ impossible position";
DBUG_ASSERT(opt_debug_sync_timeout > 0);
DBUG_ASSERT(!debug_sync_set_action(current_thd,
STRING_WITH_LEN(act)));
+ const char act2[]=
+ "now "
+ "signal signal.continued";
+ DBUG_ASSERT(!debug_sync_set_action(current_thd,
+ STRING_WITH_LEN(act2)));
}
});
@@ -1891,6 +1897,11 @@ int init_replication_sys_vars()
return 0;
}
+#elif defined(__WIN__)
+
+// Remove linker warning 4221 about empty file
+namespace { char dummy; };
+
#endif /* HAVE_REPLICATION */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 516c9c37473..b79bb8ef604 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates.
+ 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,6 +37,12 @@
#include <my_bit.h>
#include <hash.h>
#include <ft_global.h>
+#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
+#include "../storage/maria/ha_maria.h"
+#define TMP_ENGINE_HTON maria_hton
+#else
+#define TMP_ENGINE_HTON myisam_hton
+#endif
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"MAYBE_REF","ALL","range","index","fulltext",
@@ -55,7 +62,6 @@ static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
table_map table_map, SELECT_LEX *select_lex,
st_sargable_param **sargables);
static int sort_keyuse(KEYUSE *a,KEYUSE *b);
-static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
table_map used_tables);
static bool choose_plan(JOIN *join,table_map join_tables);
@@ -110,7 +116,7 @@ static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
COND *conds, bool top);
static bool check_interleaving_with_nj(JOIN_TAB *next);
static void restore_prev_nj_state(JOIN_TAB *last);
-static void reset_nj_counters(List<TABLE_LIST> *join_list);
+static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list);
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
uint first_unused);
@@ -119,8 +125,13 @@ static COND *optimize_cond(JOIN *join, COND *conds,
Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
-static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- ulonglong options);
+static bool create_internal_tmp_table(TABLE *,TMP_TABLE_PARAM *, ulonglong);
+static bool create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
+ TMP_TABLE_PARAM *param,
+ int error,
+ bool ignore_last_dupp,
+ handlerton *hton,
+ const char *proc_info);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
@@ -329,11 +340,23 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
bool
fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
- Item **ref_pointer_array, ORDER *group_list)
+ Item **ref_pointer_array)
{
Item_outer_ref *ref;
- List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
+ /*
+ Mark the references from the inner_refs_list that are occurred in
+ the group by expressions. Those references will contain direct
+ references to the referred fields. The markers are set in
+ the found_in_group_by field of the references from the list.
+ */
+ List_iterator_fast <Item_outer_ref> ref_it(select->inner_refs_list);
+ for (ORDER *group= select->join->group_list; group; group= group->next)
+ {
+ (*group->item)->walk(&Item::check_inner_refs_processor,
+ TRUE, (uchar *) &ref_it);
+ }
+
while ((ref= ref_it++))
{
bool direct_ref= false;
@@ -378,22 +401,9 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
}
}
}
- else
- {
- /*
- Check if GROUP BY item trees contain the outer ref:
- in this case we have to use Item_direct_ref instead of Item_ref.
- */
- for (ORDER *group= group_list; group; group= group->next)
- {
- if ((*group->item)->walk(&Item::find_item_processor, TRUE,
- (uchar *) ref))
- {
- direct_ref= TRUE;
- break;
- }
- }
- }
+ else if (ref->found_in_group_by)
+ direct_ref= TRUE;
+
new_ref= direct_ref ?
new Item_direct_ref(ref->context, item_ref, ref->table_name,
ref->field_name, ref->alias_name_used) :
@@ -608,8 +618,7 @@ JOIN::prepare(Item ***rref_pointer_array,
}
if (select_lex->inner_refs_list.elements &&
- fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array,
- group_list))
+ fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array))
DBUG_RETURN(-1);
if (group_list)
@@ -1085,7 +1094,7 @@ JOIN::optimize()
DBUG_RETURN(1);
}
- reset_nj_counters(join_list);
+ reset_nj_counters(this, join_list);
make_outerjoin_info(this);
/*
@@ -1125,30 +1134,6 @@ JOIN::optimize()
conds=new Item_int((longlong) 0,1); // Always false
}
- /*
- It's necessary to check const part of HAVING cond as
- there is a chance that some cond parts may become
- const items after make_join_statisctics(for example
- when Item is a reference to cost table field from
- outer join).
- This check is performed only for those conditions
- which do not use aggregate functions. In such case
- temporary table may not be used and const condition
- elements may be lost during further having
- condition transformation in JOIN::exec.
- */
- if (having && const_table_map && !having->with_sum_func)
- {
- having->update_used_tables();
- having= remove_eq_conds(thd, having, &having_value);
- if (having_value == Item::COND_FALSE)
- {
- having= new Item_int((longlong) 0,1);
- zero_result_cause= "Impossible HAVING noticed after reading const tables";
- DBUG_RETURN(0);
- }
- }
-
if (make_join_select(this, select, conds))
{
zero_result_cause=
@@ -1718,6 +1703,16 @@ JOIN::reinit()
func->clear();
}
+ if (no_rows_in_result_called)
+ {
+ /* Reset effect of possible no_rows_in_result() */
+ List_iterator_fast<Item> it(fields_list);
+ Item *item;
+ no_rows_in_result_called= 0;
+ while ((item= it++))
+ item->restore_to_before_no_rows_in_result();
+ }
+
if (!(select_options & SELECT_DESCRIBE))
init_ftfuncs(thd, select_lex, test(order));
@@ -1820,7 +1815,7 @@ JOIN::exec()
{
if (do_send_rows &&
(procedure ? (procedure->send_row(procedure_fields_list) ||
- procedure->end_of_records()) : result->send_data(fields_list)))
+ procedure->end_of_records()) : result->send_data(fields_list)> 0))
error= 1;
else
{
@@ -1944,7 +1939,9 @@ JOIN::exec()
curr_join->having= curr_join->tmp_having= 0; // Allready done
/* Change sum_fields reference to calculated fields in tmp_table */
+#ifdef HAVE_valgrind
if (curr_join != this)
+#endif
curr_join->all_fields= *curr_all_fields;
if (!items1)
{
@@ -1964,7 +1961,9 @@ JOIN::exec()
fields_list.elements, all_fields))
DBUG_VOID_RETURN;
}
+#ifdef HAVE_valgrind
if (curr_join != this)
+#endif
{
curr_join->tmp_all_fields1= tmp_all_fields1;
curr_join->tmp_fields_list1= tmp_fields_list1;
@@ -2010,8 +2009,8 @@ JOIN::exec()
*/
if ((curr_join->group_list && (!test_if_subpart(curr_join->group_list,
- curr_join->order) ||
- curr_join->select_distinct)) ||
+ curr_join->order) ||
+ curr_join->select_distinct)) ||
(curr_join->select_distinct &&
curr_join->tmp_table_param.using_indirect_summary_function))
{ /* Must copy to another table */
@@ -2116,7 +2115,13 @@ JOIN::exec()
tmp_fields_list2, tmp_all_fields2,
fields_list.elements, tmp_all_fields1))
DBUG_VOID_RETURN;
+#ifdef HAVE_valgrind
+ /*
+ Some GCCs use memcpy() for struct assignment, even for x=x.
+ GCC bug 19410: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410
+ */
if (curr_join != this)
+#endif
{
curr_join->tmp_fields_list2= tmp_fields_list2;
curr_join->tmp_all_fields2= tmp_all_fields2;
@@ -2176,7 +2181,9 @@ JOIN::exec()
tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field;
tmp_table_param.save_copy_field_end=
curr_join->tmp_table_param.copy_field_end;
+#ifdef HAVE_valgrind
if (curr_join != this)
+#endif
{
curr_join->tmp_all_fields3= tmp_all_fields3;
curr_join->tmp_fields_list3= tmp_fields_list3;
@@ -2392,7 +2399,7 @@ JOIN::destroy()
anywhere else (as we need to keep the join is reusable).
*/
tmp_table_param.cleanup();
- tmp_table_param.copy_field= tmp_join->tmp_table_param.copy_field= 0;
+ tmp_join->tmp_table_param.copy_field= 0;
DBUG_RETURN(tmp_join->destroy());
}
cond_equal= 0;
@@ -2509,10 +2516,9 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
}
else
{
- err= join->prepare(rref_pointer_array, tables, wild_num,
- conds, og_num, order, group, having, proc_param,
- select_lex, unit);
- if (err)
+ if ((err= join->prepare(rref_pointer_array, tables, wild_num,
+ conds, og_num, order, group, having,
+ proc_param, select_lex, unit)))
{
goto err;
}
@@ -2523,14 +2529,20 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
}
else
{
+ /*
+ When in EXPLAIN, delay deleting the joins so that they are still
+ available when we're producing EXPLAIN EXTENDED warning text.
+ */
+ if (select_options & SELECT_DESCRIBE)
+ free_join= 0;
+
if (!(join= new JOIN(thd, fields, select_options, result)))
DBUG_RETURN(TRUE);
thd_proc_info(thd, "init");
- thd->lex->used_tables=0; // Updated by setup_fields
- err= join->prepare(rref_pointer_array, tables, wild_num,
- conds, og_num, order, group, having, proc_param,
- select_lex, unit);
- if (err)
+ thd->lex->used_tables=0;
+ if ((err= join->prepare(rref_pointer_array, tables, wild_num,
+ conds, og_num, order, group, having, proc_param,
+ select_lex, unit)))
{
goto err;
}
@@ -2597,6 +2609,7 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
if (select)
{
select->head=table;
+ table->reginfo.impossible_range=0;
if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
limit, 0)) == 1)
DBUG_RETURN(select->quick->records);
@@ -2647,6 +2660,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
KEYUSE *keyuse,*start_keyuse;
table_map outer_join=0;
+ table_map no_rows_const_tables= 0;
SARGABLE_PARAM *sargables= 0;
JOIN_TAB *stat_vector[MAX_TABLES+1];
DBUG_ENTER("make_join_statistics");
@@ -2707,6 +2721,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
#endif
{ // Empty table
s->dependent= 0; // Ignore LEFT JOIN depend.
+ no_rows_const_tables |= table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
continue;
}
@@ -2743,6 +2758,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
!table->fulltext_searched && !join->no_const_tables)
{
set_position(join,const_count++,s,(KEYUSE*) 0);
+ no_rows_const_tables |= table->map;
}
}
stat_vector[i]=0;
@@ -2753,53 +2769,45 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
/*
Build transitive closure for relation 'to be dependent on'.
This will speed up the plan search for many cases with outer joins,
- as well as allow us to catch illegal cross references.
+ as well as allow us to catch illegal cross references/
Warshall's algorithm is used to build the transitive closure.
- As we may restart the outer loop upto 'table_count' times, the
- complexity of the algorithm is O((number of tables)^3).
- However, most of the iterations will be shortcircuited when
- there are no pedendencies to propogate.
+ As we use bitmaps to represent the relation the complexity
+ of the algorithm is O((number of tables)^2).
+
+ The classic form of the Warshall's algorithm would look like:
+ for (i= 0; i < table_count; i++)
+ {
+ for (j= 0; j < table_count; j++)
+ {
+ for (k= 0; k < table_count; k++)
+ {
+ if (bitmap_is_set(stat[j].dependent, i) &&
+ bitmap_is_set(stat[i].dependent, k))
+ bitmap_set_bit(stat[j].dependent, k);
+ }
+ }
*/
- for (i= 0 ; i < table_count ; i++)
+
+ for (s= stat ; s < stat_end ; s++)
{
- uint j;
- table= stat[i].table;
-
- if (!table->reginfo.join_tab->dependent)
- continue;
-
- /* Add my dependencies to other tables depending on me */
- for (j= 0, s= stat ; j < table_count ; j++, s++)
+ table= s->table;
+ for (JOIN_TAB *t= stat ; t < stat_end ; t++)
{
- if (s->dependent & table->map)
- {
- table_map was_dependent= s->dependent;
- s->dependent |= table->reginfo.join_tab->dependent;
- /*
- If we change dependencies for a table we already have
- processed: Redo dependency propagation from this table.
- */
- if (i > j && s->dependent != was_dependent)
- {
- i = j-1;
- break;
- }
- }
+ if (t->dependent & table->map)
+ t->dependent |= table->reginfo.join_tab->dependent;
}
+ if (outer_join & s->table->map)
+ s->table->maybe_null= 1;
}
-
+ /* Catch illegal cross references for outer joins */
for (i= 0, s= stat ; i < table_count ; i++, s++)
{
- /* Catch illegal cross references for outer joins */
if (s->dependent & s->table->map)
{
join->tables=0; // Don't use join->table
my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
goto error;
}
-
- if (outer_join & s->table->map)
- s->table->maybe_null= 1;
s->key_dependent= s->dependent;
}
}
@@ -2810,24 +2818,32 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
~outer_join, join->select_lex, &sargables))
goto error;
- /* Read tables with 0 or 1 rows (system tables) */
- join->const_table_map= 0;
+ join->const_table_map= no_rows_const_tables;
+ join->const_tables= const_count;
+ eliminate_tables(join);
+ join->const_table_map &= ~no_rows_const_tables;
+ const_count= join->const_tables;
+ found_const_table_map= join->const_table_map;
+ /* Read tables with 0 or 1 rows (system tables) */
for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
p_pos < p_end ;
p_pos++)
{
- int tmp;
s= p_pos->table;
- s->type=JT_SYSTEM;
- join->const_table_map|=s->table->map;
- if ((tmp=join_read_const_table(s, p_pos)))
+ if (! (s->table->map & join->eliminated_tables))
{
- if (tmp > 0)
- goto error; // Fatal error
+ int tmp;
+ s->type=JT_SYSTEM;
+ join->const_table_map|=s->table->map;
+ if ((tmp=join_read_const_table(s, p_pos)))
+ {
+ if (tmp > 0)
+ goto error; // Fatal error
+ }
+ else
+ found_const_table_map|= s->table->map;
}
- else
- found_const_table_map|= s->table->map;
}
/* loop until no more const tables are found */
@@ -2852,7 +2868,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
substitution of a const table the key value happens to be null
then we can state that there are no matches for this equi-join.
*/
- if ((keyuse= s->keyuse) && *s->on_expr_ref && !s->embedding_map)
+ if ((keyuse= s->keyuse) && *s->on_expr_ref && !s->embedding_map &&
+ !(table->map & join->eliminated_tables))
{
/*
When performing an outer join operation if there are no matching rows
@@ -3129,14 +3146,45 @@ typedef struct key_field_t {
This is called for OR between different levels.
- To be able to do 'ref_or_null' we merge a comparison of a column
- and 'column IS NULL' to one test. This is useful for sub select queries
- that are internally transformed to something like:.
+ That is, the function operates on an array of KEY_FIELD elements which has
+ two parts:
+
+ $LEFT_PART $RIGHT_PART
+ +-----------------------+-----------------------+
+ start new_fields end
+
+ $LEFT_PART and $RIGHT_PART are arrays that have KEY_FIELD elements for two
+ parts of the OR condition. Our task is to produce an array of KEY_FIELD
+ elements that would correspond to "$LEFT_PART OR $RIGHT_PART".
+
+ The rules for combining elements are as follows:
+
+ (keyfieldA1 AND keyfieldA2 AND ...) OR (keyfieldB1 AND keyfieldB2 AND ...)=
+
+ = AND_ij (keyfieldA_i OR keyfieldB_j)
+
+ We discard all (keyfieldA_i OR keyfieldB_j) that refer to different
+ fields. For those referring to the same field, the logic is as follows:
+
+ t.keycol=expr1 OR t.keycol=expr2 -> (since expr1 and expr2 are different
+ we can't produce a single equality,
+ so produce nothing)
+
+ t.keycol=expr1 OR t.keycol=expr1 -> t.keycol=expr1
+
+ t.keycol=expr1 OR t.keycol IS NULL -> t.keycol=expr1, and also set
+ KEY_OPTIMIZE_REF_OR_NULL flag
+
+ The last one is for ref_or_null access. We have handling for this special
+ because it's needed for evaluating IN subqueries that are internally
+ transformed into
@code
- SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
+ EXISTS(SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL)
@endcode
+ See add_key_fields() for discussion of what is and_level.
+
KEY_FIELD::null_rejecting is processed as follows: @n
result has null_rejecting=true if it is set for both ORed references.
for example:
@@ -3265,6 +3313,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
@param field Field used in comparision
@param eq_func True if we used =, <=> or IS NULL
@param value Value used for comparison with field
+ @param num_values Number of values[] that we are comparing against
@param usable_tables Tables which can be used for key optimization
@param sargables IN/OUT Array of found sargable candidates
@@ -3479,6 +3528,25 @@ is_local_field (Item *field)
}
+/*
+ In this and other functions, and_level is a number that is ever-growing
+ and is different for the contents of every AND or OR clause. For example,
+ when processing clause
+
+ (a AND b AND c) OR (x AND y)
+
+ we'll have
+ * KEY_FIELD elements for (a AND b AND c) are assigned and_level=1
+ * KEY_FIELD elements for (x AND y) are assigned and_level=2
+ * OR operation is performed, and whatever elements are left after it are
+ assigned and_level=3.
+
+ The primary reason for having and_level attribute is the OR operation which
+ uses and_level to mark KEY_FIELDs that should get into the result of the OR
+ operation
+
+*/
+
static void
add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
COND *cond, table_map usable_tables,
@@ -3585,7 +3653,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
condition is of the form::
'<field> BETWEEN value[1] AND value[2]'
*/
- if (is_local_field (values[0]))
+ if (is_local_field(values[0]))
{
field_item= (Item_field *) (values[0]->real_item());
add_key_equal_fields(key_fields, *and_level, cond_func,
@@ -3599,7 +3667,7 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
*/
for (uint i= 1; i <= num_values; i++)
{
- if (is_local_field (values[i]))
+ if (is_local_field(values[i]))
{
field_item= (Item_field *) (values[i]->real_item());
add_key_equal_fields(key_fields, *and_level, cond_func,
@@ -3699,8 +3767,9 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
{
if (!field->eq(item->field))
{
+ Item *tmp_item= item;
add_key_field(key_fields, *and_level, cond_func, field,
- TRUE, (Item **) &item, 1, usable_tables,
+ TRUE, &tmp_item, 1, usable_tables,
sargables);
}
}
@@ -3791,16 +3860,16 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
Item *arg0= func->arguments()[0],
*arg1= func->arguments()[1];
if (arg1->const_item() && arg1->cols() == 1 &&
- ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) ||
- (functype == Item_func::GT_FUNC && arg1->val_real() >= 0)) &&
arg0->type() == Item::FUNC_ITEM &&
- ((Item_func *) arg0)->functype() == Item_func::FT_FUNC)
+ ((Item_func *) arg0)->functype() == Item_func::FT_FUNC &&
+ ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) ||
+ (functype == Item_func::GT_FUNC && arg1->val_real() >= 0)))
cond_func= (Item_func_match *) arg0;
else if (arg0->const_item() && arg0->cols() == 1 &&
- ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) ||
- (functype == Item_func::LT_FUNC && arg0->val_real() >= 0)) &&
arg1->type() == Item::FUNC_ITEM &&
- ((Item_func *) arg1)->functype() == Item_func::FT_FUNC)
+ ((Item_func *) arg1)->functype() == Item_func::FT_FUNC &&
+ ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) ||
+ (functype == Item_func::LT_FUNC && arg0->val_real() >= 0)))
cond_func= (Item_func_match *) arg1;
}
}
@@ -4075,14 +4144,13 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
continue;
}
-#if defined(__GNUC__) && !MY_GNUC_PREREQ(4,4)
/*
Old gcc used a memcpy(), which is undefined if save_pos==use:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480
+ This also disables a valgrind warning, so better to have the test.
*/
if (save_pos != use)
-#endif
*save_pos= *use;
prev=use;
found_eq_constant= !use->used_tables;
@@ -4209,8 +4277,7 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
/** Save const tables first as used tables. */
-static void
-set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
+void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
{
join->positions[idx].table= table;
join->positions[idx].key=key;
@@ -4811,7 +4878,7 @@ choose_plan(JOIN *join, table_map join_tables)
DBUG_ENTER("choose_plan");
join->cur_embedding_map= 0;
- reset_nj_counters(join->join_list);
+ reset_nj_counters(join, join->join_list);
/*
if (SELECT_STRAIGHT_JOIN option is set)
reorder tables so dependent tables come after tables they depend
@@ -5383,7 +5450,7 @@ best_extension_by_limited_search(JOIN *join,
if (best_record_count > current_record_count ||
best_read_time > current_read_time ||
(idx == join->const_tables && // 's' is the first table in the QEP
- s->table == join->sort_by_table))
+ s->table == join->sort_by_table))
{
if (best_record_count >= current_record_count &&
best_read_time >= current_read_time &&
@@ -5983,6 +6050,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
tables= 1;
const_tables= 0;
const_table_map= 0;
+ eliminated_tables= 0;
tmp_table_param.field_count= tmp_table_param.sum_func_count=
tmp_table_param.func_count= 0;
/*
@@ -6254,7 +6322,7 @@ make_outerjoin_info(JOIN *join)
}
if (!tab->first_inner)
tab->first_inner= nested_join->first_nested;
- if (++nested_join->counter < nested_join->join_list.elements)
+ if (++nested_join->counter < nested_join->n_tables)
break;
/* Table tab is the last inner table for nested join. */
nested_join->first_nested->last_inner= tab;
@@ -6465,7 +6533,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/
if ((cond &&
- !tab->keys.is_subset(tab->const_keys) && i > 0) ||
+ (!tab->keys.is_subset(tab->const_keys) && i > 0)) ||
(!tab->const_keys.is_clear_all() && i == join->const_tables &&
join->unit->select_limit_cnt <
join->best_positions[i].records_read &&
@@ -6602,6 +6670,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (tmp_cond)
{
JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
+ Item **sel_cond_ref= tab < first_inner_tab ?
+ &first_inner_tab->on_precond :
+ &tab->select_cond;
/*
First add the guards for match variables of
all embedding outer join operations.
@@ -6624,14 +6695,14 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
tmp_cond->quick_fix_field();
/* Add the predicate to other pushed down predicates */
DBUG_PRINT("info", ("Item_cond_and"));
- cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
- new Item_cond_and(cond_tab->select_cond,
- tmp_cond);
+ *sel_cond_ref= !(*sel_cond_ref) ?
+ tmp_cond :
+ new Item_cond_and(*sel_cond_ref, tmp_cond);
DBUG_PRINT("info", ("Item_cond_and 0x%lx",
- (ulong)cond_tab->select_cond));
- if (!cond_tab->select_cond)
- DBUG_RETURN(1);
- cond_tab->select_cond->quick_fix_field();
+ (ulong)(*sel_cond_ref)));
+ if (!(*sel_cond_ref))
+ DBUG_RETURN(1);
+ (*sel_cond_ref)->quick_fix_field();
}
}
first_inner_tab= first_inner_tab->first_upper;
@@ -6759,7 +6830,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
case JT_CONST: // Only happens with left join
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
- table->set_keyread(TRUE);
+ table->enable_keyread();
break;
case JT_ALL:
/*
@@ -6798,7 +6869,10 @@ make_join_readinfo(JOIN *join, ulonglong options)
{
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
if (statistics)
+ {
status_var_increment(join->thd->status_var.select_scan_count);
+ join->thd->query_plan_flags|= QPLAN_FULL_SCAN;
+ }
}
}
else
@@ -6812,7 +6886,10 @@ make_join_readinfo(JOIN *join, ulonglong options)
{
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
if (statistics)
+ {
status_var_increment(join->thd->status_var.select_full_join_count);
+ join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
+ }
}
}
if (!table->no_keyread)
@@ -6820,7 +6897,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
if (tab->select && tab->select->quick &&
tab->select->quick->index != MAX_KEY && //not index_merge
table->covering_keys.is_set(tab->select->quick->index))
- table->set_keyread(TRUE);
+ table->enable_keyread();
else if (!table->covering_keys.is_clear_all() &&
!(tab->select && tab->select->quick))
{ // Only read index tree
@@ -6906,7 +6983,7 @@ void JOIN_TAB::cleanup()
limit= 0;
if (table)
{
- table->set_keyread(FALSE);
+ table->disable_keyread();
table->file->ha_index_or_rnd_end();
/*
We need to reset this for next select
@@ -7376,7 +7453,7 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
Item *item;
while ((item= it++))
item->no_rows_in_result();
- send_error= result->send_data(fields);
+ send_error= result->send_data(fields) > 0;
}
if (!send_error)
result->send_eof(); // Should be safe
@@ -8271,6 +8348,8 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item *item_const= item_equal->get_const();
Item_equal_iterator it(*item_equal);
Item *head;
+ DBUG_ASSERT(!cond || cond->type() == Item::COND_ITEM);
+
if (item_const)
head= item_const;
else
@@ -8306,27 +8385,30 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
return 0;
eq_item->set_cmp_func();
eq_item->quick_fix_field();
- }
+ }
}
- if (!cond && !eq_list.head())
+ if (!cond)
{
- if (!eq_item)
- return new Item_int((longlong) 1,1);
- return eq_item;
- }
-
- if (eq_item)
+ if (eq_list.is_empty())
+ {
+ if (eq_item)
+ return eq_item;
+ return new Item_int((longlong) 1, 1);
+ }
+ /* eq_item is always set if list is not empty */
+ DBUG_ASSERT(eq_item);
eq_list.push_back(eq_item);
- if (!cond)
- cond= new Item_cond_and(eq_list);
+ if (!(cond= new Item_cond_and(eq_list)))
+ return 0; // Error
+ }
else
{
- DBUG_ASSERT(cond->type() == Item::COND_ITEM);
- if (eq_list.elements)
+ if (eq_item)
+ eq_list.push_back(eq_item);
+ if (!eq_list.is_empty())
((Item_cond *) cond)->add_at_head(&eq_list);
}
-
cond->quick_fix_field();
cond->update_used_tables();
@@ -8367,6 +8449,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
void *table_join_idx)
{
Item_equal *item_equal;
+ COND *org_cond= cond; // Return this in case of fatal error
if (cond->type() == Item::COND_ITEM)
{
@@ -8390,7 +8473,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
Item *item;
while ((item= li++))
{
- Item *new_item =substitute_for_best_equal_field(item, cond_equal,
+ Item *new_item= substitute_for_best_equal_field(item, cond_equal,
table_join_idx);
/*
This works OK with PS/SP re-execution as changes are made to
@@ -8409,6 +8492,8 @@ static COND* substitute_for_best_equal_field(COND *cond,
// This occurs when eliminate_item_equal() founds that cond is
// always false and substitutes it with Item_int 0.
// Due to this, value of item_equal will be 0, so just return it.
+ if (!cond)
+ return org_cond; // Error
if (cond->type() != Item::COND_ITEM)
break;
}
@@ -8425,7 +8510,8 @@ static COND* substitute_for_best_equal_field(COND *cond,
item_equal->sort(&compare_fields_by_table_order, table_join_idx);
if (cond_equal && cond_equal->current_level.head() == item_equal)
cond_equal= 0;
- return eliminate_item_equal(0, cond_equal, item_equal);
+ cond= eliminate_item_equal(0, cond_equal, item_equal);
+ return cond ? cond : org_cond;
}
else
cond->transform(&Item::replace_equal_field, 0);
@@ -8843,6 +8929,8 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
conds= simplify_joins(join, &nested_join->join_list, conds, top);
used_tables= nested_join->used_tables;
not_null_tables= nested_join->not_null_tables;
+ /* The following two might become unequal after table elimination: */
+ nested_join->n_tables= nested_join->join_list.elements;
}
else
{
@@ -8865,6 +8953,8 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
For some of the inner tables there are conjunctive predicates
that reject nulls => the outer join can be replaced by an inner join.
*/
+ if (table->outer_join && !table->embedding && table->table)
+ table->table->maybe_null= FALSE;
table->outer_join= 0;
if (table->on_expr)
{
@@ -8928,7 +9018,8 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
For example it might happen if RAND() function
is used in JOIN ON clause.
*/
- if (!((prev_table->on_expr->used_tables() & ~RAND_TABLE_BIT) &
+ if (!((prev_table->on_expr->used_tables() &
+ ~(OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) &
~prev_used_tables))
prev_table->dep_tables|= used_tables;
}
@@ -8950,6 +9041,8 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
while ((tbl= it++))
{
tbl->embedding= table->embedding;
+ if (!tbl->embedding && !tbl->on_expr && tbl->table)
+ tbl->table->maybe_null= FALSE;
tbl->join_list= table->join_list;
}
li.replace(nested_join->join_list);
@@ -9007,7 +9100,7 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
with anything)
2. we could run out bits in nested_join_map otherwise.
*/
- if (nested_join->join_list.elements != 1)
+ if (nested_join->n_tables != 1)
{
nested_join->nj_map= (nested_join_map) 1 << first_unused++;
first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
@@ -9029,21 +9122,26 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
tables which will be ignored.
*/
-static void reset_nj_counters(List<TABLE_LIST> *join_list)
+static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list)
{
List_iterator<TABLE_LIST> li(*join_list);
TABLE_LIST *table;
DBUG_ENTER("reset_nj_counters");
+ uint n=0;
while ((table= li++))
{
NESTED_JOIN *nested_join;
if ((nested_join= table->nested_join))
{
nested_join->counter= 0;
- reset_nj_counters(&nested_join->join_list);
+ //nested_join->n_tables= my_count_bits(nested_join->used_tables &
+ // ~join->eliminated_tables);
+ nested_join->n_tables= reset_nj_counters(join, &nested_join->join_list);
}
+ if (!table->table || (table->table->map & ~join->eliminated_tables))
+ n++;
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(n);
}
@@ -9168,7 +9266,7 @@ static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
join->cur_embedding_map |= next_emb->nested_join->nj_map;
}
- if (next_emb->nested_join->join_list.elements !=
+ if (next_emb->nested_join->n_tables !=
next_emb->nested_join->counter)
break;
@@ -9264,7 +9362,10 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
DBUG_ENTER("optimize_cond");
if (!conds)
+ {
*cond_value= Item::COND_TRUE;
+ build_equal_items(join->thd, NULL, NULL, join_list, &join->cond_equal);
+ }
else
{
/*
@@ -9819,7 +9920,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
If item have to be able to store NULLs but underlaid field can't do it,
create_tmp_field_from_field() can't be used for tmp field creation.
*/
- if (field->maybe_null && !field->field->maybe_null())
+ if (field->maybe_null && field->in_rollup && !field->field->maybe_null())
{
result= create_tmp_field_from_item(thd, item, table, NULL,
modify_item, convert_blob_length);
@@ -9848,7 +9949,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
((Item_ref*)orig_item)->set_result_field(result);
/*
Fields that are used as arguments to the DEFAULT() function already have
- their data pointers set to the default value during name resulotion. See
+ their data pointers set to the default value during name resolution. See
Item_default_value::fix_fields.
*/
if (orig_type != Item::DEFAULT_VALUE_ITEM && field->field->eq_def(result))
@@ -10000,7 +10101,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
KEY *keyinfo;
KEY_PART_INFO *key_part_info;
Item **copy_func;
- MI_COLUMNDEF *recinfo;
+ ENGINE_COLUMNDEF *recinfo;
/*
total_uneven_bit_length is uneven bit length for visible fields
hidden_uneven_bit_length is uneven bit length for hidden fields
@@ -10016,6 +10117,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(ulong) rows_limit,test(group)));
status_var_increment(thd->status_var.created_tmp_tables);
+ thd->query_plan_flags|= QPLAN_TMP_TABLE;
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
@@ -10026,16 +10128,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
else
{
/* if we run out of slots or we are not using tempool */
- sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
+ sprintf(path, "%s%lx_%lx_%x", tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
}
/*
No need to change table name to lower case as we are only creating
- MyISAM or HEAP tables here
+ MyISAM, Maria or HEAP tables here
*/
- fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
-
+ fn_format(path, path, mysql_tmpdir, "",
+ MY_REPLACE_EXT|MY_UNPACK_FILENAME);
if (group)
{
@@ -10100,7 +10202,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
DBUG_RETURN(NULL); /* purecov: inspected */
}
param->items_to_copy= copy_func;
- strmov(tmpname,path);
+ strmov(tmpname, path);
/* make table according to fields */
bzero((char*) table,sizeof(*table));
@@ -10129,7 +10231,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
share->blob_field= blob_field;
share->blob_ptr_size= portable_sizeof_char_ptr;
- share->db_low_byte_first=1; // True for HEAP and MyISAM
+ share->db_low_byte_first=1; // True for HEAP, MyISAM and Maria
share->table_charset= param->table_charset;
share->primary_key= MAX_KEY; // Indicate no primary key
share->keys_for_keyread.init();
@@ -10261,6 +10363,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*blob_field++= fieldnr;
blob_count++;
}
+ if (new_field->real_type() == MYSQL_TYPE_STRING ||
+ new_field->real_type() == MYSQL_TYPE_VARCHAR)
+ {
+ string_count++;
+ string_total_length+= new_field->pack_length();
+ }
if (item->marker == 4 && item->maybe_null)
{
group_null_items++;
@@ -10303,9 +10411,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/* future: storage engine selection can be made dynamic? */
if (blob_count || using_unique_constraint ||
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
- OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
+ OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM) ||
+ !thd->variables.tmp_table_size)
{
- share->db_plugin= ha_lock_engine(0, myisam_hton);
+ share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
table->file= get_new_handler(share, &table->mem_root,
share->db_type());
if (group &&
@@ -10322,7 +10431,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!table->file)
goto err;
-
if (!using_unique_constraint)
reclength+= group_null_items; // null flag is stored separately
@@ -10345,8 +10453,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/* Use packed rows if there is blobs or a lot of space to gain */
if (blob_count ||
(string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS &&
- (reclength / string_total_length <= RATIO_TO_PACK_ROWS ||
- string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
+ (reclength / string_total_length <= RATIO_TO_PACK_ROWS ||
+ string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
use_packed_rows= 1;
share->reclength= reclength;
@@ -10377,7 +10485,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->null_flags= (uchar*) table->record[0];
share->null_fields= null_count+ hidden_null_count;
- share->null_bytes= null_pack_length;
+ share->null_bytes= share->null_bytes_for_compare= null_pack_length;
}
null_count= (blob_count == 0) ? 1 : 0;
hidden_field_count=param->hidden_field_count;
@@ -10459,13 +10567,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/* Make entry for create table */
recinfo->length=length;
if (field->flags & BLOB_FLAG)
- recinfo->type= (int) FIELD_BLOB;
+ recinfo->type= FIELD_BLOB;
else if (use_packed_rows &&
field->real_type() == MYSQL_TYPE_STRING &&
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
- recinfo->type=FIELD_SKIP_ENDSPACE;
+ recinfo->type= FIELD_SKIP_ENDSPACE;
+ else if (field->real_type() == MYSQL_TYPE_VARCHAR)
+ recinfo->type= FIELD_VARCHAR;
else
- recinfo->type=FIELD_NORMAL;
+ recinfo->type= FIELD_NORMAL;
+
if (!--hidden_field_count)
null_count=(null_count+7) & ~7; // move to next byte
@@ -10526,15 +10637,30 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
0 : FIELDFLAG_BINARY;
+
if (!using_unique_constraint)
{
cur_group->buff=(char*) group_buff;
+
+ if (maybe_null && !field->null_bit)
+ {
+ /*
+ This can only happen in the unusual case where an outer join
+ table was found to be not-nullable by the optimizer and we
+ the item can't really be null.
+ We solve this by marking the item as !maybe_null to ensure
+ that the key,field and item definition match.
+ */
+ (*cur_group->item)->maybe_null= maybe_null= 0;
+ }
+
if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
group_buff +
test(maybe_null),
field->null_ptr,
field->null_bit)))
goto err; /* purecov: inspected */
+
if (maybe_null)
{
/*
@@ -10556,6 +10682,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
keyinfo->key_length+= key_part_info->length;
}
+ /*
+ Ensure we didn't overrun the group buffer. The < is only true when
+ some maybe_null fields was changed to be not null fields.
+ */
+ DBUG_ASSERT(using_unique_constraint ||
+ group_buff <= param->group_buff + param->group_length);
}
if (distinct && field_count != param->hidden_field_count)
@@ -10629,9 +10761,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
share->db_record_offset= 1;
- if (share->db_type() == myisam_hton)
+ if (share->db_type() == TMP_ENGINE_HTON)
{
- if (create_myisam_tmp_table(table,param,select_options))
+ if (create_internal_tmp_table(table,param,select_options))
goto err;
}
if (open_tmp_table(table))
@@ -10740,7 +10872,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
{
table->null_flags= (uchar*) table->record[0];
share->null_fields= null_count;
- share->null_bytes= null_pack_length;
+ share->null_bytes= share->null_bytes_for_compare= null_pack_length;
}
table->in_use= thd; /* field->reset() may access table->in_use */
@@ -10793,15 +10925,150 @@ static bool open_tmp_table(TABLE *table)
}
-static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
- ulonglong options)
+#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
+
+/* Create internal Maria temporary table */
+
+static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
+ ulonglong options)
+{
+ int error;
+ MARIA_KEYDEF keydef;
+ MARIA_UNIQUEDEF uniquedef;
+ KEY *keyinfo=param->keyinfo;
+ TABLE_SHARE *share= table->s;
+ MARIA_CREATE_INFO create_info;
+ DBUG_ENTER("create_internal_tmp_table");
+
+ if (share->keys)
+ { // Get keys for ni_create
+ bool using_unique_constraint=0;
+ HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
+ sizeof(*seg) * keyinfo->key_parts);
+ if (!seg)
+ goto err;
+
+ bzero(seg, sizeof(*seg) * keyinfo->key_parts);
+ if (keyinfo->key_length >= table->file->max_key_length() ||
+ keyinfo->key_parts > table->file->max_key_parts() ||
+ share->uniques)
+ {
+ /* Can't create a key; Make a unique constraint instead of a key */
+ share->keys= 0;
+ share->uniques= 1;
+ using_unique_constraint=1;
+ bzero((char*) &uniquedef,sizeof(uniquedef));
+ uniquedef.keysegs=keyinfo->key_parts;
+ uniquedef.seg=seg;
+ uniquedef.null_are_equal=1;
+
+ /* Create extra column for hash value */
+ bzero((uchar*) param->recinfo,sizeof(*param->recinfo));
+ param->recinfo->type= FIELD_CHECK;
+ param->recinfo->length= MARIA_UNIQUE_HASH_LENGTH;
+ param->recinfo++;
+ share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
+ }
+ else
+ {
+ /* Create an unique key */
+ bzero((char*) &keydef,sizeof(keydef));
+ keydef.flag=HA_NOSAME;
+ keydef.keysegs= keyinfo->key_parts;
+ keydef.seg= seg;
+ }
+ for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
+ {
+ Field *field=keyinfo->key_part[i].field;
+ seg->flag= 0;
+ seg->language= field->charset()->number;
+ seg->length= keyinfo->key_part[i].length;
+ seg->start= keyinfo->key_part[i].offset;
+ if (field->flags & BLOB_FLAG)
+ {
+ seg->type=
+ ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
+ HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
+ seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
+ seg->flag= HA_BLOB_PART;
+ seg->length=0; // Whole blob in unique constraint
+ }
+ else
+ {
+ seg->type= keyinfo->key_part[i].type;
+ /* Tell handler if it can do suffic space compression */
+ if (field->real_type() == MYSQL_TYPE_STRING &&
+ keyinfo->key_part[i].length > 32)
+ seg->flag|= HA_SPACE_PACK;
+ }
+ if (!(field->flags & NOT_NULL_FLAG))
+ {
+ seg->null_bit= field->null_bit;
+ seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
+ /*
+ We are using a GROUP BY on something that contains NULL
+ In this case we have to tell Maria that two NULL should
+ on INSERT be regarded at the same value
+ */
+ if (!using_unique_constraint)
+ keydef.flag|= HA_NULL_ARE_EQUAL;
+ }
+ }
+ }
+ bzero((char*) &create_info,sizeof(create_info));
+
+ if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
+ OPTION_BIG_TABLES)
+ create_info.data_file_length= ~(ulonglong) 0;
+
+ if ((error= maria_create(share->table_name.str,
+ share->reclength < 64 &&
+ !share->blob_fields ? STATIC_RECORD :
+ BLOCK_RECORD,
+ share->keys, &keydef,
+ (uint) (param->recinfo-param->start_recinfo),
+ param->start_recinfo,
+ share->uniques, &uniquedef,
+ &create_info,
+ HA_CREATE_TMP_TABLE)))
+ {
+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
+ table->db_stat=0;
+ goto err;
+ }
+ status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
+ table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
+ share->db_record_offset= 1;
+ DBUG_RETURN(0);
+ err:
+ DBUG_RETURN(1);
+}
+
+
+bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
+ TMP_TABLE_PARAM *param,
+ int error,
+ bool ignore_last_dupp_key_error)
+{
+ return create_internal_tmp_table_from_heap2(thd, table, param, error,
+ ignore_last_dupp_key_error,
+ maria_hton,
+ "converting HEAP to Maria");
+}
+
+#else
+
+/* Create internal MyISAM temporary table */
+
+static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
+ ulonglong options)
{
int error;
MI_KEYDEF keydef;
MI_UNIQUEDEF uniquedef;
KEY *keyinfo=param->keyinfo;
TABLE_SHARE *share= table->s;
- DBUG_ENTER("create_myisam_tmp_table");
+ DBUG_ENTER("create_internal_tmp_table");
if (share->keys)
{ // Get keys for ni_create
@@ -10904,58 +11171,44 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
}
-void
-free_tmp_table(THD *thd, TABLE *entry)
-{
- MEM_ROOT own_root= entry->mem_root;
- const char *save_proc_info;
- DBUG_ENTER("free_tmp_table");
- DBUG_PRINT("enter",("table: %s",entry->alias));
-
- save_proc_info=thd->proc_info;
- thd_proc_info(thd, "removing tmp table");
-
- // Release latches since this can take a long time
- ha_release_temporary_latches(thd);
-
- if (entry->file)
- {
- if (entry->db_stat)
- entry->file->ha_drop_table(entry->s->table_name.str);
- else
- entry->file->ha_delete_table(entry->s->table_name.str);
- delete entry->file;
- }
-
- /* free blobs */
- for (Field **ptr=entry->field ; *ptr ; ptr++)
- (*ptr)->free();
- free_io_cache(entry);
-
- if (entry->temp_pool_slot != MY_BIT_NONE)
- bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
+/**
+ If a HEAP table gets full, create a MyISAM table and copy all rows to this
+*/
- plugin_unlock(0, entry->s->db_plugin);
+bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
+ TMP_TABLE_PARAM *param,
+ int error,
+ bool ignore_last_dupp_key_error)
+{
+ return create_internal_tmp_table_from_heap2(thd, table, param, error,
+ ignore_last_dupp_key_error,
+ myisam_hton,
+ "converting HEAP to MyISAM");
+}
- free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
- thd_proc_info(thd, save_proc_info);
+#endif /* WITH_MARIA_STORAGE_ENGINE */
- DBUG_VOID_RETURN;
-}
-/**
- If a HEAP table gets full, create a MyISAM table and copy all rows
- to this.
+/*
+ If a HEAP table gets full, create a internal table in MyISAM or Maria
+ and copy all rows to this
*/
-bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
- int error, bool ignore_last_dupp_key_error)
+
+static bool
+create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
+ TMP_TABLE_PARAM *param,
+ int error,
+ bool ignore_last_dupp_key_error,
+ handlerton *hton,
+ const char *proc_info)
{
TABLE new_table;
TABLE_SHARE share;
const char *save_proc_info;
int write_err;
- DBUG_ENTER("create_myisam_from_heap");
+ DBUG_ENTER("create_internal_tmp_table_from_heap2");
+ LINT_INIT(write_err);
if (table->s->db_type() != heap_hton ||
error != HA_ERR_RECORD_FILE_FULL)
@@ -10968,22 +11221,18 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
table->file->print_error(error,MYF(0));
DBUG_RETURN(1);
}
-
- // Release latches since this can take a long time
- ha_release_temporary_latches(thd);
-
new_table= *table;
share= *table->s;
new_table.s= &share;
- new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
+ new_table.s->db_plugin= ha_lock_engine(thd, hton);
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
new_table.s->db_type())))
DBUG_RETURN(1); // End of memory
save_proc_info=thd->proc_info;
- thd_proc_info(thd, "converting HEAP to MyISAM");
+ thd_proc_info(thd, proc_info);
- if (create_myisam_tmp_table(&new_table, param,
+ if (create_internal_tmp_table(&new_table, param,
thd->lex->select_lex.options | thd->options))
goto err2;
if (open_tmp_table(&new_table))
@@ -11022,6 +11271,11 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
if (write_err)
goto err;
+ if (thd->killed)
+ {
+ thd->send_kill_message();
+ goto err_killed;
+ }
}
/* copy row that filled HEAP table */
if ((write_err=new_table.file->ha_write_row(table->record[0])))
@@ -11037,7 +11291,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
delete table->file;
table->file=0;
plugin_unlock(0, table->s->db_plugin);
- share.db_plugin= my_plugin_lock(0, &share.db_plugin);
+ share.db_plugin= my_plugin_lock(0, share.db_plugin);
new_table.s= table->s; // Keep old share
*table= new_table;
*table->s= share;
@@ -11046,12 +11300,13 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
table->use_all_columns();
if (save_proc_info)
thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
- "Copying to tmp table on disk" : save_proc_info));
+ "Copying to tmp table on disk" : save_proc_info));
DBUG_RETURN(0);
err:
DBUG_PRINT("error",("Got error: %d",write_err));
table->file->print_error(write_err, MYF(0));
+err_killed:
(void) table->file->ha_rnd_end();
(void) new_table.file->close();
err1:
@@ -11064,6 +11319,43 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
}
+void
+free_tmp_table(THD *thd, TABLE *entry)
+{
+ MEM_ROOT own_root= entry->mem_root;
+ const char *save_proc_info;
+ DBUG_ENTER("free_tmp_table");
+ DBUG_PRINT("enter",("table: %s",entry->alias));
+
+ save_proc_info=thd->proc_info;
+ thd_proc_info(thd, "removing tmp table");
+
+ if (entry->file)
+ {
+ if (entry->db_stat)
+ entry->file->ha_drop_table(entry->s->table_name.str);
+ else
+ entry->file->ha_delete_table(entry->s->table_name.str);
+ delete entry->file;
+ }
+
+ /* free blobs */
+ for (Field **ptr=entry->field ; *ptr ; ptr++)
+ (*ptr)->free();
+ free_io_cache(entry);
+
+ if (entry->temp_pool_slot != MY_BIT_NONE)
+ bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
+
+ plugin_unlock(0, entry->s->db_plugin);
+
+ free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
+ thd_proc_info(thd, save_proc_info);
+
+ DBUG_VOID_RETURN;
+}
+
+
/**
@details
Rows produced by a join sweep may end up in a temporary table or be sent
@@ -11159,8 +11451,9 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
int rc= 0;
enum_nested_loop_state error= NESTED_LOOP_OK;
- JOIN_TAB *join_tab= NULL;
+ JOIN_TAB *join_tab;
DBUG_ENTER("do_select");
+ LINT_INIT(join_tab);
join->procedure=procedure;
join->tmp_table= table; /* Save for easy recursion */
@@ -11172,7 +11465,14 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
empty_record(table);
if (table->group && join->tmp_table_param.sum_func_count &&
table->s->keys && !table->file->inited)
- table->file->ha_index_init(0, 0);
+ {
+ int tmp_error;
+ if ((tmp_error= table->file->ha_index_init(0, 0)))
+ {
+ table->file->print_error(tmp_error, MYF(0)); /* purecov: inspected */
+ DBUG_RETURN(-1); /* purecov: inspected */
+ }
+ }
}
/* Set up select_end */
Next_select_func end_select= setup_end_select_func(join);
@@ -11208,7 +11508,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
fields);
- rc= join->result->send_data(*columns_list);
+ rc= join->result->send_data(*columns_list) > 0;
}
}
else
@@ -11223,12 +11523,14 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
if (error == NESTED_LOOP_NO_MORE_ROWS)
error= NESTED_LOOP_OK;
- if (table == NULL) // If sending data to client
+ if (table == NULL) // If sending data to client
+ {
/*
The following will unlock all cursors if the command wasn't an
update command
*/
- join->join_free(); // Unlock all cursors
+ join->join_free(); // Unlock all cursors
+ }
if (error == NESTED_LOOP_OK)
{
/*
@@ -11424,7 +11726,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
return (*join_tab->next_select)(join,join_tab+1,end_of_records);
int error;
- enum_nested_loop_state rc;
+ enum_nested_loop_state rc= NESTED_LOOP_OK;
READ_RECORD *info= &join_tab->read_record;
if (join->resume_nested_loop)
@@ -11452,11 +11754,16 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
/* Set first_unmatched for the last inner table of this group */
join_tab->last_inner->first_unmatched= join_tab;
+ if (join_tab->on_precond && !join_tab->on_precond->val_int())
+ rc= NESTED_LOOP_NO_MORE_ROWS;
}
join->thd->row_count= 0;
- error= (*join_tab->read_first_record)(join_tab);
- rc= evaluate_join_record(join, join_tab, error);
+ if (rc != NESTED_LOOP_NO_MORE_ROWS)
+ {
+ error= (*join_tab->read_first_record)(join_tab);
+ rc= evaluate_join_record(join, join_tab, error);
+ }
}
while (rc == NESTED_LOOP_OK)
@@ -11519,6 +11826,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
condition is true => a match is found.
*/
bool found= 1;
+ bool use_not_exists_opt= 0;
while (join_tab->first_unmatched && found)
{
/*
@@ -11535,7 +11843,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
{
if (tab->table->reginfo.not_exists_optimize)
- return NESTED_LOOP_NO_MORE_ROWS;
+ use_not_exists_opt= 1;
/* Check all predicates that has just been activated. */
/*
Actually all predicates non-guarded by first_unmatched->found
@@ -11568,6 +11876,9 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
join_tab->first_unmatched= first_unmatched;
}
+ if (use_not_exists_opt)
+ return NESTED_LOOP_NO_MORE_ROWS;
+
/*
It was not just a return to lower loop level when one
of the newly activated predicates is evaluated as false
@@ -11685,6 +11996,7 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
enum_nested_loop_state rc= NESTED_LOOP_OK;
int error;
READ_RECORD *info;
+ SQL_SELECT *select;
join_tab->table->null_row= 0;
if (!join_tab->cache.records)
@@ -11699,63 +12011,65 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
join_tab->select->quick=0;
}
}
- /* read through all records */
+ /* read through all records */
if ((error=join_init_read_record(join_tab)))
{
reset_cache_write(&join_tab->cache);
return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
}
- for (JOIN_TAB *tmp=join->join_tab; tmp != join_tab ; tmp++)
+ for (JOIN_TAB *tmp= join_tab-1;
+ tmp >= join->join_tab && !tmp->cache.buff; tmp--)
{
tmp->status=tmp->table->status;
tmp->table->status=0;
}
info= &join_tab->read_record;
+ select= join_tab->select;
+
do
{
+ int err= 0;
if (join->thd->killed)
{
join->thd->send_kill_message();
return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
}
- SQL_SELECT *select=join_tab->select;
- if (rc == NESTED_LOOP_OK)
+ if (rc == NESTED_LOOP_OK &&
+ (!join_tab->cache.select ||
+ (err= join_tab->cache.select->skip_record(join->thd)) != 0 ))
{
- bool skip_record= FALSE;
- if (join_tab->cache.select &&
- join_tab->cache.select->skip_record(join->thd, &skip_record))
+ if (err < 0)
{
reset_cache_write(&join_tab->cache);
return NESTED_LOOP_ERROR;
}
- if (!skip_record)
+ reset_cache_read(&join_tab->cache);
+ for (uint i= (join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
{
- uint i;
- reset_cache_read(&join_tab->cache);
- for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
+ read_cached_record(join_tab);
+ err= 0;
+ if (!select || (err= select->skip_record(join->thd)) != 0)
{
- read_cached_record(join_tab);
- skip_record= FALSE;
- if (select && select->skip_record(join->thd, &skip_record))
+ if (err < 0)
{
reset_cache_write(&join_tab->cache);
return NESTED_LOOP_ERROR;
}
- if (!skip_record)
+ rc= (join_tab->next_select)(join,join_tab+1,0);
+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
{
- rc= (join_tab->next_select)(join,join_tab+1,0);
- if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
- {
- reset_cache_write(&join_tab->cache);
- return rc;
- }
+ reset_cache_write(&join_tab->cache);
+ return rc;
}
}
}
}
+
+ rc= NESTED_LOOP_OK;
+
} while (!(error=info->read_record(info)));
if (skip_last)
@@ -11763,7 +12077,8 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
reset_cache_write(&join_tab->cache);
if (error > 0) // Fatal error
return NESTED_LOOP_ERROR; /* purecov: inspected */
- for (JOIN_TAB *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
+ for (JOIN_TAB *tmp2= join_tab-1;
+ tmp2 >= join->join_tab && !tmp2->cache.buff; tmp2--)
tmp2->table->status=tmp2->status;
return NESTED_LOOP_OK;
}
@@ -11829,6 +12144,11 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
if (!table->maybe_null || error > 0)
DBUG_RETURN(error);
}
+ /*
+ The optimizer trust the engine that when stats.records is 0, there
+ was no found rows
+ */
+ DBUG_ASSERT(table->file->stats.records > 0 || error);
}
else
{
@@ -11836,11 +12156,11 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
!table->no_keyread &&
(int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY)
{
- table->set_keyread(TRUE);
+ table->enable_keyread();
tab->index= tab->ref.key;
}
error=join_read_const(tab);
- table->set_keyread(FALSE);
+ table->disable_keyread();
if (error)
{
tab->info="unique row not found";
@@ -11853,6 +12173,17 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
}
if (*tab->on_expr_ref && !table->null_row)
{
+#if !defined(DBUG_OFF) && defined(NOT_USING_ITEM_EQUAL)
+ /*
+ This test could be very useful to find bugs in the optimizer
+ where we would call this function with an expression that can't be
+ evaluated yet. We can't have this enabled by default as long as
+ have items like Item_equal, that doesn't report they are const but
+ they can still be called even if they contain not const items.
+ */
+ (*tab->on_expr_ref)->update_used_tables();
+ DBUG_ASSERT((*tab->on_expr_ref)->const_item());
+#endif
if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
mark_as_null_row(table);
}
@@ -11967,7 +12298,11 @@ join_read_key(JOIN_TAB *tab)
if (!table->file->inited)
{
- table->file->ha_index_init(tab->ref.key, tab->sorted);
+ if ((error= table->file->ha_index_init(tab->ref.key, tab->sorted)))
+ {
+ table->file->print_error(error, MYF(0));/* purecov: inspected */
+ return 1; /* purecov: inspected */
+ }
}
if (cmp_buffer_with_ref(tab) ||
(table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
@@ -12053,8 +12388,14 @@ join_read_always_key(JOIN_TAB *tab)
/* Initialize the index first */
if (!table->file->inited)
- table->file->ha_index_init(tab->ref.key, tab->sorted);
-
+ {
+ if ((error= table->file->ha_index_init(tab->ref.key, tab->sorted)))
+ {
+ table->file->print_error(error, MYF(0));/* purecov: inspected */
+ return(1); /* purecov: inspected */
+ }
+ }
+
/* Perform "Late NULLs Filtering" (see internals manual for explanations) */
for (uint i= 0 ; i < tab->ref.key_parts ; i++)
{
@@ -12089,7 +12430,13 @@ join_read_last_key(JOIN_TAB *tab)
TABLE *table= tab->table;
if (!table->file->inited)
- table->file->ha_index_init(tab->ref.key, tab->sorted);
+ {
+ if ((error= table->file->ha_index_init(tab->ref.key, tab->sorted)))
+ {
+ table->file->print_error(error, MYF(0));/* purecov: inspected */
+ return(1); /* purecov: inspected */
+ }
+ }
if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
return -1;
if ((error=table->file->index_read_last_map(table->record[0],
@@ -12193,10 +12540,11 @@ join_init_read_record(JOIN_TAB *tab)
static int
join_read_first(JOIN_TAB *tab)
{
- int error;
+ int error= 0;
TABLE *table=tab->table;
- if (table->covering_keys.is_set(tab->index) && !table->no_keyread)
- table->set_keyread(TRUE);
+ if (table->covering_keys.is_set(tab->index) && !table->no_keyread &&
+ !table->key_read)
+ table->enable_keyread();
tab->table->status=0;
tab->read_record.read_record=join_read_next;
tab->read_record.table=table;
@@ -12204,8 +12552,10 @@ join_read_first(JOIN_TAB *tab)
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
if (!table->file->inited)
- table->file->ha_index_init(tab->index, tab->sorted);
- if ((error=tab->table->file->index_first(tab->table->record[0])))
+ error= table->file->ha_index_init(tab->index, tab->sorted);
+ if (!error)
+ error= table->file->prepare_index_scan();
+ if (error || (error=tab->table->file->index_first(tab->table->record[0])))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
report_error(table, error);
@@ -12229,9 +12579,10 @@ static int
join_read_last(JOIN_TAB *tab)
{
TABLE *table=tab->table;
- int error;
- if (table->covering_keys.is_set(tab->index) && !table->no_keyread)
- table->set_keyread(TRUE);
+ int error= 0;
+ if (table->covering_keys.is_set(tab->index) && !table->no_keyread &&
+ !table->key_read)
+ table->enable_keyread();
tab->table->status=0;
tab->read_record.read_record=join_read_prev;
tab->read_record.table=table;
@@ -12239,8 +12590,10 @@ join_read_last(JOIN_TAB *tab)
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
if (!table->file->inited)
- table->file->ha_index_init(tab->index, 1);
- if ((error= tab->table->file->index_last(tab->table->record[0])))
+ error= table->file->ha_index_init(tab->index, 1);
+ if (!error)
+ error= table->file->prepare_index_scan();
+ if (error || (error= tab->table->file->index_last(tab->table->record[0])))
return report_error(table, error);
return 0;
}
@@ -12262,8 +12615,12 @@ join_ft_read_first(JOIN_TAB *tab)
int error;
TABLE *table= tab->table;
- if (!table->file->inited)
- table->file->ha_index_init(tab->ref.key, 1);
+ if (!table->file->inited &&
+ (error= table->file->ha_index_init(tab->ref.key, 1)))
+ {
+ table->file->print_error(error, MYF(0)); /* purecov: inspected */
+ return(1); /* purecov: inspected */
+ }
#if NOT_USED_YET
/* as ft-key doesn't use store_key's, see also FT_SELECT::init() */
if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
@@ -12355,7 +12712,6 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_ENTER("end_send");
if (!end_of_records)
{
- int error;
if (join->having && join->having->val_int() == 0)
DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having
if (join->procedure)
@@ -12364,11 +12720,13 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(NESTED_LOOP_ERROR);
DBUG_RETURN(NESTED_LOOP_OK);
}
- error=0;
if (join->do_send_rows)
- error=join->result->send_data(*join->fields);
- if (error)
- DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
+ {
+ int error;
+ /* result < 0 if row was not accepted and should not be counted */
+ if ((error= join->result->send_data(*join->fields)))
+ DBUG_RETURN(error < 0 ? NESTED_LOOP_OK : NESTED_LOOP_ERROR);
+ }
if (++join->send_records >= join->unit->select_limit_cnt &&
join->do_send_rows)
{
@@ -12464,8 +12822,11 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
List_iterator_fast<Item> it(*join->fields);
Item *item;
+ DBUG_PRINT("info", ("no matching rows"));
+
/* No matching rows for group function */
join->clear();
+ join->no_rows_in_result_called= 1;
while ((item= it++))
item->no_rows_in_result();
@@ -12475,7 +12836,15 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
else
{
if (join->do_send_rows)
- error=join->result->send_data(*join->fields) ? 1 : 0;
+ {
+ error= join->result->send_data(*join->fields);
+ if (error < 0)
+ {
+ /* Duplicate row, don't count */
+ join->send_records--;
+ error= 0;
+ }
+ }
join->send_records++;
}
if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
@@ -12582,7 +12951,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
goto end;
- if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
+ if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param,
error,1))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
table->s->uniques=0; // To ensure rows are the same
@@ -12667,11 +13036,16 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
if ((error=table->file->ha_write_row(table->record[0])))
{
- if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
- error, 0))
+ if (create_internal_tmp_table_from_heap(join->thd, table,
+ &join->tmp_table_param,
+ error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
/* Change method to update rows */
- table->file->ha_index_init(0, 0);
+ if ((error= table->file->ha_index_init(0, 0)))
+ {
+ table->file->print_error(error, MYF(0));/* purecov: inspected */
+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
+ }
join->join_tab[join->tables-1].next_select=end_unique_update;
}
join->send_records++;
@@ -12763,7 +13137,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->having || join->having->val_int())
{
int error= table->file->ha_write_row(table->record[0]);
- if (error && create_myisam_from_heap(join->thd, table,
+ if (error && create_internal_tmp_table_from_heap(join->thd, table,
&join->tmp_table_param,
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR);
@@ -13127,23 +13501,6 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
@param table Table to scan
@param usable_keys Allowed keys
- @note
- As far as
- 1) clustered primary key entry data set is a set of all record
- fields (key fields and not key fields) and
- 2) secondary index entry data is a union of its key fields and
- primary key fields (at least InnoDB and its derivatives don't
- duplicate primary key fields there, even if the primary and
- the secondary keys have a common subset of key fields),
- then secondary index entry data is always a subset of primary key entry.
- Unfortunately, key_info[nr].key_length doesn't show the length
- of key/pointer pair but a sum of key field lengths only, thus
- we can't estimate index IO volume comparing only this key_length
- value of secondary keys and clustered PK.
- So, try secondary keys first, and choose PK only if there are no
- usable secondary covering keys or found best secondary key include
- all table fields (i.e. same as PK):
-
@return
MAX_KEY no suitable key found
key index otherwise
@@ -13151,41 +13508,23 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
uint find_shortest_key(TABLE *table, const key_map *usable_keys)
{
+ double min_cost= DBL_MAX;
uint best= MAX_KEY;
- uint usable_clustered_pk= (table->file->primary_key_is_clustered() &&
- table->s->primary_key != MAX_KEY &&
- usable_keys->is_set(table->s->primary_key)) ?
- table->s->primary_key : MAX_KEY;
if (!usable_keys->is_clear_all())
{
- uint min_length= (uint) ~0;
for (uint nr=0; nr < table->s->keys ; nr++)
{
- if (nr == usable_clustered_pk)
- continue;
if (usable_keys->is_set(nr))
{
- if (table->key_info[nr].key_length < min_length)
+ double cost= table->file->keyread_time(nr, 1, table->file->records());
+ if (cost < min_cost)
{
- min_length=table->key_info[nr].key_length;
+ min_cost= cost;
best=nr;
}
}
}
}
- if (usable_clustered_pk != MAX_KEY)
- {
- /*
- If the primary key is clustered and found shorter key covers all table
- fields then primary key scan normally would be faster because amount of
- data to scan is the same but PK is clustered.
- It's safe to compare key parts with table fields since duplicate key
- parts aren't allowed.
- */
- if (best == MAX_KEY ||
- table->key_info[best].key_parts >= table->s->fields)
- best= usable_clustered_pk;
- }
return best;
}
@@ -13291,8 +13630,6 @@ static bool
list_contains_unique_index(TABLE *table,
bool (*find_func) (Field *, void *), void *data)
{
- if (table->pos_in_table_list->outer_join)
- return 0;
for (uint keynr= 0; keynr < table->s->keys; keynr++)
{
if (keynr == table->s->primary_key ||
@@ -13306,7 +13643,7 @@ list_contains_unique_index(TABLE *table,
key_part < key_part_end;
key_part++)
{
- if (key_part->field->real_maybe_null() ||
+ if (key_part->field->maybe_null() ||
!find_func(key_part->field, data))
break;
}
@@ -13419,7 +13756,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
key_map usable_keys;
QUICK_SELECT_I *save_quick= 0;
int best_key= -1;
-
DBUG_ENTER("test_if_skip_sort_order");
LINT_INIT(ref_key_parts);
@@ -13523,6 +13859,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
new_ref_key_map.clear_all(); // Force the creation of quick select
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
+ /* Reset quick; This will be restored in 'use_filesort' if needed */
select->quick= 0;
if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
(tab->join->select_options &
@@ -13550,10 +13887,10 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
uint nr;
key_map keys;
- uint best_key_parts= 0;
+ uint best_key_parts;
uint saved_best_key_parts= 0;
- int best_key_direction= 0;
- ha_rows best_records= 0;
+ int best_key_direction;
+ ha_rows best_records;
double read_time;
bool is_best_covering= FALSE;
double fanout= 1;
@@ -13562,6 +13899,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
ha_rows table_records= table->file->stats.records;
bool group= join->group && order == join->group_list;
ha_rows ref_key_quick_rows= HA_POS_ERROR;
+ LINT_INIT(best_key_parts);
+ LINT_INIT(best_key_direction);
+ LINT_INIT(best_records);
/*
If not used with LIMIT, only use keys if the whole query can be
@@ -13637,10 +13977,48 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
key (e.g. as in Innodb).
See Bug #28591 for details.
*/
- rec_per_key= used_key_parts &&
- used_key_parts <= keyinfo->key_parts ?
- keyinfo->rec_per_key[used_key_parts-1] : 1;
- set_if_bigger(rec_per_key, 1);
+ uint used_index_parts= keyinfo->key_parts;
+ uint used_pk_parts= 0;
+ if (used_key_parts > used_index_parts)
+ used_pk_parts= used_key_parts-used_index_parts;
+ rec_per_key= keyinfo->rec_per_key[used_key_parts-1];
+ /* Take into account the selectivity of the used pk prefix */
+ if (used_pk_parts)
+ {
+ KEY *pkinfo=tab->table->key_info+table->s->primary_key;
+ /*
+ If the values of of records per key for the prefixes
+ of the primary key are considered unknown we assume
+ they are equal to 1.
+ */
+ if (used_key_parts == pkinfo->key_parts ||
+ pkinfo->rec_per_key[0] == 0)
+ rec_per_key= 1;
+ if (rec_per_key > 1)
+ {
+ rec_per_key*= pkinfo->rec_per_key[used_pk_parts-1];
+ rec_per_key/= pkinfo->rec_per_key[0];
+ /*
+ The value of rec_per_key for the extended key has
+ to be adjusted accordingly if some components of
+ the secondary key are included in the primary key.
+ */
+ for(uint i= 0; i < used_pk_parts; i++)
+ {
+ if (pkinfo->key_part[i].field->key_start.is_set(nr))
+ {
+ /*
+ We presume here that for any index rec_per_key[i] != 0
+ if rec_per_key[0] != 0.
+ */
+ DBUG_ASSERT(pkinfo->rec_per_key[i]);
+ rec_per_key*= pkinfo->rec_per_key[i-1];
+ rec_per_key/= pkinfo->rec_per_key[i];
+ }
+ }
+ }
+ }
+ set_if_bigger(rec_per_key, 1);
/*
With a grouping query each group containing on average
rec_per_key records produces only one row that will
@@ -13766,6 +14144,7 @@ check_reverse_order:
if (order_direction == -1) // If ORDER BY ... DESC
{
+ int quick_type;
if (select && select->quick)
{
/*
@@ -13774,25 +14153,22 @@ check_reverse_order:
*/
if (select->quick->reverse_sorted())
goto skipped_filesort;
- else
+
+ quick_type= select->quick->get_type();
+ if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
+ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
+ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
+ quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
{
- int quick_type= select->quick->get_type();
- if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
- quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
- quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
- quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
- {
- tab->limit= 0;
- goto use_filesort; // Use filesort
- }
+ tab->limit= 0;
+ goto use_filesort; // Use filesort
}
}
}
/*
- Update query plan with access pattern for doing
- ordered access according to what we have decided
- above.
+ Update query plan with access pattern for doing ordered access
+ according to what we have decided above.
*/
if (!no_changes) // We are allowed to update QEP
{
@@ -13806,7 +14182,7 @@ check_reverse_order:
and best_key doesn't, then revert the decision.
*/
if (!table->covering_keys.is_set(best_key))
- table->set_keyread(FALSE);
+ table->disable_keyread();
if (!quick_created)
{
if (select) // Throw any existing quick select
@@ -13817,8 +14193,8 @@ check_reverse_order:
join_read_first:join_read_last;
tab->type=JT_NEXT; // Read with index_first(), index_next()
- if (table->covering_keys.is_set(best_key))
- table->set_keyread(TRUE);
+ if (table->covering_keys.is_set(best_key) && ! table->key_read)
+ table->enable_keyread();
table->file->ha_index_or_rnd_end();
if (tab->join->select_options & SELECT_DESCRIBE)
{
@@ -13995,7 +14371,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
and in index_merge 'Only index' cannot be used
*/
if (((uint) tab->ref.key != select->quick->index))
- table->set_keyread(FALSE);
+ table->disable_keyread();
}
else
{
@@ -14051,7 +14427,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
tab->type=JT_ALL; // Read with normal read_record
tab->read_first_record= join_init_read_record;
tab->join->examined_rows+=examined_rows;
- table->set_keyread(FALSE); // Restore if we used indexes
+ table->disable_keyread(); // Restore if we used indexes
DBUG_RETURN(table->sort.found_records == HA_POS_ERROR);
err:
DBUG_RETURN(-1);
@@ -14254,13 +14630,14 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
else if (!found)
{
found=1;
- file->position(record); // Remember position
+ if ((error= file->remember_rnd_pos()))
+ goto err;
}
}
if (!found)
break; // End of file
- /* Restart search on next row */
- error=file->restart_rnd_next(record,file->ref);
+ /* Restart search on saved row */
+ error=file->restart_rnd_next(record);
}
file->extra(HA_EXTRA_NO_CACHE);
@@ -14595,12 +14972,15 @@ store_record_in_cache(JOIN_CACHE *cache)
{
uchar *str,*end;
Field *field= copy->field;
- if (field && field->maybe_null() && field->is_null())
+ if (field && field->is_null())
end= str= copy->str;
else
+ {
for (str=copy->str,end= str+copy->length;
end > str && end[-1] == ' ' ;
- end--) ;
+ end--)
+ ;
+ }
length=(uint) (end-str);
memcpy(pos+2, str, length);
int2store(pos, length);
@@ -14815,8 +15195,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
/* Lookup the current GROUP field in the FROM clause. */
order_item_type= order_item->type();
from_field= (Field*) not_found_field;
- if ((is_group_field &&
- order_item_type == Item::FIELD_ITEM) ||
+ if ((is_group_field && order_item_type == Item::FIELD_ITEM) ||
order_item_type == Item::REF_ITEM)
{
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
@@ -14876,30 +15255,12 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
time.
We check order_item->fixed because Item_func_group_concat can put
- arguments for which fix_fields already was called.
-
- group_fix_field= TRUE is to resolve aliases from the SELECT list
- without creating of Item_ref-s: JOIN::exec() wraps aliased items
- in SELECT list with Item_copy items. To re-evaluate such a tree
- that includes Item_copy items we have to refresh Item_copy caches,
- but:
- - filesort() never refresh Item_copy items,
- - end_send_group() checks every record for group boundary by the
- test_if_group_changed function that obtain data from these
- Item_copy items, but the copy_fields function that
- refreshes Item copy items is called after group boundaries only -
- that is a vicious circle.
- So we prevent inclusion of Item_copy items.
+ arguments for which fix_fields already was called.
*/
- bool save_group_fix_field= thd->lex->current_select->group_fix_field;
- if (is_group_field)
- thd->lex->current_select->group_fix_field= TRUE;
- bool ret= (!order_item->fixed &&
+ if (!order_item->fixed &&
(order_item->fix_fields(thd, order->item) ||
(order_item= *order->item)->check_cols(1) ||
- thd->is_fatal_error));
- thd->lex->current_select->group_fix_field= save_group_fix_field;
- if (ret)
+ thd->is_fatal_error))
return TRUE; /* Wrong field. */
uint el= all_fields.elements;
@@ -14971,6 +15332,8 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
uint org_fields=all_fields.elements;
thd->where="group statement";
+ enum_parsing_place save_place= thd->lex->current_select->parsing_place;
+ thd->lex->current_select->parsing_place= IN_GROUP_BY;
for (ord= order; ord; ord= ord->next)
{
if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
@@ -14983,6 +15346,8 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
return 1;
}
}
+ thd->lex->current_select->parsing_place= save_place;
+
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
{
/*
@@ -15517,7 +15882,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
pos= item;
if (item->field->flags & BLOB_FLAG)
{
- if (!(pos= Item_copy::create(pos)))
+ if (!(pos= new Item_copy_string(pos)))
goto err;
/*
Item_copy_string::copy for function can call
@@ -15551,7 +15916,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
DBUG_ASSERT (param->field_count > (uint) (copy - copy_start));
copy->set(tmp, item->result_field);
item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
copy->to_ptr[copy->from_length]= 0;
#endif
copy++;
@@ -15571,7 +15936,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
on how the value is to be used: In some cases this may be an
argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
*/
- if (!(pos= Item_copy::create(pos)))
+ if (!(pos=new Item_copy_string(pos)))
goto err;
if (i < border) // HAVING, ORDER and GROUP BY
{
@@ -15624,8 +15989,8 @@ copy_fields(TMP_TABLE_PARAM *param)
(*ptr->do_copy)(ptr);
List_iterator_fast<Item> it(param->copy_funcs);
- Item_copy *item;
- while ((item = (Item_copy*) it++))
+ Item_copy_string *item;
+ while ((item = (Item_copy_string*) it++))
item->copy();
}
@@ -16023,7 +16388,11 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
DBUG_RETURN(TRUE);
if (!cond->fixed)
- cond->fix_fields(thd, (Item**)&cond);
+ {
+ Item *tmp_item= (Item*) cond;
+ cond->fix_fields(thd, &tmp_item);
+ DBUG_ASSERT(cond == tmp_item);
+ }
if (join_tab->select)
{
if (join_tab->select->cond)
@@ -16135,6 +16504,7 @@ static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
if (arg_changed)
{
expr->maybe_null= 1;
+ expr->in_rollup= 1;
*changed= TRUE;
}
}
@@ -16198,6 +16568,7 @@ bool JOIN::rollup_init()
if (*group_tmp->item == item)
{
item->maybe_null= 1;
+ item->in_rollup= 1;
found_in_group= 1;
break;
}
@@ -16428,6 +16799,7 @@ int JOIN::rollup_send_data(uint idx)
uint i;
for (i= send_group_parts ; i-- > idx ; )
{
+ int res= 0;
/* Get reference pointers to sum functions in place */
memcpy((char*) ref_pointer_array,
(char*) rollup.ref_pointer_arrays[i],
@@ -16435,9 +16807,10 @@ int JOIN::rollup_send_data(uint idx)
if ((!having || having->val_int()))
{
if (send_records < unit->select_limit_cnt && do_send_rows &&
- result->send_data(rollup.fields[i]))
+ (res= result->send_data(rollup.fields[i])) > 0)
return 1;
- send_records++;
+ if (!res)
+ send_records++;
}
}
/* Restore ref_pointer_array */
@@ -16487,7 +16860,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
{
- if (create_myisam_from_heap(thd, table_arg, &tmp_table_param,
+ if (create_internal_tmp_table_from_heap(thd, table_arg, &tmp_table_param,
write_error, 0))
return 1;
}
@@ -16570,7 +16943,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
the UNION to provide precise EXPLAIN information will hardly be
appreciated :)
*/
- char table_name_buffer[NAME_LEN];
+ char table_name_buffer[SAFE_NAME_LEN];
item_list.empty();
/* id */
item_list.push_back(new Item_null);
@@ -16643,7 +17016,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
char buff1[512], buff2[512], buff3[512];
char keylen_str_buf[64];
String extra(buff, sizeof(buff),cs);
- char table_name_buffer[NAME_LEN];
+ char table_name_buffer[SAFE_NAME_LEN];
String tmp1(buff1,sizeof(buff1),cs);
String tmp2(buff2,sizeof(buff2),cs);
String tmp3(buff3,sizeof(buff3),cs);
@@ -16653,6 +17026,14 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
tmp3.length(0);
quick_type= -1;
+
+ /* Don't show eliminated tables */
+ if (table->map & join->eliminated_tables)
+ {
+ used_tables|=table->map;
+ continue;
+ }
+
item_list.empty();
/* id */
item_list.push_back(new Item_uint((uint32)
@@ -16983,8 +17364,11 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
unit;
unit= unit->next_unit())
{
- if (mysql_explain_union(thd, unit, result))
- DBUG_VOID_RETURN;
+ if (!(unit->item && unit->item->eliminated))
+ {
+ if (mysql_explain_union(thd, unit, result))
+ DBUG_VOID_RETURN;
+ }
}
DBUG_VOID_RETURN;
}
@@ -17025,7 +17409,6 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
unit->fake_select_lex->options|= SELECT_DESCRIBE;
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
res= unit->exec();
- res|= unit->cleanup();
}
else
{
@@ -17058,6 +17441,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
*/
static void print_join(THD *thd,
+ table_map eliminated_tables,
String *str,
List<TABLE_LIST> *tables,
enum_query_type query_type)
@@ -17073,12 +17457,33 @@ static void print_join(THD *thd,
*t= ti++;
DBUG_ASSERT(tables->elements >= 1);
- (*table)->print(thd, str, query_type);
+ /*
+ Assert that the first table in the list isn't eliminated. This comes from
+ the fact that the first table can't be inner table of an outer join.
+ */
+ DBUG_ASSERT(!eliminated_tables ||
+ !(((*table)->table && ((*table)->table->map & eliminated_tables)) ||
+ ((*table)->nested_join && !((*table)->nested_join->used_tables &
+ ~eliminated_tables))));
+ (*table)->print(thd, eliminated_tables, str, query_type);
TABLE_LIST **end= table + tables->elements;
for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
{
TABLE_LIST *curr= *tbl;
+ /*
+ The "eliminated_tables &&" check guards againist the case of
+ printing the query for CREATE VIEW. We do that without having run
+ JOIN::optimize() and so will have nested_join->used_tables==0.
+ */
+ if (eliminated_tables &&
+ ((curr->table && (curr->table->map & eliminated_tables)) ||
+ (curr->nested_join && !(curr->nested_join->used_tables &
+ ~eliminated_tables))))
+ {
+ continue;
+ }
+
if (curr->outer_join)
{
/* MySQL converts right to left joins */
@@ -17088,7 +17493,7 @@ static void print_join(THD *thd,
str->append(STRING_WITH_LEN(" straight_join "));
else
str->append(STRING_WITH_LEN(" join "));
- curr->print(thd, str, query_type);
+ curr->print(thd, eliminated_tables, str, query_type);
if (curr->on_expr)
{
str->append(STRING_WITH_LEN(" on("));
@@ -17142,12 +17547,13 @@ Index_hint::print(THD *thd, String *str)
@param str string where table should be printed
*/
-void TABLE_LIST::print(THD *thd, String *str, enum_query_type query_type)
+void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
+ enum_query_type query_type)
{
if (nested_join)
{
str->append('(');
- print_join(thd, str, &nested_join->join_list, query_type);
+ print_join(thd, eliminated_tables, str, &nested_join->join_list, query_type);
str->append(')');
}
else
@@ -17279,7 +17685,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
else
str->append(',');
- if (master_unit()->item && item->is_autogenerated_name)
+ if (is_subquery_function() && item->is_autogenerated_name)
{
/*
Do not print auto-generated aliases in subqueries. It has no purpose
@@ -17299,7 +17705,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
{
str->append(STRING_WITH_LEN(" from "));
/* go through join tree */
- print_join(thd, str, &top_join_list, query_type);
+ print_join(thd, join? join->eliminated_tables: 0, str, &top_join_list, query_type);
}
else if (where)
{
diff --git a/sql/sql_select.h b/sql/sql_select.h
index bb644a94906..1d1a023d9cf 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -154,7 +155,9 @@ typedef struct st_join_table {
TABLE *table;
KEYUSE *keyuse; /**< pointer to first used key */
SQL_SELECT *select;
- COND *select_cond;
+ COND *select_cond;
+ COND *on_precond; /**< part of on condition to check before
+ accessing the first inner table */
QUICK_SELECT_I *quick;
Item **on_expr_ref; /**< pointer to the associated on expression */
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
@@ -303,7 +306,15 @@ public:
fetching data from a cursor
*/
bool resume_nested_loop;
- table_map const_table_map,found_const_table_map;
+ table_map const_table_map;
+ /*
+ Constant tables for which we have found a row (as opposed to those for
+ which we didn't).
+ */
+ table_map found_const_table_map;
+
+ /* Tables removed by table elimination. Set to 0 before the elimination. */
+ table_map eliminated_tables;
/*
Bitmap of all inner tables from outer joins
*/
@@ -357,24 +368,31 @@ public:
the number of rows in it may vary from one subquery execution to another.
*/
bool no_const_tables;
+ /*
+ This flag is set if we call no_rows_in_result() as par of end_group().
+ This is used as a simple speed optimization to avoiding calling
+ restore_no_rows_in_result() in ::reinit()
+ */
+ bool no_rows_in_result_called;
/**
Copy of this JOIN to be used with temporary tables.
- tmp_join is used when the JOIN needs to be "reusable" (e.g. in a subquery
- that gets re-executed several times) and we know will use temporary tables
- for materialization. The materialization to a temporary table overwrites the
- JOIN structure to point to the temporary table after the materialization is
- done. This is where tmp_join is used : it's a copy of the JOIN before the
- materialization and is used in restoring before re-execution by overwriting
- the current JOIN structure with the saved copy.
- Because of this we should pay extra care of not freeing up helper structures
- that are referenced by the original contents of the JOIN. We can check for
- this by making sure the "current" join is not the temporary copy, e.g.
- !tmp_join || tmp_join != join
+ tmp_join is used when the JOIN needs to be "reusable" (e.g. in a
+ subquery that gets re-executed several times) and we know will use
+ temporary tables for materialization. The materialization to a
+ temporary table overwrites the JOIN structure to point to the
+ temporary table after the materialization is done. This is where
+ tmp_join is used : it's a copy of the JOIN before the
+ materialization and is used in restoring before re-execution by
+ overwriting the current JOIN structure with the saved copy.
+ Because of this we should pay extra care of not freeing up helper
+ structures that are referenced by the original contents of the
+ JOIN. We can check for this by making sure the "current" join is
+ not the temporary copy, e.g. !tmp_join || tmp_join != join
- We should free these sub-structures at JOIN::destroy() if the "current" join
- has a copy is not that copy.
+ We should free these sub-structures at JOIN::destroy() if the
+ "current" join has a copy is not that copy.
*/
JOIN *tmp_join;
ROLLUP rollup; ///< Used with rollup
@@ -463,6 +481,7 @@ public:
table= 0;
tables= 0;
const_tables= 0;
+ eliminated_tables= 0;
join_list= 0;
implicit_grouping= FALSE;
sort_and_group= 0;
@@ -503,6 +522,7 @@ public:
optimized= 0;
cond_equal= 0;
group_optimized_away= 0;
+ no_rows_in_result_called= 0;
all_fields= fields_arg;
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
@@ -570,6 +590,10 @@ public:
return (unit == &thd->lex->unit && (unit->fake_select_lex == 0 ||
select_lex == unit->fake_select_lex));
}
+ inline table_map all_tables_map()
+ {
+ return (table_map(1) << tables) - 1;
+ }
private:
/**
TRUE if the query contains an aggregate function but has no GROUP
@@ -603,7 +627,7 @@ bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
uint elements, List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param);
bool copy_funcs(Item **func_ptr, const THD *thd);
-bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
+bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
int error, bool ignore_last_dupp_error);
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
Field* create_tmp_field_from_field(THD *thd, Field* org_field,
@@ -790,9 +814,12 @@ bool error_if_full_join(JOIN *join);
int report_error(TABLE *table, int error);
int safe_index_read(JOIN_TAB *tab);
COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value);
+void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key);
inline bool optimizer_flag(THD *thd, uint flag)
{
return (thd->variables.optimizer_switch & flag);
}
+void eliminate_tables(JOIN *join);
+
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index da77bf329b1..bb9a4a1e062 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -75,6 +76,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
grant_names, NULL};
#endif
+/* Match the values of enum ha_choice */
+static const char *ha_choice_values[] = {"", "0", "1"};
+
static void store_key_options(THD *thd, String *packet, TABLE *table,
KEY *key_info);
@@ -110,7 +114,6 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin,
make_version_string(version_buf, sizeof(version_buf), plug->version),
cs);
-
switch (plugin_state(plugin)) {
/* case PLUGIN_IS_FREED: does not happen */
case PLUGIN_IS_DELETED:
@@ -171,15 +174,15 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin,
switch (plug->license) {
case PLUGIN_LICENSE_GPL:
- table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
+ table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
strlen(PLUGIN_LICENSE_GPL_STRING), cs);
break;
case PLUGIN_LICENSE_BSD:
- table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
+ table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
strlen(PLUGIN_LICENSE_BSD_STRING), cs);
break;
default:
- table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
+ table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
break;
}
@@ -478,8 +481,6 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
wild_length= strlen(wild);
}
-
-
bzero((char*) &table_list,sizeof(table_list));
if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
@@ -493,11 +494,11 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
{
- char uname[NAME_LEN + 1]; /* Unencoded name */
+ char uname[SAFE_NAME_LEN + 1]; /* Unencoded name */
file=dirp->dir_entry+i;
if (dir)
{ /* Return databases */
- if ((file->name[0] == '.' &&
+ if ((file->name[0] == '.' &&
((file->name[1] == '.' && file->name[2] == '\0') ||
file->name[1] == '\0')))
continue; /* . or .. */
@@ -528,7 +529,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
if (my_wildcmp(files_charset_info,
uname, uname + file_name_len,
wild, wild + wild_length,
- wild_prefix, wild_one,wild_many))
+ wild_prefix, wild_one, wild_many))
continue;
}
else if (wild_compare(uname, wild, 0))
@@ -570,7 +571,7 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
continue;
}
#endif
- if (!(file_name=
+ if (!(file_name=
thd->make_lex_string(file_name, uname, file_name_len, TRUE)) ||
files->push_back(file_name))
{
@@ -906,7 +907,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
Field **ptr,*field;
for (ptr=table->field ; (field= *ptr); ptr++)
{
- if (!wild || !wild[0] ||
+ if (!wild || !wild[0] ||
!wild_case_compare(system_charset_info, field->field_name,wild))
{
if (table_list->view)
@@ -1117,11 +1118,11 @@ static bool get_field_default_value(THD *thd, TABLE *table,
bool has_default;
bool has_now_default;
enum enum_field_types field_type= field->type();
- /*
- We are using CURRENT_TIMESTAMP instead of NOW because it is
- more standard
+ /*
+ We are using CURRENT_TIMESTAMP instead of NOW because it is
+ more standard
*/
- has_now_default= table->timestamp_field == field &&
+ has_now_default= table->timestamp_field == field &&
field->unireg_check != Field::TIMESTAMP_UN_FIELD;
has_default= (field_type != FIELD_TYPE_BLOB &&
@@ -1145,7 +1146,7 @@ static bool get_field_default_value(THD *thd, TABLE *table,
char *ptr= longlong2str(dec, tmp + 2, 2);
uint32 length= (uint32) (ptr - tmp);
tmp[0]= 'b';
- tmp[1]= '\'';
+ tmp[1]= '\'';
tmp[length]= '\'';
type.length(length + 1);
quoted= 0;
@@ -1190,11 +1191,11 @@ static bool get_field_default_value(THD *thd, TABLE *table,
to tailor the format of the statement. Can be
NULL, in which case only SQL_MODE is considered
when building the statement.
-
+
NOTE
Currently always return 0, but might return error code in the
future.
-
+
RETURN
0 OK
*/
@@ -1214,7 +1215,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
handler *file= table->file;
TABLE_SHARE *share= table->s;
HA_CREATE_INFO create_info;
- bool show_table_options= FALSE;
+ bool show_table_options __attribute__ ((unused))= FALSE;
bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
MODE_ORACLE |
MODE_MSSQL |
@@ -1295,7 +1296,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
field->sql_type(type);
packet->append(type.ptr(), type.length(), system_charset_info);
- if (field->has_charset() &&
+ if (field->has_charset() &&
!(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
{
if (field->charset() != share->table_charset)
@@ -1303,8 +1304,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
packet->append(field->charset()->csname);
}
- /*
- For string types dump collation name only if
+ /*
+ For string types dump collation name only if
collation is not primary for the given charset
*/
if (!(field->charset()->state & MY_CS_PRIMARY))
@@ -1331,11 +1332,11 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
}
- if (!limited_mysql_mode && table->timestamp_field == field &&
+ if (!limited_mysql_mode && table->timestamp_field == field &&
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
- if (field->unireg_check == Field::NEXT_NUMBER &&
+ if (field->unireg_check == Field::NEXT_NUMBER &&
!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
@@ -1348,8 +1349,10 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
key_info= table->key_info;
bzero((char*) &create_info, sizeof(create_info));
- /* Allow update_create_info to update row type */
+ /* Allow update_create_info to update row type, page checksums and options */
create_info.row_type= share->row_type;
+ create_info.page_checksum= share->page_checksum;
+ create_info.options= share->db_create_options;
file->update_create_info(&create_info);
primary_key= share->primary_key;
@@ -1429,7 +1432,9 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN("\n)"));
if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
{
+#ifdef WITH_PARTITION_STORAGE_ENGINE
show_table_options= TRUE;
+#endif
/*
Get possible table space definitions and append them
to the CREATE TABLE statement
@@ -1484,7 +1489,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(buff, (uint) (end - buff));
}
-
+
if (share->table_charset &&
!(thd->variables.sql_mode & MODE_MYSQL323) &&
!(thd->variables.sql_mode & MODE_MYSQL40))
@@ -1530,20 +1535,30 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(buff, (uint) (end - buff));
}
- if (share->db_create_options & HA_OPTION_PACK_KEYS)
+ if (create_info.options & HA_OPTION_PACK_KEYS)
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
- if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
+ if (create_info.options & HA_OPTION_NO_PACK_KEYS)
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
- if (share->db_create_options & HA_OPTION_CHECKSUM)
+ if (create_info.options & HA_OPTION_CHECKSUM)
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
- if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
+ if (create_info.page_checksum != HA_CHOICE_UNDEF)
+ {
+ packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
+ packet->append(ha_choice_values[create_info.page_checksum], 1);
+ }
+ if (create_info.options & HA_OPTION_DELAY_KEY_WRITE)
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
if (create_info.row_type != ROW_TYPE_DEFAULT)
{
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
packet->append(ha_row_type[(uint) create_info.row_type]);
}
+ if (share->transactional != HA_CHOICE_UNDEF)
+ {
+ packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
+ packet->append(ha_choice_values[(uint) share->transactional], 1);
+ }
if (table->s->key_block_size)
{
char *end;
@@ -1645,7 +1660,7 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
/*
Append DEFINER clause to the given buffer.
-
+
SYNOPSIS
append_definer()
thd [in] thread handle
@@ -1674,7 +1689,7 @@ static void append_algorithm(TABLE_LIST *table, String *buff)
/*
Append DEFINER clause to the given buffer.
-
+
SYNOPSIS
append_definer()
thd [in] thread handle
@@ -1839,12 +1854,13 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
"%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
}
else
- thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
- tmp_sctx->host_or_ip :
+ thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
+ tmp_sctx->host_or_ip :
tmp_sctx->host ? tmp_sctx->host : "");
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
if ((mysys_var= tmp->mysys_var))
pthread_mutex_lock(&mysys_var->mutex);
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
@@ -1864,6 +1880,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
#endif
if (mysys_var)
pthread_mutex_unlock(&mysys_var->mutex);
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
thd_info->start_time= tmp->start_time;
thd_info->query=0;
@@ -1912,7 +1929,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info;
char *user;
- time_t now= my_time(0);
+ ulonglong unow= my_micro_time();
DBUG_ENTER("fill_process_list");
user= thd->security_ctx->master_access & PROCESS_ACL ?
@@ -1970,8 +1987,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[4]->store(command_name[tmp->command].str,
command_name[tmp->command].length, cs);
/* MYSQL_TIME */
- table->field[5]->store((longlong)(tmp->start_time ?
- now - tmp->start_time : 0), FALSE);
+ const ulonglong utime= tmp->start_utime ? unow - tmp->start_utime : 0;
+ table->field[5]->store(utime / 1000000, TRUE);
/* STATE */
#ifndef EMBEDDED_LIBRARY
val= (char*) (tmp->locked ? "Locked" :
@@ -2008,6 +2025,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
}
pthread_mutex_unlock(&tmp->LOCK_thd_data);
+ /* TIME_MS */
+ table->field[8]->store((double)(utime / 1000.0));
+
if (schema_table_store_record(thd, table))
{
VOID(pthread_mutex_unlock(&LOCK_thread_count));
@@ -2117,7 +2137,7 @@ void reset_status_vars()
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
if (ptr->type == SHOW_LONG)
*(ulong*) ptr->value= 0;
- }
+ }
}
/*
@@ -2221,7 +2241,7 @@ static bool show_status_array(THD *thd, const char *wild,
CHARSET_INFO *charset= system_charset_info;
DBUG_ENTER("show_status_array");
- thd->count_cuted_fields= CHECK_FIELD_WARN;
+ thd->count_cuted_fields= CHECK_FIELD_WARN;
null_lex_str.str= 0; // For sys_var->value_ptr()
null_lex_str.length= 0;
@@ -2264,7 +2284,6 @@ static bool show_status_array(THD *thd, const char *wild,
const char *pos, *end; // We assign a lot of const's
pthread_mutex_lock(&LOCK_global_system_variables);
-
if (show_type == SHOW_SYS)
{
sys_var *var= ((sys_var *) value);
@@ -2280,20 +2299,20 @@ static bool show_status_array(THD *thd, const char *wild,
*/
switch (show_type) {
case SHOW_DOUBLE_STATUS:
- value= ((char *) status_var + (ulong) value);
+ value= ((char *) status_var + (intptr) value);
/* fall through */
case SHOW_DOUBLE:
- end= buff + sprintf(buff, "%f", *(double*) value);
+ end= buff + my_sprintf(buff, (buff, "%f", *(double*) value));
break;
case SHOW_LONG_STATUS:
- value= ((char *) status_var + (ulong) value);
+ value= ((char *) status_var + (intptr) value);
/* fall through */
case SHOW_LONG:
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
end= int10_to_str(*(long*) value, buff, 10);
break;
case SHOW_LONGLONG_STATUS:
- value= ((char *) status_var + (ulonglong) value);
+ value= ((char *) status_var + (intptr) value);
/* fall through */
case SHOW_LONGLONG:
end= longlong10_to_str(*(longlong*) value, buff, 10);
@@ -2346,12 +2365,11 @@ static bool show_status_array(THD *thd, const char *wild,
DBUG_ASSERT(0);
break;
}
+ pthread_mutex_unlock(&LOCK_global_system_variables);
table->field[1]->store(pos, (uint32) (end - pos), charset);
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
table->field[1]->set_notnull();
- pthread_mutex_unlock(&LOCK_global_system_variables);
-
if (schema_table_store_record(thd, table))
{
res= TRUE;
@@ -2377,14 +2395,14 @@ void calc_sum_of_all_status(STATUS_VAR *to)
I_List_iterator<THD> it(threads);
THD *tmp;
-
+
/* Get global values as base */
*to= global_status_var;
-
+
/* Add to this status from existing threads */
while ((tmp= it++))
add_to_status(to, &tmp->status_var);
-
+
VOID(pthread_mutex_unlock(&LOCK_thread_count));
DBUG_VOID_RETURN;
}
@@ -2419,7 +2437,7 @@ bool schema_table_store_record(THD *thd, TABLE *table)
int error;
if ((error= table->file->ha_write_row(table->record[0])))
{
- if (create_myisam_from_heap(thd, table,
+ if (create_internal_tmp_table_from_heap(thd, table,
table->pos_in_table_list->schema_table_param,
error, 0))
return 1;
@@ -2440,17 +2458,17 @@ static int make_table_list(THD *thd, SELECT_LEX *sel,
/**
- @brief Get lookup value from the part of 'WHERE' condition
+ @brief Get lookup value from the part of 'WHERE' condition
- @details This function gets lookup value from
- the part of 'WHERE' condition if it's possible and
+ @details This function gets lookup value from
+ the part of 'WHERE' condition if it's possible and
fill appropriate lookup_field_vals struct field
with this value.
@param[in] thd thread handler
@param[in] item_func part of WHERE condition
@param[in] table I_S table
- @param[in, out] lookup_field_vals Struct which holds lookup values
+ @param[in, out] lookup_field_vals Struct which holds lookup values
@return
0 success
@@ -2458,7 +2476,7 @@ static int make_table_list(THD *thd, SELECT_LEX *sel,
*/
bool get_lookup_value(THD *thd, Item_func *item_func,
- TABLE_LIST *table,
+ TABLE_LIST *table,
LOOKUP_FIELD_VALUES *lookup_field_vals)
{
ST_SCHEMA_TABLE *schema_table= table->schema_table;
@@ -2524,16 +2542,16 @@ bool get_lookup_value(THD *thd, Item_func *item_func,
/**
- @brief Calculates lookup values from 'WHERE' condition
+ @brief Calculates lookup values from 'WHERE' condition
@details This function calculates lookup value(database name, table name)
- from 'WHERE' condition if it's possible and
+ from 'WHERE' condition if it's possible and
fill lookup_field_vals struct fields with these values.
@param[in] thd thread handler
@param[in] cond WHERE condition
@param[in] table I_S table
- @param[in, out] lookup_field_vals Struct which holds lookup values
+ @param[in, out] lookup_field_vals Struct which holds lookup values
@return
0 success
@@ -2682,7 +2700,7 @@ static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
@param[in] thd thread handler
@param[in] cond WHERE condition
@param[in] tables I_S table
- @param[in, out] lookup_field_values Struct which holds lookup values
+ @param[in, out] lookup_field_values Struct which holds lookup values
@return
0 success
@@ -2762,7 +2780,7 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
idx_field_vals idx_field_vals->db_name contains db name or
wild string
with_i_schema returns 1 if we added 'IS' name to list
- otherwise returns 0
+ otherwise returns 0
RETURN
zero success
@@ -2786,7 +2804,7 @@ int make_db_list(THD *thd, List<LEX_STRING> *files,
LIKE clause (see also get_index_field_values() function)
*/
if (!lookup_field_vals->db_value.str ||
- !wild_case_compare(system_charset_info,
+ !wild_case_compare(system_charset_info,
INFORMATION_SCHEMA_NAME.str,
lookup_field_vals->db_value.str))
{
@@ -2830,7 +2848,7 @@ int make_db_list(THD *thd, List<LEX_STRING> *files,
}
-struct st_add_schema_table
+struct st_add_schema_table
{
List<LEX_STRING> *files;
const char *wild;
@@ -2894,7 +2912,7 @@ int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
continue;
}
- if ((file_name=
+ if ((file_name=
thd->make_lex_string(file_name, tmp_schema_table->table_name,
strlen(tmp_schema_table->table_name), TRUE)) &&
!files->push_back(file_name))
@@ -2956,7 +2974,7 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
}
}
else
- {
+ {
if (table_names->push_back(&lookup_field_vals->table_value))
return 1;
/*
@@ -3033,6 +3051,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
LEX_STRING db_name, table_name;
TABLE_LIST *table_list;
bool result= true;
+ DBUG_ENTER("fill_schema_table_by_open");
/*
When a view is opened its structures are allocated on a permanent
@@ -3110,11 +3129,9 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
Let us set fake sql_command so views won't try to merge
themselves into main statement. If we don't do this,
SELECT * from information_schema.xxxx will cause problems.
- SQLCOM_SHOW_FIELDS is used because it satisfies
- 'only_view_structure()'.
+ SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
*/
lex->sql_command= SQLCOM_SHOW_FIELDS;
-
result= open_normal_and_derived_tables(thd, table_list,
MYSQL_LOCK_IGNORE_FLUSH);
@@ -3174,7 +3191,7 @@ end:
thd->stmt_arena= old_arena;
thd->restore_active_arena(&i_s_arena, &backup_arena);
- return result;
+ DBUG_RETURN(result);
}
@@ -3303,7 +3320,7 @@ uint get_table_open_method(TABLE_LIST *tables,
*/
static int fill_schema_table_from_frm(THD *thd,TABLE *table,
- ST_SCHEMA_TABLE *schema_table,
+ ST_SCHEMA_TABLE *schema_table,
LEX_STRING *db_name,
LEX_STRING *table_name,
enum enum_schema_tables schema_table_idx)
@@ -3330,7 +3347,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table,
res= 0;
goto err;
}
-
+
if (share->is_view)
{
if (schema_table->i_s_requested_object & OPEN_TABLE_ONLY)
@@ -3342,7 +3359,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table,
else if (schema_table->i_s_requested_object & OPEN_VIEW_FULL)
{
/*
- tell get_all_tables() to fall back to
+ tell get_all_tables() to fall back to
open_normal_and_derived_tables()
*/
res= 1;
@@ -3423,7 +3440,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
*/
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
- /*
+ /*
this branch processes SHOW FIELDS, SHOW INDEXES commands.
see sql_parse.cc, prepare_schema_table() function where
this values are initialized
@@ -3458,7 +3475,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
{
- /*
+ /*
if lookup value is empty string then
it's impossible table name or db name
*/
@@ -3476,7 +3493,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
!lookup_field_vals.wild_db_value)
tables->has_db_lookup_value= TRUE;
if (lookup_field_vals.table_value.length &&
- !lookup_field_vals.wild_table_value)
+ !lookup_field_vals.wild_table_value)
tables->has_table_lookup_value= TRUE;
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
@@ -3530,7 +3547,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
{
/*
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
- we can skip table opening and we don't have lookup value for
+ we can skip table opening and we don't have lookup value for
table name or lookup value is wild string(table name list is
already created by make_table_name_list() function).
*/
@@ -3552,7 +3569,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
}
else
{
- if (!(table_open_method & ~OPEN_FRM_ONLY) &&
+ if (!(table_open_method & ~OPEN_FRM_ONLY) &&
!with_i_schema)
{
if (!fill_schema_table_from_frm(thd, table, schema_table, db_name,
@@ -3563,7 +3580,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
thd->no_warnings_for_error= 1;
DEBUG_SYNC(thd, "before_open_in_get_all_tables");
-
if (fill_schema_table_by_open(thd, FALSE,
table, schema_table,
db_name, table_name,
@@ -3619,9 +3635,9 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
DBUG_RETURN(0);
- DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
- lookup_field_vals.db_value.str,
- lookup_field_vals.table_value.str));
+ DBUG_PRINT("INDEX VALUES",("db_name: %s table_name: %s",
+ val_or_null(lookup_field_vals.db_value.str),
+ val_or_null(lookup_field_vals.table_value.str)));
if (make_db_list(thd, &db_names, &lookup_field_vals,
&with_i_schema))
DBUG_RETURN(1);
@@ -3762,23 +3778,29 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
if (share->db_create_options & HA_OPTION_CHECKSUM)
ptr=strmov(ptr," checksum=1");
+ if (share->page_checksum != HA_CHOICE_UNDEF)
+ ptr= strxmov(ptr, " page_checksum=",
+ ha_choice_values[(uint) share->page_checksum], NullS);
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
ptr=strmov(ptr," delay_key_write=1");
if (share->row_type != ROW_TYPE_DEFAULT)
- ptr=strxmov(ptr, " row_format=",
+ ptr=strxmov(ptr, " row_format=",
ha_row_type[(uint) share->row_type],
NullS);
if (share->key_block_size)
{
- ptr= strmov(ptr, " KEY_BLOCK_SIZE=");
+ ptr= strmov(ptr, " key_block_size=");
ptr= longlong10_to_str(share->key_block_size, ptr, 10);
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (is_partitioned)
ptr= strmov(ptr, " partitioned");
#endif
+ if (share->transactional != HA_CHOICE_UNDEF)
+ ptr= strxmov(ptr, " transactional=",
+ ha_choice_values[(uint) share->transactional], NullS);
table->field[19]->store(option_buff+1,
- (ptr == option_buff ? 0 :
+ (ptr == option_buff ? 0 :
(uint) (ptr-option_buff)-1), cs);
tmp_buff= (share->table_charset ?
@@ -3821,7 +3843,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
tmp_buff= "Compact";
break;
case ROW_TYPE_PAGE:
- tmp_buff= "Paged";
+ tmp_buff= "Page";
break;
}
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
@@ -3866,7 +3888,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
table->field[16]->set_notnull();
}
- if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
+ if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
{
table->field[18]->store((longlong) file->checksum(), TRUE);
table->field[18]->set_notnull();
@@ -3917,7 +3939,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
/*
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
rather than in SHOW COLUMNS
- */
+ */
if (thd->is_error())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
thd->main_da.sql_errno(), thd->main_da.message());
@@ -3955,7 +3977,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
uint col_access;
check_access(thd,SELECT_ACL | EXTRA_ACL, db_name->str,
&tables->grant.privilege, 0, 0, test(tables->schema_table));
- col_access= get_column_grant(thd, &tables->grant,
+ col_access= get_column_grant(thd, &tables->grant,
db_name->str, table_name->str,
field->field_name) & COL_ACLS;
if (!tables->schema_table && !col_access)
@@ -3984,7 +4006,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
base_type [(dimension)] [unsigned] [zerofill].
For DATA_TYPE column we extract only base type.
*/
- tmp_buff= strchr(type.ptr(), '(');
+ tmp_buff= strchr(type.c_ptr_safe(), '(');
if (!tmp_buff)
/*
if there is no dimention part then check the presence of
@@ -4011,7 +4033,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
uint32 octet_max_length= field->max_display_length();
if (is_blob && octet_max_length != (uint32) 4294967295U)
octet_max_length /= field->charset()->mbmaxlen;
- longlong char_max_len= is_blob ?
+ longlong char_max_len= is_blob ?
(longlong) octet_max_length / field->charset()->mbminlen :
(longlong) octet_max_length / field->charset()->mbmaxlen;
table->field[8]->store(char_max_len, TRUE);
@@ -4047,7 +4069,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
field_length= field->max_display_length();
decimals= -1; // return NULL
break;
- case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
field_length= field->field_length;
if (decimals == NOT_FIXED_DEC)
@@ -4112,7 +4134,7 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
{
CHARSET_INFO *tmp_cs= cs[0];
- if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
+ if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
(tmp_cs->state & MY_CS_AVAILABLE) &&
!(tmp_cs->state & MY_CS_HIDDEN) &&
!(wild && wild[0] &&
@@ -4225,7 +4247,7 @@ int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
{
CHARSET_INFO *tmp_cl= cl[0];
- if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
+ if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
!my_charset_same(tmp_cs, tmp_cl))
continue;
if (!(wild && wild[0] &&
@@ -4259,13 +4281,13 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
{
CHARSET_INFO **cl;
CHARSET_INFO *tmp_cs= cs[0];
- if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
+ if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
!(tmp_cs->state & MY_CS_PRIMARY))
continue;
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
{
CHARSET_INFO *tmp_cl= cl[0];
- if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
+ if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
!my_charset_same(tmp_cs,tmp_cl))
continue;
restore_record(table, s->default_values);
@@ -4294,7 +4316,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
MYSQL_TIME time;
LEX *lex= thd->lex;
CHARSET_INFO *cs= system_charset_info;
- char sp_db_buff[NAME_LEN + 1], sp_name_buff[NAME_LEN + 1],
+ char sp_db_buff[SAFE_NAME_LEN + 1], sp_name_buff[SAFE_NAME_LEN + 1],
definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 2];
String sp_db(sp_db_buff, sizeof(sp_db_buff), cs);
String sp_name(sp_name_buff, sizeof(sp_name_buff), cs);
@@ -4313,9 +4335,9 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
return 0;
if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
- proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE) ||
+ proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE) ||
(lex->sql_command == SQLCOM_SHOW_STATUS_FUNC &&
- proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) ||
+ proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) ||
(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
{
restore_record(table, s->default_values);
@@ -4645,10 +4667,10 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
if (res && thd->is_error())
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
thd->main_da.sql_errno(), thd->main_da.message());
}
- if (res)
+ if (res)
thd->clear_error();
DBUG_RETURN(0);
}
@@ -4689,10 +4711,6 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
TABLE *show_table= tables->table;
KEY *key_info=show_table->key_info;
uint primary_key= show_table->s->primary_key;
-
- // This is not needed since no statistics are displayed.
- // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
-
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
{
if (i != primary_key && !(key_info->flags & HA_NOSAME))
@@ -4719,7 +4737,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
while ((f_key_info=it++))
{
- if (store_constraints(thd, table, db_name, table_name,
+ if (store_constraints(thd, table, db_name, table_name,
f_key_info->forein_id->str,
strlen(f_key_info->forein_id->str),
"FOREIGN KEY", 11))
@@ -4758,8 +4776,7 @@ static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name,
table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
- sys_var_thd_sql_mode::symbolic_mode_representation(thd, sql_mode,
- &sql_mode_rep);
+ sys_var::make_set(thd, sql_mode, &sql_mode_typelib, &sql_mode_rep);
table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs);
table->field[18]->store(definer_buffer->str, definer_buffer->length, cs);
table->field[19]->store(client_cs_name->str, client_cs_name->length, cs);
@@ -4874,10 +4891,6 @@ static int get_schema_key_column_usage_record(THD *thd,
TABLE *show_table= tables->table;
KEY *key_info=show_table->key_info;
uint primary_key= show_table->s->primary_key;
-
- // This is not needed since no statistics are displayed.
- // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
-
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
{
if (i != primary_key && !(key_info->flags & HA_NOSAME))
@@ -4892,8 +4905,8 @@ static int get_schema_key_column_usage_record(THD *thd,
restore_record(table, s->default_values);
store_key_column_usage(table, db_name, table_name,
key_info->name,
- strlen(key_info->name),
- key_part->field->field_name,
+ strlen(key_info->name),
+ key_part->field->field_name,
strlen(key_part->field->field_name),
(longlong) f_idx);
if (schema_table_store_record(thd, table))
@@ -4929,7 +4942,7 @@ static int get_schema_key_column_usage_record(THD *thd,
system_charset_info);
table->field[9]->set_notnull();
table->field[10]->store(f_key_info->referenced_table->str,
- f_key_info->referenced_table->length,
+ f_key_info->referenced_table->length,
system_charset_info);
table->field[10]->set_notnull();
table->field[11]->store(r_info->str, r_info->length,
@@ -5003,7 +5016,7 @@ static void store_schema_partitions_record(THD *thd, TABLE *schema_table,
table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
table->field[20]->set_notnull();
}
- if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
+ if (file->ha_table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
{
table->field[21]->store((longlong) stat_info.check_sum, TRUE);
table->field[21]->set_notnull();
@@ -5097,7 +5110,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
tmp_res.append(partition_keywords[PKW_KEY].str,
partition_keywords[PKW_KEY].length);
else
- tmp_res.append(partition_keywords[PKW_HASH].str,
+ tmp_res.append(partition_keywords[PKW_HASH].str,
partition_keywords[PKW_HASH].length);
table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
break;
@@ -5133,7 +5146,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
tmp_res.append(partition_keywords[PKW_KEY].str,
partition_keywords[PKW_KEY].length);
else
- tmp_res.append(partition_keywords[PKW_HASH].str,
+ tmp_res.append(partition_keywords[PKW_HASH].str,
partition_keywords[PKW_HASH].length);
table->field[8]->store(tmp_res.ptr(), tmp_res.length(), cs);
table->field[8]->set_notnull();
@@ -5212,7 +5225,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
/* SUBPARTITION_ORDINAL_POSITION */
table->field[6]->store((longlong) ++subpart_pos, TRUE);
table->field[6]->set_notnull();
-
+
store_schema_partitions_record(thd, table, show_table, subpart_elem,
file, part_id);
part_id++;
@@ -5353,8 +5366,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
/* SQL_MODE */
{
LEX_STRING sql_mode;
- sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
- &sql_mode);
+ sys_var::make_set(thd, et.sql_mode, &sql_mode_typelib, &sql_mode);
sch_table->field[ISE_SQL_MODE]->
store(sql_mode.str, sql_mode.length, scs);
}
@@ -5430,7 +5442,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
else
sch_table->field[ISE_ON_COMPLETION]->
store(STRING_WITH_LEN("PRESERVE"), scs);
-
+
number_to_datetime(et.created, &time, 0, &not_used);
DBUG_ASSERT(not_used==0);
sch_table->field[ISE_CREATED]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
@@ -5551,7 +5563,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
tmp1= &tmp;
}
else
- {
+ {
option_type= OPT_SESSION;
tmp1= &thd->status_var;
}
@@ -5607,9 +5619,6 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
List<FOREIGN_KEY_INFO> f_key_list;
TABLE *show_table= tables->table;
- // This is not needed since no statistics are displayed.
- // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
-
show_table->file->get_foreign_key_list(thd, &f_key_list);
FOREIGN_KEY_INFO *f_key_info;
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
@@ -5620,22 +5629,22 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
table->field[9]->store(table_name->str, table_name->length, cs);
table->field[2]->store(f_key_info->forein_id->str,
f_key_info->forein_id->length, cs);
- table->field[4]->store(f_key_info->referenced_db->str,
+ table->field[4]->store(f_key_info->referenced_db->str,
f_key_info->referenced_db->length, cs);
- table->field[10]->store(f_key_info->referenced_table->str,
+ table->field[10]->store(f_key_info->referenced_table->str,
f_key_info->referenced_table->length, cs);
if (f_key_info->referenced_key_name)
{
- table->field[5]->store(f_key_info->referenced_key_name->str,
+ table->field[5]->store(f_key_info->referenced_key_name->str,
f_key_info->referenced_key_name->length, cs);
table->field[5]->set_notnull();
}
else
table->field[5]->set_null();
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
- table->field[7]->store(f_key_info->update_method->str,
+ table->field[7]->store(f_key_info->update_method->str,
f_key_info->update_method->length, cs);
- table->field[8]->store(f_key_info->delete_method->str,
+ table->field[8]->store(f_key_info->delete_method->str,
f_key_info->delete_method->length, cs);
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
@@ -5644,7 +5653,7 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
DBUG_RETURN(0);
}
-struct schema_table_ref
+struct schema_table_ref
{
const char *table_name;
ST_SCHEMA_TABLE *schema_table;
@@ -5711,7 +5720,7 @@ ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
}
schema_table_a.table_name= table_name;
- if (plugin_foreach(thd, find_schema_table_in_plugin,
+ if (plugin_foreach(thd, find_schema_table_in_plugin,
MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
DBUG_RETURN(schema_table_a.schema_table);
@@ -5733,7 +5742,7 @@ ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
into it two numbers, based on modulus of base-10 numbers. In the ones
position is the number of decimals. Tens position is unused. In the
hundreds and thousands position is a two-digit decimal number representing
- length. Encode this value with (decimals*100)+length , where
+ length. Encode this value with (length*100)+decimals , where
0<decimals<10 and 0<=length<100 .
@param
@@ -5786,7 +5795,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
break;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
- if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
+ if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
fields_info->field_length)) == NULL)
DBUG_RETURN(NULL);
break;
@@ -5796,6 +5805,12 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
{
DBUG_RETURN(0);
}
+ /*
+ Create a type holder, as we want the type of the item to defined
+ the type of the object, not the value
+ */
+ if (!(item= new Item_type_holder(thd, item)))
+ DBUG_RETURN(0);
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
item->decimals= fields_info->field_length%10;
item->max_length= (fields_info->field_length/100)%100;
@@ -5840,7 +5855,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
tmp_table_param->schema_table= 1;
SELECT_LEX *select_lex= thd->lex->current_select;
if (!(table= create_tmp_table(thd, tmp_table_param,
- field_list, (ORDER*) 0, 0, 0,
+ field_list, (ORDER*) 0, 0, 0,
(select_lex->options | thd->options |
TMP_TABLE_ALL_COLUMNS),
HA_POS_ERROR, table_list->alias)))
@@ -6185,7 +6200,7 @@ bool get_schema_tables_result(JOIN *join,
thd->no_warnings_for_error= 1;
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
- {
+ {
if (!tab->table || !tab->table->pos_in_table_list)
break;
@@ -6310,17 +6325,17 @@ ST_FIELD_INFO tables_fields_info[]=
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
- {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
- {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
- {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
+ {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
- {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
+ {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
@@ -6402,7 +6417,7 @@ ST_FIELD_INFO engines_fields_info[]=
{
{"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine", SKIP_OPEN_TABLE},
{"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support", SKIP_OPEN_TABLE},
- {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE},
+ {"COMMENT", 160, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE},
{"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 1, "Transactions", SKIP_OPEN_TABLE},
{"XA", 3, MYSQL_TYPE_STRING, 0, 1, "XA", SKIP_OPEN_TABLE},
{"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 1, "Savepoints", SKIP_OPEN_TABLE},
@@ -6627,8 +6642,8 @@ ST_FIELD_INFO table_names_fields_info[]=
{
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
{"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
- {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
- SKIP_OPEN_TABLE},
+ {"TABLE_NAME", NAME_CHAR_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
+ MYSQL_TYPE_STRING, 0, 0, "Tables_in_", SKIP_OPEN_TABLE},
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
OPEN_FRM_ONLY},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
@@ -6748,6 +6763,8 @@ ST_FIELD_INFO processlist_fields_info[]=
{"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
{"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
SKIP_OPEN_TABLE},
+ {"TIME_MS", 100 * (MY_INT64_NUM_DECIMAL_DIGITS + 1) + 3, MYSQL_TYPE_DECIMAL,
+ 0, 0, "Time_ms", SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
@@ -6791,9 +6808,9 @@ ST_FIELD_INFO files_fields_info[]=
{"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
{"INITIAL_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
- {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
+ {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
- {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
+ {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
{"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
{"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
@@ -6805,20 +6822,20 @@ ST_FIELD_INFO files_fields_info[]=
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", SKIP_OPEN_TABLE},
{"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", SKIP_OPEN_TABLE},
- {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", SKIP_OPEN_TABLE},
- {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", SKIP_OPEN_TABLE},
- {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", SKIP_OPEN_TABLE},
- {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", SKIP_OPEN_TABLE},
- {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", SKIP_OPEN_TABLE},
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", SKIP_OPEN_TABLE},
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", SKIP_OPEN_TABLE},
{"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", SKIP_OPEN_TABLE},
- {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
+ {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", SKIP_OPEN_TABLE},
{"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
{"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
@@ -6867,13 +6884,13 @@ ST_FIELD_INFO referential_constraints_fields_info[]=
ST_SCHEMA_TABLE schema_tables[]=
{
- {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
+ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
- {"COLLATIONS", collation_fields_info, create_schema_table,
+ {"COLLATIONS", collation_fields_info, create_schema_table,
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
- {"COLUMNS", columns_fields_info, create_schema_table,
+ {"COLUMNS", columns_fields_info, create_schema_table,
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
{"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
@@ -6905,12 +6922,12 @@ ST_SCHEMA_TABLE schema_tables[]=
{"PROCESSLIST", processlist_fields_info, create_schema_table,
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
{"PROFILING", query_profile_statistics_info, create_schema_table,
- fill_query_profile_statistics_info, make_profile_table_for_show,
+ fill_query_profile_statistics_info, make_profile_table_for_show,
NULL, -1, -1, false, 0},
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
1, 9, 0, OPEN_TABLE_ONLY},
- {"ROUTINES", proc_fields_info, create_schema_table,
+ {"ROUTINES", proc_fields_info, create_schema_table,
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
{"SCHEMATA", schema_fields_info, create_schema_table,
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
@@ -6920,12 +6937,12 @@ ST_SCHEMA_TABLE schema_tables[]=
fill_status, make_old_format, 0, 0, -1, 0, 0},
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
fill_variables, make_old_format, 0, 0, -1, 0, 0},
- {"STATISTICS", stat_fields_info, create_schema_table,
+ {"STATISTICS", stat_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
- {"STATUS", variables_fields_info, create_schema_table, fill_status,
+ {"STATUS", variables_fields_info, create_schema_table, fill_status,
make_old_format, 0, 0, -1, 1, 0},
- {"TABLES", tables_fields_info, create_schema_table,
+ {"TABLES", tables_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
OPTIMIZE_I_S_TABLE},
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
@@ -6937,11 +6954,11 @@ ST_SCHEMA_TABLE schema_tables[]=
{"TRIGGERS", triggers_fields_info, create_schema_table,
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
OPEN_TABLE_ONLY},
- {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
+ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
make_old_format, 0, 0, -1, 1, 0},
- {"VIEWS", view_fields_info, create_schema_table,
+ {"VIEWS", view_fields_info, create_schema_table,
get_all_tables, 0, get_schema_views_record, 1, 2, 0,
OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
@@ -6967,8 +6984,8 @@ int initialize_schema_table(st_plugin_int *plugin)
{
schema_table->create_table= create_schema_table;
schema_table->old_format= make_old_format;
- schema_table->idx_field1= -1,
- schema_table->idx_field2= -1;
+ schema_table->idx_field1= -1,
+ schema_table->idx_field2= -1;
/* Make the name available to the init() function. */
schema_table->table_name= plugin->name.str;
@@ -6981,7 +6998,7 @@ int initialize_schema_table(st_plugin_int *plugin)
my_free(schema_table, MYF(0));
DBUG_RETURN(1);
}
-
+
/* Make sure the plugin name is not set inside the init() function. */
schema_table->table_name= plugin->name.str;
}
@@ -7062,9 +7079,7 @@ static bool show_create_trigger_impl(THD *thd,
&trg_connection_cl_name,
&trg_db_cl_name);
- sys_var_thd_sql_mode::symbolic_mode_representation(thd,
- trg_sql_mode,
- &trg_sql_mode_str);
+ sys_var::make_set(thd, trg_sql_mode, &sql_mode_typelib, &trg_sql_mode_str);
/* Resolve trigger client character set. */
diff --git a/sql/sql_sort.h b/sql/sql_sort.h
index 1e9322f7f5b..f54b085eeda 100644
--- a/sql/sql_sort.h
+++ b/sql/sql_sort.h
@@ -34,7 +34,9 @@
the callback function 'unpack_addon_fields'.
*/
-typedef struct st_sort_addon_field { /* Sort addon packed field */
+typedef struct st_sort_addon_field
+{
+ /* Sort addon packed field */
Field *field; /* Original field */
uint offset; /* Offset from the last sorted field */
uint null_offset; /* Offset to to null bit from the last sorted field */
@@ -42,14 +44,6 @@ typedef struct st_sort_addon_field { /* Sort addon packed field */
uint8 null_bit; /* Null bit mask for the field */
} SORT_ADDON_FIELD;
-typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
- my_off_t file_pos; /* Where we are in the sort file */
- uchar *base,*key; /* key pointers */
- ha_rows count; /* Number of rows in table */
- ulong mem_count; /* numbers of keys in memory */
- ulong max_keys; /* Max keys in buffert */
-} BUFFPEK;
-
struct BUFFPEK_COMPARE_CONTEXT
{
qsort_cmp2 key_compare;
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index f99dbbcea01..a997a0eb258 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -29,14 +29,6 @@
#include <floatingpoint.h>
#endif
-/*
- The following extern declarations are ok as these are interface functions
- required by the string function
-*/
-
-extern uchar* sql_alloc(unsigned size);
-extern void sql_element_free(void *ptr);
-
#include "sql_string.h"
/*****************************************************************************
@@ -89,10 +81,10 @@ bool String::real_alloc(uint32 arg_length)
*/
bool String::realloc(uint32 alloc_length)
{
- uint32 len=ALIGN_SIZE(alloc_length+1);
- if (Alloced_length < len)
+ if (Alloced_length <= alloc_length)
{
char *new_ptr;
+ uint32 len= ALIGN_SIZE(alloc_length+1);
if (alloced)
{
if (!(new_ptr= (char*) my_realloc(Ptr,len,MYF(MY_WME))))
@@ -136,8 +128,7 @@ bool String::set_real(double num,uint decimals, CHARSET_INFO *cs)
str_charset=cs;
if (decimals >= NOT_FIXED_DEC)
{
- // Enough for a DATETIME
- uint32 len= sprintf(buff, "%.15g", num);
+ uint32 len= my_sprintf(buff,(buff, "%.15g",num));// Enough for a DATETIME
return copy(buff, len, &my_charset_latin1, cs, &dummy_errors);
}
#ifdef HAVE_FCONVERT
@@ -712,7 +703,7 @@ void String::qs_append(const char *str, uint32 len)
void String::qs_append(double d)
{
char *buff = Ptr + str_length;
- str_length+= sprintf(buff, "%.15g", d);
+ str_length+= my_sprintf(buff, (buff, "%.15g", d));
}
void String::qs_append(double *d)
@@ -830,10 +821,11 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
*/
-uint32
-copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
- const char *from, uint32 from_length, CHARSET_INFO *from_cs,
- uint *errors)
+static uint32
+copy_and_convert_extended(char *to, uint32 to_length, CHARSET_INFO *to_cs,
+ const char *from, uint32 from_length,
+ CHARSET_INFO *from_cs,
+ uint *errors)
{
int cnvres;
my_wc_t wc;
@@ -948,6 +940,65 @@ my_copy_with_hex_escaping(CHARSET_INFO *cs,
}
/*
+ Optimized for quick copying of ASCII characters in the range 0x00..0x7F.
+*/
+uint32
+copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
+ const char *from, uint32 from_length, CHARSET_INFO *from_cs,
+ uint *errors)
+{
+ /*
+ If any of the character sets is not ASCII compatible,
+ immediately switch to slow mb_wc->wc_mb method.
+ */
+ if ((to_cs->state | from_cs->state) & MY_CS_NONASCII)
+ return copy_and_convert_extended(to, to_length, to_cs,
+ from, from_length, from_cs, errors);
+
+ uint32 length= min(to_length, from_length), length2= length;
+
+#if defined(__i386__)
+ /*
+ Special loop for i386, it allows to refer to a
+ non-aligned memory block as UINT32, which makes
+ it possible to copy four bytes at once. This
+ gives about 10% performance improvement comparing
+ to byte-by-byte loop.
+ */
+ for ( ; length >= 4; length-= 4, from+= 4, to+= 4)
+ {
+ if ((*(uint32*)from) & 0x80808080)
+ break;
+ *((uint32*) to)= *((const uint32*) from);
+ }
+#endif
+
+ for (; ; *to++= *from++, length--)
+ {
+ if (!length)
+ {
+ *errors= 0;
+ return length2;
+ }
+ if (*((unsigned char*) from) > 0x7F) /* A non-ASCII character */
+ {
+ uint32 copied_length= length2 - length;
+ to_length-= copied_length;
+ from_length-= copied_length;
+ return copied_length + copy_and_convert_extended(to, to_length,
+ to_cs,
+ from, from_length,
+ from_cs,
+ errors);
+ }
+ }
+
+ DBUG_ASSERT(FALSE); // Should never get to here
+ return 0; // Make compiler happy
+}
+
+
+/*
copy a string,
with optional character set conversion,
with optional left padding (for binary -> UCS2 conversion)
diff --git a/sql/sql_string.h b/sql/sql_string.h
index e5a41352992..44e7c1894bb 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -68,6 +68,11 @@ public:
Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0;
str_charset=cs;
}
+ /*
+ NOTE: If one intend to use the c_ptr() method, the following two
+ contructors need the size of memory for STR to be at least LEN+1 (to make
+ room for zero termination).
+ */
String(const char *str,uint32 len, CHARSET_INFO *cs)
{
Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 105b5e7a43c..b69c538322d 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -56,6 +56,7 @@ static bool
mysql_prepare_alter_table(THD *thd, TABLE *table,
HA_CREATE_INFO *create_info,
Alter_info *alter_info);
+static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list);
#ifndef DBUG_OFF
@@ -2014,9 +2015,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{
TABLE *locked_table;
abort_locked_tables(thd, db, table->table_name);
+ table->deleting= TRUE;
remove_table_from_cache(thd, db, table->table_name,
RTFC_WAIT_OTHER_THREAD_FLAG |
- RTFC_CHECK_KILLED_FLAG);
+ RTFC_CHECK_KILLED_FLAG, FALSE);
/*
If the table was used in lock tables, remember it so that
unlock_table_names can free it
@@ -2043,7 +2045,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
(!drop_view &&
mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
{
- // Table was not found on disk and table can't be created from engine
+ /* Table was not found on disk and table can't be created from engine */
if (if_exists)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
@@ -2864,7 +2866,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/* Don't pack rows in old tables if the user has requested this */
if ((sql_field->flags & BLOB_FLAG) ||
(sql_field->sql_type == MYSQL_TYPE_VARCHAR &&
- create_info->row_type != ROW_TYPE_FIXED))
+ create_info->row_type != ROW_TYPE_FIXED))
(*db_options)|= HA_OPTION_PACK_RECORD;
it2.rewind();
}
@@ -3309,10 +3311,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
length=column->length;
}
- else if (length == 0)
+ else if (length == 0 && (sql_field->flags & NOT_NULL_FLAG))
{
my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name);
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(TRUE);
}
if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
{
@@ -3622,6 +3624,68 @@ static inline int write_create_table_bin_log(THD *thd,
}
+/**
+ Check that there is no frm file for given table
+
+ @param old_path path to the old frm file
+ @param path path to the frm file in new encoding
+ @param db database name
+ @param table_name table name
+ @param alias table name for error message (for new encoding)
+ @param issue_error should we issue error messages
+
+ @retval FALSE there is no frm file
+ @retval TRUE there is frm file
+*/
+
+bool check_table_file_presence(char *old_path,
+ char *path,
+ const char *db,
+ const char *table_name,
+ const char *alias,
+ bool issue_error)
+{
+ if (!access(path,F_OK))
+ {
+ if (issue_error)
+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),alias);
+ return TRUE;
+ }
+ {
+ /*
+ Check if file of the table in 5.0 file name encoding exists.
+
+ Except case when it is the same table.
+ */
+ char tbl50[FN_REFLEN];
+#ifdef _WIN32
+ if (check_if_legal_tablename(table_name) != 0)
+ {
+ /*
+ Check for reserved device names for which access() returns 0
+ (CON, AUX etc).
+ */
+ return FALSE;
+ }
+#endif
+ strxmov(tbl50, mysql_data_home, "/", db, "/", table_name, NullS);
+ fn_format(tbl50, tbl50, "", reg_ext, MY_UNPACK_FILENAME);
+ if (!access(tbl50, F_OK) &&
+ (old_path == NULL ||
+ strcmp(old_path, tbl50) != 0))
+ {
+ if (issue_error)
+ {
+ strxmov(tbl50, MYSQL50_TABLE_NAME_PREFIX, table_name, NullS);
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), tbl50);
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
/*
Create a table
@@ -3684,8 +3748,9 @@ bool mysql_create_table_no_lock(THD *thd,
if (check_engine(thd, table_name, create_info))
DBUG_RETURN(TRUE);
db_options= create_info->table_options;
- if (create_info->row_type == ROW_TYPE_DYNAMIC)
- db_options|=HA_OPTION_PACK_RECORD;
+ if (create_info->row_type != ROW_TYPE_FIXED &&
+ create_info->row_type != ROW_TYPE_DEFAULT)
+ db_options|= HA_OPTION_PACK_RECORD;
alias= table_case_name(create_info, table_name);
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
create_info->db_type)))
@@ -3891,14 +3956,23 @@ bool mysql_create_table_no_lock(THD *thd,
goto err;
}
+ /* Give warnings for not supported table options */
+ if (create_info->transactional && !file->ht->commit)
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ ER(ER_ILLEGAL_HA_CREATE_OPTION),
+ file->engine_name()->str,
+ "TRANSACTIONAL=1");
+
VOID(pthread_mutex_lock(&LOCK_open));
if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
{
- if (!access(path,F_OK))
+ if (check_table_file_presence(NULL, path, db, table_name, table_name,
+ !(create_info->options &
+ HA_LEX_CREATE_IF_NOT_EXISTS)))
{
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
goto warn;
- my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
goto unlock_and_end;
}
/*
@@ -3943,7 +4017,6 @@ bool mysql_create_table_no_lock(THD *thd,
goto warn;
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
goto unlock_and_end;
- break;
default:
DBUG_PRINT("info", ("error: %u from storage engine", retcode));
my_error(retcode, MYF(0),table_name);
@@ -4177,7 +4250,7 @@ mysql_rename_table(handlerton *base, const char *old_db,
char from[FN_REFLEN + 1], to[FN_REFLEN + 1],
lc_from[FN_REFLEN + 1], lc_to[FN_REFLEN + 1];
char *from_base= from, *to_base= to;
- char tmp_name[NAME_LEN+1];
+ char tmp_name[SAFE_NAME_LEN+1];
handler *file;
int error=0;
DBUG_ENTER("mysql_rename_table");
@@ -4251,7 +4324,7 @@ mysql_rename_table(handlerton *base, const char *old_db,
Win32 clients must also have a WRITE LOCK on the table !
*/
-void wait_while_table_is_used(THD *thd, TABLE *table,
+void wait_while_table_is_used(THD *thd,TABLE *table,
enum ha_extra_function function)
{
DBUG_ENTER("wait_while_table_is_used");
@@ -4260,15 +4333,17 @@ void wait_while_table_is_used(THD *thd, TABLE *table,
table->db_stat, table->s->version));
safe_mutex_assert_owner(&LOCK_open);
-
- VOID(table->file->extra(function));
+
/* Mark all tables that are in use as 'old' */
mysql_lock_abort(thd, table, TRUE); /* end threads waiting on lock */
/* Wait until all there are no other threads that has this table open */
remove_table_from_cache(thd, table->s->db.str,
table->s->table_name.str,
- RTFC_WAIT_OTHER_THREAD_FLAG);
+ RTFC_WAIT_OTHER_THREAD_FLAG, FALSE);
+ /* extra() call must come only after all instances above are closed */
+ if (function != HA_EXTRA_NOT_USED)
+ VOID(table->file->extra(function));
DBUG_VOID_RETURN;
}
@@ -4567,6 +4642,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
Protocol *protocol= thd->protocol;
LEX *lex= thd->lex;
int result_code;
+ bool need_repair_or_alter= 0;
DBUG_ENTER("mysql_admin_table");
if (end_active_trans(thd))
@@ -4587,7 +4663,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
for (table= tables; table; table= table->next_local)
{
- char table_name[NAME_LEN*2+2];
+ char table_name[SAFE_NAME_LEN*2+2];
char* db = table->db;
bool fatal_error=0;
@@ -4767,7 +4843,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
remove_table_from_cache(thd, table->table->s->db.str,
table->table->s->table_name.str,
RTFC_WAIT_OTHER_THREAD_FLAG |
- RTFC_CHECK_KILLED_FLAG);
+ RTFC_CHECK_KILLED_FLAG, FALSE);
thd->exit_cond(old_message);
DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
if (thd->killed)
@@ -4795,32 +4871,38 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (operator_func == &handler::ha_repair &&
!(check_opt->sql_flags & TT_USEFRM))
{
- if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
- (table->table->file->ha_check_for_upgrade(check_opt) ==
- HA_ADMIN_NEEDS_ALTER))
+ handler *file= table->table->file;
+ int check_old_types= file->check_old_types();
+ int check_for_upgrade= file->ha_check_for_upgrade(check_opt);
+
+ if (check_old_types == HA_ADMIN_NEEDS_ALTER ||
+ check_for_upgrade == HA_ADMIN_NEEDS_ALTER)
{
- DBUG_PRINT("admin", ("recreating table"));
- ha_autocommit_or_rollback(thd, 1);
- close_thread_tables(thd);
- tmp_disable_binlog(thd); // binlogging is done by caller if wanted
- result_code= mysql_recreate_table(thd, table);
- reenable_binlog(thd);
- /*
- mysql_recreate_table() can push OK or ERROR.
- Clear 'OK' status. If there is an error, keep it:
- we will store the error message in a result set row
- and then clear.
- */
- if (thd->main_da.is_ok())
- thd->main_da.reset_diagnostics_area();
+ /* We use extra_open_options to be able to open crashed tables */
+ thd->open_options|= extra_open_options;
+ result_code= admin_recreate_table(thd, table);
+ thd->open_options= ~extra_open_options;
goto send_result;
}
+ if (check_old_types || check_for_upgrade)
+ {
+ /* If repair is not implemented for the engine, run ALTER TABLE */
+ need_repair_or_alter= 1;
+ }
}
DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
result_code = (table->table->file->*operator_func)(thd, check_opt);
DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
+ if (result_code == HA_ADMIN_NOT_IMPLEMENTED && need_repair_or_alter)
+ {
+ /*
+ repair was not implemented and we need to upgrade the table
+ to a new version so we recreate the table with ALTER TABLE
+ */
+ result_code= admin_recreate_table(thd, table);
+ }
send_result:
lex->cleanup_after_one_table_open();
@@ -4920,23 +5002,13 @@ send_result_message:
system_charset_info);
if (protocol->write())
goto err;
- ha_autocommit_or_rollback(thd, 0);
- close_thread_tables(thd);
DBUG_PRINT("info", ("HA_ADMIN_TRY_ALTER, trying analyze..."));
TABLE_LIST *save_next_local= table->next_local,
*save_next_global= table->next_global;
table->next_local= table->next_global= 0;
- tmp_disable_binlog(thd); // binlogging is done by caller if wanted
- result_code= mysql_recreate_table(thd, table);
- reenable_binlog(thd);
- /*
- mysql_recreate_table() can push OK or ERROR.
- Clear 'OK' status. If there is an error, keep it:
- we will store the error message in a result set row
- and then clear.
- */
- if (thd->main_da.is_ok())
- thd->main_da.reset_diagnostics_area();
+
+ result_code= admin_recreate_table(thd, table);
+
ha_autocommit_or_rollback(thd, 0);
close_thread_tables(thd);
if (!result_code) // recreation went ok
@@ -5025,7 +5097,8 @@ send_result_message:
{
pthread_mutex_lock(&LOCK_open);
remove_table_from_cache(thd, table->table->s->db.str,
- table->table->s->table_name.str, RTFC_NO_FLAG);
+ table->table->s->table_name.str,
+ RTFC_NO_FLAG, FALSE);
pthread_mutex_unlock(&LOCK_open);
}
/* May be something modified consequently we have to invalidate cache */
@@ -5742,6 +5815,9 @@ compare_tables(TABLE *table,
Alter_info tmp_alter_info(*alter_info, thd->mem_root);
uint db_options= 0; /* not used */
+ /* Set default value for return value (to ensure it's always set) */
+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+
/* Create the prepared information. */
if (mysql_prepare_create_table(thd, create_info,
&tmp_alter_info,
@@ -5790,6 +5866,8 @@ compare_tables(TABLE *table,
create_info->used_fields & HA_CREATE_USED_CHARSET ||
create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
(table->s->row_type != create_info->row_type) ||
+ create_info->used_fields & HA_CREATE_USED_PAGE_CHECKSUM ||
+ create_info->used_fields & HA_CREATE_USED_TRANSACTIONAL ||
create_info->used_fields & HA_CREATE_USED_PACK_KEYS ||
create_info->used_fields & HA_CREATE_USED_MAX_ROWS ||
(alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
@@ -5797,7 +5875,7 @@ compare_tables(TABLE *table,
!table->s->mysql_version ||
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
{
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ DBUG_PRINT("info", ("Basic checks -> ALTER_TABLE_DATA_CHANGED"));
DBUG_RETURN(0);
}
@@ -5808,8 +5886,7 @@ compare_tables(TABLE *table,
new_field_it.init(alter_info->create_list);
tmp_new_field_it.init(tmp_alter_info.create_list);
- /*
- Go through fields and check if the original ones are compatible
+ /* Go through fields and check if the original ones are compatible
with new table.
*/
for (f_ptr= table->field, new_field= new_field_it++,
@@ -5826,16 +5903,17 @@ compare_tables(TABLE *table,
if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
(uint) (field->flags & NOT_NULL_FLAG))
{
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ DBUG_PRINT("info", ("NULL behaviour difference in field '%s' -> "
+ "ALTER_TABLE_DATA_CHANGED", new_field->field_name));
DBUG_RETURN(0);
}
/* Don't pack rows in old tables if the user has requested this. */
- if (create_info->row_type == ROW_TYPE_DYNAMIC ||
- (tmp_new_field->flags & BLOB_FLAG) ||
- (tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR &&
- create_info->row_type != ROW_TYPE_FIXED))
- create_info->table_options|= HA_OPTION_PACK_RECORD;
+ if (create_info->row_type == ROW_TYPE_DYNAMIC ||
+ (tmp_new_field->flags & BLOB_FLAG) ||
+ (tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR &&
+ create_info->row_type != ROW_TYPE_FIXED))
+ create_info->table_options|= HA_OPTION_PACK_RECORD;
/* Check if field was renamed */
field->flags&= ~FIELD_IS_RENAMED;
@@ -5847,7 +5925,8 @@ compare_tables(TABLE *table,
/* Evaluate changes bitmap and send to check_if_incompatible_data() */
if (!(tmp= field->is_equal(tmp_new_field)))
{
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
+ new_field->field_name));
DBUG_RETURN(0);
}
// Clear indexed marker
@@ -5980,16 +6059,21 @@ compare_tables(TABLE *table,
/* Check if changes are compatible with current handler without a copy */
if (table->file->check_if_incompatible_data(create_info, changes))
{
- *need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ DBUG_PRINT("info", ("check_if_incompatible_data() -> "
+ "ALTER_TABLE_DATA_CHANGED"));
DBUG_RETURN(0);
}
if (*index_drop_count || *index_add_count)
{
+ DBUG_PRINT("info", ("Index dropped=%u added=%u -> "
+ "ALTER_TABLE_INDEX_CHANGED",
+ *index_drop_count, *index_add_count));
*need_copy_table= ALTER_TABLE_INDEX_CHANGED;
DBUG_RETURN(0);
}
+ DBUG_PRINT("info", (" -> ALTER_TABLE_METADATA_ONLY"));
*need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible
DBUG_RETURN(0);
}
@@ -6080,6 +6164,7 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
Sets create_info->varchar if the table has a VARCHAR column.
Prepares alter_info->create_list and alter_info->key_list with
columns and keys of the new table.
+
@retval TRUE error, out of memory or a semantical error in ALTER
TABLE instructions
@retval FALSE success
@@ -6106,7 +6191,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
uint used_fields= create_info->used_fields;
KEY *key_info=table->key_info;
bool rc= TRUE;
-
+ Create_field *def;
+ Field **f_ptr,*field;
DBUG_ENTER("mysql_prepare_alter_table");
create_info->varchar= FALSE;
@@ -6127,6 +6213,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
create_info->key_block_size= table->s->key_block_size;
+ if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
+ create_info->transactional= table->s->transactional;
if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY)
{
@@ -6140,18 +6228,16 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
create_info->tablespace= tablespace;
}
restore_record(table, s->default_values); // Empty record for DEFAULT
- Create_field *def;
/*
First collect all fields from table which isn't in drop_list
*/
- Field **f_ptr,*field;
for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
{
+ Alter_drop *drop;
if (field->type() == MYSQL_TYPE_STRING)
create_info->varchar= TRUE;
/* Check if field should be dropped */
- Alter_drop *drop;
drop_it.rewind();
while ((drop=drop_it++))
{
@@ -6231,7 +6317,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{
if (def->change && ! def->field)
{
- my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
+ my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change,
+ table->s->table_name.str);
goto err;
}
/*
@@ -6273,7 +6360,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
if (!find)
{
- my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
+ my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after,
+ table->s->table_name.str);
goto err;
}
find_it.after(def); // Put element after this
@@ -6327,6 +6415,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
continue; // Wrong field (from UNIREG)
const char *key_part_name=key_part->field->field_name;
Create_field *cfield;
+ uint key_part_length;
+
field_it.rewind();
while ((cfield=field_it++))
{
@@ -6342,7 +6432,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
if (!cfield)
continue; // Field is removed
- uint key_part_length=key_part->length;
+ key_part_length= key_part->length;
if (cfield->field) // Not new field
{
/*
@@ -6515,6 +6605,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
TABLE *table, *new_table= 0, *name_lock= 0;
int error= 0;
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1];
+ char old_name_buff[FN_REFLEN + 1];
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
char index_file[FN_REFLEN], data_file[FN_REFLEN];
char path[FN_REFLEN + 1];
@@ -6536,6 +6627,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
uint *index_add_buffer= NULL;
uint candidate_key_count= 0;
bool no_pk;
+ ulong explicit_used_fields= 0;
DBUG_ENTER("mysql_alter_table");
/*
@@ -6743,10 +6835,12 @@ view_err:
build_table_filename(new_name_buff, sizeof(new_name_buff) - 1,
new_db, new_name_buff, reg_ext, 0);
- if (!access(new_name_buff, F_OK))
+ build_table_filename(old_name_buff, sizeof(old_name_buff) - 1,
+ db, table_name, reg_ext, 0);
+ if (check_table_file_presence(old_name_buff, new_name_buff, new_db,
+ new_name, new_alias, TRUE))
{
/* Table will be closed in do_command() */
- my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
goto err;
}
}
@@ -6792,19 +6886,21 @@ view_err:
}
/*
- If this is an ALTER TABLE and no explicit row type specified reuse
- the table's row type.
- Note : this is the same as if the row type was specified explicitly.
+ If this is an ALTER TABLE and no explicit row type specified reuse
+ the table's row type.
+ Note: this is the same as if the row type was specified explicitly and
+ we must thus set HA_CREATE_USED_ROW_FORMAT!
*/
if (create_info->row_type == ROW_TYPE_NOT_USED)
{
/* ALTER TABLE without explicit row type */
create_info->row_type= table->s->row_type;
- }
- else
- {
- /* ALTER TABLE with specific row type */
- create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
+ /*
+ We have to mark the row type as used, as otherwise the engine may
+ change the row format in update_create_info().
+ */
+ create_info->used_fields|= HA_CREATE_USED_ROW_FORMAT;
+ explicit_used_fields|= HA_CREATE_USED_ROW_FORMAT;
}
DBUG_PRINT("info", ("old type: %s new type: %s",
@@ -6836,7 +6932,9 @@ view_err:
from concurrent DDL statements.
*/
VOID(pthread_mutex_lock(&LOCK_open));
- wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ wait_while_table_is_used(thd, table,
+ thd->locked_tables ? HA_EXTRA_NOT_USED :
+ HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
@@ -6844,7 +6942,9 @@ view_err:
break;
case DISABLE:
VOID(pthread_mutex_lock(&LOCK_open));
- wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ wait_while_table_is_used(thd, table,
+ thd->locked_tables ? HA_EXTRA_NOT_USED :
+ HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open));
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */
@@ -6971,6 +7071,9 @@ view_err:
if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
goto err;
+ /* Remove markers set for update_create_info */
+ create_info->used_fields&= ~explicit_used_fields;
+
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
need_copy_table= alter_info->change_level;
@@ -7125,6 +7228,16 @@ view_err:
/* Non-primary unique key. */
needed_online_flags|= HA_ONLINE_ADD_UNIQUE_INDEX;
needed_fast_flags|= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
+ if (ignore)
+ {
+ /*
+ If ignore is used, we have to remove all duplicate rows,
+ which require a full table copy.
+ */
+ need_copy_table= ALTER_TABLE_DATA_CHANGED;
+ pk_changed= 2; // Don't change need_copy_table
+ break;
+ }
}
}
else
@@ -7313,7 +7426,9 @@ view_err:
else
{
VOID(pthread_mutex_lock(&LOCK_open));
- wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ wait_while_table_is_used(thd, table,
+ thd->locked_tables ? HA_EXTRA_NOT_USED :
+ HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open));
thd_proc_info(thd, "manage keys");
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
@@ -7357,14 +7472,18 @@ view_err:
/* Add the indexes. */
if ((error= table->file->add_index(table, key_info, index_add_count)))
{
- /*
- Exchange the key_info for the error message. If we exchange
- key number by key name in the message later, we need correct info.
- */
- KEY *save_key_info= table->key_info;
- table->key_info= key_info;
- table->file->print_error(error, MYF(0));
- table->key_info= save_key_info;
+ /* Only report error if handler has not already reported an error */
+ if (!thd->main_da.is_error())
+ {
+ /*
+ Exchange the key_info for the error message. If we exchange
+ key number by key name in the message later, we need correct info.
+ */
+ KEY *save_key_info= table->key_info;
+ table->key_info= key_info;
+ table->file->print_error(error, MYF(0));
+ table->key_info= save_key_info;
+ }
goto err1;
}
}
@@ -7514,11 +7633,11 @@ view_err:
else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
new_alias, FN_FROM_IS_TMP) ||
((new_name != table_name || new_db != db) && // we also do rename
- (need_copy_table != ALTER_TABLE_METADATA_ONLY ||
- mysql_rename_table(save_old_db_type, db, table_name, new_db,
- new_alias, NO_FRM_RENAME)) &&
- Table_triggers_list::change_table_name(thd, db, table_name,
- new_db, new_alias)))
+ (need_copy_table != ALTER_TABLE_METADATA_ONLY ||
+ mysql_rename_table(save_old_db_type, db, table_name, new_db,
+ new_alias, NO_FRM_RENAME)) &&
+ Table_triggers_list::change_table_name(thd, db, table_name,
+ new_db, new_alias)))
{
/* Try to get everything back. */
error=1;
@@ -7715,7 +7834,9 @@ err_with_placeholders:
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(TRUE);
}
-/* mysql_alter_table */
+
+
+/* Copy all rows from one table to another */
static int
copy_data_between_tables(TABLE *from,TABLE *to,
@@ -7727,9 +7848,9 @@ copy_data_between_tables(TABLE *from,TABLE *to,
enum enum_enable_or_disable keys_onoff,
bool error_if_not_empty)
{
- int error;
- Copy_field *copy,*copy_end;
- ulong found_count,delete_count;
+ int error= 1, errpos= 0;
+ Copy_field *copy= NULL, *copy_end;
+ ha_rows found_count= 0, delete_count= 0;
THD *thd= current_thd;
uint length= 0;
SORT_FIELD *sortorder;
@@ -7739,8 +7860,10 @@ copy_data_between_tables(TABLE *from,TABLE *to,
List<Item> all_fields;
ha_rows examined_rows;
bool auto_increment_field_copied= 0;
- ulong save_sql_mode;
+ ulong save_sql_mode= thd->variables.sql_mode;
ulonglong prev_insert_id;
+ List_iterator<Create_field> it(create);
+ Create_field *def;
DBUG_ENTER("copy_data_between_tables");
/*
@@ -7749,15 +7872,16 @@ copy_data_between_tables(TABLE *from,TABLE *to,
This needs to be done before external_lock
*/
- error= ha_enable_transaction(thd, FALSE);
- if (error)
- DBUG_RETURN(-1);
-
+ if (ha_enable_transaction(thd, FALSE))
+ goto err;
+ errpos=1;
+
if (!(copy= new Copy_field[to->s->fields]))
- DBUG_RETURN(-1); /* purecov: inspected */
+ goto err; /* purecov: inspected */
if (to->file->ha_external_lock(thd, F_WRLCK))
- DBUG_RETURN(-1);
+ goto err;
+ errpos= 2;
/* We need external lock before we can disable/enable keys */
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
@@ -7769,11 +7893,8 @@ copy_data_between_tables(TABLE *from,TABLE *to,
from->file->info(HA_STATUS_VARIABLE);
to->file->ha_start_bulk_insert(from->file->stats.records);
+ errpos= 3;
- save_sql_mode= thd->variables.sql_mode;
-
- List_iterator<Create_field> it(create);
- Create_field *def;
copy_end=copy;
for (Field **ptr=to->field ; *ptr ; ptr++)
{
@@ -7797,8 +7918,6 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
- found_count=delete_count=0;
-
if (order)
{
if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
@@ -7818,7 +7937,6 @@ copy_data_between_tables(TABLE *from,TABLE *to,
tables.table= from;
tables.alias= tables.table_name= from->s->table_name.str;
tables.db= from->s->db.str;
- error= 1;
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
@@ -7835,6 +7953,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
/* Tell handler that we have values for all columns in the to table */
to->use_all_columns();
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
+ errpos= 4;
if (ignore)
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->row_count= 0;
@@ -7898,22 +8017,24 @@ copy_data_between_tables(TABLE *from,TABLE *to,
else
found_count++;
}
- end_read_record(&info);
+
+err:
+ if (errpos >= 4)
+ end_read_record(&info);
free_io_cache(from);
- delete [] copy; // This is never 0
+ delete [] copy;
- if (to->file->ha_end_bulk_insert() && error <= 0)
+ if (error > 0)
+ to->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
+ if (errpos >= 3 && to->file->ha_end_bulk_insert() && error <= 0)
{
to->file->print_error(my_errno,MYF(0));
- error=1;
+ error= 1;
}
to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
- if (ha_enable_transaction(thd, TRUE))
- {
+ if (errpos >= 1 && ha_enable_transaction(thd, TRUE))
error= 1;
- goto err;
- }
/*
Ensure that the new table is saved properly to disk so that we
@@ -7924,19 +8045,43 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (end_active_trans(thd))
error=1;
- err:
thd->variables.sql_mode= save_sql_mode;
thd->abort_on_warning= 0;
- free_io_cache(from);
*copied= found_count;
*deleted=delete_count;
to->file->ha_release_auto_increment();
- if (to->file->ha_external_lock(thd,F_UNLCK))
+ if (errpos >= 2 && to->file->ha_external_lock(thd,F_UNLCK))
error=1;
+ if (error < 0 && to->file->extra(HA_EXTRA_PREPARE_FOR_RENAME))
+ error= 1;
DBUG_RETURN(error > 0 ? -1 : 0);
}
+/* Prepare, run and cleanup for mysql_recreate_table() */
+
+static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
+{
+ bool result_code;
+ DBUG_ENTER("admin_recreate_table");
+
+ ha_autocommit_or_rollback(thd, 1);
+ close_thread_tables(thd);
+ tmp_disable_binlog(thd); // binlogging is done by caller if wanted
+ result_code= mysql_recreate_table(thd, table_list);
+ reenable_binlog(thd);
+ /*
+ mysql_recreate_table() can push OK or ERROR.
+ Clear 'OK' status. If there is an error, keep it:
+ we will store the error message in a result set row
+ and then clear.
+ */
+ if (thd->main_da.is_ok())
+ thd->main_da.reset_diagnostics_area();
+ DBUG_RETURN(result_code);
+}
+
+
/*
Recreates tables by calling mysql_alter_table().
@@ -7993,7 +8138,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
/* Open one table after the other to keep lock time as short as possible. */
for (table= tables; table; table= table->next_local)
{
- char table_name[NAME_LEN*2+2];
+ char table_name[SAFE_NAME_LEN*2+2];
TABLE *t;
strxmov(table_name, table->db ,".", table->table_name, NullS);
@@ -8012,11 +8157,14 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
}
else
{
- if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
- !(check_opt->flags & T_EXTEND))
+ /* Call ->checksum() if the table checksum matches 'old_mode' settings */
+ if (!(check_opt->flags & T_EXTEND) &&
+ (((t->file->ha_table_flags() & HA_HAS_OLD_CHECKSUM) &&
+ thd->variables.old_mode) ||
+ ((t->file->ha_table_flags() & HA_HAS_NEW_CHECKSUM) &&
+ !thd->variables.old_mode)))
protocol->store((ulonglong)t->file->checksum());
- else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
- (check_opt->flags & T_QUICK))
+ else if (check_opt->flags & T_QUICK)
protocol->store_null();
else
{
@@ -8064,6 +8212,9 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
{
Field *f= t->field[i];
+ if (! thd->variables.old_mode &&
+ f->is_real_null(0))
+ continue;
/*
BLOB and VARCHAR have pointers in their field, we must convert
to string; GEOMETRY is implemented on top of BLOB.
@@ -8136,7 +8287,7 @@ static bool check_engine(THD *thd, const char *table_name,
if (create_info->used_fields & HA_CREATE_USED_ENGINE)
{
my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
- ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
+ hton_name(*new_engine)->str, "TEMPORARY");
*new_engine= 0;
return TRUE;
}
diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc
index 5cdc022528f..d4a14dea8b5 100644
--- a/sql/sql_tablespace.cc
+++ b/sql/sql_tablespace.cc
@@ -37,7 +37,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_WARN_USING_OTHER_HANDLER,
ER(ER_WARN_USING_OTHER_HANDLER),
- ha_resolve_storage_engine_name(hton),
+ hton_name(hton)->str,
ts_info->tablespace_name ? ts_info->tablespace_name
: ts_info->logfile_group_name);
}
@@ -46,13 +46,14 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
{
if ((error= hton->alter_tablespace(hton, thd, ts_info)))
{
- if (error == HA_ADMIN_NOT_IMPLEMENTED)
+ if (error == 1)
{
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "");
+ DBUG_RETURN(1);
}
- else if (error == 1)
+
+ if (error == HA_ADMIN_NOT_IMPLEMENTED)
{
- DBUG_RETURN(1);
+ my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "");
}
else
{
@@ -66,7 +67,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_ILLEGAL_HA_CREATE_OPTION,
ER(ER_ILLEGAL_HA_CREATE_OPTION),
- ha_resolve_storage_engine_name(hton),
+ hton_name(hton)->str,
"TABLESPACE or LOGFILE GROUP");
}
error= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 4e056739d96..3de7aded51e 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2004, 2011, Oracle and/or its affiliates.
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
@@ -547,9 +547,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
thd->in_lock_tables= 1;
if (reopen_tables(thd, 1, 1))
{
- /* To be safe remove this table from the set of LOCKED TABLES */
- unlink_open_table(thd, tables->table, FALSE);
-
/*
Ignore reopen_tables errors for now. It's better not leave master/slave
in a inconsistent state.
@@ -1487,7 +1484,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
To remove this prefix we use check_n_cut_mysql50_prefix().
*/
- char fname[NAME_LEN + 1];
+ char fname[SAFE_NAME_LEN + 1];
DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) ||
(check_n_cut_mysql50_prefix(db, fname, sizeof(fname)) &&
!my_strcasecmp(table_alias_charset, lex.query_tables->db, fname))));
@@ -2024,7 +2021,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
*/
if (my_strcasecmp(table_alias_charset, db, new_db))
{
- char dbname[NAME_LEN + 1];
+ char dbname[SAFE_NAME_LEN + 1];
if (check_n_cut_mysql50_prefix(db, dbname, sizeof(dbname)) &&
!my_strcasecmp(table_alias_charset, dbname, new_db))
{
@@ -2191,7 +2188,8 @@ void Table_triggers_list::mark_fields_used(trg_event_type event)
void Table_triggers_list::set_parse_error_message(char *error_message)
{
m_has_unparseable_trigger= true;
- strcpy(m_parse_error_message, error_message);
+ strnmov(m_parse_error_message, error_message,
+ sizeof(m_parse_error_message)-1);
}
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 7d7d1d42bdc..a7224bd74bd 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2004, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index fd0d8391255..063321f9902 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -208,7 +208,7 @@ void udf_init()
}
tmp->dlhandle = dl;
{
- char buf[NAME_LEN+16], *missing;
+ char buf[SAFE_NAME_LEN+16], *missing;
if ((missing= init_syms(tmp, buf)))
{
sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), missing);
@@ -457,7 +457,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
}
udf->dlhandle=dl;
{
- char buf[NAME_LEN+16], *missing;
+ char buf[SAFE_NAME_LEN+16], *missing;
if ((missing= init_syms(udf, buf)))
{
my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), missing);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index a70de945492..6a6c91f90df 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2001, 2010, Oracle and/or its affiliates.
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
@@ -51,7 +51,7 @@ int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
}
-bool select_union::send_data(List<Item> &values)
+int select_union::send_data(List<Item> &values)
{
int error= 0;
if (unit->offset_limit_cnt)
@@ -65,9 +65,17 @@ bool select_union::send_data(List<Item> &values)
if ((error= table->file->ha_write_row(table->record[0])))
{
- /* create_myisam_from_heap will generate error if needed */
+ if (error == HA_ERR_FOUND_DUPP_KEY)
+ {
+ /*
+ Inform upper level that we found a duplicate key, that should not
+ be counted as part of limit
+ */
+ return -1;
+ }
+ /* create_internal_tmp_table_from_heap will generate error if needed */
if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
- create_myisam_from_heap(thd, table, &tmp_table_param, error, 1))
+ create_internal_tmp_table_from_heap(thd, table, &tmp_table_param, error, 1))
return 1;
}
return 0;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index d9435754c4c..8041de66ade 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -28,7 +28,7 @@
/**
True if the table's input and output record buffers are comparable using
- compare_records(TABLE*).
+ compare_record(TABLE*).
*/
bool records_are_comparable(const TABLE *table) {
return ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) ||
@@ -38,60 +38,20 @@ bool records_are_comparable(const TABLE *table) {
/**
Compares the input and outbut record buffers of the table to see if a row
- has changed. The algorithm iterates over updated columns and if they are
- nullable compares NULL bits in the buffer before comparing actual
- data. Special care must be taken to compare only the relevant NULL bits and
- mask out all others as they may be undefined. The storage engine will not
- and should not touch them.
-
- @param table The table to evaluate.
+ has changed.
@return true if row has changed.
@return false otherwise.
*/
-bool compare_records(const TABLE *table)
-{
- DBUG_ASSERT(records_are_comparable(table));
- if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) != 0)
- {
- /*
- Storage engine may not have read all columns of the record. Fields
- (including NULL bits) not in the write_set may not have been read and
- can therefore not be compared.
- */
- for (Field **ptr= table->field ; *ptr != NULL; ptr++)
- {
- Field *field= *ptr;
- if (bitmap_is_set(table->write_set, field->field_index))
- {
- if (field->real_maybe_null())
- {
- uchar null_byte_index= field->null_ptr - table->record[0];
-
- if (((table->record[0][null_byte_index]) & field->null_bit) !=
- ((table->record[1][null_byte_index]) & field->null_bit))
- return TRUE;
- }
- if (field->cmp_binary_offset(table->s->rec_buff_length))
- return TRUE;
- }
- }
- return FALSE;
- }
-
- /*
- The storage engine has read all columns, so it's safe to compare all bits
- including those not in the write_set. This is cheaper than the field-by-field
- comparison done above.
- */
- if (table->s->blob_fields + table->s->varchar_fields == 0)
- // Fixed-size record: do bitwise comparison of the records
+bool compare_record(const TABLE *table)
+{
+ if (table->s->can_cmp_whole_record)
return cmp_record(table,record[1]);
/* Compare null bits */
if (memcmp(table->null_flags,
table->null_flags+table->s->rec_buff_length,
- table->s->null_bytes))
+ table->s->null_bytes_for_compare))
return TRUE; // Diff in NULL value
/* Compare updated fields */
for (Field **ptr= table->field ; *ptr ; ptr++)
@@ -243,6 +203,7 @@ int mysql_update(THD *thd,
bool using_limit= limit != HA_POS_ERROR;
bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
bool used_key_is_modified, transactional_table, will_batch;
+ bool can_compare_record;
int res;
int error, loc_error;
uint used_index= MAX_KEY, dup_key_found;
@@ -329,8 +290,7 @@ int mysql_update(THD *thd,
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
else
{
- if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
- table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
+ if (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE)
bitmap_set_bit(table->write_set,
table->timestamp_field->field_index);
}
@@ -364,10 +324,8 @@ int mysql_update(THD *thd,
update force the table handler to retrieve write-only fields to be able
to compare records and detect data change.
*/
- if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
- table->timestamp_field &&
- (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
- table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
+ if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
+ (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE))
bitmap_union(table->read_set, table->write_set);
// Don't count on usage of 'only index' when calculating which key to use
table->covering_keys.clear_all();
@@ -529,14 +487,7 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
thd->examined_row_count++;
- bool skip_record= FALSE;
- if (select && select->skip_record(thd, &skip_record))
- {
- error= 1;
- table->file->unlock_row();
- break;
- }
- if (!skip_record)
+ if (!select || (error= select->skip_record(thd)) > 0)
{
if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */
@@ -555,7 +506,15 @@ int mysql_update(THD *thd,
}
}
else
+ {
table->file->unlock_row();
+ if (error < 0)
+ {
+ /* Fatal error from select->skip_record() */
+ error= 1;
+ break;
+ }
+ }
}
if (thd->killed && !error)
error= 1; // Aborted
@@ -631,11 +590,17 @@ int mysql_update(THD *thd,
if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
table->prepare_for_position();
+ /*
+ We can use compare_record() to optimize away updates if
+ the table handler is returning all columns OR if
+ if all updated columns are read
+ */
+ can_compare_record= records_are_comparable(table);
+
while (!(error=info.read_record(&info)) && !thd->killed)
{
thd->examined_row_count++;
- bool skip_record;
- if (!select || (!select->skip_record(thd, &skip_record) && !skip_record))
+ if (!select || select->skip_record(thd) > 0)
{
if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */
@@ -648,7 +613,7 @@ int mysql_update(THD *thd,
found++;
- if (!records_are_comparable(table) || compare_records(table))
+ if (!can_compare_record || compare_record(table))
{
if ((res= table_list->view_check_option(thd, ignore)) !=
VIEW_CHECK_OK)
@@ -899,7 +864,7 @@ int mysql_update(THD *thd,
err:
delete select;
free_underlaid_joins(thd, select_lex);
- table->set_keyread(FALSE);
+ table->disable_keyread();
thd->abort_on_warning= 0;
DBUG_RETURN(1);
}
@@ -1375,10 +1340,9 @@ int multi_update::prepare(List<Item> &not_used_values,
update force the table handler to retrieve write-only fields to be able
to compare records and detect data change.
*/
- if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
- table->timestamp_field &&
- (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
- table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
+ if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
+ (((uint) table->timestamp_field_type) &
+ TIMESTAMP_AUTO_SET_ON_UPDATE))
bitmap_union(table->read_set, table->write_set);
}
}
@@ -1718,7 +1682,7 @@ multi_update::~multi_update()
}
-bool multi_update::send_data(List<Item> &not_used_values)
+int multi_update::send_data(List<Item> &not_used_values)
{
TABLE_LIST *cur_table;
DBUG_ENTER("multi_update::send_data");
@@ -1744,6 +1708,14 @@ bool multi_update::send_data(List<Item> &not_used_values)
if (table == table_to_update)
{
+ /*
+ We can use compare_record() to optimize away updates if
+ the table handler is returning all columns OR if
+ if all updated columns are read
+ */
+ bool can_compare_record;
+ can_compare_record= records_are_comparable(table);
+
table->status|= STATUS_UPDATED;
store_record(table,record[1]);
if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset],
@@ -1758,7 +1730,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
*/
table->auto_increment_field_not_null= FALSE;
found++;
- if (!records_are_comparable(table) || compare_records(table))
+ if (!can_compare_record || compare_record(table))
{
int error;
if ((error= cur_table->view_check_option(thd, ignore)) !=
@@ -1857,7 +1829,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
{
if (error &&
- create_myisam_from_heap(thd, tmp_table,
+ create_internal_tmp_table_from_heap(thd, tmp_table,
tmp_table_param + offset, error, 1))
{
do_update= 0;
@@ -1945,6 +1917,7 @@ int multi_update::do_updates()
DBUG_RETURN(0);
for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local)
{
+ bool can_compare_record;
uint offset= cur_table->shared;
table = cur_table->table;
@@ -1968,9 +1941,11 @@ int multi_update::do_updates()
Setup copy functions to copy fields from temporary table
*/
List_iterator_fast<Item> field_it(*fields_for_table[offset]);
- Field **field= tmp_table->field +
- 1 + unupdated_check_opt_tables.elements; // Skip row pointers
+ Field **field;
Copy_field *copy_field_ptr= copy_field, *copy_field_end;
+
+ /* Skip row pointers */
+ field= tmp_table->field + 1 + unupdated_check_opt_tables.elements;
for ( ; *field ; field++)
{
Item_field *item= (Item_field* ) field_it++;
@@ -1981,6 +1956,8 @@ int multi_update::do_updates()
if ((local_error = tmp_table->file->ha_rnd_init(1)))
goto err;
+ can_compare_record= records_are_comparable(table);
+
for (;;)
{
if (thd->killed && trans_safe)
@@ -2021,7 +1998,7 @@ int multi_update::do_updates()
TRG_ACTION_BEFORE, TRUE))
goto err2;
- if (!records_are_comparable(table) || compare_records(table))
+ if (!can_compare_record || compare_record(table))
{
int error;
if ((error= cur_table->view_check_option(thd, ignore)) !=
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index ab6da7c1925..e4695b09234 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates.
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
@@ -1063,10 +1063,12 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
bool parse_status;
bool result, view_is_mergeable;
TABLE_LIST *UNINIT_VAR(view_main_select_tables);
-
DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
+ LINT_INIT(parse_status);
+ LINT_INIT(view_select);
+
if (table->view)
{
/*
@@ -1187,7 +1189,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
table->view= lex= thd->lex= (LEX*) new(thd->mem_root) st_lex_local;
{
- char old_db_buf[NAME_LEN+1];
+ char old_db_buf[SAFE_NAME_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
Parser_state parser_state;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index f4fb822b294..1741a1197fe 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -656,6 +656,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type, const char *name,
enum enum_tx_isolation tx_isolation;
enum Cast_target cast_type;
enum Item_udftype udf_type;
+ enum ha_choice choice;
CHARSET_INFO *charset;
thr_lock_type lock_type;
interval_type interval, interval_time_st;
@@ -1050,6 +1051,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token OWNER_SYM
%token PACK_KEYS_SYM
%token PAGE_SYM
+%token PAGE_CHECKSUM_SYM
%token PARAM_MARKER
%token PARSER_SYM
%token PARTIAL /* SQL-2003-N */
@@ -1208,6 +1210,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token TO_SYM /* SQL-2003-R */
%token TRAILING /* SQL-2003-R */
%token TRANSACTION_SYM
+%token TRANSACTIONAL_SYM
%token TRIGGERS_SYM
%token TRIGGER_SYM /* SQL-2003-R */
%token TRIM /* SQL-2003-N */
@@ -1267,6 +1270,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token YEAR_SYM /* SQL-2003-R */
%token ZEROFILL
+%token IMPOSSIBLE_ACTION /* To avoid warning for yyerrlab1 */
+
%left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT
/* A dummy token to force the priority of table_ref production in a join. */
%left TABLE_REF_PRIORITY
@@ -1326,6 +1331,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <ulonglong_number>
ulonglong_num real_ulonglong_num size_number
+%type <choice> choice
+
%type <p_elem_value>
part_bit_expr
@@ -1463,6 +1470,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
init_key_options normal_key_options normal_key_opts all_key_opt
spatial_key_options fulltext_key_options normal_key_opt
fulltext_key_opt spatial_key_opt fulltext_key_opts spatial_key_opts
+ keep_gcc_happy
key_using_alg
server_def server_options_list server_option
definer_opt no_definer definer
@@ -1592,11 +1600,12 @@ statement:
| help
| insert
| install
+ | keep_gcc_happy
+ | keycache
| kill
| load
| lock
| optimize
- | keycache
| partition_entry
| preload
| prepare
@@ -1853,7 +1862,7 @@ create:
push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_USING_OTHER_HANDLER,
ER(ER_WARN_USING_OTHER_HANDLER),
- ha_resolve_storage_engine_name(lex->create_info.db_type),
+ hton_name(lex->create_info.db_type)->str,
$5->table.str);
}
}
@@ -4497,6 +4506,12 @@ opt_part_option:
lex->part_info->curr_part_elem->engine_type= $4;
lex->part_info->default_engine_type= $4;
}
+ | CONNECTION_SYM opt_equal TEXT_STRING_sys
+ {
+ LEX *lex= Lex;
+ lex->part_info->curr_part_elem->connect_string.str= $3.str;
+ lex->part_info->curr_part_elem->connect_string.length= $3.length;
+ }
| NODEGROUP_SYM opt_equal real_ulong_num
{ Lex->part_info->curr_part_elem->nodegroup_id= (uint16) $3; }
| MAX_ROWS opt_equal real_ulonglong_num
@@ -4688,6 +4703,11 @@ create_table_option:
Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM;
Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM;
}
+ | PAGE_CHECKSUM_SYM opt_equal choice
+ {
+ Lex->create_info.used_fields|= HA_CREATE_USED_PAGE_CHECKSUM;
+ Lex->create_info.page_checksum= $3;
+ }
| DELAY_KEY_WRITE_SYM opt_equal ulong_num
{
Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE;
@@ -4745,6 +4765,11 @@ create_table_option:
Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
Lex->create_info.key_block_size= $3;
}
+ | TRANSACTIONAL_SYM opt_equal choice
+ {
+ Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
+ Lex->create_info.transactional= $3;
+ }
;
default_charset:
@@ -4826,6 +4851,7 @@ row_types:
| COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
| REDUNDANT_SYM { $$= ROW_TYPE_REDUNDANT; }
| COMPACT_SYM { $$= ROW_TYPE_COMPACT; }
+ | PAGE_SYM { $$= ROW_TYPE_PAGE; }
;
merge_insert_types:
@@ -6313,7 +6339,7 @@ slave_until:
{
LEX *lex=Lex;
if (((lex->mi.log_file_name || lex->mi.pos) &&
- (lex->mi.relay_log_name || lex->mi.relay_log_pos)) ||
+ (lex->mi.relay_log_name || lex->mi.relay_log_pos)) ||
!((lex->mi.log_file_name && lex->mi.pos) ||
(lex->mi.relay_log_name && lex->mi.relay_log_pos)))
{
@@ -8090,7 +8116,7 @@ function_call_generic:
builder= find_qualified_function_builder(thd);
DBUG_ASSERT(builder);
- item= builder->create(thd, $1, $3, true, $5);
+ item= builder->create_with_db(thd, $1, $3, true, $5);
if (! ($$= item))
{
@@ -9008,7 +9034,7 @@ where_clause:
expr
{
SELECT_LEX *select= Select;
- select->where= $3;
+ select->where= normalize_cond($3);
select->parsing_place= NO_MATTER;
if ($3)
$3->top_level_item();
@@ -9024,7 +9050,7 @@ having_clause:
expr
{
SELECT_LEX *sel= Select;
- sel->having= $3;
+ sel->having= normalize_cond($3);
sel->parsing_place= NO_MATTER;
if ($3)
$3->top_level_item();
@@ -9298,6 +9324,11 @@ dec_num:
| FLOAT_NUM
;
+choice:
+ ulong_num { $$= $1 != 0 ? HA_CHOICE_YES : HA_CHOICE_NO; }
+ | DEFAULT { $$= HA_CHOICE_UNDEF; }
+ ;
+
procedure_clause:
/* empty */
| PROCEDURE ident /* Procedure name */
@@ -9690,16 +9721,12 @@ replace:
insert_lock_option:
/* empty */
{
-#ifdef HAVE_QUERY_CACHE
/*
- If it is SP we do not allow insert optimisation whan result of
+ If it is SP we do not allow insert optimisation when result of
insert visible only after the table unlocking but everyone can
read table.
*/
$$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
-#else
- $$= TL_WRITE_CONCURRENT_INSERT;
-#endif
}
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
| DELAYED_SYM { $$= TL_WRITE_DELAYED; }
@@ -10461,7 +10488,7 @@ wild_and_where:
}
| WHERE expr
{
- Select->where= $2;
+ Select->where= normalize_cond($2);
if ($2)
$2->top_level_item();
}
@@ -10722,15 +10749,11 @@ load_data_lock:
/* empty */ { $$= TL_WRITE_DEFAULT; }
| CONCURRENT
{
-#ifdef HAVE_QUERY_CACHE
/*
- Ignore this option in SP to avoid problem with query cache
+ Ignore this option in SP to avoid problem with query cache and
+ triggers with non default priority locks
*/
- if (Lex->sphead != 0)
- $$= TL_WRITE_DEFAULT;
- else
-#endif
- $$= TL_WRITE_CONCURRENT_INSERT;
+ $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
}
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
;
@@ -11887,6 +11910,7 @@ keyword_sp:
| TEXT_SYM {}
| THAN_SYM {}
| TRANSACTION_SYM {}
+ | TRANSACTIONAL_SYM {}
| TRIGGERS_SYM {}
| TIMESTAMP {}
| TIMESTAMP_ADD {}
@@ -12407,6 +12431,11 @@ table_lock:
lock_option:
READ_SYM { $$= TL_READ_NO_INSERT; }
| WRITE_SYM { $$= TL_WRITE_DEFAULT; }
+ | WRITE_SYM CONCURRENT
+ {
+ $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
+ }
+
| LOW_PRIORITY WRITE_SYM { $$= TL_WRITE_LOW_PRIORITY; }
| READ_SYM LOCAL_SYM { $$= TL_READ; }
;
@@ -13751,6 +13780,13 @@ uninstall:
}
;
+/* Avoid compiler warning from sql_yacc.cc where yyerrlab1 is not used */
+keep_gcc_happy:
+ IMPOSSIBLE_ACTION
+ {
+ YYERROR;
+ }
+
/**
@} (end of group Parser)
*/
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index 19f0938ffca..83da635d8c3 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -41,12 +41,14 @@
static const char field_separator=',';
-ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
+ulonglong find_set(TYPELIB *lib, const char *str, uint length,
+ CHARSET_INFO *cs,
char **err_pos, uint *err_len, bool *set_warning)
{
CHARSET_INFO *strip= cs ? cs : &my_charset_latin1;
const char *end= str + strip->cset->lengthsp(strip, str, length);
ulonglong found= 0;
+
*err_pos= 0; // No error yet
if (str != end)
{
@@ -76,9 +78,13 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
find_type(lib, start, var_len, (bool) 0);
if (!find)
{
- *err_pos= (char*) start;
- *err_len= var_len;
- *set_warning= 1;
+ /* Report first error */
+ if (!*err_pos)
+ {
+ *err_pos= (char*) start;
+ *err_len= var_len;
+ *set_warning= 1;
+ }
}
else
found|= ((longlong) 1 << (find - 1));
@@ -150,8 +156,10 @@ static uint parse_name(TYPELIB *lib, const char **strpos, const char *end,
}
}
else
- for (; pos != end && *pos != '=' && *pos !=',' ; pos++) ;
-
+ {
+ for (; pos != end && *pos != '=' && *pos !=',' ; pos++)
+ ;
+ }
uint var_len= (uint) (pos - start);
/* Determine which flag it is */
uint find= cs ? find_type2(lib, start, var_len, cs) :
diff --git a/sql/table.cc b/sql/table.cc
index 9b7f3e66ea6..0bfa74dba75 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2008-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -458,34 +459,34 @@ inline bool is_system_table_name(const char *name, uint length)
CHARSET_INFO *ci= system_charset_info;
return (
- /* mysql.proc table */
- (length == 4 &&
- my_tolower(ci, name[0]) == 'p' &&
- my_tolower(ci, name[1]) == 'r' &&
- my_tolower(ci, name[2]) == 'o' &&
- my_tolower(ci, name[3]) == 'c') ||
-
- (length > 4 &&
- (
- /* one of mysql.help* tables */
- (my_tolower(ci, name[0]) == 'h' &&
- my_tolower(ci, name[1]) == 'e' &&
- my_tolower(ci, name[2]) == 'l' &&
- my_tolower(ci, name[3]) == 'p') ||
-
- /* one of mysql.time_zone* tables */
- (my_tolower(ci, name[0]) == 't' &&
- my_tolower(ci, name[1]) == 'i' &&
- my_tolower(ci, name[2]) == 'm' &&
- my_tolower(ci, name[3]) == 'e') ||
-
- /* mysql.event table */
- (my_tolower(ci, name[0]) == 'e' &&
- my_tolower(ci, name[1]) == 'v' &&
- my_tolower(ci, name[2]) == 'e' &&
- my_tolower(ci, name[3]) == 'n' &&
- my_tolower(ci, name[4]) == 't')
- )
+ /* mysql.proc table */
+ (length == 4 &&
+ my_tolower(ci, name[0]) == 'p' &&
+ my_tolower(ci, name[1]) == 'r' &&
+ my_tolower(ci, name[2]) == 'o' &&
+ my_tolower(ci, name[3]) == 'c') ||
+
+ (length > 4 &&
+ (
+ /* one of mysql.help* tables */
+ (my_tolower(ci, name[0]) == 'h' &&
+ my_tolower(ci, name[1]) == 'e' &&
+ my_tolower(ci, name[2]) == 'l' &&
+ my_tolower(ci, name[3]) == 'p') ||
+
+ /* one of mysql.time_zone* tables */
+ (my_tolower(ci, name[0]) == 't' &&
+ my_tolower(ci, name[1]) == 'i' &&
+ my_tolower(ci, name[2]) == 'm' &&
+ my_tolower(ci, name[3]) == 'e') ||
+
+ /* mysql.event table */
+ (my_tolower(ci, name[0]) == 'e' &&
+ my_tolower(ci, name[1]) == 'v' &&
+ my_tolower(ci, name[2]) == 'e' &&
+ my_tolower(ci, name[3]) == 'n' &&
+ my_tolower(ci, name[4]) == 't')
+ )
)
);
}
@@ -495,11 +496,11 @@ inline bool is_system_table_name(const char *name, uint length)
Check if a string contains path elements
*/
-static inline bool has_disabled_path_chars(const char *str)
+static bool has_disabled_path_chars(const char *str)
{
for (; *str; str++)
- switch (*str)
- {
+ {
+ switch (*str) {
case FN_EXTCHAR:
case '/':
case '\\':
@@ -507,6 +508,7 @@ static inline bool has_disabled_path_chars(const char *str)
case '@':
return TRUE;
}
+ }
return FALSE;
}
@@ -693,6 +695,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
const char **interval_array;
enum legacy_db_type legacy_db_type;
my_bitmap_map *bitmaps;
+ bool null_bits_are_used;
DBUG_ENTER("open_binary_frm");
new_field_pack_flag= head[27];
@@ -739,6 +742,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (!head[32]) // New frm file in 3.23
{
share->avg_row_length= uint4korr(head+34);
+ share->transactional= (ha_choice) (head[39] & 3);
+ share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
share->row_type= (row_type) head[40];
share->table_charset= get_charset((uint) head[38],MYF(0));
share->null_field_first= 1;
@@ -869,7 +874,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
/* Read extra data segment */
uchar *buff, *next_chunk, *buff_end;
DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
- if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
+ if (!(next_chunk= buff= (uchar*) my_malloc(n_length+1, MYF(MY_WME))))
goto err;
if (my_pread(file, buff, n_length, record_offset + share->reclength,
MYF(MY_NABP)))
@@ -913,7 +918,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
replacing it with a globally locked version of tmp_plugin
*/
plugin_unlock(NULL, share->db_plugin);
- share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
+ share->db_plugin= my_plugin_lock(NULL, tmp_plugin);
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
str_db_type_length, next_chunk + 2,
ha_legacy_type(share->db_type())));
@@ -948,6 +953,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
{
/* purecov: begin inspected */
error= 8;
+ name.str[name.length]= 0;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
my_free(buff, MYF(0));
goto err;
@@ -1138,6 +1144,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
goto err;
record= share->default_values-1; /* Fieldstart = 1 */
+ null_bits_are_used= share->null_fields != 0;
if (share->null_field_first)
{
null_flags= null_pos= (uchar*) record+1;
@@ -1310,6 +1317,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
reg_field->comment=comment;
if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag))
{
+ null_bits_are_used= 1;
if ((null_bit_pos+= field_length & 7) > 7)
{
null_pos++;
@@ -1598,6 +1606,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
share->null_bytes= (null_pos - (uchar*) null_flags +
(null_bit_pos + 7) / 8);
share->last_null_bit_pos= null_bit_pos;
+ share->null_bytes_for_compare= null_bits_are_used ? share->null_bytes : 0;
+ share->can_cmp_whole_record= (share->blob_fields == 0 &&
+ share->varchar_fields == 0);
share->db_low_byte_first= handler_file->low_byte_first();
share->column_bitmap_size= bitmap_buffer_size(share->fields);
@@ -1731,7 +1742,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
outparam->record[1]= outparam->record[0]; // Safety
}
-#ifdef HAVE_purify
+#ifdef HAVE_valgrind
/*
We need this because when we read var-length rows, we are not updating
bytes after end of varchar
@@ -1953,7 +1964,7 @@ partititon_err:
}
}
-#if defined(HAVE_purify) && !defined(DBUG_OFF)
+#if defined(HAVE_valgrind) && !defined(DBUG_OFF)
bzero((char*) bitmaps, bitmap_size*3);
#endif
@@ -1996,7 +2007,11 @@ int closefrm(register TABLE *table, bool free_share)
DBUG_PRINT("enter", ("table: 0x%lx", (long) table));
if (table->db_stat)
+ {
+ if (table->s->deleting)
+ table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
error=table->file->close();
+ }
my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
table->alias= 0;
if (table->field)
@@ -2205,13 +2220,17 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
{
int err_no;
char buff[FN_REFLEN];
- myf errortype= ME_ERROR+ME_WAITTANG;
+ myf errortype= ME_ERROR+ME_WAITTANG; // Write fatals error to log
DBUG_ENTER("open_table_error");
switch (error) {
case 7:
case 1:
- if (db_errno == ENOENT)
+ /*
+ Test if file didn't exists. We have to also test for EINVAL as this
+ may happen on windows when opening a file with a not legal file name
+ */
+ if (db_errno == ENOENT || db_errno == EINVAL)
my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
else
{
@@ -2478,7 +2497,7 @@ File create_frm(THD *thd, const char *name, const char *db,
if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
{
- uint key_length, tmp_key_length;
+ ulong key_length, tmp_key_length;
uint tmp;
bzero((char*) fileinfo,64);
/* header */
@@ -2521,11 +2540,8 @@ File create_frm(THD *thd, const char *name, const char *db,
int4store(fileinfo+34,create_info->avg_row_length);
fileinfo[38]= (create_info->default_table_charset ?
create_info->default_table_charset->number : 0);
- /*
- In future versions, we will store in fileinfo[39] the values of the
- TRANSACTIONAL and PAGE_CHECKSUM clauses of CREATE TABLE.
- */
- fileinfo[39]= 0;
+ fileinfo[39]= (uchar) ((uint) create_info->transactional |
+ ((uint) create_info->page_checksum << 2));
fileinfo[40]= (uchar) create_info->row_type;
/* Next few bytes where for RAID support */
fileinfo[41]= 0;
@@ -2578,6 +2594,8 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
create_info->default_table_charset= share->table_charset;
create_info->table_charset= 0;
create_info->comment= share->comment;
+ create_info->transactional= share->transactional;
+ create_info->page_checksum= share->page_checksum;
DBUG_VOID_RETURN;
}
@@ -2699,15 +2717,15 @@ bool check_db_name(LEX_STRING *org_name)
uint name_length= org_name->length;
bool check_for_path_chars;
- if (!name_length || name_length > NAME_LEN)
- return 1;
-
if ((check_for_path_chars= check_mysql50_prefix(name)))
{
name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
name_length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
}
+ if (!name_length || name_length > NAME_LEN)
+ return 1;
+
if (lower_case_table_names && name != any_db)
my_casedn_str(files_charset_info, name);
@@ -2725,6 +2743,15 @@ bool check_table_name(const char *name, uint length, bool check_for_path_chars)
{
uint name_length= 0; // name length in symbols
const char *end= name+length;
+
+
+ if (!check_for_path_chars &&
+ (check_for_path_chars= check_mysql50_prefix(name)))
+ {
+ name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
+ length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH;
+ }
+
if (!length || length > NAME_LEN)
return 1;
#if defined(USE_MB) && defined(USE_MB_IDENT)
@@ -2743,7 +2770,7 @@ bool check_table_name(const char *name, uint length, bool check_for_path_chars)
int len=my_ismbchar(system_charset_info, name, end);
if (len)
{
- name += len;
+ name+= len;
name_length++;
continue;
}
@@ -3345,7 +3372,7 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
const char *save_where= thd->where;
thd->where= "check option";
if ((!check_option->fixed &&
- check_option->fix_fields(thd, &check_option)) ||
+ check_option->fix_fields(thd, &check_option)) ||
check_option->check_cols(1))
{
DBUG_RETURN(TRUE);
@@ -4067,15 +4094,15 @@ void Field_iterator_table_ref::set_field_iterator()
DBUG_ASSERT(table_ref->is_natural_join ||
table_ref->nested_join ||
(table_ref->join_columns &&
- /* This is a merge view. */
- ((table_ref->field_translation &&
- table_ref->join_columns->elements ==
- (ulong)(table_ref->field_translation_end -
- table_ref->field_translation)) ||
- /* This is stored table or a tmptable view. */
- (!table_ref->field_translation &&
- table_ref->join_columns->elements ==
- table_ref->table->s->fields))));
+ /* This is a merge view. */
+ ((table_ref->field_translation &&
+ table_ref->join_columns->elements ==
+ (ulong)(table_ref->field_translation_end -
+ table_ref->field_translation)) ||
+ /* This is stored table or a tmptable view. */
+ (!table_ref->field_translation &&
+ table_ref->join_columns->elements ==
+ table_ref->table->s->fields))));
field_it= &natural_join_it;
DBUG_PRINT("info",("field_it for '%s' is Field_iterator_natural_join",
table_ref->alias));
@@ -4378,7 +4405,7 @@ void st_table::mark_columns_used_by_index(uint index)
MY_BITMAP *bitmap= &tmp_set;
DBUG_ENTER("st_table::mark_columns_used_by_index");
- set_keyread(TRUE);
+ enable_keyread();
bitmap_clear_all(bitmap);
mark_columns_used_by_index_no_reset(index, bitmap);
column_bitmaps_set(bitmap, bitmap);
@@ -4399,7 +4426,7 @@ void st_table::add_read_columns_used_by_index(uint index)
MY_BITMAP *bitmap= &tmp_set;
DBUG_ENTER("st_table::add_read_columns_used_by_index");
- set_keyread(TRUE);
+ enable_keyread();
bitmap_copy(bitmap, read_set);
mark_columns_used_by_index_no_reset(index, bitmap);
column_bitmaps_set(bitmap, write_set);
@@ -4422,7 +4449,7 @@ void st_table::restore_column_maps_after_mark_index()
{
DBUG_ENTER("st_table::restore_column_maps_after_mark_index");
- set_keyread(FALSE);
+ disable_keyread();
default_column_bitmaps();
file->column_bitmaps_signal();
DBUG_VOID_RETURN;
diff --git a/sql/table.h b/sql/table.h
index 20f11f4e7e1..687d0296e1e 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -390,14 +390,21 @@ typedef struct st_table_share
}
enum row_type row_type; /* How rows are stored */
enum tmp_table_type tmp_table;
- enum enum_ha_unused unused1;
- enum enum_ha_unused unused2;
+ /** Transactional or not. */
+ enum ha_choice transactional;
+ /** Per-page checksums or not. */
+ enum ha_choice page_checksum;
uint ref_count; /* How many TABLE objects uses this */
uint open_count; /* Number of tables in open list */
uint blob_ptr_size; /* 4 or 8 */
uint key_block_size; /* create key_block_size, if used */
uint null_bytes, last_null_bit_pos;
+ /*
+ Same as null_bytes, except that if there is only a 'delete-marker' in
+ the record then this value is 0.
+ */
+ uint null_bytes_for_compare;
uint fields; /* Number of fields */
uint rec_buff_length; /* Size of table->record[] buffer */
uint keys, key_parts;
@@ -428,6 +435,8 @@ typedef struct st_table_share
bool is_view;
bool name_lock, replace_with_name_lock;
bool waiting_on_cond; /* Protection against free */
+ bool deleting; /* going to delete this table */
+ bool can_cmp_whole_record;
ulong table_map_id; /* for row-based replication */
/*
@@ -902,19 +911,23 @@ struct st_table {
inline bool needs_reopen_or_name_lock()
{ return s->version != refresh_version; }
bool is_children_attached(void);
- inline void set_keyread(bool flag)
+ inline void enable_keyread()
{
- DBUG_ASSERT(file);
- if (flag && !key_read)
- {
- key_read= 1;
- file->extra(HA_EXTRA_KEYREAD);
- }
- else if (!flag && key_read)
+ DBUG_ENTER("enable_keyread");
+ DBUG_ASSERT(key_read == 0);
+ key_read= 1;
+ file->extra(HA_EXTRA_KEYREAD);
+ DBUG_VOID_RETURN;
+ }
+ inline void disable_keyread()
+ {
+ DBUG_ENTER("disable_keyread");
+ if (key_read)
{
key_read= 0;
file->extra(HA_EXTRA_NO_KEYREAD);
}
+ DBUG_VOID_RETURN;
}
};
@@ -1391,7 +1404,7 @@ struct TABLE_LIST
*/
bool create;
bool internal_tmp_table;
-
+ bool deleting; /* going to delete this table */
/* View creation context. */
@@ -1437,10 +1450,11 @@ struct TABLE_LIST
void cleanup_items();
bool placeholder()
{
- return derived || view || schema_table || (create && !table->db_stat) ||
- !table;
+ return (derived || view || schema_table || (create && !table->db_stat) ||
+ !table);
}
- void print(THD *thd, String *str, enum_query_type query_type);
+ void print(THD *thd, table_map eliminated_tables, String *str,
+ enum_query_type query_type);
bool check_single_table(TABLE_LIST **table, table_map map,
TABLE_LIST *view);
bool set_insert_values(MEM_ROOT *mem_root);
@@ -1689,7 +1703,11 @@ public:
typedef struct st_nested_join
{
List<TABLE_LIST> join_list; /* list of elements in the nested join */
- table_map used_tables; /* bitmap of tables in the nested join */
+ /*
+ Bitmap of tables within this nested join (including those embedded within
+ its children), including tables removed by table elimination.
+ */
+ table_map used_tables;
table_map not_null_tables; /* tables that rejects nulls */
/**
Used for pointing out the first table in the plan being covered by this
@@ -1704,6 +1722,11 @@ typedef struct st_nested_join
Before each use the counters are zeroed by reset_nj_counters.
*/
uint counter;
+ /*
+ Number of elements in join_list that were not (or contain table(s) that
+ weren't) removed by table elimination.
+ */
+ uint n_tables;
nested_join_map nj_map; /* Bit used to identify this nested join*/
/**
True if this join nest node is completely covered by the query execution
@@ -1713,7 +1736,7 @@ typedef struct st_nested_join
2. All child join nest nodes are fully covered.
*/
- bool is_fully_covered() const { return join_list.elements == counter; }
+ bool is_fully_covered() const { return n_tables == counter; }
} NESTED_JOIN;
diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc
index 3bc90cf5ccd..c96171c4e74 100644
--- a/sql/thr_malloc.cc
+++ b/sql/thr_malloc.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/time.cc b/sql/time.cc
index 22d0fe2271c..ebbb5d4c583 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -564,7 +564,7 @@ bool parse_date_time_format(timestamp_type format_type,
return 0;
break;
default:
- DBUG_ASSERT(1);
+ DBUG_ASSERT(0);
break;
}
return 1; // Error
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 922cfd1fad6..3cdc1853c14 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2004, 2010, Oracle and/or its affiliates.
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
@@ -450,7 +450,7 @@ prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage)
if (end_t == MY_TIME_T_MAX ||
((cur_off_and_corr > 0) &&
- (end_t >= MY_TIME_T_MAX - cur_off_and_corr)))
+ (end_t >= MY_TIME_T_MAX - cur_off_and_corr)))
/* end of t space */
break;
diff --git a/sql/udf_example.c b/sql/udf_example.c
index 3c58c080974..b68a9fd2b79 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -209,7 +209,7 @@ char *is_const(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long
** try to keep the error message less than 80 bytes long!
**
** This function should return 1 if something goes wrong. In this case
-** message should contain something usefull!
+** message should contain something useful!
**************************************************************************/
#define MAXMETAPH 8
diff --git a/sql/udf_example.def b/sql/udf_example.def
index 3d569941cc8..41150b24e8f 100644
--- a/sql/udf_example.def
+++ b/sql/udf_example.def
@@ -3,8 +3,10 @@ VERSION 1.0
EXPORTS
lookup
lookup_init
+ lookup_deinit
reverse_lookup
reverse_lookup_init
+ reverse_lookup_deinit
metaphon_init
metaphon_deinit
metaphon
diff --git a/sql/uniques.cc b/sql/uniques.cc
index b2a2ef0eeca..fd6056ae8a6 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -606,9 +606,10 @@ bool Unique::get(TABLE *table)
outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
MYF(MY_ZEROFILL));
- if (!outfile || (! my_b_inited(outfile) &&
- open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
- MYF(MY_WME))))
+ if (!outfile ||
+ (! my_b_inited(outfile) &&
+ open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
+ MYF(MY_WME))))
return 1;
reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 620232b6685..a5d9edbf181 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
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
@@ -158,8 +158,7 @@ bool mysql_create_frm(THD *thd, const char *file_name,
reclength=uint2korr(forminfo+266);
/* Calculate extra data segment length */
- str_db_type.str= (char *) ha_resolve_storage_engine_name(create_info->db_type);
- str_db_type.length= strlen(str_db_type.str);
+ str_db_type= *hton_name(create_info->db_type);
/* str_db_type */
create_info->extra_size= (2 + str_db_type.length +
2 + create_info->connect_string.length);
@@ -532,7 +531,7 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
int2store(pos+6, key->block_size);
pos+=8;
key_parts+=key->key_parts;
- DBUG_PRINT("loop", ("flags: %lu key_parts: %d at 0x%lx",
+ DBUG_PRINT("loop", ("flags: %lu key_parts: %d key_part: 0x%lx",
key->flags, key->key_parts,
(long) key->key_part));
for (key_part=key->key_part,key_part_end=key_part+key->key_parts ;
diff --git a/sql/unireg.h b/sql/unireg.h
index d35a7715b68..b0530931ac6 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
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
@@ -53,7 +53,7 @@
#define MAX_FIELD_NAME 34 /* Max colum name length +2 */
#define MAX_SYS_VAR_LENGTH 32
#define MAX_KEY MAX_INDEXES /* Max used keys */
-#define MAX_REF_PARTS 16 /* Max parts used as ref */
+#define MAX_REF_PARTS 32 /* Max parts used as ref */
#define MAX_KEY_LENGTH 3072 /* max possible key */
#if SIZEOF_OFF_T > 4
#define MAX_REFLENGTH 8 /* Max length for record ref */