diff options
Diffstat (limited to 'libmysqld')
-rw-r--r-- | libmysqld/CMakeLists.txt | 169 | ||||
-rw-r--r-- | libmysqld/Makefile.am | 150 | ||||
-rw-r--r-- | libmysqld/emb_qcache.cc | 122 | ||||
-rw-r--r-- | libmysqld/emb_qcache.h | 13 | ||||
-rw-r--r-- | libmysqld/examples/CMakeLists.txt | 41 | ||||
-rw-r--r-- | libmysqld/examples/Makefile.am | 18 | ||||
-rw-r--r-- | libmysqld/examples/builder-sample/emb_samples.cpp | 2 | ||||
-rw-r--r-- | libmysqld/lib_sql.cc | 292 | ||||
-rw-r--r-- | libmysqld/libmysqld.c | 5 | ||||
-rw-r--r-- | libmysqld/libmysqld.def | 77 |
10 files changed, 621 insertions, 268 deletions
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt new file mode 100644 index 00000000000..db398258b69 --- /dev/null +++ b/libmysqld/CMakeLists.txt @@ -0,0 +1,169 @@ +# Copyright (C) 2006 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., 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") + +# Need to set USE_TLS, since __declspec(thread) approach to thread local +# storage does not work properly in DLLs. +IF(WIN32) + ADD_DEFINITIONS(-DUSE_TLS) +ENDIF(WIN32) + +ADD_DEFINITIONS(-DMYSQL_SERVER -DEMBEDDED_LIBRARY -DHAVE_DLOPEN) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/libmysqld + ${CMAKE_SOURCE_DIR}/libmysql + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/zlib) + +SET(GEN_SOURCES ${CMAKE_SOURCE_DIR}/sql/sql_yacc.cc + ${CMAKE_SOURCE_DIR}/sql/sql_yacc.h + ${CMAKE_SOURCE_DIR}/sql/message.h + ${CMAKE_SOURCE_DIR}/sql/message.rc + ${CMAKE_SOURCE_DIR}/sql/sql_builtin.cc + ${CMAKE_SOURCE_DIR}/sql/lex_hash.h) + +SET_SOURCE_FILES_PROPERTIES(${GEN_SOURCES} PROPERTIES GENERATED 1) + +# Include and add the directory path +SET(SOURCE_SUBLIBS TRUE) +SET(LIB_SOURCES "") + +INCLUDE(${CMAKE_SOURCE_DIR}/zlib/CMakeLists.txt) +FOREACH(rpath ${ZLIB_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../zlib/${rpath}) +ENDFOREACH(rpath) + +# FIXME only needed if build type is "Debug", but CMAKE_BUILD_TYPE is +# not set during configure time. +INCLUDE(${CMAKE_SOURCE_DIR}/dbug/CMakeLists.txt) +FOREACH(rpath ${DBUG_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../dbug/${rpath}) +ENDFOREACH(rpath) + +INCLUDE(${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/CMakeLists.txt) +FOREACH(rpath ${TAOCRYPT_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../extra/yassl/taocrypt/${rpath}) +ENDFOREACH(rpath) + +INCLUDE(${CMAKE_SOURCE_DIR}/extra/yassl/CMakeLists.txt) +FOREACH(rpath ${YASSL_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../extra/yassl/${rpath}) +ENDFOREACH(rpath) + +INCLUDE(${CMAKE_SOURCE_DIR}/strings/CMakeLists.txt) +FOREACH(rpath ${STRINGS_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../strings/${rpath}) +ENDFOREACH(rpath) + +INCLUDE(${CMAKE_SOURCE_DIR}/regex/CMakeLists.txt) +FOREACH(rpath ${REGEX_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../regex/${rpath}) +ENDFOREACH(rpath) + +INCLUDE(${CMAKE_SOURCE_DIR}/mysys/CMakeLists.txt) +FOREACH(rpath ${MYSYS_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../mysys/${rpath}) +ENDFOREACH(rpath) + +INCLUDE(${CMAKE_SOURCE_DIR}/vio/CMakeLists.txt) +FOREACH(rpath ${VIO_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ../vio/${rpath}) +ENDFOREACH(rpath) + + + +FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS}) + STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER) + SET(ENGINE_DIR ${${ENGINE_LIB_UPPER}_DIR}) + INCLUDE(${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/CMakeLists.txt) + FOREACH(rpath ${${ENGINE_LIB_UPPER}_SOURCES}) + SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/${rpath}) + ENDFOREACH(rpath) +ENDFOREACH(ENGINE_LIB) + + +SET(SOURCE_SUBLIBS FALSE) + +SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc + ../libmysql/libmysql.c ../libmysql/errmsg.c ../client/get_password.c + ../sql-common/client.c ../sql-common/my_time.c + ../sql-common/my_user.c ../sql-common/pack.c + ../sql/password.c ../sql/discover.cc ../sql/derror.cc + ../sql/field.cc ../sql/field_conv.cc + ../sql/filesort.cc ../sql/gstream.cc ../sql/ha_partition.cc + ../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc + ../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc + ../sql/item.cc ../sql/item_create.cc ../sql/item_func.cc + ../sql/item_geofunc.cc ../sql/item_row.cc ../sql/item_strfunc.cc + ../sql/item_subselect.cc ../sql/item_sum.cc ../sql/item_timefunc.cc + ../sql/item_xmlfunc.cc ../sql/key.cc ../sql/lock.cc ../sql/log.cc + ../sql/log_event.cc ../sql/mf_iocache.cc ../sql/my_decimal.cc + ../sql/net_serv.cc ../sql/opt_range.cc ../sql/opt_sum.cc + ../sql/parse_file.cc ../sql/procedure.cc ../sql/protocol.cc + ../sql/records.cc ../sql/repl_failsafe.cc ../sql/rpl_filter.cc + ../sql/rpl_record.cc + ../sql/rpl_injector.cc ../sql/set_var.cc ../sql/spatial.cc + ../sql/sp_cache.cc ../sql/sp.cc ../sql/sp_head.cc + ../sql/sp_pcontext.cc ../sql/sp_rcontext.cc ../sql/sql_acl.cc + ../sql/sql_analyse.cc ../sql/sql_base.cc ../sql/sql_cache.cc + ../sql/sql_class.cc ../sql/sql_crypt.cc ../sql/sql_cursor.cc + ../sql/sql_db.cc ../sql/sql_delete.cc ../sql/sql_derived.cc + ../sql/sql_do.cc ../sql/sql_error.cc ../sql/sql_handler.cc + ../sql/sql_help.cc ../sql/sql_insert.cc ../sql/sql_lex.cc + ../sql/sql_list.cc ../sql/sql_load.cc ../sql/sql_locale.cc + ../sql/sql_binlog.cc ../sql/sql_manager.cc ../sql/sql_map.cc + ../sql/sql_parse.cc ../sql/sql_partition.cc ../sql/sql_plugin.cc + ../sql/debug_sync.cc + ../sql/sql_prepare.cc ../sql/sql_rename.cc ../sql/sql_repl.cc + ../sql/sql_select.cc ../sql/sql_servers.cc + ../sql/sql_show.cc ../sql/sql_state.c ../sql/sql_string.cc + ../sql/sql_tablespace.cc ../sql/sql_table.cc ../sql/sql_test.cc + ../sql/sql_trigger.cc ../sql/sql_udf.cc ../sql/sql_union.cc + ../sql/sql_update.cc ../sql/sql_view.cc ../sql/sql_profile.cc + ../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc + ../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc + ../sql/partition_info.cc ../sql/sql_connect.cc + ../sql/scheduler.cc ../sql/event_parse_data.cc + ${GEN_SOURCES} + ${LIB_SOURCES}) + +# Seems we cannot make a library without at least one source file. So use a +# dummy empty file +FILE(WRITE cmake_dummy.c " ") + +# Tried use the correct ${GEN_SOURCES} as dependency, worked on Unix +# but not on Windows and Visual Studio generators. Likely because they +# are no real targets from the Visual Studio project files view. Added +# custom targets to "sql/CMakeLists.txt" and reference them here. +ADD_LIBRARY(mysqlserver STATIC ${LIBMYSQLD_SOURCES}) +ADD_DEPENDENCIES(mysqlserver GenServerSource GenError) +TARGET_LINK_LIBRARIES(mysqlserver) + +# Add any additional libraries requested by engine(s) +FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS}) + STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER) + IF(${ENGINE_LIB_UPPER}_LIBS) + TARGET_LINK_LIBRARIES(mysqlserver ${${ENGINE_LIB_UPPER}_LIBS}) + ENDIF(${ENGINE_LIB_UPPER}_LIBS) +ENDFOREACH(ENGINE_LIB) + +ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def) +ADD_DEPENDENCIES(libmysqld mysqlserver) +TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32) diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index fd2609d026e..16c45816bbf 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -20,17 +20,21 @@ MYSQLDATAdir = $(localstatedir) MYSQLSHAREdir = $(pkgdatadir) MYSQLBASEdir= $(prefix) +MYSQLLIBdir= $(libdir) +pkgplugindir = $(pkglibdir)/plugin +EXTRA_DIST = libmysqld.def CMakeLists.txt DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \ - -DSHAREDIR="\"$(MYSQLSHAREdir)\"" -INCLUDES= @bdb_includes@ @innodb_includes@ @ndbcluster_includes@ \ - -I$(top_builddir)/include -I$(top_srcdir)/include \ + -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \ + -DPLUGINDIR="\"$(pkgplugindir)\"" +INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/sql -I$(top_srcdir)/sql \ -I$(top_srcdir)/sql/examples \ -I$(top_srcdir)/regex \ - $(openssl_includes) @ZLIB_INCLUDES@ + $(openssl_includes) @ZLIB_INCLUDES@ \ + @condition_dependent_plugin_includes@ noinst_LIBRARIES = libmysqld_int.a pkglib_LIBRARIES = libmysqld.a @@ -38,52 +42,102 @@ SUBDIRS = . examples libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \ my_time.c -sqlexamplessources = ha_example.cc ha_tina.cc noinst_HEADERS = embedded_priv.h emb_qcache.h sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ - ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_federated.cc \ - ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \ + ha_ndbcluster.cc ha_ndbcluster_cond.cc \ + ha_ndbcluster_binlog.cc ha_partition.cc \ + handler.cc sql_handler.cc \ hostname.cc init.cc password.c \ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \ - item_geofunc.cc item_uniq.cc item_subselect.cc item_row.cc\ - key.cc lock.cc log.cc log_event.cc sql_state.c \ + item_geofunc.cc item_subselect.cc item_row.cc\ + item_xmlfunc.cc \ + key.cc lock.cc log.cc sql_state.c \ + log_event.cc rpl_record.cc \ + log_event_old.cc rpl_record_old.cc \ protocol.cc net_serv.cc opt_range.cc \ opt_sum.cc procedure.cc records.cc sql_acl.cc \ sql_load.cc discover.cc sql_locale.cc \ sql_profile.cc \ sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \ sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \ - sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc sql_parse.cc \ + sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \ + scheduler.cc sql_connect.cc sql_parse.cc \ sql_prepare.cc sql_derived.cc sql_rename.cc \ sql_select.cc sql_do.cc sql_show.cc set_var.cc \ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \ - unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \ + unireg.cc uniques.cc sql_union.cc hash_filo.cc \ spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ - ha_blackhole.cc ha_archive.cc my_user.c - -libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources) + rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \ + debug_sync.cc \ + sql_tablespace.cc \ + rpl_injector.cc my_user.c partition_info.cc \ + sql_servers.cc event_parse_data.cc + +libmysqld_int_a_SOURCES= $(libmysqld_sources) +nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources) libmysqld_a_SOURCES= +sqlstoragesources = $(EXTRA_libmysqld_a_SOURCES) +storagesources = @condition_dependent_plugin_modules@ +storageobjects = @condition_dependent_plugin_objects@ +storagesourceslinks = @condition_dependent_plugin_links@ + # automake misses these sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy # The following libraries should be included in libmysqld.a INC_LIB= $(top_builddir)/regex/libregex.a \ - $(top_builddir)/myisam/libmyisam.a \ - $(top_builddir)/myisammrg/libmyisammrg.a \ - $(top_builddir)/heap/libheap.a \ - @innodb_libs@ @bdb_libs_with_path@ \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a \ $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/vio/libvio.a @NDB_SCI_LIBS@ + $(top_builddir)/vio/libvio.a \ + @NDB_SCI_LIBS@ \ + @mysql_plugin_libs@ \ + $(yassl_inc_libs) + +if HAVE_YASSL +yassl_inc_libs= $(top_builddir)/extra/yassl/src/.libs/libyassl.a \ + $(top_builddir)/extra/yassl/taocrypt/src/.libs/libtaocrypt.a +endif + +# Storage engine specific compilation options +ha_ndbcluster.o:ha_ndbcluster.cc + $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< + +ha_ndbcluster_cond.o:ha_ndbcluster_cond.cc + $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< + +ha_ndbcluster_binlog.o: ha_ndbcluster_binlog.cc + $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< + +# Until we can remove dependency on ha_ndbcluster.h +handler.o: handler.cc + $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $< + +# We need rules to compile these as no good way +# found to append fileslists that collected by configure +# to the sources list +ha_federated.o:ha_federated.cc + $(CXXCOMPILE) $(LM_CFLAGS) -c $< + +ha_heap.o:ha_heap.cc + $(CXXCOMPILE) $(LM_CFLAGS) -c $< + +ha_innodb.o:ha_innodb.cc + $(CXXCOMPILE) $(LM_CFLAGS) -c $< + +ha_myisam.o:ha_myisam.cc + $(CXXCOMPILE) $(LM_CFLAGS) -c $< + +ha_myisammrg.o:ha_myisammrg.cc + $(CXXCOMPILE) $(LM_CFLAGS) -c $< # # To make it easy for the end user to use the embedded library we @@ -95,20 +149,31 @@ INC_LIB= $(top_builddir)/regex/libregex.a \ # need to add the same file twice to the library, so 'sort -u' save us # some time and spares unnecessary work. -libmysqld.a: libmysqld_int.a $(INC_LIB) +libmysqld.a: libmysqld_int.a $(INC_LIB) $(libmysqld_a_DEPENDENCIES) $(storageobjects) if DARWIN_MWCC - mwld -lib -o $@ libmysqld_int.a `echo $(INC_LIB) | sort -u` + mwld -lib -o $@ libmysqld_int.a `echo $(INC_LIB) | sort -u` $(storageobjects) else -rm -f libmysqld.a if test "$(host_os)" = "netware" ; \ then \ - $(libmysqld_a_AR) libmysqld.a libmysqld_int.a $(INC_LIB) ; \ + $(libmysqld_a_AR) libmysqld.a $(INC_LIB) libmysqld_int.a $(storageobjects); \ else \ - for arc in ./libmysqld_int.a $(INC_LIB); do \ - arpath=`echo $$arc|sed 's|[^/]*$$||'`; \ - $(AR) t $$arc|sed "s|^|$$arpath|"; \ - done | sort -u | xargs $(AR) cq libmysqld.a ; \ + current_dir=`pwd`; \ + rm -rf tmp; mkdir tmp; \ + (for arc in $(INC_LIB) ./libmysqld_int.a; do \ + arpath=`echo $$arc|sed 's|[^/]*$$||'|sed 's|\.libs/$$||'`; \ + artmp=`echo $$arc|sed 's|^.*/|tmp/lib-|'`; \ + for F in `$(AR) t $$arc | grep -v SYMDEF`; do \ + if test -e "$$arpath/$$F" ; then echo "$$arpath/$$F"; else \ + mkdir $$artmp; cd $$artmp > /dev/null; \ + $(AR) x ../../$$arc; \ + cd $$current_dir > /dev/null; \ + ls $$artmp/* | grep -v SYMDEF; \ + continue 2; fi; done; \ + done; echo $(libmysqld_a_DEPENDENCIES) ) | sort -u | xargs $(AR) cq libmysqld.a ; \ + $(AR) r libmysqld.a $(storageobjects); \ $(RANLIB) libmysqld.a ; \ + rm -rf tmp; \ fi endif @@ -120,11 +185,11 @@ endif #libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@ #CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la -# This is called from the toplevel makefile. If we can link now -# to an existing file in source, we do that, else we assume it -# will show up in the build tree eventually (generated file). +BUILT_SOURCES = link_sources + +CLEANFILES = $(BUILT_SOURCES) + link_sources: - set -x; \ for f in $(sqlsources); do \ rm -f $$f; \ if test -e $(top_srcdir)/sql/$$f ; \ @@ -143,17 +208,28 @@ link_sources: @LN_CP_F@ $(top_builddir)/libmysql/$$f $$f; \ fi ; \ done; \ - for f in $(sqlexamplessources); do \ - rm -f $$f; \ - @LN_CP_F@ $(top_srcdir)/sql/examples/$$f $$f; \ - done; \ + if test -n "$(sqlstoragesources)" ; \ + then \ + for f in "$(sqlstoragesources)"; do \ + rm -f "$$f"; \ + @LN_CP_F@ `find $(srcdir)/../sql -name "$$f"` "$$f"; \ + done; \ + fi; \ + if test -n "$(storagesources)" ; \ + then \ + rm -f $(storagesources); \ + for f in $(storagesourceslinks); do \ + @LN_CP_F@ $(top_srcdir)/$$f . ; \ + done; \ + fi; \ rm -f client_settings.h; \ - @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h + @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h \ + client_settings.h; \ + echo timestamp > link_sources clean-local: - rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlexamplessources) | sed "s;\.lo;.c;g"` \ - $(top_srcdir)/linked_libmysqld_sources; \ + rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) $(storagesources) | sed "s;\.lo;.c;g"`; \ rm -f client_settings.h # Don't update the files from bitkeeper diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc index e6f35aa33a0..b4eddf39c1f 100644 --- a/libmysqld/emb_qcache.cc +++ b/libmysqld/emb_qcache.cc @@ -19,7 +19,7 @@ #include "emb_qcache.h" #include "embedded_priv.h" -void Querycache_stream::store_char(char c) +void Querycache_stream::store_uchar(uchar c) { if (data_end == cur_data) use_next_block(TRUE); @@ -47,9 +47,9 @@ void Querycache_stream::store_short(ushort s) cur_data+= 2; return; } - *cur_data= ((byte *)(&s))[0]; + *cur_data= ((uchar *)(&s))[0]; use_next_block(TRUE); - *(cur_data++)= ((byte *)(&s))[1]; + *(cur_data++)= ((uchar *)(&s))[1]; } void Querycache_stream::store_int(uint i) @@ -100,7 +100,7 @@ void Querycache_stream::store_ll(ulonglong ll) } memcpy(cur_data, &ll, rest_len); use_next_block(TRUE); - memcpy(cur_data, ((byte*)&ll)+rest_len, 8-rest_len); + memcpy(cur_data, ((uchar*)&ll)+rest_len, 8-rest_len); cur_data+= 8-rest_len; } @@ -142,7 +142,7 @@ void Querycache_stream::store_safe_str(const char *str, uint str_len) store_int(0); } -char Querycache_stream::load_char() +uchar Querycache_stream::load_uchar() { if (cur_data == data_end) use_next_block(FALSE); @@ -165,9 +165,9 @@ ushort Querycache_stream::load_short() cur_data+= 2; return result; } - ((byte*)&result)[0]= *cur_data; + ((uchar*)&result)[0]= *cur_data; use_next_block(FALSE); - ((byte*)&result)[1]= *(cur_data++); + ((uchar*)&result)[1]= *(cur_data++); return result; } @@ -216,7 +216,7 @@ ulonglong Querycache_stream::load_ll() } memcpy(&result, cur_data, rest_len); use_next_block(FALSE); - memcpy(((byte*)&result)+rest_len, cur_data, 8-rest_len); + memcpy(((uchar*)&result)+rest_len, cur_data, 8-rest_len); cur_data+= 8-rest_len; return result; } @@ -245,7 +245,7 @@ char *Querycache_stream::load_str(MEM_ROOT *alloc, uint *str_len) { char *result; *str_len= load_int(); - if (!(result= alloc_root(alloc, *str_len + 1))) + if (!(result= (char*) alloc_root(alloc, *str_len + 1))) return 0; load_str_only(result, *str_len); return result; @@ -259,7 +259,7 @@ int Querycache_stream::load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len) return 0; } (*str_len)--; - if (!(*str= alloc_root(alloc, *str_len + 1))) + if (!(*str= (char*) alloc_root(alloc, *str_len + 1))) return 1; load_str_only(*str, *str_len); return 0; @@ -301,8 +301,8 @@ uint emb_count_querycache_size(THD *thd) *data->embedded_info->prev_ptr= NULL; // this marks the last record cur_row= data->data; n_rows= data->rows; - /* n_fields + n_rows + (field_info + strlen * n_rows) * n_fields */ - result+= (uint) (4+8 + (42 + 4*n_rows)*data->fields); + /* n_fields + n_rows + field_info * n_fields */ + result+= (uint) (4+8 + 42*data->fields); for(; field < field_end; field++) { @@ -313,13 +313,23 @@ uint emb_count_querycache_size(THD *thd) result+= field->def_length; } - for (; cur_row; cur_row=cur_row->next) + if (thd->protocol == &thd->protocol_binary) { - MYSQL_ROW col= cur_row->data; - MYSQL_ROW col_end= col + data->fields; - for (; col < col_end; col++) - if (*col) - result+= *(uint *)((*col) - sizeof(uint)); + result+= (uint) (4*n_rows); + for (; cur_row; cur_row=cur_row->next) + result+= cur_row->length; + } + else + { + result+= (uint) (4*n_rows*data->fields); + for (; cur_row; cur_row=cur_row->next) + { + MYSQL_ROW col= cur_row->data; + MYSQL_ROW col_end= col + data->fields; + for (; col < col_end; col++) + if (*col) + result+= *(uint *)((*col) - sizeof(uint)); + } } return result; } @@ -353,10 +363,10 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd) { dst->store_int((uint)field->length); dst->store_int((uint)field->max_length); - dst->store_char((char)field->type); + dst->store_uchar((uchar)field->type); dst->store_short((ushort)field->flags); dst->store_short((ushort)field->charsetnr); - dst->store_char((char)field->decimals); + dst->store_uchar((uchar)field->decimals); dst->store_str(field->name, field->name_length); dst->store_str(field->table, field->table_length); dst->store_str(field->org_name, field->org_name_length); @@ -366,14 +376,22 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd) dst->store_safe_str(field->def, field->def_length); } - for (; cur_row; cur_row=cur_row->next) + if (thd->protocol == &thd->protocol_binary) { - MYSQL_ROW col= cur_row->data; - MYSQL_ROW col_end= col + data->fields; - for (; col < col_end; col++) + for (; cur_row; cur_row=cur_row->next) + dst->store_str((char *) cur_row->data, cur_row->length); + } + else + { + for (; cur_row; cur_row=cur_row->next) { - uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0; - dst->store_safe_str(*col, len); + MYSQL_ROW col= cur_row->data; + MYSQL_ROW col_end= col + data->fields; + for (; col < col_end; col++) + { + uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0; + dst->store_safe_str(*col, len); + } } } DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size); @@ -408,10 +426,10 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src) { field->length= src->load_int(); field->max_length= (unsigned int)src->load_int(); - field->type= (enum enum_field_types)src->load_char(); + field->type= (enum enum_field_types)src->load_uchar(); field->flags= (unsigned int)src->load_short(); field->charsetnr= (unsigned int)src->load_short(); - field->decimals= (unsigned int)src->load_char(); + field->decimals= src->load_uchar(); if (!(field->name= src->load_str(f_alloc, &field->name_length)) || !(field->table= src->load_str(f_alloc,&field->table_length)) || @@ -423,31 +441,49 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src) goto err; } - row= (MYSQL_ROWS *)alloc_root(&data->alloc, - (uint) (rows * sizeof(MYSQL_ROWS) + - rows*(data->fields+1)*sizeof(char*))); - end_row= row + rows; - columns= (MYSQL_ROW)end_row; - data->rows= rows; - data->data= row; if (!rows) goto return_ok; + if (thd->protocol == &thd->protocol_binary) + { + uint length; + row= (MYSQL_ROWS *)alloc_root(&data->alloc, + (size_t) (rows * sizeof(MYSQL_ROWS))); + end_row= row + rows; + data->data= row; - for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++) + for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++) + { + *prev_row= row; + row->data= (MYSQL_ROW) src->load_str(&data->alloc, &length); + row->length= length; + } + } + else { - *prev_row= row; - row->data= columns; - MYSQL_ROW col_end= columns + data->fields; - for (; columns < col_end; columns++) - src->load_column(&data->alloc, columns); + row= (MYSQL_ROWS *)alloc_root(&data->alloc, + (uint) (rows * sizeof(MYSQL_ROWS) + + rows*(data->fields+1)*sizeof(char*))); + end_row= row + rows; + columns= (MYSQL_ROW)end_row; - *(columns++)= NULL; + data->data= row; + + for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++) + { + *prev_row= row; + row->data= columns; + MYSQL_ROW col_end= columns + data->fields; + for (; columns < col_end; columns++) + src->load_column(&data->alloc, columns); + + *(columns++)= NULL; + } } *prev_row= NULL; data->embedded_info->prev_ptr= prev_row; return_ok: - send_eof(thd); + net_send_eof(thd, thd->server_status, thd->total_warn_count); DBUG_RETURN(0); err: DBUG_RETURN(1); diff --git a/libmysqld/emb_qcache.h b/libmysqld/emb_qcache.h index 5c5209902a1..ecf91487667 100644 --- a/libmysqld/emb_qcache.h +++ b/libmysqld/emb_qcache.h @@ -15,8 +15,8 @@ class Querycache_stream { - byte *cur_data; - byte *data_end; + uchar *cur_data; + uchar *data_end; Query_cache_block *block; uint headers_len; public: @@ -27,7 +27,7 @@ public: Querycache_stream(Query_cache_block *ini_block, uint ini_headers_len) : block(ini_block), headers_len(ini_headers_len) { - cur_data= ((byte*)block)+headers_len; + cur_data= ((uchar*)block)+headers_len; data_end= cur_data + (block->used-headers_len); #ifndef DBUG_OFF first_block= ini_block; @@ -54,11 +54,11 @@ public: else DBUG_ASSERT(block->type == Query_cache_block::RES_CONT); - cur_data= ((byte*)block)+headers_len; + cur_data= ((uchar*)block)+headers_len; data_end= cur_data + (block->used-headers_len); } - void store_char(char c); + void store_uchar(uchar c); void store_short(ushort s); void store_int(uint i); void store_ll(ulonglong ll); @@ -66,7 +66,7 @@ public: void store_str(const char *str, uint str_len); void store_safe_str(const char *str, uint str_len); - char load_char(); + uchar load_uchar(); ushort load_short(); uint load_int(); ulonglong load_ll(); @@ -79,3 +79,4 @@ public: uint emb_count_querycache_size(THD *thd); int emb_load_querycache_result(THD *thd, Querycache_stream *src); void emb_store_querycache_result(Querycache_stream *dst, THD* thd); +bool net_send_eof(THD *thd, uint server_status, uint total_warn_count); diff --git a/libmysqld/examples/CMakeLists.txt b/libmysqld/examples/CMakeLists.txt new file mode 100644 index 00000000000..5194836a728 --- /dev/null +++ b/libmysqld/examples/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/libmysqld/include + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/zlib + ${CMAKE_SOURCE_DIR}/extra/yassl/include) + +# Currently does not work with DBUG, there are missing symbols reported. +IF(WIN32) + ADD_DEFINITIONS(-DUSE_TLS) +ENDIF(WIN32) + +ADD_DEFINITIONS(-DEMBEDDED_LIBRARY) + +ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc + ../../client/mysql.cc ../../client/readline.cc + ../../client/sql_string.cc) +TARGET_LINK_LIBRARIES(mysql_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) +TARGET_LINK_LIBRARIES(mysql_embedded libmysqld) + +ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.cc) +TARGET_LINK_LIBRARIES(mysqltest_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) +TARGET_LINK_LIBRARIES(mysqltest_embedded libmysqld) + +ADD_EXECUTABLE(mysql_client_test_embedded ../../tests/mysql_client_test.c) +TARGET_LINK_LIBRARIES(mysql_client_test_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32) +TARGET_LINK_LIBRARIES(mysql_client_test_embedded libmysqld) diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index e0dd8491688..109d33a85ae 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -15,12 +15,13 @@ noinst_PROGRAMS = mysql bin_PROGRAMS = mysqltest_embedded mysql_client_test_embedded -client_sources = $(mysqltest_embedded_SOURCES) $(mysql_SOURCES) -tests_sources = $(mysql_client_test_embedded_SOURCES) -CLEANFILES = $(client_sources) $(tests_sources) +client_sources = $(nodist_mysqltest_embedded_SOURCES) $(nodist_mysql_SOURCES) +tests_sources = $(nodist_mysql_client_test_embedded_SOURCES) +BUILT_SOURCES = link_sources +CLEANFILES = $(client_sources) $(tests_sources) $(BUILT_SOURCES) +EXTRA_DIST = CMakeLists.txt link_sources: - set -x; \ for f in $(client_sources); do \ rm -f $$f; \ @LN_CP_F@ $(top_srcdir)/client/$$f $$f; \ @@ -29,25 +30,26 @@ link_sources: rm -f $$f; \ @LN_CP_F@ $(top_srcdir)/tests/$$f $$f; \ done + echo timestamp > link_sources DEFS = -DEMBEDDED_LIBRARY INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir) \ -I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \ $(openssl_includes) LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs) -LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) \ +LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @LIBDL@ $(CXXLDFLAGS) \ @NDB_SCI_LIBS@ mysqltest_embedded_LINK = $(CXXLINK) -mysqltest_embedded_SOURCES = mysqltest.c +nodist_mysqltest_embedded_SOURCES = mysqltest.cc mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a -mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \ +nodist_mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \ my_readline.h sql_string.h completion_hash.h mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) mysql_client_test_embedded_LINK = $(CXXLINK) -mysql_client_test_embedded_SOURCES = mysql_client_test.c +nodist_mysql_client_test_embedded_SOURCES = mysql_client_test.c # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/libmysqld/examples/builder-sample/emb_samples.cpp b/libmysqld/examples/builder-sample/emb_samples.cpp index 411de26149b..be3f1931af5 100644 --- a/libmysqld/examples/builder-sample/emb_samples.cpp +++ b/libmysqld/examples/builder-sample/emb_samples.cpp @@ -3,7 +3,7 @@ #pragma hdrstop #include "emb_samples.h" -#include <winsock.h> +#include <winsock2.h> #include <mysql.h> #include <stdarg.h> #include <stdio.h> diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index b0a47727c7c..778d4874ad4 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -28,16 +28,7 @@ extern "C" extern unsigned long max_allowed_packet, net_buffer_length; } -#if defined (__WIN__) -#include "../sql/mysqld.cpp" -#else #include "../sql/mysqld.cc" -#endif - -int check_user(THD *thd, enum enum_server_command command, - const char *passwd, uint passwd_len, const char *db, - bool check_count); -void thd_init_client_charset(THD *thd, uint cs_number); C_MODE_START @@ -52,6 +43,15 @@ extern char mysql_server_last_error[MYSQL_ERRMSG_SIZE]; static my_bool emb_read_query_result(MYSQL *mysql); +extern "C" void unireg_clear(int exit_code) +{ + DBUG_ENTER("unireg_clear"); + clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */ + my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); + DBUG_VOID_RETURN; +} + + /* Reads error information from the MYSQL_DATA and puts it into proper MYSQL members @@ -73,39 +73,53 @@ void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data) NET *net= &mysql->net; struct embedded_query_result *ei= data->embedded_info; net->last_errno= ei->last_errno; - strmake(net->last_error, ei->info, sizeof(net->last_error)); + strmake(net->last_error, ei->info, sizeof(net->last_error)-1); memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate)); mysql->server_status= ei->server_status; - my_free((gptr) data, MYF(0)); + my_free(data, MYF(0)); } static my_bool emb_advanced_command(MYSQL *mysql, enum enum_server_command command, - const char *header, ulong header_length, - const char *arg, ulong arg_length, my_bool skip_check, + const uchar *header, ulong header_length, + const uchar *arg, ulong arg_length, my_bool skip_check, MYSQL_STMT *stmt) { my_bool result= 1; THD *thd=(THD *) mysql->thd; NET *net= &mysql->net; + my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE; + + if (!thd) + { + /* Do "reconnect" if possible */ + if (mysql_reconnect(mysql) || stmt_skip) + return 1; + thd= (THD *) mysql->thd; + } + +#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) + thd->profiling.start_new_query(); +#endif thd->clear_data_list(); /* Check that we are calling the client functions in right order */ if (mysql->status != MYSQL_STATUS_READY) { - strmov(net->last_error, - ER(net->last_errno=CR_COMMANDS_OUT_OF_SYNC)); + set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); return 1; } /* Clear result variables */ thd->clear_error(); + thd->main_da.reset_diagnostics_area(); mysql->affected_rows= ~(my_ulonglong) 0; mysql->field_count= 0; - net->last_errno= 0; + net_clear_error(net); thd->current_stmt= stmt; thd->store_globals(); // Fix if more than one connect + lex_start(thd); /* We have to call free_old_query before we start to fill mysql->fields for new query. In the case of embedded server we collect field data @@ -122,13 +136,17 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, arg_length= header_length; } - thd->net.no_send_error= 0; - result= dispatch_command(command, thd, (char *) arg, arg_length + 1); + result= dispatch_command(command, thd, (char *) arg, arg_length); thd->cur_data= 0; if (!skip_check) - result= thd->net.last_errno ? -1 : 0; + result= thd->is_error() ? -1 : 0; + thd->mysys_var= 0; + +#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) + thd->profiling.finish_current_query(); +#endif return result; } @@ -188,7 +206,7 @@ static MYSQL_FIELD *emb_list_fields(MYSQL *mysql) res= ((THD*) mysql->thd)->cur_data; ((THD*) mysql->thd)->cur_data= 0; mysql->field_alloc= res->alloc; - my_free((gptr) res,MYF(0)); + my_free(res,MYF(0)); mysql->status= MYSQL_STATUS_READY; return mysql->fields; } @@ -217,7 +235,7 @@ static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) stmt->fields= mysql->fields; stmt->mem_root= res->alloc; mysql->fields= NULL; - my_free((gptr) res,MYF(0)); + my_free(res,MYF(0)); } return 0; @@ -254,11 +272,12 @@ static my_bool emb_read_query_result(MYSQL *mysql) mysql->warning_count= res->embedded_info->warning_count; mysql->server_status= res->embedded_info->server_status; mysql->field_count= res->fields; - mysql->fields= res->embedded_info->fields_list; - mysql->affected_rows= res->embedded_info->affected_rows; - mysql->insert_id= res->embedded_info->insert_id; - mysql->net.last_errno= 0; - mysql->net.last_error[0]= 0; + if (!(mysql->fields= res->embedded_info->fields_list)) + { + mysql->affected_rows= res->embedded_info->affected_rows; + mysql->insert_id= res->embedded_info->insert_id; + } + net_clear_error(&mysql->net); mysql->info= 0; if (res->embedded_info->info[0]) @@ -273,7 +292,7 @@ static my_bool emb_read_query_result(MYSQL *mysql) thd->cur_data= res; } else - my_free((gptr) res, MYF(0)); + my_free(res, MYF(0)); return 0; } @@ -281,12 +300,12 @@ static my_bool emb_read_query_result(MYSQL *mysql) static int emb_stmt_execute(MYSQL_STMT *stmt) { DBUG_ENTER("emb_stmt_execute"); - char header[5]; + uchar header[5]; THD *thd; my_bool res; int4store(header, stmt->stmt_id); - header[4]= stmt->flags; + header[4]= (uchar) stmt->flags; thd= (THD*)stmt->mysql->thd; thd->client_param_count= stmt->param_count; thd->client_params= stmt->params; @@ -300,7 +319,7 @@ static int emb_stmt_execute(MYSQL_STMT *stmt) if (res) { NET *net= &stmt->mysql->net; - set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); + set_stmt_errmsg(stmt, net); DBUG_RETURN(1); } DBUG_RETURN(0); @@ -311,14 +330,12 @@ int emb_read_binary_rows(MYSQL_STMT *stmt) MYSQL_DATA *data; if (!(data= emb_read_rows(stmt->mysql, 0, 0))) { - set_stmt_errmsg(stmt, stmt->mysql->net.last_error, - stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate); + set_stmt_errmsg(stmt, &stmt->mysql->net); return 1; } stmt->result= *data; my_free((char *) data, MYF(0)); - set_stmt_errmsg(stmt, stmt->mysql->net.last_error, - stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate); + set_stmt_errmsg(stmt, &stmt->mysql->net); return 0; } @@ -332,16 +349,14 @@ int emb_read_rows_from_cursor(MYSQL_STMT *stmt) if (res->embedded_info->last_errno) { embedded_get_error(mysql, res); - set_stmt_errmsg(stmt, mysql->net.last_error, - mysql->net.last_errno, mysql->net.sqlstate); + set_stmt_errmsg(stmt, &mysql->net); return 1; } thd->cur_data= res; mysql->warning_count= res->embedded_info->warning_count; mysql->server_status= res->embedded_info->server_status; - mysql->net.last_errno= 0; - mysql->net.last_error[0]= 0; + net_clear_error(&mysql->net); return emb_read_binary_rows(stmt); } @@ -380,14 +395,16 @@ static void emb_free_embedded_thd(MYSQL *mysql) thd->clear_data_list(); thread_count--; thd->store_globals(); + thd->unlink(); delete thd; + my_pthread_setspecific_ptr(THR_THD, 0); mysql->thd=0; } static const char * emb_read_statistics(MYSQL *mysql) { THD *thd= (THD*)mysql->thd; - return thd->net.last_error; + return thd->is_error() ? thd->main_da.message() : ""; } @@ -478,6 +495,12 @@ int init_embedded_server(int argc, char **argv, char **groups) my_progname= (char *)"mysql_embedded"; + /* + Perform basic logger initialization logger. Should be called after + MY_INIT, as it initializes mutexes. Log tables are inited later. + */ + logger.init_base(); + if (init_common_variables("my", *argcp, *argvp, (const char **)groups)) { mysql_server_end(); @@ -528,16 +551,12 @@ int init_embedded_server(int argc, char **argv, char **groups) (void) thr_setconcurrency(concurrency); // 10 by default - if ( -#ifdef HAVE_BERKELEY_DB - (have_berkeley_db == SHOW_OPTION_YES) || -#endif - (flush_time && flush_time != ~(ulong) 0L)) - { - pthread_t hThread; - if (pthread_create(&hThread,&connection_attrib,handle_manager,0)) - sql_print_error("Warning: Can't create thread to manage maintenance"); - } + start_handle_manager(); + + // FIXME initialize binlog_filter and rpl_filter if not already done + // corresponding delete is in clean_up() + if(!binlog_filter) binlog_filter = new Rpl_filter; + if(!rpl_filter) rpl_filter = new Rpl_filter; if (opt_init_file) { @@ -548,6 +567,7 @@ int init_embedded_server(int argc, char **argv, char **groups) } } + execute_ddl_log_recovery(); return 0; } @@ -567,10 +587,21 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag) init_alloc_root(&mysql->field_alloc, 8192, 0); } +/** + @brief Initialize a new THD for a connection in the embedded server + + @param client_flag Client capabilities which this thread supports + @return pointer to the created THD object + + @todo + This function copies code from several places in the server, including + create_new_thread(), and prepare_new_connection_state(). This should + be refactored to avoid code duplication. +*/ void *create_embedded_thd(int client_flag) { THD * thd= new THD; - thd->thread_id= thread_id++; + thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; thd->thread_stack= (char*) &thd; if (thd->store_globals()) @@ -578,12 +609,9 @@ void *create_embedded_thd(int client_flag) fprintf(stderr,"store_globals failed.\n"); goto err; } + lex_start(thd); - thd->mysys_var= my_thread_var; - thd->dbug_thread_id= my_thread_id(); - thd->thread_stack= (char*) &thd; - -/* TODO - add init_connect command execution */ + /* TODO - add init_connect command execution */ if (thd->variables.max_join_size == HA_POS_ERROR) thd->options |= OPTION_BIG_SELECTS; @@ -593,7 +621,7 @@ void *create_embedded_thd(int client_flag) thd->set_time(); thd->init_for_queries(); thd->client_capabilities= client_flag; - thd->real_id= (pthread_t)thd->thread_id; + thd->real_id= pthread_self(); thd->db= NULL; thd->db_length= 0; @@ -607,6 +635,8 @@ void *create_embedded_thd(int client_flag) bzero((char*) &thd->net, sizeof(thd->net)); thread_count++; + threads.append(thd); + thd->mysys_var= 0; return thd; err: delete(thd); @@ -626,6 +656,7 @@ int check_embedded_connection(MYSQL *mysql, const char *db) strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1); sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0)); result= check_user(thd, COM_CONNECT, NULL, 0, db, true); + net_end_statement(thd); emb_read_query_result(mysql); return result; } @@ -675,8 +706,10 @@ int check_embedded_connection(MYSQL *mysql, const char *db) err: { NET *net= &mysql->net; - memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error)); - memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate)); + strmake(net->last_error, thd->main_da.message(), sizeof(net->last_error)-1); + memcpy(net->sqlstate, + mysql_errno_to_sqlstate(thd->main_da.sql_errno()), + sizeof(net->sqlstate)-1); } return result; } @@ -699,9 +732,8 @@ void THD::clear_data_list() void THD::clear_error() { - net.last_error[0]= 0; - net.last_errno= 0; - net.report_error= 0; + if (main_da.is_error()) + main_da.reset_diagnostics_area(); } static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length, @@ -764,23 +796,21 @@ MYSQL_DATA *THD::alloc_new_dataset() } -/* - stores server_status and warning_count in the current - query result structures - - SYNOPSIS - write_eof_packet() - thd current thread +/** + Stores server_status and warning_count in the current + query result structures. - NOTES - should be called to after we get the recordset-result + @param thd current thread + @note Should be called after we get the recordset-result. */ -static void write_eof_packet(THD *thd) +static +bool +write_eof_packet(THD *thd, uint server_status, uint total_warn_count) { if (!thd->mysql) // bootstrap file handling - return; + return FALSE; /* The following test should never be true, but it's better to do it because if 'is_fatal_error' is set the server is not going to execute @@ -788,13 +818,14 @@ static void write_eof_packet(THD *thd) */ if (thd->is_fatal_error) thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; - thd->cur_data->embedded_info->server_status= thd->server_status; + thd->cur_data->embedded_info->server_status= server_status; /* Don't send warn count during SP execution, as the warn_list is cleared between substatements, and mysqltest gets confused */ thd->cur_data->embedded_info->warning_count= - (thd->spcont ? 0 : min(thd->total_warn_count, 65535)); + (thd->spcont ? 0 : min(total_warn_count, 65535)); + return FALSE; } @@ -825,7 +856,7 @@ int Protocol::begin_dataset() remove last row of current recordset SYNOPSIS - Protocol_simple::remove_last_row() + Protocol_text::remove_last_row() NOTES does the loop from the beginning of the current recordset to @@ -833,12 +864,12 @@ int Protocol::begin_dataset() Not supposed to be frequently called. */ -void Protocol_simple::remove_last_row() +void Protocol_text::remove_last_row() { MYSQL_DATA *data= thd->cur_data; MYSQL_ROWS **last_row_hook= &data->data; - uint count= data->rows; - DBUG_ENTER("Protocol_simple::remove_last_row"); + my_ulonglong count= data->rows; + DBUG_ENTER("Protocol_text::remove_last_row"); while (--count) last_row_hook= &(*last_row_hook)->next; @@ -950,7 +981,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags) } if (flags & SEND_EOF) - write_eof_packet(thd); + write_eof_packet(thd, thd->server_status, thd->total_warn_count); DBUG_RETURN(prepare_for_send(list)); err: @@ -967,7 +998,7 @@ bool Protocol::write() return false; } -bool Protocol_prep::write() +bool Protocol_binary::write() { MYSQL_ROWS *cur; MYSQL_DATA *data= thd->cur_data; @@ -990,52 +1021,96 @@ bool Protocol_prep::write() return false; } -void -send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message) + +/** + Embedded library implementation of OK response. + + This function is used by the server to write 'OK' packet to + the "network" when the server is compiled as an embedded library. + Since there is no network in the embedded configuration, + a different implementation is necessary. + Instead of marshalling response parameters to a network representation + and then writing it to the socket, here we simply copy the data to the + corresponding client-side connection structures. + + @sa Server implementation of net_send_ok in protocol.cc for + description of the arguments. + + @return + @retval TRUE An error occurred + @retval FALSE Success +*/ + +bool +net_send_ok(THD *thd, + uint server_status, uint total_warn_count, + ha_rows affected_rows, ulonglong id, const char *message) { - DBUG_ENTER("send_ok"); + DBUG_ENTER("emb_net_send_ok"); MYSQL_DATA *data; + bool error; MYSQL *mysql= thd->mysql; - + if (!mysql) // bootstrap file handling - DBUG_VOID_RETURN; - if (thd->net.no_send_ok) // hack for re-parsing queries - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); if (!(data= thd->alloc_new_dataset())) - return; + return TRUE; data->embedded_info->affected_rows= affected_rows; data->embedded_info->insert_id= id; if (message) strmake(data->embedded_info->info, message, sizeof(data->embedded_info->info)-1); - write_eof_packet(thd); + error= write_eof_packet(thd, server_status, total_warn_count); thd->cur_data= 0; - DBUG_VOID_RETURN; + DBUG_RETURN(error); } -void -send_eof(THD *thd) + +/** + Embedded library implementation of EOF response. + + @sa net_send_ok + + @return + @retval TRUE An error occurred + @retval FALSE Success +*/ + +bool +net_send_eof(THD *thd, uint server_status, uint total_warn_count) { - write_eof_packet(thd); + bool error= write_eof_packet(thd, server_status, total_warn_count); thd->cur_data= 0; + return error; } -void net_send_error_packet(THD *thd, uint sql_errno, const char *err) +bool net_send_error_packet(THD *thd, uint sql_errno, const char *err) { - MYSQL_DATA *data= thd->cur_data ? thd->cur_data : thd->alloc_new_dataset(); - struct embedded_query_result *ei= data->embedded_info; + MYSQL_DATA *data= thd->cur_data; + struct embedded_query_result *ei; + + if (!thd->mysql) // bootstrap file handling + { + fprintf(stderr, "ERROR: %d %s\n", sql_errno, err); + return TRUE; + } + if (!data) + data= thd->alloc_new_dataset(); + + ei= data->embedded_info; ei->last_errno= sql_errno; strmake(ei->info, err, sizeof(ei->info)-1); strmov(ei->sqlstate, mysql_errno_to_sqlstate(sql_errno)); ei->server_status= thd->server_status; thd->cur_data= 0; + return FALSE; } -void Protocol_simple::prepare_for_resend() +void Protocol_text::prepare_for_resend() { MYSQL_ROWS *cur; MYSQL_DATA *data= thd->cur_data; @@ -1056,41 +1131,48 @@ void Protocol_simple::prepare_for_resend() data->embedded_info->prev_ptr= &cur->next; next_field=cur->data; next_mysql_field= data->embedded_info->fields_list; +#ifndef DBUG_OFF + field_pos= 0; +#endif DBUG_VOID_RETURN; } -bool Protocol_simple::store_null() +bool Protocol_text::store_null() { *(next_field++)= NULL; ++next_mysql_field; return false; } -bool Protocol::net_store_data(const char *from, uint length) +bool Protocol::net_store_data(const uchar *from, size_t length) { char *field_buf; if (!thd->mysql) // bootstrap file handling - return false; + return FALSE; - if (!(field_buf=alloc_root(alloc, length + sizeof(uint) + 1))) - return true; + if (!(field_buf= (char*) alloc_root(alloc, length + sizeof(uint) + 1))) + return TRUE; *(uint *)field_buf= length; *next_field= field_buf + sizeof(uint); - memcpy(*next_field, from, length); + memcpy((uchar*) *next_field, from, length); (*next_field)[length]= 0; if (next_mysql_field->max_length < length) next_mysql_field->max_length=length; ++next_field; ++next_mysql_field; - return false; + return FALSE; } +#if defined(_MSC_VER) && _MSC_VER < 1400 +#define vsnprintf _vsnprintf +#endif -void vprint_msg_to_log(enum loglevel level __attribute__((unused)), +int vprint_msg_to_log(enum loglevel level __attribute__((unused)), const char *format, va_list argsi) { vsnprintf(mysql_server_last_error, sizeof(mysql_server_last_error), format, argsi); mysql_server_last_errno= CR_UNKNOWN_ERROR; + return 0; } diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 969ea442622..0c20b35236d 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -210,8 +210,9 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, DBUG_RETURN(mysql); error: - DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno, - mysql->net.last_error)); + DBUG_PRINT("error",("message: %u (%s)", + mysql->net.last_errno, + mysql->net.last_error)); { /* Free alloced memory */ my_bool free_me=mysql->free_me; diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index 8829112fefd..e0f02003963 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -1,34 +1,7 @@ LIBRARY LIBMYSQLD -DESCRIPTION 'MySQL 5.0 Embedded Server Library' -VERSION 5.0 +DESCRIPTION 'MySQL 5.1 Embedded Server Library' +VERSION 5.1 EXPORTS - _dig_vec_upper - _dig_vec_lower - bmove_upp - delete_dynamic - free_defaults - getopt_compare_strings - getopt_ull_limit_value - handle_options - init_dynamic_array - insert_dynamic - int2str - is_prefix - list_add - list_delete - load_defaults - max_allowed_packet - my_end - my_getopt_print_errors - my_init - my_malloc - my_memdup - my_no_flags_free - my_path - my_print_help - my_print_variables - my_realloc - my_strdup mysql_thread_end mysql_thread_init myodbc_remove_escape @@ -40,11 +13,14 @@ EXPORTS mysql_commit mysql_data_seek mysql_debug + mysql_disable_rpl_parse mysql_dump_debug_info + mysql_enable_rpl_parse mysql_eof mysql_errno mysql_error mysql_escape_string + mysql_hex_string mysql_fetch_field mysql_fetch_field_direct mysql_fetch_fields @@ -54,15 +30,18 @@ EXPORTS mysql_field_seek mysql_field_tell mysql_free_result + mysql_get_character_set_info mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info + mysql_get_client_version mysql_get_ssl_cipher mysql_info mysql_init mysql_insert_id mysql_kill + mysql_set_server_option mysql_list_dbs mysql_list_fields mysql_list_processes @@ -83,6 +62,8 @@ EXPORTS mysql_rollback mysql_row_seek mysql_row_tell + mysql_rpl_parse_enabled + mysql_rpl_probe mysql_select_db mysql_send_query mysql_shutdown @@ -94,43 +75,12 @@ EXPORTS mysql_thread_safe mysql_use_result mysql_warning_count - set_dynamic - strcend - strcont - strdup_root - strfill - strinstr - strmake - strmov - strxmov mysql_server_end mysql_server_init get_tty_password - sql_protocol_typelib mysql_get_server_version + mysql_set_character_set mysql_sqlstate - charsets_dir - disabled_my_option - my_charset_latin1 - init_alloc_root - my_progname - get_charset_name - get_charset_by_csname - print_defaults - find_type - strxnmov - strend - my_fopen - my_fclose - unpack_filename - str2int - int10_to_str - longlong10_to_str - my_snprintf_8bit - alloc_root - free_root - my_read - llstr mysql_get_parameters mysql_stmt_bind_param mysql_stmt_bind_result @@ -159,8 +109,3 @@ EXPORTS mysql_stmt_attr_get mysql_stmt_attr_set mysql_stmt_field_count - get_defaults_options - my_charset_bin - my_charset_same - modify_defaults_file - mysql_set_server_option |