From 5490cdfb24695ff23dad57d3b7b0976238800e4b Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Sat, 23 Jul 2005 12:06:02 +0200 Subject: [PATCH 01/11] Add tool to extract config info from ndb_mgmd --- ndb/include/mgmapi/mgmapi.h | 7 + ndb/src/mgmapi/mgmapi.cpp | 62 ++++-- ndb/src/mgmsrv/ConfigInfo.hpp | 6 +- ndb/tools/Makefile.am | 13 +- ndb/tools/config.cpp | 407 ++++++++++++++++++++++++++++++++++ 5 files changed, 467 insertions(+), 28 deletions(-) create mode 100644 ndb/tools/config.cpp diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h index fa0774afa06..26b9dc65947 100644 --- a/ndb/include/mgmapi/mgmapi.h +++ b/ndb/include/mgmapi/mgmapi.h @@ -49,6 +49,7 @@ * @{ */ +#include #include #include "mgmapi_config_parameters.h" @@ -351,6 +352,12 @@ extern "C" { int ndb_mgm_get_latest_error_line(const NdbMgmHandle handle); #endif + /** + * Set error stream + */ + void ndb_mgm_set_error_stream(NdbMgmHandle, FILE *); + + /** @} *********************************************************************/ /** * @name Functions: Create/Destroy Management Server Handles diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 863f54ce51a..c14847ef512 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -100,6 +100,7 @@ struct ndb_mgm_handle { #ifdef MGMAPI_LOG FILE* logfile; #endif + FILE *errstream; }; #define SET_ERROR(h, e, s) setError(h, e, __LINE__, s) @@ -152,6 +153,7 @@ ndb_mgm_create_handle() h->read_timeout = 50000; h->write_timeout = 100; h->cfg_i = 0; + h->errstream = stdout; strncpy(h->last_error_desc, "No error", NDB_MGM_MAX_ERR_DESC_SIZE); @@ -205,6 +207,13 @@ ndb_mgm_destroy_handle(NdbMgmHandle * handle) * handle = 0; } +extern "C" +void +ndb_mgm_set_error_stream(NdbMgmHandle handle, FILE * file) +{ + handle->errstream = file; +} + /***************************************************************************** * Error handling *****************************************************************************/ @@ -369,8 +378,8 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries, break; if (verbose > 0) { char buf[1024]; - ndbout_c("Unable to connect with connect string: %s", - cfg.makeConnectString(buf,sizeof(buf))); + fprintf(handle->errstream, "Unable to connect with connect string: %s\n", + cfg.makeConnectString(buf,sizeof(buf))); verbose= -1; } if (no_retries == 0) { @@ -379,32 +388,35 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries, "Unable to connect with connect string: %s", cfg.makeConnectString(buf,sizeof(buf))); if (verbose == -2) - ndbout << ", failed." << endl; + fprintf(handle->errstream, ", failed.\n"); return -1; } if (verbose == -1) { - ndbout << "Retrying every " << retry_delay_in_seconds << " seconds"; + fprintf(handle->errstream, "Retrying every %d seconds", + retry_delay_in_seconds); if (no_retries > 0) - ndbout << ". Attempts left:"; + fprintf(handle->errstream, ". Attempts left:"); else - ndbout << ", until connected.";; - ndbout << flush; + fprintf(handle->errstream, ", until connected."); + fflush(handle->errstream); verbose= -2; } if (no_retries > 0) { if (verbose == -2) { - ndbout << " " << no_retries; - ndbout << flush; + fprintf(handle->errstream, " %d", no_retries); + fflush(handle->errstream); } no_retries--; } NdbSleep_SecSleep(retry_delay_in_seconds); } if (verbose == -2) - ndbout << endl; - + { + fprintf(handle->errstream, "\n"); + fflush(handle->errstream); + } handle->cfg_i = i; - + handle->socket = sockfd; handle->connected = 1; @@ -456,7 +468,9 @@ ndb_mgm_match_node_type(const char * type) for(int i = 0; iget("result", &buf) || strcmp(buf, "Ok") != 0){ - ndbout_c("ERROR Message: %s\n", buf); + fprintf(handle->errstream, "ERROR Message: %s\n\n", buf); break; } buf = ""; if(!prop->get("Content-Type", &buf) || strcmp(buf, "ndbconfig/octet-stream") != 0){ - ndbout_c("Unhandled response type: %s", buf); + fprintf(handle->errstream, "Unhandled response type: %s\n", buf); break; } buf = ""; if(!prop->get("Content-Transfer-Encoding", &buf) || strcmp(buf, "base64") != 0){ - ndbout_c("Unhandled encoding: %s", buf); + fprintf(handle->errstream, "Unhandled encoding: %s\n", buf); break; } buf = ""; Uint32 len = 0; if(!prop->get("Content-Length", &len)){ - ndbout_c("Invalid response: %s\n", buf); + fprintf(handle->errstream, "Invalid response: %s\n\n", buf); break; } @@ -1697,14 +1711,14 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { const int res = base64_decode(buf64, len-1, tmp); delete[] buf64; if(res != 0){ - ndbout_c("Failed to decode buffer"); + fprintf(handle->errstream, "Failed to decode buffer\n"); break; } ConfigValuesFactory cvf; const int res2 = cvf.unpack(tmp); if(!res2){ - ndbout_c("Failed to unpack buffer"); + fprintf(handle->errstream, "Failed to unpack buffer\n"); break; } @@ -1808,7 +1822,7 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype) } Uint32 _nodeid; if(!prop->get("nodeid", &_nodeid) != 0){ - ndbout_c("ERROR Message: \n"); + fprintf(handle->errstream, "ERROR Message: \n"); break; } nodeid= _nodeid; @@ -1884,7 +1898,7 @@ ndb_mgm_set_int_parameter(NdbMgmHandle handle, do { const char * buf; if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ - ndbout_c("ERROR Message: %s\n", buf); + fprintf(handle->errstream, "ERROR Message: %s\n", buf); break; } res= 0; @@ -1927,7 +1941,7 @@ ndb_mgm_set_int64_parameter(NdbMgmHandle handle, do { const char * buf; if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ - ndbout_c("ERROR Message: %s\n", buf); + fprintf(handle->errstream, "ERROR Message: %s\n", buf); break; } res= 0; @@ -1970,7 +1984,7 @@ ndb_mgm_set_string_parameter(NdbMgmHandle handle, do { const char * buf; if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ - ndbout_c("ERROR Message: %s\n", buf); + fprintf(handle->errstream, "ERROR Message: %s\n", buf); break; } res= 0; @@ -2007,7 +2021,7 @@ ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){ do { const char * buf; if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ - ndbout_c("ERROR Message: %s\n", buf); + fprintf(handle->errstream, "ERROR Message: %s\n", buf); break; } if (purged) { diff --git a/ndb/src/mgmsrv/ConfigInfo.hpp b/ndb/src/mgmsrv/ConfigInfo.hpp index dff8b34bf4a..94f1cebde04 100644 --- a/ndb/src/mgmsrv/ConfigInfo.hpp +++ b/ndb/src/mgmsrv/ConfigInfo.hpp @@ -126,14 +126,14 @@ private: Properties m_info; Properties m_systemDefaults; - static const ParamInfo m_ParamInfo[]; - static const int m_NoOfParams; - static const AliasPair m_sectionNameAliases[]; static const char* m_sectionNames[]; static const int m_noOfSectionNames; public: + static const ParamInfo m_ParamInfo[]; + static const int m_NoOfParams; + static const SectionRule m_SectionRules[]; static const ConfigRule m_ConfigRules[]; static const int m_NoOfRules; diff --git a/ndb/tools/Makefile.am b/ndb/tools/Makefile.am index c350fb0a141..1f11122fb70 100644 --- a/ndb/tools/Makefile.am +++ b/ndb/tools/Makefile.am @@ -9,7 +9,7 @@ ndbtools_PROGRAMS = \ ndb_show_tables \ ndb_select_all \ ndb_select_count \ - ndb_restore + ndb_restore ndb_config tools_common_sources = ../test/src/NDBT_ReturnCodes.cpp \ ../test/src/NDBT_Table.cpp \ @@ -32,6 +32,16 @@ ndb_restore_SOURCES = restore/restore_main.cpp \ restore/consumer_printer.cpp \ restore/Restore.cpp +ndb_config_SOURCES = config.cpp \ + ../src/mgmsrv/Config.cpp \ + ../src/mgmsrv/ConfigInfo.cpp \ + ../src/mgmsrv/InitConfigFileParser.cpp +ndb_config_CXXFLAGS = -I$(top_srcdir)/ndb/src/mgmapi \ + -I$(top_srcdir)/ndb/src/mgmsrv \ + -I$(top_srcdir)/ndb/include/mgmcommon \ + -DMYSQLCLUSTERDIR="\"\"" + + include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_ndbapitools.mk.am @@ -45,6 +55,7 @@ ndb_show_tables_LDFLAGS = @ndb_bin_am_ldflags@ ndb_select_all_LDFLAGS = @ndb_bin_am_ldflags@ ndb_select_count_LDFLAGS = @ndb_bin_am_ldflags@ ndb_restore_LDFLAGS = @ndb_bin_am_ldflags@ +ndb_config_LDFLAGS = @ndb_bin_am_ldflags@ # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/ndb/tools/config.cpp b/ndb/tools/config.cpp new file mode 100644 index 00000000000..8dd69e050f7 --- /dev/null +++ b/ndb/tools/config.cpp @@ -0,0 +1,407 @@ +/* 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; either version 2 of the License, or + (at your option) any later version. + + 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 */ + +/** + * ndb_config --nodes --query=nodeid --type=ndbd --host=local1 + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static int g_verbose = 0; +static int try_reconnect = 3; + +static int g_nodes = 1; +static const char * g_connectstring = 0; +static const char * g_query = 0; + +static int g_nodeid = 0; +static const char * g_type = 0; +static const char * g_host = 0; +static const char * g_field_delimiter=","; +static const char * g_row_delimiter=" "; + +int g_print_full_config, opt_ndb_shm; + +typedef ndb_mgm_configuration_iterator Iter; + +static void ndb_std_print_version() +{ + printf("MySQL distrib %s, for %s (%s)\n", + MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); +} + +static struct my_option my_long_options[] = +{ + { "usage", '?', "Display this help and exit.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "help", '?', "Display this help and exit.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "version", 'V', "Output version information and exit.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "ndb-connectstring", 256, + "Set connect string for connecting to ndb_mgmd. " + "Syntax: \"[nodeid=;][host=][:]\". " + "Overides specifying entries in NDB_CONNECTSTRING and Ndb.cfg", + (gptr*) &g_connectstring, (gptr*) &g_connectstring, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "nodes", 256, "Print nodes", + (gptr*) &g_nodes, (gptr*) &g_nodes, + 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + { "query", 'q', "Query option(s)", + (gptr*) &g_query, (gptr*) &g_query, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "host", 257, "Host", + (gptr*) &g_host, (gptr*) &g_host, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "type", 258, "Type of node/connection", + (gptr*) &g_type, (gptr*) &g_type, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "id", 258, "Nodeid", + (gptr*) &g_nodeid, (gptr*) &g_nodeid, + 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "nodeid", 258, "Nodeid", + (gptr*) &g_nodeid, (gptr*) &g_nodeid, + 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "fields", 'f', "Field separator", + (gptr*) &g_field_delimiter, (gptr*) &g_field_delimiter, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "rows", 'r', "Row separator", + (gptr*) &g_row_delimiter, (gptr*) &g_row_delimiter, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + +static void usage() +{ + char desc[] = + "This program will retreive config options for a ndb cluster\n"; + ndb_std_print_version(); + my_print_help(my_long_options); + my_print_variables(my_long_options); +} +static my_bool +ndb_std_get_one_option(int optid, + const struct my_option *opt __attribute__((unused)), + char *argument) +{ + switch (optid) { + case 'V': + ndb_std_print_version(); + exit(0); + case '?': + usage(); + exit(0); + } + return 0; +} + +/** + * Match/Apply framework + */ +struct Match +{ + int m_key; + BaseString m_value; + virtual int eval(NdbMgmHandle, const Iter&); +}; + +struct Apply +{ + Apply() {} + Apply(int val) { m_key = val;} + int m_key; + virtual int apply(NdbMgmHandle, const Iter&); +}; + +struct NodeTypeApply : public Apply +{ + virtual int apply(NdbMgmHandle, const Iter&); +}; + +static int parse_query(Vector&, int &argc, char**& argv); +static int parse_where(Vector&, int &argc, char**& argv); +static int eval(NdbMgmHandle, const Iter&, const Vector&); +static int apply(NdbMgmHandle, const Iter&, const Vector&); +int +main(int argc, char** argv){ + NDB_INIT(argv[0]); + const char *load_default_groups[]= { "mysql_cluster",0 }; + load_defaults("my",load_default_groups,&argc,&argv); + int ho_error; + if ((ho_error=handle_options(&argc, &argv, my_long_options, + ndb_std_get_one_option))) + return -1; + + NdbMgmHandle mgm = ndb_mgm_create_handle(); + if(mgm == NULL) { + fprintf(stderr, "Cannot create handle to management server.\n"); + exit(-1); + } + + ndb_mgm_set_error_stream(mgm, stderr); + + if (ndb_mgm_set_connectstring(mgm, g_connectstring)) + { + fprintf(stderr, "* %5d: %s\n", + ndb_mgm_get_latest_error(mgm), + ndb_mgm_get_latest_error_msg(mgm)); + fprintf(stderr, + "* %s", ndb_mgm_get_latest_error_desc(mgm)); + exit(-1); + } + + if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1)) + { + fprintf(stderr, "Connect failed"); + fprintf(stderr, " code: %d, msg: %s\n", + ndb_mgm_get_latest_error(mgm), + ndb_mgm_get_latest_error_msg(mgm)); + exit(-1); + } + else if(g_verbose) + { + fprintf(stderr, "Connected to %s:%d\n", + ndb_mgm_get_connected_host(mgm), + ndb_mgm_get_connected_port(mgm)); + } + + ndb_mgm_configuration * conf = ndb_mgm_get_configuration(mgm, 0); + if(conf == 0) + { + fprintf(stderr, "Could not get configuration"); + fprintf(stderr, "code: %d, msg: %s\n", + ndb_mgm_get_latest_error(mgm), + ndb_mgm_get_latest_error_msg(mgm)); + exit(-1); + } + else if(g_verbose) + { + fprintf(stderr, "Fetched configuration\n"); + } + + Vector select_list; + Vector where_clause; + + if(strcmp(g_row_delimiter, "\\n") == 0) + g_row_delimiter = "\n"; + if(strcmp(g_field_delimiter, "\\n") == 0) + g_field_delimiter = "\n"; + + if(parse_query(select_list, argc, argv)) + { + exit(0); + } + + if(parse_where(where_clause, argc, argv)) + { + exit(0); + } + + Iter iter(* conf, CFG_SECTION_NODE); + bool prev= false; + iter.first(); + for(iter.first(); iter.valid(); iter.next()) + { + if(eval(mgm, iter, where_clause)) + { + if(prev) + printf("%s", g_row_delimiter); + prev= true; + apply(mgm, iter, select_list); + } + } + printf("\n"); + return 0; +} + +static +int +parse_query(Vector& select, int &argc, char**& argv) +{ + if(g_query) + { + BaseString q(g_query); + Vector list; + q.split(list, ","); + for(unsigned i = 0; i& where, int &argc, char**& argv) +{ + Match m; + if(g_host) + { + m.m_key = CFG_NODE_HOST; + m.m_value.assfmt("%s", g_host); + where.push_back(new Match(m)); + } + + if(g_type) + { + m.m_key = CFG_TYPE_OF_SECTION; + m.m_value.assfmt("%d", ndb_mgm_match_node_type(g_type)); + where.push_back(new Match(m)); + } + + if(g_nodeid) + { + m.m_key = CFG_NODE_ID; + m.m_value.assfmt("%d", g_nodeid); + where.push_back(new Match(m)); + } + return 0; +} + +template Vector; +template Vector; + +static +int +eval(NdbMgmHandle mgm, const Iter& iter, const Vector& where) +{ + for(unsigned i = 0; ieval(mgm, iter) == 0) + return 0; + } + + return 1; +} + +static +int +apply(NdbMgmHandle mgm, const Iter& iter, const Vector& list) +{ + for(unsigned i = 0; iapply(mgm, iter); + if(i + 1 != list.size()) + printf("%s", g_field_delimiter); + } + return 0; +} + +int +Match::eval(NdbMgmHandle h, const Iter& iter) +{ + Uint32 val32; + Uint64 val64; + const char* valc; + if (iter.get(m_key, &val32) == 0) + { + if(atoi(m_value.c_str()) != val32) + return 0; + } + else if(iter.get(m_key, &val64) == 0) + { + if(atoll(m_value.c_str()) != val64) + return 0; + } + else if(iter.get(m_key, &valc) == 0) + { + if(strcmp(m_value.c_str(), valc) != 0) + return 0; + } + else + { + return 0; + } + return 1; +} + +int +Apply::apply(NdbMgmHandle h, const Iter& iter) +{ + Uint32 val32; + Uint64 val64; + const char* valc; + if (iter.get(m_key, &val32) == 0) + { + printf("%u", val32); + } + else if(iter.get(m_key, &val64) == 0) + { + printf("%llu", val64); + } + else if(iter.get(m_key, &valc) == 0) + { + printf("%s", valc); + } + return 0; +} + +int +NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter) +{ + Uint32 val32; + if (iter.get(CFG_TYPE_OF_SECTION, &val32) == 0) + { + printf("%s", ndb_mgm_get_node_type_alias_string((ndb_mgm_node_type)val32, 0)); + } + return 0; +} From b285050e52cd22202559b8dd9c18f4a3645fa598 Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Sun, 24 Jul 2005 17:35:39 +0200 Subject: [PATCH 02/11] ndb - add mysql-test-run test case for ndb_config --- mysql-test/r/ndb_config.result | 5 +++++ mysql-test/t/ndb_config.test | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 mysql-test/r/ndb_config.result create mode 100644 mysql-test/t/ndb_config.test diff --git a/mysql-test/r/ndb_config.result b/mysql-test/r/ndb_config.result new file mode 100644 index 00000000000..f720b8e98df --- /dev/null +++ b/mysql-test/r/ndb_config.result @@ -0,0 +1,5 @@ +ndbd,1,localhost ndbd,2,localhost ndb_mgmd,3, mysqld,4, mysqld,5, mysqld,6, mysqld,7, +1,localhost,41943040,12582912 2,localhost,41943040,12582912 +1 localhost 41943040 12582912 +2 localhost 41943040 12582912 +1 2 diff --git a/mysql-test/t/ndb_config.test b/mysql-test/t/ndb_config.test new file mode 100644 index 00000000000..27ffdbdcd6e --- /dev/null +++ b/mysql-test/t/ndb_config.test @@ -0,0 +1,4 @@ +--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=type,nodeid,host 2> /dev/null +--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null +--exec $NDB_TOOLS_DIR/ndb_config --no-defaults -r \\n -f " " --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null +--exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid --type=ndbd --host=localhost 2> /dev/null From 5498a13751c9954a70d048b02065138e9db863c4 Mon Sep 17 00:00:00 2001 From: "georg@lmy002.wdf.sap.corp" <> Date: Mon, 25 Jul 2005 07:51:17 +0200 Subject: [PATCH 03/11] fix for bug #7924. added export symbols mysql_server_init and mysql_server_end to allow client to connect to external and embedded server using the same code (required for Connector/OO.org). (Backport from 5.0 - cs. 1.35) --- libmysql/libmysql.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index 57c97ab08ee..dce91c1e4c1 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -147,4 +147,6 @@ EXPORTS mysql_slave_query mysql_embedded mysql_set_character_set + mysql_server_init + mysql_server_end get_defaults_files From 07cdfdca69cbf6e348aa4cbe2fa2bce65c82f30a Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Mon, 25 Jul 2005 12:41:25 +0200 Subject: [PATCH 04/11] ndb - Fix LCP during SR parameters --- ndb/include/mgmapi/mgmapi_config_parameters.h | 7 +++++-- ndb/src/kernel/blocks/dbacc/DbaccMain.cpp | 6 ++++-- ndb/src/kernel/blocks/dbtup/DbtupGen.cpp | 6 ++++-- ndb/src/mgmsrv/ConfigInfo.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h index 432854d1d36..2e3b47eb42e 100644 --- a/ndb/include/mgmapi/mgmapi_config_parameters.h +++ b/ndb/include/mgmapi/mgmapi_config_parameters.h @@ -50,8 +50,11 @@ #define CFG_DB_FILESYSTEM_PATH 125 #define CFG_DB_NO_REDOLOG_FILES 126 -#define CFG_DB_DISC_BANDWIDTH 127 -#define CFG_DB_SR_DISC_BANDWITH 128 + +#define CFG_DB_LCP_DISC_PAGES_TUP 127 +#define CFG_DB_LCP_DISC_PAGES_TUP_SR 128 +#define CFG_DB_LCP_DISC_PAGES_ACC 137 +#define CFG_DB_LCP_DISC_PAGES_ACC_SR 138 #define CFG_DB_TRANSACTION_CHECK_INTERVAL 129 #define CFG_DB_TRANSACTION_INACTIVE_TIMEOUT 130 diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index 3313e22fe3a..1f0053e209a 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -722,10 +722,12 @@ void Dbacc::execREAD_CONFIG_REQ(Signal* signal) ndbrestart1Lab(signal); clblPagesPerTick = 50; - //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTick); + ndb_mgm_get_int_parameter(p, CFG_DB_LCP_DISC_PAGES_ACC_SR, + &clblPagesPerTick); clblPagesPerTickAfterSr = 50; - //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTickAfterSr); + ndb_mgm_get_int_parameter(p, CFG_DB_LCP_DISC_PAGES_ACC, + &clblPagesPerTickAfterSr); tdata0 = 0; initialiseRecordsLab(signal, ref, senderData); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 0d7430e662d..27f817d8abc 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -663,10 +663,12 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal) initialiseRecordsLab(signal, 0, ref, senderData); clblPagesPerTick = 50; - //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTick); + ndb_mgm_get_int_parameter(p, CFG_DB_LCP_DISC_PAGES_TUP_SR, + &clblPagesPerTick); clblPagesPerTickAfterSr = 50; - //ndb_mgm_get_int_parameter(p, CFG_DB_, &clblPagesPerTickAfterSr); + ndb_mgm_get_int_parameter(p, CFG_DB_LCP_DISC_PAGES_TUP, + &clblPagesPerTickAfterSr); }//Dbtup::execSIZEALT_REP() diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 4612d17c9ce..41a3aa8c782 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -928,7 +928,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { STR_VALUE(MAX_INT_RNIL) }, { - KEY_INTERNAL, + CFG_DB_LCP_DISC_PAGES_TUP_SR, "NoOfDiskPagesToDiskDuringRestartTUP", DB_TOKEN, "?", @@ -940,7 +940,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { STR_VALUE(MAX_INT_RNIL) }, { - KEY_INTERNAL, + CFG_DB_LCP_DISC_PAGES_TUP, "NoOfDiskPagesToDiskAfterRestartTUP", DB_TOKEN, "?", @@ -952,7 +952,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { STR_VALUE(MAX_INT_RNIL) }, { - KEY_INTERNAL, + CFG_DB_LCP_DISC_PAGES_ACC_SR, "NoOfDiskPagesToDiskDuringRestartACC", DB_TOKEN, "?", @@ -964,7 +964,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { STR_VALUE(MAX_INT_RNIL) }, { - KEY_INTERNAL, + CFG_DB_LCP_DISC_PAGES_ACC, "NoOfDiskPagesToDiskAfterRestartACC", DB_TOKEN, "?", From 0cd9e2e269ae0660d8461f7454eea0887d30cd1a Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Mon, 25 Jul 2005 13:47:40 +0200 Subject: [PATCH 05/11] fix compile error --- ndb/tools/config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ndb/tools/config.cpp b/ndb/tools/config.cpp index 8dd69e050f7..7944f66f71c 100644 --- a/ndb/tools/config.cpp +++ b/ndb/tools/config.cpp @@ -317,8 +317,8 @@ parse_where(Vector& where, int &argc, char**& argv) return 0; } -template Vector; -template Vector; +template class Vector; +template class Vector; static int From d9bacfa236ceaf1b91caf6197122ad01ad8bfe37 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Mon, 25 Jul 2005 14:14:24 +0200 Subject: [PATCH 06/11] - Make sure the scripts make_binary_distribution, make_sharedlib_distribution and make_win_src_distribution are created, but not installed - removed make_win_binary_distribution.sh as it's obsolete and outdated --- scripts/Makefile.am | 5 +- scripts/make_win_binary_distribution.sh | 181 ------------------------ 2 files changed, 4 insertions(+), 182 deletions(-) delete mode 100644 scripts/make_win_binary_distribution.sh diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 533545aba25..a5e6b094bf6 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -34,10 +34,13 @@ bin_SCRIPTS = @server_scripts@ \ mysql_tableinfo \ mysqld_multi +noinst_SCRIPTS = make_binary_distribution \ + make_sharedlib_distribution \ + make_win_src_distribution + EXTRA_SCRIPTS = make_binary_distribution.sh \ make_sharedlib_distribution.sh \ make_win_src_distribution.sh \ - make_win_binary_distribution.sh \ msql2mysql.sh \ mysql_config.sh \ mysql_fix_privilege_tables.sh \ diff --git a/scripts/make_win_binary_distribution.sh b/scripts/make_win_binary_distribution.sh deleted file mode 100644 index 9b2cc2d7d22..00000000000 --- a/scripts/make_win_binary_distribution.sh +++ /dev/null @@ -1,181 +0,0 @@ -#!/bin/sh - -# -# Script to create a Windows binary package -# -# This is intended to be used under Cygwin, and will generate -# an archive named in the form mysql--noinstall.zip - -version=@VERSION@ - -DEBUG=0 -SUFFIX="" -DIRNAME="" -EXTRA="" - -# -# This script must run from MySQL top directory -# - -if [ ! -f scripts/make_win_binary_distribution ]; then - echo "ERROR : You must run this script from the MySQL top-level directory" - exit 1 -fi - -# -# Debug print of the status -# - -print_debug() -{ - for statement - do - if [ "$DEBUG" = "1" ] ; then - echo $statement - fi - done -} - -# -# Usage of the script -# - -show_usage() -{ - echo "MySQL utility script to create a Windows binary package" - echo "" - echo "This is intended to be used under Cygwin, and will generate" - echo "an archive named in the form mysql--noinstall.zip" - echo "Takes the following arguments:" - echo "" - echo " --dirname Directory to use for copying files" - echo " --extra Directory to get extra files from" - echo " --suffix Name to append to 'mysql' for this binary" - echo " --help Show this help message" - exit 0 -} - -# -# Parse the input arguments -# - -parse_arguments() { - for arg do - case "$arg" in - --debug) DEBUG=1;; - --extra=*) EXTRA=`echo "$arg" | sed -e "s;--extra=;;"` ;; - --suffix=*) SUFFIX=`echo "$arg" | sed -e "s;--suffix=;;"` ;; - --dirname=*) DIRNAME=`echo "$arg" | sed -e "s;--dirname=;;"` ;; - --help) show_usage ;; - *) - echo "Unknown argument '$arg'" - exit 1 - ;; - esac - done -} - -parse_arguments "$@" - -if [ -z "$DIRNAME" ]; then - $DIRNAME="dist" -fi - -print_debug "Making directories" -mkdir $DIRNAME -$DIRNAME="$DIRNAME/mysql-$version" -mkdir $DIRNAME - -for dir in bin lib lib/opt lib/debug Embedded Embedded/DLL Embedded/DLL/debug Embedded/DLL/release Embedded/static Embedded/static/release examples examples/libmysqltest -do - mkdir $DIRNAME/$dir -done - -if [ $EXTRA ]; then - print_debug "Copying extra files" - cp -fr $EXTRA/* $DIRNAME -fi - -# Dirs to be copied as-is -for dir in data Docs include scripts share -do - print_debug "Copying $dir to $DIRNAME/" - cp -fr $dir $DIRNAME -done - -print_debug "Copying tests to $DIRNAME/examples/" -cp -fr tests $DIRNAME/examples - -print_debug "Copying sql-bench to $DIRNAME/bench" -mkdir $DIRNAME/bench -cp -fr sql-bench/* $DIRNAME/bench - -print_debug "Copying support-files to $DIRNAME" -cp support-files/* $DIRNAME - -# Files for bin -for i in client_release/* client_debug/mysqld.exe lib_release/libmySQL.dll -do - print_debug "Copying $i to $DIRNAME/bin" - cp $i $DIRNAME/bin -done - -# Files for include -for i in libmysql/libmysql.def libmysqld/libmysqld.def -do - print_debug "Copying $i to $DIRNAME/include" - cp $i $DIRNAME/include -done - -# Windows users are used to having dbug.h ? -cp include/my_dbug.h $DIRNAME/include/dbug.h - -# Libraries found in lib_release and lib_debug -for i in libmySQL.dll libmysql.lib zlib.lib mysqlclient.lib mysys.lib regex.lib strings.lib -do - print_debug "Copying lib_release/$i to $DIRNAME/lib/opt" - cp lib_release/$i $DIRNAME/lib/opt - print_debug "Copying lib_debug/$i to $DIRNAME/lib/debug" - cp lib_debug/$i $DIRNAME/lib/debug -done - -print_debug "Copying lib_release/mysys-max.lib to $DIRNAME/lib/opt" -cp lib_release/mysys-max.lib $DIRNAME/lib/opt - -# Embedded server -for i in libmysqld.dll libmysqld.lib libmysqld.exp -do - print_debug "Copying lib_release/$i to $DIRNAME/Embedded/DLL/release" - cp lib_release/$i $DIRNAME/Embedded/DLL/release - print_debug "Copying lib_debug/$i to $DIRNAME/Embedded/DLL/debug" - cp lib_debug/$i $DIRNAME/Embedded/DLL/debug -done - -# Static embedded -print_debug "Copying lib_release/mysqlserver.lib to $DIRNAME/Embedded/static/release" -cp lib_release/mysqlserver.lib $DIRNAME/Embedded/static/release - -# libmysqltest -for i in mytest.c mytest.dsp mytest.dsw mytest.exe -do - print_debug "Copying libmysqltest/release/$i to $DIRNAME/examples/libmysqltest" - cp libmysqltest/release/$i $DIRNAME/examples/libmysqltest -done - -print_debug "Copying README.txt" -cp README.txt $DIRNAME - -if [ -f MySQLEULA.txt ]; then - print_debug "Commercial version: copying MySQLEULA.txt" - cp MySQLEULA.txt $DIRNAME - rm $DIRNAME/Docs/COPYING -else - print_debug "GPL version: copying COPYING" - cp Docs/COPYING $DIRNAME -fi - -print_debug "Invoking zip to package the binary" -zip -r mysql$SUFFIX-$version-win-noinstall.zip $DIRNAME - -print_debug "Deleting intermediate directory" -rm -rf $DIRNAME From 975b4969a5af736a0b46fce3831510ff65a57ea2 Mon Sep 17 00:00:00 2001 From: "bar@mysql.com" <> Date: Mon, 25 Jul 2005 21:34:20 +0500 Subject: [PATCH 07/11] charset.c: Bug#12109 possible locking bug in init_available_charset Recheck charset_initialized inside locked code, to garantee two threads are not entering consequently. --- mysys/charset.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/mysys/charset.c b/mysys/charset.c index 4b7ad3e59f4..cabdbad3413 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -383,26 +383,28 @@ static my_bool init_available_charsets(myf myflags) while we may changing the cs_info_table */ pthread_mutex_lock(&THR_LOCK_charset); - - bzero(&all_charsets,sizeof(all_charsets)); - init_compiled_charsets(myflags); - - /* Copy compiled charsets */ - for (cs=all_charsets; - cs < all_charsets+array_elements(all_charsets)-1 ; - cs++) + if (!charset_initialized) { - if (*cs) + bzero(&all_charsets,sizeof(all_charsets)); + init_compiled_charsets(myflags); + + /* Copy compiled charsets */ + for (cs=all_charsets; + cs < all_charsets+array_elements(all_charsets)-1 ; + cs++) { - if (cs[0]->ctype) - if (init_state_maps(*cs)) - *cs= NULL; + if (*cs) + { + if (cs[0]->ctype) + if (init_state_maps(*cs)) + *cs= NULL; + } } + + strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); + error= my_read_charset_file(fname,myflags); + charset_initialized=1; } - - strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); - error= my_read_charset_file(fname,myflags); - charset_initialized=1; pthread_mutex_unlock(&THR_LOCK_charset); } return error; From be8d46028f233aac0119d88b5759cddf8823bbb4 Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Tue, 26 Jul 2005 07:59:10 +0200 Subject: [PATCH 08/11] ndb_config test requires ndb --- mysql-test/t/ndb_config.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/ndb_config.test b/mysql-test/t/ndb_config.test index 27ffdbdcd6e..ea78a32b1ba 100644 --- a/mysql-test/t/ndb_config.test +++ b/mysql-test/t/ndb_config.test @@ -1,3 +1,6 @@ +-- source include/have_ndb.inc +-- source include/not_embedded.inc + --exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=type,nodeid,host 2> /dev/null --exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null --exec $NDB_TOOLS_DIR/ndb_config --no-defaults -r \\n -f " " --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null From 0c2035b7bd4a742871414627f315df68fa4dcd34 Mon Sep 17 00:00:00 2001 From: "bar@mysql.com" <> Date: Tue, 26 Jul 2005 12:52:02 +0500 Subject: [PATCH 09/11] func_gconcat.result, func_gconcat.test: Adding test item_sum.cc: Adding a call for collation/charset aggregation, to collect attributes from the arguments. The actual bug fix. item_func.h, item_func.cc, item.h, item.cc: - Removing collation aggrgation functions from Item_func class in item.cc, and adding it as non-class functions in item.cc to be able to reuse this code for group_concat. - Adding replacement for these functions into Item_func class as wrappers for moved functions, to minizize patch size, --- mysql-test/r/func_gconcat.result | 24 +++++ mysql-test/t/func_gconcat.test | 18 ++++ sql/item.cc | 164 +++++++++++++++++++++++++++++++ sql/item.h | 9 ++ sql/item_func.cc | 162 ------------------------------ sql/item_func.h | 16 ++- sql/item_sum.cc | 4 + 7 files changed, 232 insertions(+), 165 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 7a256edc91a..661793821a0 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -445,6 +445,30 @@ group_concat(distinct b order by b) Warnings: Warning 1260 2 line(s) were cut by GROUP_CONCAT() drop table t1; +create table t1 (a varchar(255) character set cp1250 collate cp1250_general_ci, +b varchar(255) character set koi8r); +insert into t1 values ('xxx','yyy'); +select collation(a) from t1; +collation(a) +cp1250_general_ci +select collation(group_concat(a)) from t1; +collation(group_concat(a)) +cp1250_general_ci +create table t2 select group_concat(a) as a from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` longtext character set cp1250 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select collation(group_concat(a,_koi8r'test')) from t1; +collation(group_concat(a,_koi8r'test')) +cp1250_general_ci +select collation(group_concat(a,_koi8r 0xC1C2)) from t1; +ERROR HY000: Illegal mix of collations (cp1250_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation 'group_concat' +select collation(group_concat(a,b)) from t1; +ERROR HY000: Illegal mix of collations (cp1250_general_ci,IMPLICIT) and (koi8r_general_ci,IMPLICIT) for operation 'group_concat' +drop table t1; +drop table t2; CREATE TABLE t1 (id int); SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; gc diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 5f02db7707c..edb4d42e3c2 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -263,6 +263,24 @@ select group_concat(distinct b order by b) from t1 group by a; drop table t1; +# +# Bug#10201 +# +create table t1 (a varchar(255) character set cp1250 collate cp1250_general_ci, + b varchar(255) character set koi8r); +insert into t1 values ('xxx','yyy'); +select collation(a) from t1; +select collation(group_concat(a)) from t1; +create table t2 select group_concat(a) as a from t1; +show create table t2; +select collation(group_concat(a,_koi8r'test')) from t1; +--error 1267 +select collation(group_concat(a,_koi8r 0xC1C2)) from t1; +--error 1267 +select collation(group_concat(a,b)) from t1; +drop table t1; +drop table t2; + # # bug #7769: group_concat returning null is checked in having # diff --git a/sql/item.cc b/sql/item.cc index 71940c824e7..84dbc382a52 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -523,6 +523,170 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) return 0; } +/******************************/ +static +void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +{ + my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); +} + + +static +void my_coll_agg_error(DTCollation &c1, DTCollation &c2, DTCollation &c3, + const char *fname) +{ + my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + c3.collation->name,c3.derivation_name(), + fname); +} + + +static +void my_coll_agg_error(Item** args, uint count, const char *fname) +{ + if (count == 2) + my_coll_agg_error(args[0]->collation, args[1]->collation, fname); + else if (count == 3) + my_coll_agg_error(args[0]->collation, args[1]->collation, + args[2]->collation, fname); + else + my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname); +} + + +bool agg_item_collations(DTCollation &c, const char *fname, + Item **av, uint count, uint flags) +{ + uint i; + c.set(av[0]->collation); + for (i= 1; i < count; i++) + { + if (c.aggregate(av[i]->collation, flags)) + { + my_coll_agg_error(av, count, fname); + return TRUE; + } + } + if ((flags & MY_COLL_DISALLOW_NONE) && + c.derivation == DERIVATION_NONE) + { + my_coll_agg_error(av, count, fname); + return TRUE; + } + return FALSE; +} + + +bool agg_item_collations_for_comparison(DTCollation &c, const char *fname, + Item **av, uint count, uint flags) +{ + return (agg_item_collations(c, fname, av, count, + flags | MY_COLL_DISALLOW_NONE)); +} + + +/* + Collect arguments' character sets together. + We allow to apply automatic character set conversion in some cases. + The conditions when conversion is possible are: + - arguments A and B have different charsets + - A wins according to coercibility rules + (i.e. a column is stronger than a string constant, + an explicit COLLATE clause is stronger than a column) + - character set of A is either superset for character set of B, + or B is a string constant which can be converted into the + character set of A without data loss. + + If all of the above is true, then it's possible to convert + B into the character set of A, and then compare according + to the collation of A. + + For functions with more than two arguments: + + collect(A,B,C) ::= collect(collect(A,B),C) +*/ + +bool agg_item_charsets(DTCollation &coll, const char *fname, + Item **args, uint nargs, uint flags) +{ + Item **arg, **last, *safe_args[2]; + if (agg_item_collations(coll, fname, args, nargs, flags)) + return TRUE; + + /* + For better error reporting: save the first and the second argument. + We need this only if the the number of args is 3 or 2: + - for a longer argument list, "Illegal mix of collations" + doesn't display each argument's characteristics. + - if nargs is 1, then this error cannot happen. + */ + if (nargs >=2 && nargs <= 3) + { + safe_args[0]= args[0]; + safe_args[1]= args[1]; + } + + THD *thd= current_thd; + Item_arena *arena, backup; + bool res= FALSE; + /* + In case we're in statement prepare, create conversion item + in its memory: it will be reused on each execute. + */ + arena= thd->change_arena_if_needed(&backup); + + for (arg= args, last= args + nargs; arg < last; arg++) + { + Item* conv; + uint32 dummy_offset; + if (!String::needs_conversion(0, coll.collation, + (*arg)->collation.collation, + &dummy_offset)) + continue; + + if (!(conv= (*arg)->safe_charset_converter(coll.collation))) + { + if (nargs >=2 && nargs <= 3) + { + /* restore the original arguments for better error message */ + args[0]= safe_args[0]; + args[1]= safe_args[1]; + } + my_coll_agg_error(args, nargs, fname); + res= TRUE; + break; // we cannot return here, we need to restore "arena". + } + conv->fix_fields(thd, 0, &conv); + /* + If in statement prepare, then we create a converter for two + constant items, do it once and then reuse it. + If we're in execution of a prepared statement, arena is NULL, + and the conv was created in runtime memory. This can be + the case only if the argument is a parameter marker ('?'), + because for all true constants the charset converter has already + been created in prepare. In this case register the change for + rollback. + */ + if (arena) + *arg= conv; + else + thd->change_item_tree(arg, conv); + } + if (arena) + thd->restore_backup_item_arena(arena, &backup); + return res; +} + + + + +/**********************************************/ + Item_field::Item_field(Field *f) :Item_ident(NullS, f->table_name, f->field_name) { diff --git a/sql/item.h b/sql/item.h index 895463ceeca..825b37fe64c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -330,6 +330,15 @@ public: }; +bool agg_item_collations(DTCollation &c, const char *name, + Item **items, uint nitems, uint flags= 0); +bool agg_item_collations_for_comparison(DTCollation &c, const char *name, + Item **items, uint nitems, + uint flags= 0); +bool agg_item_charsets(DTCollation &c, const char *name, + Item **items, uint nitems, uint flags= 0); + + class Item_num: public Item { public: diff --git a/sql/item_func.cc b/sql/item_func.cc index 44917eb48e4..2514a4beacf 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -39,73 +39,6 @@ bool check_reserved_words(LEX_STRING *name) } -static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, - const char *fname) -{ - my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - fname); -} - -static void my_coll_agg_error(DTCollation &c1, - DTCollation &c2, - DTCollation &c3, - const char *fname) -{ - my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - c3.collation->name,c3.derivation_name(), - fname); -} - - -static void my_coll_agg_error(Item** args, uint count, const char *fname) -{ - if (count == 2) - my_coll_agg_error(args[0]->collation, args[1]->collation, fname); - else if (count == 3) - my_coll_agg_error(args[0]->collation, - args[1]->collation, - args[2]->collation, - fname); - else - my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname); -} - - -bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count, - uint flags) -{ - uint i; - c.set(av[0]->collation); - for (i= 1; i < count; i++) - { - if (c.aggregate(av[i]->collation, flags)) - { - my_coll_agg_error(av, count, func_name()); - return TRUE; - } - } - if ((flags & MY_COLL_DISALLOW_NONE) && - c.derivation == DERIVATION_NONE) - { - my_coll_agg_error(av, count, func_name()); - return TRUE; - } - return FALSE; -} - - -bool Item_func::agg_arg_collations_for_comparison(DTCollation &c, - Item **av, uint count, - uint flags) -{ - return (agg_arg_collations(c, av, count, flags | MY_COLL_DISALLOW_NONE)); -} - - /* return TRUE if item is a constant */ bool @@ -115,101 +48,6 @@ eval_const_cond(COND *cond) } - -/* - Collect arguments' character sets together. - We allow to apply automatic character set conversion in some cases. - The conditions when conversion is possible are: - - arguments A and B have different charsets - - A wins according to coercibility rules - (i.e. a column is stronger than a string constant, - an explicit COLLATE clause is stronger than a column) - - character set of A is either superset for character set of B, - or B is a string constant which can be converted into the - character set of A without data loss. - - If all of the above is true, then it's possible to convert - B into the character set of A, and then compare according - to the collation of A. - - For functions with more than two arguments: - - collect(A,B,C) ::= collect(collect(A,B),C) -*/ - -bool Item_func::agg_arg_charsets(DTCollation &coll, - Item **args, uint nargs, uint flags) -{ - Item **arg, **last, *safe_args[2]; - if (agg_arg_collations(coll, args, nargs, flags)) - return TRUE; - - /* - For better error reporting: save the first and the second argument. - We need this only if the the number of args is 3 or 2: - - for a longer argument list, "Illegal mix of collations" - doesn't display each argument's characteristics. - - if nargs is 1, then this error cannot happen. - */ - if (nargs >=2 && nargs <= 3) - { - safe_args[0]= args[0]; - safe_args[1]= args[1]; - } - - THD *thd= current_thd; - Item_arena *arena, backup; - bool res= FALSE; - /* - In case we're in statement prepare, create conversion item - in its memory: it will be reused on each execute. - */ - arena= thd->change_arena_if_needed(&backup); - - for (arg= args, last= args + nargs; arg < last; arg++) - { - Item* conv; - uint32 dummy_offset; - if (!String::needs_conversion(0, coll.collation, - (*arg)->collation.collation, - &dummy_offset)) - continue; - - if (!(conv= (*arg)->safe_charset_converter(coll.collation))) - { - if (nargs >=2 && nargs <= 3) - { - /* restore the original arguments for better error message */ - args[0]= safe_args[0]; - args[1]= safe_args[1]; - } - my_coll_agg_error(args, nargs, func_name()); - res= TRUE; - break; // we cannot return here, we need to restore "arena". - } - conv->fix_fields(thd, 0, &conv); - /* - If in statement prepare, then we create a converter for two - constant items, do it once and then reuse it. - If we're in execution of a prepared statement, arena is NULL, - and the conv was created in runtime memory. This can be - the case only if the argument is a parameter marker ('?'), - because for all true constants the charset converter has already - been created in prepare. In this case register the change for - rollback. - */ - if (arena) - *arg= conv; - else - thd->change_item_tree(arg, conv); - } - if (arena) - thd->restore_backup_item_arena(arena, &backup); - return res; -} - - - void Item_func::set_arguments(List &list) { allowed_arg_cols= 1; diff --git a/sql/item_func.h b/sql/item_func.h index 5e36f9863bb..5d6cc445317 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -145,12 +145,22 @@ public: Item *get_tmp_table_item(THD *thd); bool agg_arg_collations(DTCollation &c, Item **items, uint nitems, - uint flags= 0); + uint flags= 0) + { + return agg_item_collations(c, func_name(), items, nitems, flags); + } bool agg_arg_collations_for_comparison(DTCollation &c, Item **items, uint nitems, - uint flags= 0); + uint flags= 0) + { + return agg_item_collations_for_comparison(c, func_name(), + items, nitems, flags); + } bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems, - uint flags= 0); + uint flags= 0) + { + return agg_item_charsets(c, func_name(), items, nitems, flags); + } bool walk(Item_processor processor, byte *arg); }; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 0e252259f53..6ca3f024f61 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1925,6 +1925,10 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) maybe_null|= args[i]->maybe_null; } + if (agg_item_charsets(collation, func_name(), + args, arg_count, MY_COLL_ALLOW_CONV)) + return 1; + result_field= 0; null_value= 1; max_length= group_concat_max_len; From a89939c8e75e57015c8d6fa81330fb7fbc7f9ea4 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Tue, 26 Jul 2005 14:03:34 +0300 Subject: [PATCH 10/11] InnoDB: Do not flush after each write, not even when creating the data files. Previously, writes were flushed until the doublewrite buffer was created. That would be too slow on systems where os_file_flush() [or fsync(2)] is slow. (Bug #12125) --- innobase/include/os0file.h | 2 ++ innobase/os/os0file.c | 14 ++++++++++++++ innobase/trx/trx0sys.c | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 63cd41a6d28..280a949c1c5 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -17,7 +17,9 @@ Created 10/21/1995 Heikki Tuuri #include #endif +#ifdef UNIV_DO_FLUSH extern ibool os_do_not_call_flush_at_each_write; +#endif /* UNIV_DO_FLUSH */ extern ibool os_has_said_disk_full; extern ibool os_aio_print_debug; diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 4313b7f7019..49f88c0d62a 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -33,9 +33,13 @@ ulint os_innodb_umask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; ulint os_innodb_umask = 0; #endif +#ifdef UNIV_DO_FLUSH /* If the following is set to TRUE, we do not call os_file_flush in every os_file_write. We can set this TRUE when the doublewrite buffer is used. */ ibool os_do_not_call_flush_at_each_write = FALSE; +#else +/* We do not call os_file_flush in every os_file_write. */ +#endif /* UNIV_DO_FLUSH */ /* We use these mutexes to protect lseek + file i/o operation, if the OS does not provide an atomic pread or pwrite, or similar */ @@ -1974,6 +1978,7 @@ os_file_pwrite( os_file_n_pending_pwrites--; os_mutex_exit(os_file_count_mutex); +# ifdef UNIV_DO_FLUSH if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC && srv_unix_file_flush_method != SRV_UNIX_NOSYNC && !os_do_not_call_flush_at_each_write) { @@ -1984,6 +1989,7 @@ os_file_pwrite( ut_a(TRUE == os_file_flush(file)); } +# endif /* UNIV_DO_FLUSH */ return(ret); #else @@ -2006,6 +2012,7 @@ os_file_pwrite( ret = write(file, buf, (ssize_t)n); +# ifdef UNIV_DO_FLUSH if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC && srv_unix_file_flush_method != SRV_UNIX_NOSYNC && !os_do_not_call_flush_at_each_write) { @@ -2016,6 +2023,7 @@ os_file_pwrite( ut_a(TRUE == os_file_flush(file)); } +# endif /* UNIV_DO_FLUSH */ os_mutex_exit(os_file_seek_mutexes[i]); @@ -2282,9 +2290,11 @@ retry: /* Always do fsync to reduce the probability that when the OS crashes, a database page is only partially physically written to disk. */ +# ifdef UNIV_DO_FLUSH if (!os_do_not_call_flush_at_each_write) { ut_a(TRUE == os_file_flush(file)); } +# endif /* UNIV_DO_FLUSH */ os_mutex_exit(os_file_seek_mutexes[i]); @@ -3498,10 +3508,12 @@ os_aio_windows_handle( if (ret && len == slot->len) { ret_val = TRUE; +# ifdef UNIV_DO_FLUSH if (slot->type == OS_FILE_WRITE && !os_do_not_call_flush_at_each_write) { ut_a(TRUE == os_file_flush(slot->file)); } +# endif /* UNIV_DO_FLUSH */ } else { os_file_handle_error(slot->name, "Windows aio"); @@ -3582,10 +3594,12 @@ os_aio_posix_handle( *message1 = slot->message1; *message2 = slot->message2; +# ifdef UNIV_DO_FLUSH if (slot->type == OS_FILE_WRITE && !os_do_not_call_flush_at_each_write) { ut_a(TRUE == os_file_flush(slot->file)); } +# endif /* UNIV_DO_FLUSH */ os_mutex_exit(array->mutex); diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index 51e193d563b..c7292fb7650 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -97,8 +97,9 @@ trx_doublewrite_init( /* Since we now start to use the doublewrite buffer, no need to call fsync() after every write to a data file */ - +#ifdef UNIV_DO_FLUSH os_do_not_call_flush_at_each_write = TRUE; +#endif /* UNIV_DO_FLUSH */ mutex_create(&(trx_doublewrite->mutex)); mutex_set_level(&(trx_doublewrite->mutex), SYNC_DOUBLEWRITE); From 637ec56206d19df6b073d04d9c08fd576b51ed00 Mon Sep 17 00:00:00 2001 From: "bar@mysql.com" <> Date: Tue, 26 Jul 2005 16:38:10 +0500 Subject: [PATCH 11/11] ctype-big5.c: ctype-cp932.c: ctype-gbk.c: ctype-mb.c: ctype-simple.c: ctype-sjis.c: ctype-ucs2.c: ctype-ujis.c: ctype-utf8.c: Adding explicit cast to return type in pointer substructions to avoid warnings from some compilers. --- strings/ctype-big5.c | 2 +- strings/ctype-cp932.c | 4 ++-- strings/ctype-gbk.c | 2 +- strings/ctype-mb.c | 4 ++-- strings/ctype-simple.c | 8 ++++---- strings/ctype-sjis.c | 4 ++-- strings/ctype-ucs2.c | 8 ++++---- strings/ctype-ujis.c | 10 +++++----- strings/ctype-utf8.c | 2 +- 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index ff4ce6fdb51..b467c8c5ba3 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6309,7 +6309,7 @@ uint my_well_formed_len_big5(CHARSET_INFO *cs __attribute__((unused)), break; } } - return b - b0; + return (uint) (b - b0); } diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index c77ce858dff..be3526519cb 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -213,7 +213,7 @@ static int my_strnncoll_cp932_internal(CHARSET_INFO *cs, uint a_char= cp932code(*a, *(a+1)); uint b_char= cp932code(*b, *(b+1)); if (a_char != b_char) - return a_char - b_char; + return (int) a_char - (int) b_char; a += 2; b += 2; } else @@ -5449,7 +5449,7 @@ uint my_well_formed_len_cp932(CHARSET_INFO *cs __attribute__((unused)), break; } } - return b - b0; + return (uint) (b - b0); } diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 6fb072d266d..7196d004ad5 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9956,7 +9956,7 @@ uint my_well_formed_len_gbk(CHARSET_INFO *cs __attribute__((unused)), break; } } - return b - b0; + return (uint) (b - b0); } diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index cbbd035c631..4b22f158284 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -260,7 +260,7 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1; length--; } - return length ? end+2-start : pos-start; + return length ? (uint) (end + 2 - start) : (uint) (pos - start); } @@ -282,7 +282,7 @@ uint my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e, b+= mblen; pos--; } - return b - b_start; + return (uint) (b - b_start); } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 9e3a328ec26..af673b78254 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1051,7 +1051,7 @@ ulong my_scan_8bit(CHARSET_INFO *cs, const char *str, const char *end, int sq) if (*str == '.') { for(str++ ; str != end && *str == '0' ; str++); - return str-str0; + return (ulong) (str - str0); } return 0; @@ -1061,7 +1061,7 @@ ulong my_scan_8bit(CHARSET_INFO *cs, const char *str, const char *end, int sq) if (!my_isspace(cs,*str)) break; } - return str-str0; + return (ulong) (str - str0); default: return 0; } @@ -1078,14 +1078,14 @@ void my_fill_8bit(CHARSET_INFO *cs __attribute__((unused)), uint my_numchars_8bit(CHARSET_INFO *cs __attribute__((unused)), const char *b, const char *e) { - return e-b; + return (uint) (e - b); } uint my_numcells_8bit(CHARSET_INFO *cs __attribute__((unused)), const char *b, const char *e) { - return e-b; + return (uint) (e - b); } diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 7f34ee3fa2d..900acefd4ea 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -213,7 +213,7 @@ static int my_strnncoll_sjis_internal(CHARSET_INFO *cs, uint a_char= sjiscode(*a, *(a+1)); uint b_char= sjiscode(*b, *(b+1)); if (a_char != b_char) - return a_char - b_char; + return (int) a_char - (int) b_char; a += 2; b += 2; } else @@ -4605,7 +4605,7 @@ uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)), break; } } - return b - b0; + return (uint) (b - b0); } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index c3caaeadfb3..025fdd5a7f6 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -215,7 +215,7 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs, s+=s_res; t+=t_res; } - return t_is_prefix ? t-te : ((se-s) - (te-t)); + return t_is_prefix ? (int) (t - te) : (int) ((se - s) - (te - t)); } /* @@ -326,7 +326,7 @@ static int my_strncasecmp_ucs2(CHARSET_INFO *cs, s+=s_res; t+=t_res; } - return ( (se-s) - (te-t) ); + return (int) ( (se-s) - (te-t) ); } @@ -1349,7 +1349,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs, s+=s_res; t+=t_res; } - return t_is_prefix ? t-te : ((se-s) - (te-t)); + return t_is_prefix ? (int) (t - te) : (int) ((se-s) - (te-t)); } static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs, @@ -1494,7 +1494,7 @@ ulong my_scan_ucs2(CHARSET_INFO *cs __attribute__((unused)), if (str[0] != '\0' || str[1] != ' ') break; } - return str - str0; + return (ulong) (str - str0); default: return 0; } diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 612dda2b3eb..f20e2756810 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8270,7 +8270,7 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)), if (b >= (uchar *) end) /* need more bytes */ { *error= 1; - return chbeg - beg; /* unexpected EOL */ + return (uint) (chbeg - beg); /* unexpected EOL */ } if (ch == 0x8E) /* [x8E][xA0-xDF] */ @@ -8278,7 +8278,7 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)), if (*b >= 0xA0 && *b <= 0xDF) continue; *error= 1; - return chbeg - beg; /* invalid sequence */ + return (uint) (chbeg - beg); /* invalid sequence */ } if (ch == 0x8F) /* [x8F][xA1-xFE][xA1-xFE] */ @@ -8287,7 +8287,7 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)), if (b >= (uchar*) end) { *error= 1; - return chbeg - beg; /* unexpected EOL */ + return (uint) (chbeg - beg);/* unexpected EOL */ } } @@ -8295,9 +8295,9 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)), *b >= 0xA1 && *b <= 0xFE) /* [xA1-xFE][xA1-xFE] */ continue; *error= 1; - return chbeg - beg; /* invalid sequence */ + return (uint) (chbeg - beg); /* invalid sequence */ } - return b - (uchar *) beg; + return (uint) (b - (uchar *) beg); } diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 205701e87c7..0bf57967630 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2008,7 +2008,7 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, s+=s_res; t+=t_res; } - return t_is_prefix ? t-te : ((se-s) - (te-t)); + return t_is_prefix ? (int) (t-te) : (int) ((se-s) - (te-t)); }