From ab69b24928615c41461908f808465315bb57dca9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Jan 2005 14:29:06 -0800 Subject: [PATCH 01/26] Fix handling of table-name matching in mysqlhotcopy when newer versions of DBD::mysql that quote table names are used by removing the quoting. Also fix a bug that stripped all '~' characters out of the table regex instead of just the leading one used to negate the expression. (Bug #8136) scripts/mysqlhotcopy.sh: remove quotes around table names --- scripts/mysqlhotcopy.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 2cfe91da115..e3f4fdaf3ee 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -272,10 +272,7 @@ foreach my $rdb ( @db_desc ) { my $negated; if ($rdb->{t_regex}) { $t_regex = $rdb->{t_regex}; ## assign temporary regex - $negated = $t_regex =~ tr/~//d; ## remove and count - ## negation operator: we - ## don't allow ~ in table - ## names + $negated = $t_regex =~ s/^~//; ## note and remove negation operator $t_regex = qr/$t_regex/; ## make regex string from ## user regex @@ -820,6 +817,13 @@ sub get_list_of_tables { }); my @dbh_tables = eval { $dbh->tables() }; + + ## Remove quotes around table names + my $quote = $dbh->get_info(29); # SQL_IDENTIFIER_QUOTE_CHAR + if ($quote) { + foreach (@dbh_tables) { s/^$quote(.*)$quote$/$1/; } + } + $dbh->disconnect(); return @dbh_tables; } From bf12579c1f85e935ea25c7a36a6d0cdc846034e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 Feb 2005 12:37:18 -0800 Subject: [PATCH 02/26] Remove doubled quotes (used for escaping) in table names in mysqlhotcopy. Part of fix for Bug #8136. scripts/mysqlhotcopy.sh: Un-escape doubled quotes within table names. --- scripts/mysqlhotcopy.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index e3f4fdaf3ee..632174dc41a 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -821,7 +821,10 @@ sub get_list_of_tables { ## Remove quotes around table names my $quote = $dbh->get_info(29); # SQL_IDENTIFIER_QUOTE_CHAR if ($quote) { - foreach (@dbh_tables) { s/^$quote(.*)$quote$/$1/; } + foreach (@dbh_tables) { + s/^$quote(.*)$quote$/$1/; + s/$quote$quote/$quote/g; + } } $dbh->disconnect(); From 239543f725e27d0f9b842f74ccf1add91b64883e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Feb 2005 18:09:35 -0800 Subject: [PATCH 03/26] Include a timestamp on the 'ready for connections' message by printing it using sql_print_information() instead of directly to stdout. (Bug #8444) sql/mysqld.cc: Consolidate the "ready for connection" message into a single message, including the MYSQL_COMPILATION_COMMENT. sql/share/errmsg.txt: Include compilation comment in ER_READY --- sql/mysqld.cc | 12 +++++------- sql/share/errmsg.txt | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9013a7f5c3d..e58a2e69c75 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3113,13 +3113,11 @@ we force server id to 2, but this MySQL server will not act as a slave."); create_shutdown_thread(); create_maintenance_thread(); - printf(ER(ER_READY),my_progname,server_version, - ((unix_sock == INVALID_SOCKET) ? (char*) "" : mysqld_unix_port), - mysqld_port); - if (MYSQL_COMPILATION_COMMENT[0] != '\0') - fputs(" " MYSQL_COMPILATION_COMMENT, stdout); - putchar('\n'); - fflush(stdout); + sql_print_information(ER(ER_READY),my_progname,server_version, + ((unix_sock == INVALID_SOCKET) ? (char*) "" + : mysqld_unix_port), + mysqld_port, + MYSQL_COMPILATION_COMMENT); #if defined(__NT__) || defined(HAVE_SMEM) handle_connections_methods(); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index fa20e52f7e7..82205b04b93 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -1824,7 +1824,7 @@ ER_READY cze "%s: p-Bipraven na spojen" dan "%s: klar til tilslutninger" nla "%s: klaar voor verbindingen" - eng "%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d" + eng "%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d %s" jps "%s: ", est "%s: ootab hendusi" fre "%s: Prt pour des connections" @@ -1839,7 +1839,7 @@ ER_READY pol "%s: gotowe do po?czenia" por "%s: Pronto para conexes" rum "%s: sint gata pentru conectii" - rus "%s: .\n: '%s' : '%s' : %d" + rus "%s: .\n: '%s' : '%s' : %d %s" serbian "%s: Spreman za konekcije\n" slo "%s: pripraven na spojenie" spa "%s: preparado para conexiones" From a1db28a290643374df78809e418a3e80e141c694 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Feb 2005 13:59:04 -0800 Subject: [PATCH 04/26] Don't try to create a symlink if the DATA DIRECTORY specified for a table is the same as the normal datadir for that database. (Bug #8707) mysys/my_symlink2.c: Expand path of linkname before checking it against filename to decide if we need to create a link. mysql-test/t/symlink.test: Add new regression test mysql-test/r/symlink.result: Add new results --- mysql-test/r/symlink.result | 14 ++++++++++++++ mysql-test/t/symlink.test | 11 +++++++++++ mysys/my_symlink2.c | 7 ++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 08d75d8b562..50210d82c69 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -84,3 +84,17 @@ t1 CREATE TABLE `t1` ( `b` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +create table t1 (i int) data directory = "/home/jimw/my/mysql-4.1-8707/mysql-test/var/master-data/test/"; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (i int) index directory = "/home/jimw/my/mysql-4.1-8707/mysql-test/var/master-data/test/"; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 78c9b68fde5..b53be62861e 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -115,3 +115,14 @@ eval alter table t1 index directory="$MYSQL_TEST_DIR/var/log"; enable_query_log; show create table t1; drop table t1; + +# +# Test specifying DATA DIRECTORY that is the same as what would normally +# have been chosen. (Bug #8707) +# +eval create table t1 (i int) data directory = "$MYSQL_TEST_DIR/var/master-data/test/"; +show create table t1; +drop table t1; +eval create table t1 (i int) index directory = "$MYSQL_TEST_DIR/var/master-data/test/"; +show create table t1; +drop table t1; diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c index 913f632fbb4..80dca7d56ac 100644 --- a/mysys/my_symlink2.c +++ b/mysys/my_symlink2.c @@ -32,6 +32,7 @@ File my_create_with_symlink(const char *linkname, const char *filename, int tmp_errno; /* Test if we should create a link */ int create_link; + char abs_linkname[FN_REFLEN]; DBUG_ENTER("my_create_with_symlink"); if (my_disable_symlinks) @@ -42,7 +43,11 @@ File my_create_with_symlink(const char *linkname, const char *filename, filename= linkname; } else - create_link= (linkname && strcmp(linkname,filename)); + { + if (linkname) + my_realpath(&abs_linkname, linkname, MYF(0)); + create_link= (linkname && strcmp(abs_linkname,filename)); + } if (!(MyFlags & MY_DELETE_OLD)) { From 997c8f62b2b014ae583884eac56d97d82597437b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Feb 2005 11:10:12 -0800 Subject: [PATCH 05/26] Move some code around to appease the IBM AIX compiler. (Bug #8678) sql/item_func.cc: Move udf_handler delete method so that debug compiles on AIX will work. --- sql/item_func.cc | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index 3742a13e0bc..84cce2a1bd8 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2339,26 +2339,6 @@ longlong Item_func_bit_count::val_int() #ifdef HAVE_DLOPEN -udf_handler::~udf_handler() -{ - if (!not_original) - { - if (initialized) - { - if (u_d->func_deinit != NULL) - { - void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*)) - u_d->func_deinit; - (*deinit)(&initid); - } - free_udf(u_d); - } - if (buffers) // Because of bug in ecc - delete [] buffers; - } -} - - bool udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, uint arg_count, Item **arguments) @@ -2748,6 +2728,31 @@ String *Item_func_udf_str::val_str(String *str) return res; } + +/* + This has to come last in the udf_handler methods, or the compiler for IBM + AIX fails to compile with debugging enabled. (Yes, really.) + */ + +udf_handler::~udf_handler() +{ + if (!not_original) + { + if (initialized) + { + if (u_d->func_deinit != NULL) + { + void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*)) + u_d->func_deinit; + (*deinit)(&initid); + } + free_udf(u_d); + } + if (buffers) // Because of bug in ecc + delete [] buffers; + } +} + #else bool udf_handler::get_arguments() { return 0; } #endif /* HAVE_DLOPEN */ From 1b3ffb1bcbe182f38741107da8133dfae9471fba Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Feb 2005 23:50:06 +0300 Subject: [PATCH 06/26] Fix for BUG#8562: In Item_int_with_ref::new_item() create Item_int or Item_uint depending on ref->unsigned_flag. Item_int_with_ref can refer to both signed and unsigned integers. mysql-test/r/bigint.result: Test case for BUG#8562 mysql-test/t/bigint.test: Test case for BUG#8562 --- mysql-test/r/bigint.result | 39 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/bigint.test | 33 ++++++++++++++++++++++++++++++++ sql/item.h | 5 +++++ 3 files changed, 77 insertions(+) diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 4c70e72bdfb..eb3d0da3f23 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -87,3 +87,42 @@ drop table t1; SELECT '0x8000000000000001'+0; '0x8000000000000001'+0 0 +create table t1 ( +value64 bigint unsigned not null, +value32 integer not null, +primary key(value64, value32) +); +create table t2 ( +value64 bigint unsigned not null, +value32 integer not null, +primary key(value64, value32) +); +insert into t1 values(17156792991891826145, 1); +insert into t1 values( 9223372036854775807, 2); +insert into t2 values(17156792991891826145, 3); +insert into t2 values( 9223372036854775807, 4); +select * from t1; +value64 value32 +9223372036854775807 2 +17156792991891826145 1 +select * from t2; +value64 value32 +9223372036854775807 4 +17156792991891826145 3 +select * from t1, t2 where t1.value64=17156792991891826145 and +t2.value64=17156792991891826145; +value64 value32 value64 value32 +17156792991891826145 1 17156792991891826145 3 +select * from t1, t2 where t1.value64=17156792991891826145 and +t2.value64=t1.value64; +value64 value32 value64 value32 +17156792991891826145 1 17156792991891826145 3 +select * from t1, t2 where t1.value64= 9223372036854775807 and +t2.value64=9223372036854775807; +value64 value32 value64 value32 +9223372036854775807 2 9223372036854775807 4 +select * from t1, t2 where t1.value64= 9223372036854775807 and +t2.value64=t1.value64; +value64 value32 value64 value32 +9223372036854775807 2 9223372036854775807 4 +drop table t1, t2; diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index c509a4113f4..a26b78254e7 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -71,3 +71,36 @@ drop table t1; # atof() behaviour is different of different systems. to be fixed in 4.1 SELECT '0x8000000000000001'+0; +# Test for BUG#8562: joins over BIGINT UNSIGNED value + constant propagation +create table t1 ( + value64 bigint unsigned not null, + value32 integer not null, + primary key(value64, value32) +); + +create table t2 ( + value64 bigint unsigned not null, + value32 integer not null, + primary key(value64, value32) +); + +insert into t1 values(17156792991891826145, 1); +insert into t1 values( 9223372036854775807, 2); +insert into t2 values(17156792991891826145, 3); +insert into t2 values( 9223372036854775807, 4); + +select * from t1; +select * from t2; + +select * from t1, t2 where t1.value64=17156792991891826145 and +t2.value64=17156792991891826145; +select * from t1, t2 where t1.value64=17156792991891826145 and +t2.value64=t1.value64; + +select * from t1, t2 where t1.value64= 9223372036854775807 and +t2.value64=9223372036854775807; +select * from t1, t2 where t1.value64= 9223372036854775807 and +t2.value64=t1.value64; + +drop table t1, t2; + diff --git a/sql/item.h b/sql/item.h index 97e2b0c0945..423a9d6e425 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1011,6 +1011,11 @@ public: { return ref->save_in_field(field, no_conversions); } + Item *new_item() + { + return (ref->unsigned_flag)? new Item_uint(ref->name, ref->max_length) : + new Item_int(ref->name, ref->max_length); + } }; From eab1e62c2ca74396390c891efb70819323369d18 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Mar 2005 13:32:11 +0100 Subject: [PATCH 07/26] bug#8853 - ndb - commit after nodefailure on not TC node set exec_flag in execTC_COMMITREQ so that api will get rollbackrep ndb/include/ndbapi/NdbConnection.hpp: Make getConnectedNode public ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: Fix TC_COMMITREQ in abort cases ndb/test/ndbapi/testNodeRestart.cpp: Testcase for bug#8853 ndb/test/run-test/daily-devel-tests.txt: Testcase for bug#8853 --- ndb/include/ndbapi/NdbConnection.hpp | 3 +- ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 3 +- ndb/test/ndbapi/testNodeRestart.cpp | 71 +++++++++++++++++++++++++ ndb/test/run-test/daily-devel-tests.txt | 4 ++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index 166355cae17..a013489d4c4 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -448,6 +448,8 @@ public: NdbScanOperation* getNdbScanOperation(const NdbDictionary::Table * table); NdbIndexScanOperation* getNdbIndexScanOperation(const NdbDictionary::Index * index, const NdbDictionary::Table * table); + + Uint32 getConnectedNodeId(); // Get Connected node id private: /** @@ -480,7 +482,6 @@ private: */ void setConnectedNodeId( Uint32 nodeId, Uint32 sequence); - Uint32 getConnectedNodeId(); // Get Connected node id void setMyBlockReference( int ); // Set my block refrerence void setTC_ConnectPtr( Uint32 ); // Sets TC Connect pointer int getTC_ConnectPtr(); // Gets TC Connect pointer diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index c804fa32bd2..8d8eab85858 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -5193,7 +5193,8 @@ void Dbtc::execTC_COMMITREQ(Signal* signal) const Uint32 transId1 = regApiPtr->transid[0]; const Uint32 transId2 = regApiPtr->transid[1]; Uint32 errorCode = 0; - + + regApiPtr->m_exec_flag = 1; switch (regApiPtr->apiConnectstate) { case CS_STARTED: tcConnectptr.i = regApiPtr->firstTcConnect; diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp index e844f227034..a50df91908c 100644 --- a/ndb/test/ndbapi/testNodeRestart.cpp +++ b/ndb/test/ndbapi/testNodeRestart.cpp @@ -344,6 +344,71 @@ err: return NDBT_FAILED; } +int runLateCommit(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + int i = 0; + while(iisTestStopped()){ + g_info << i << ": "; + + if(hugoOps.startTransaction(pNdb) != 0) + return NDBT_FAILED; + + if(hugoOps.pkUpdateRecord(pNdb, 1) != 0) + return NDBT_FAILED; + + if(hugoOps.execute_NoCommit(pNdb) != 0) + return NDBT_FAILED; + + Uint32 transNode= hugoOps.getTransaction()->getConnectedNodeId(); + int id = i % restarter.getNumDbNodes(); + int nodeId; + while((nodeId = restarter.getDbNodeId(id)) == transNode) + id = (id + 1) % restarter.getNumDbNodes(); + + ndbout << "Restart node " << nodeId << endl; + + restarter.restartOneDbNode(nodeId, + /** initial */ false, + /** nostart */ true, + /** abort */ true); + + restarter.waitNodesNoStart(&nodeId, 1); + + int res; + if(i & 1) + res= hugoOps.execute_Commit(pNdb); + else + res= hugoOps.execute_Rollback(pNdb); + + ndbout_c("res= %d", res); + + hugoOps.closeTransaction(pNdb); + + restarter.startNodes(&nodeId, 1); + restarter.waitNodesStarted(&nodeId, 1); + + if(i & 1) + { + if(res != 286) + return NDBT_FAILED; + } + else + { + if(res != 0) + return NDBT_FAILED; + } + i++; + } + + return NDBT_OK; +} + NDBT_TESTSUITE(testNodeRestart); TESTCASE("NoLoad", "Test that one node at a time can be stopped and then restarted "\ @@ -600,6 +665,12 @@ TESTCASE("CommittedRead", STEP(runDirtyRead); FINALIZER(runClearTable); } +TESTCASE("LateCommit", + "Test commit after node failure"){ + INITIALIZER(runLoadTable); + STEP(runLateCommit); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testNodeRestart); int main(int argc, const char** argv){ diff --git a/ndb/test/run-test/daily-devel-tests.txt b/ndb/test/run-test/daily-devel-tests.txt index 5c9b36fb836..ec90a88a77f 100644 --- a/ndb/test/run-test/daily-devel-tests.txt +++ b/ndb/test/run-test/daily-devel-tests.txt @@ -69,6 +69,10 @@ max-time: 2500 cmd: testNodeRestart args: -n CommittedRead T1 +max-time: 2500 +cmd: testNodeRestart +args: -n LateCommit T1 + max-time: 2500 cmd: testNodeRestart args: -n Terror T6 T13 From 737f7292b4cb10c1f820f932e7ff3a6fd63f44ca Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Mar 2005 20:00:48 +0400 Subject: [PATCH 08/26] a fix for --ps-protocol (bug #6089: FOUND_ROWS returns wrong values when no table/view is used) sql/sql_union.cc: a fix for --ps-protocol (bug #6089: FOUND_ROWS returns wrong values when no table/view is used) Don't touch options as itit's not needed. --- mysql-test/r/ps.result | 12 ++++++++++++ mysql-test/t/ps.test | 11 +++++++++++ sql/sql_union.cc | 30 +++++++++++------------------- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 4e1e75f1b33..89c369a51e8 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -482,3 +482,15 @@ execute stmt; pnum deallocate prepare stmt; drop table t1, t2; +prepare stmt from "SELECT SQL_CALC_FOUND_ROWS 'foo' UNION SELECT 'bar' LIMIT 0"; +execute stmt; +foo +SELECT FOUND_ROWS(); +FOUND_ROWS() +2 +execute stmt; +foo +SELECT FOUND_ROWS(); +FOUND_ROWS() +2 +deallocate prepare stmt; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 92bf4ece4e3..b204e59267e 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -485,3 +485,14 @@ execute stmt; deallocate prepare stmt; drop table t1, t2; + +# +# Bug #6089: FOUND_ROWS returns wrong values when no table/view is used +# + +prepare stmt from "SELECT SQL_CALC_FOUND_ROWS 'foo' UNION SELECT 'bar' LIMIT 0"; +execute stmt; +SELECT FOUND_ROWS(); +execute stmt; +SELECT FOUND_ROWS(); +deallocate prepare stmt; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 882316d57d7..5fd59500ace 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -215,8 +215,6 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, select_limit_cnt= sl->select_limit+sl->offset_limit; if (select_limit_cnt < sl->select_limit) select_limit_cnt= HA_POS_ERROR; // no limit - if (select_limit_cnt == HA_POS_ERROR || sl->braces) - sl->options&= ~OPTION_FOUND_ROWS; can_skip_order_by= is_union && (!sl->braces || select_limit_cnt == HA_POS_ERROR); @@ -342,7 +340,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if (arena->is_stmt_prepare()) { /* prepare fake select to initialize it correctly */ - ulong options_tmp= init_prepare_fake_select_lex(thd); + (void) init_prepare_fake_select_lex(thd); if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options, result))) { @@ -447,21 +445,14 @@ int st_select_lex_unit::exec() if (select_limit_cnt < sl->select_limit) select_limit_cnt= HA_POS_ERROR; // no limit - /* - When using braces, SQL_CALC_FOUND_ROWS affects the whole query. - We don't calculate found_rows() per union part - */ - if (select_limit_cnt == HA_POS_ERROR || sl->braces) - sl->options&= ~OPTION_FOUND_ROWS; - else - { - /* - We are doing an union without braces. In this case - SQL_CALC_FOUND_ROWS should be done on all sub parts - */ - sl->options|= found_rows_for_union; - } - sl->join->select_options=sl->options; + /* + When using braces, SQL_CALC_FOUND_ROWS affects the whole query: + we don't calculate found_rows() per union part. + Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts. + */ + sl->join->select_options= + (select_limit_cnt == HA_POS_ERROR || sl->braces) ? + sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union; res= sl->join->optimize(); } if (!res) @@ -493,7 +484,8 @@ int st_select_lex_unit::exec() } /* Needed for the following test and for records_at_start in next loop */ table->file->info(HA_STATUS_VARIABLE); - if (found_rows_for_union & sl->options) + if (found_rows_for_union && !sl->braces && + select_limit_cnt != HA_POS_ERROR) { /* This is a union without braces. Remember the number of rows that From 92014782aca228aac8b3a055b7c5d6023c7c47d7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 01:07:03 +0100 Subject: [PATCH 09/26] ndb - bug#8876 ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: typo - use of global var, spotted by mikael --- ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 97931041e2a..7311cf69763 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -5942,7 +5942,7 @@ int Dbtc::releaseAndAbort(Signal* signal) signal->theData[0] = tcConnectptr.i; signal->theData[1] = apiConnectptr.p->transid[0]; signal->theData[2] = apiConnectptr.p->transid[1]; - signal->theData[3] = hostptr.i; + signal->theData[3] = localHostptr.i; signal->theData[4] = ZFALSE; sendSignal(cownref, GSN_ABORTED, signal, 5, JBB); }//if From c9b4f8c3d7b462ecc8cee1e434de244aa0cc3c2a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Mar 2005 16:30:24 -0800 Subject: [PATCH 10/26] Fix bug in checking of table-specific grats that caused IP/NETMASK hostnames to not be matched correctly. (Bug #3309) sql/sql_acl.cc: Use an acl_host_or_ip in the GRANT_TABLE struct instead of storing the host itself, and use compare_hostname() in testing it. This adds support for IP addresses with netmasks to table-specific grants, and results in simplified code by making use of compare_hostname() in more places. mysql-test/r/grant2.result: Add new results mysql-test/t/grant2.test: Add new regression test --- mysql-test/r/grant2.result | 16 +++++++++++++++ mysql-test/t/grant2.test | 14 +++++++++++++ sql/sql_acl.cc | 42 +++++++++++++------------------------- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 6d8bdbaf8f9..8200d112709 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -63,3 +63,19 @@ delete from mysql.columns_priv where user like 'mysqltest\_%'; flush privileges; drop database mysqltest; use test; +create database mysqltest_1; +create table mysqltest_1.t1 (i int); +insert into mysqltest_1.t1 values (1),(2),(3); +GRANT ALL ON mysqltest_1.t1 TO mysqltest_1@'127.0.0.0/255.0.0.0'; +show grants for current_user(); +Grants for mysqltest_1@127.0.0.0/255.0.0.0 +GRANT USAGE ON *.* TO 'mysqltest_1'@'127.0.0.0/255.0.0.0' +GRANT ALL PRIVILEGES ON `mysqltest_1`.`t1` TO 'mysqltest_1'@'127.0.0.0/255.0.0.0' +select * from t1; +i +1 +2 +3 +REVOKE ALL ON mysqltest_1.t1 FROM mysqltest_1@'127.0.0.0/255.0.0.0'; +drop table mysqltest_1.t1; +drop database mysqltest_1; diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 7060d35e9a4..8e1314aeace 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -89,3 +89,17 @@ flush privileges; drop database mysqltest; use test; +# Bug #3309: Test IP addresses with netmask +create database mysqltest_1; +create table mysqltest_1.t1 (i int); +insert into mysqltest_1.t1 values (1),(2),(3); +GRANT ALL ON mysqltest_1.t1 TO mysqltest_1@'127.0.0.0/255.0.0.0'; +connect (n1,127.0.0.1,mysqltest_1,,mysqltest_1,$MASTER_MYPORT,$MASTER_MYSOCK); +connection n1; +show grants for current_user(); +select * from t1; +disconnect n1; +connection default; +REVOKE ALL ON mysqltest_1.t1 FROM mysqltest_1@'127.0.0.0/255.0.0.0'; +drop table mysqltest_1.t1; +drop database mysqltest_1; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 46114e2748b..0c3f2a52fd2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1788,7 +1788,8 @@ static byte* get_key_column(GRANT_COLUMN *buff,uint *length, class GRANT_TABLE :public Sql_alloc { public: - char *host,*db, *user, *tname, *hash_key, *orig_host; + acl_host_and_ip host; + char *db, *user, *tname, *hash_key; ulong privs, cols; ulong sort; uint key_length; @@ -1807,12 +1808,10 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, :privs(p), cols(c) { /* Host given by user */ - orig_host= strdup_root(&memex,h); - /* Convert empty hostname to '%' for easy comparision */ - host= orig_host[0] ? orig_host : (char*) "%"; + update_hostname(&host, strdup_root(&memex, h)); db = strdup_root(&memex,d); user = strdup_root(&memex,u); - sort= get_sort(3,host,db,user); + sort= get_sort(3,host.hostname,db,user); tname= strdup_root(&memex,t); if (lower_case_table_names) { @@ -1831,17 +1830,12 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) { byte key[MAX_KEY_LENGTH]; - orig_host= host= get_field(&memex, form->field[0]); + update_hostname(&host, get_field(&memex, form->field[0])); db= get_field(&memex,form->field[1]); user= get_field(&memex,form->field[2]); if (!user) user= (char*) ""; - if (!orig_host) - { - orig_host= (char*) ""; - host= (char*) "%"; - } - sort= get_sort(3, orig_host, db, user); + sort= get_sort(3, host.hostname, db, user); tname= get_field(&memex,form->field[3]); if (!db || !tname) { @@ -1868,7 +1862,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) if (cols) { int key_len; - col_privs->field[0]->store(orig_host,(uint) strlen(orig_host), + col_privs->field[0]->store(host.hostname,(uint) strlen(host.hostname), &my_charset_latin1); col_privs->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); col_privs->field[2]->store(user,(uint) strlen(user), &my_charset_latin1); @@ -1945,17 +1939,12 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, { if (exact) { - if ((host && - !my_strcasecmp(&my_charset_latin1, host, grant_table->host)) || - (ip && !strcmp(ip,grant_table->host))) + if (compare_hostname(&grant_table->host, host, ip)) return grant_table; } else { - if (((host && !wild_case_compare(&my_charset_latin1, - host,grant_table->host)) || - (ip && !wild_case_compare(&my_charset_latin1, - ip,grant_table->host))) && + if (compare_hostname(&grant_table->host, host, ip) && (!found || found->sort < grant_table->sort)) found=grant_table; // Host ok } @@ -2692,7 +2681,7 @@ my_bool grant_init(THD *org_thd) if (check_no_resolve) { - if (hostname_requires_resolving(mem_check->host)) + if (hostname_requires_resolving(mem_check->host.hostname)) { sql_print_warning("'tables_priv' entry '%s %s@%s' " "ignored in --skip-name-resolve mode.", @@ -2981,10 +2970,7 @@ bool check_grant_db(THD *thd,const char *db) idx); if (len < grant_table->key_length && !memcmp(grant_table->hash_key,helping,len) && - (thd->host && !wild_case_compare(&my_charset_latin1, - thd->host,grant_table->host) || - (thd->ip && !wild_case_compare(&my_charset_latin1, - thd->ip,grant_table->host)))) + compare_hostname(&grant_table->host, thd->host, thd->ip)) { error=0; // Found match break; @@ -3324,7 +3310,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(&my_charset_latin1, lex_user->host.str, - grant_table->orig_host)) + grant_table->host.hostname)) { ulong table_access= grant_table->privs; if ((table_access | grant_table->cols) != 0) @@ -3606,7 +3592,7 @@ int mysql_drop_user(THD *thd, List &list) counter); if (!(user=grant_table->user)) user= ""; - if (!(host=grant_table->host)) + if (!(host=grant_table->host.hostname)) host= ""; if (!strcmp(user_name->user.str,user) && @@ -3735,7 +3721,7 @@ int mysql_revoke_all(THD *thd, List &list) counter); if (!(user=grant_table->user)) user= ""; - if (!(host=grant_table->host)) + if (!(host=grant_table->host.hostname)) host= ""; if (!strcmp(lex_user->user.str,user) && From d88c56a63749e5e5b0828557bd81f207a29eaacd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 05:03:21 +0300 Subject: [PATCH 11/26] Comments added --- sql/item.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/item.h b/sql/item.h index 423a9d6e425..2827be2d237 100644 --- a/sql/item.h +++ b/sql/item.h @@ -997,6 +997,8 @@ public: The following class is used to optimize comparing of date and bigint columns We need to save the original item, to be able to set the field to the original value in 'opt_range'. + An instance of Item_int_with_ref may refer to a signed or an unsigned + integer. */ class Item_int_with_ref :public Item_int From d6c9c19412c4f640b161ff0909a55a093a839876 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 14:15:37 +0400 Subject: [PATCH 12/26] Bug#8840 Empty string comparison and character set 'cp1250' Secondary weight out of bounds was picked up in mistake when the string is empty, instead of returning 0. --- mysql-test/include/have_cp1250_ch.inc | 4 ++++ mysql-test/r/ctype_cp1250_ch.result | 9 +++++++++ mysql-test/r/have_cp1250_ch.require | 2 ++ mysql-test/t/ctype_cp1250_ch.test | 12 ++++++++++++ strings/ctype-win1250ch.c | 2 +- 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 mysql-test/include/have_cp1250_ch.inc create mode 100644 mysql-test/r/ctype_cp1250_ch.result create mode 100644 mysql-test/r/have_cp1250_ch.require create mode 100644 mysql-test/t/ctype_cp1250_ch.test diff --git a/mysql-test/include/have_cp1250_ch.inc b/mysql-test/include/have_cp1250_ch.inc new file mode 100644 index 00000000000..eec5d69fbd6 --- /dev/null +++ b/mysql-test/include/have_cp1250_ch.inc @@ -0,0 +1,4 @@ +-- require r/have_cp1250_ch.require +disable_query_log; +show collation like "cp1250_czech_cs"; +enable_query_log; diff --git a/mysql-test/r/ctype_cp1250_ch.result b/mysql-test/r/ctype_cp1250_ch.result new file mode 100644 index 00000000000..62936b84caf --- /dev/null +++ b/mysql-test/r/ctype_cp1250_ch.result @@ -0,0 +1,9 @@ +SHOW COLLATION LIKE 'cp1250_czech_cs'; +Collation Charset Id Default Compiled Sortlen +cp1250_czech_cs cp1250 34 Yes 2 +CREATE TABLE t1 (a char(16)) character set cp1250 collate cp1250_czech_cs; +INSERT INTO t1 VALUES (''); +SELECT a, length(a), a='', a=' ', a=' ' FROM t1; +a length(a) a='' a=' ' a=' ' + 0 1 1 1 +DROP TABLE t1; diff --git a/mysql-test/r/have_cp1250_ch.require b/mysql-test/r/have_cp1250_ch.require new file mode 100644 index 00000000000..2eb834d97e2 --- /dev/null +++ b/mysql-test/r/have_cp1250_ch.require @@ -0,0 +1,2 @@ +Collation Charset Id Default Compiled Sortlen +cp1250_czech_cs cp1250 34 Yes 2 diff --git a/mysql-test/t/ctype_cp1250_ch.test b/mysql-test/t/ctype_cp1250_ch.test new file mode 100644 index 00000000000..06aea7b9979 --- /dev/null +++ b/mysql-test/t/ctype_cp1250_ch.test @@ -0,0 +1,12 @@ +-- source include/have_cp1250_ch.inc + +SHOW COLLATION LIKE 'cp1250_czech_cs'; + +# +# Bugs: #8840: Empty string comparison and character set 'cp1250' +# + +CREATE TABLE t1 (a char(16)) character set cp1250 collate cp1250_czech_cs; +INSERT INTO t1 VALUES (''); +SELECT a, length(a), a='', a=' ', a=' ' FROM t1; +DROP TABLE t1; diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 98389a9a5a4..d843971b93f 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -416,7 +416,7 @@ static struct wordvalue doubles[] = { #define NEXT_CMP_VALUE(src, p, pass, value, len) \ while (1) { \ if (IS_END(p, src, len)) { \ - if (pass == 0) { p = src; pass++; } \ + if (pass == 0 && len > 0) { p= src; pass++; } \ else { value = 0; break; } \ } \ value = ((pass == 0) ? _sort_order_win1250ch1[*p] \ From b6a9dc96c980d125198128378e2077ac33575d6b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 11:38:50 +0100 Subject: [PATCH 13/26] ndb - bug#8876 ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: merge error? --- ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 310ba6a9a0b..b30da54479b 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -5937,7 +5937,6 @@ int Dbtc::releaseAndAbort(Signal* signal) signal->theData[2] = apiConnectptr.p->transid[0]; signal->theData[3] = apiConnectptr.p->transid[1]; sendSignal(tblockref, GSN_ABORT, signal, 4, JBB); - return 1; } else { jam(); signal->theData[0] = tcConnectptr.i; From 5841c6309ad7f3087f8c4b47852eec9ebb2692d5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 12:35:39 +0100 Subject: [PATCH 14/26] Prevent a collision with the system's '#define errno ...' by guarding the variable declaration. include/my_sys.h: There are platforms which use '#define errno ...' and then cause a collision with 'extern int errno;', one example is OpenBSD. Rather than treat them explicitly by the 'HAVE_ERRNO_AS_DEFINE', we can check for these by using '#ifndef errno'. --- include/my_sys.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/my_sys.h b/include/my_sys.h index 7c69a626366..ce785b58da4 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -206,11 +206,13 @@ void __CDECL hfree(void *ptr); #endif #endif /* MSDOS */ +#ifndef errno /* did we already get it? */ #ifdef HAVE_ERRNO_AS_DEFINE #include /* errno is a define */ #else extern int errno; /* declare errno */ #endif +#endif /* #ifndef errno */ extern char NEAR errbuff[NRERRBUFFS][ERRMSGSIZE]; extern char *home_dir; /* Home directory for user */ extern char *my_progname; /* program-name (printed in errors) */ From 0c88d48d50243d92b3764961eb561a5a5c05ca5c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 15:37:14 +0400 Subject: [PATCH 15/26] After merge fix. sql/sql_lex.cc: No need to change options here. --- sql/sql_lex.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 79996ffb65c..738a6e0dbbd 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1837,8 +1837,6 @@ void st_select_lex_unit::set_limit(SELECT_LEX *values, select_limit_cnt= values->select_limit+values->offset_limit; if (select_limit_cnt < values->select_limit) select_limit_cnt= HA_POS_ERROR; // no limit - if (select_limit_cnt == HA_POS_ERROR) - sl->options&= ~OPTION_FOUND_ROWS; } From ad5174af411b27bf183410f4d6d9eb8b3f30ab69 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 15:43:00 +0400 Subject: [PATCH 16/26] Bugs: #8063: make test mysqldump [ fail ] See mysqldump.test diff for more details --- mysql-test/r/mysqldump.result | 21 --------------------- mysql-test/t/mysqldump.test | 9 ++++++++- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index f763a16836f..ca92c44c99c 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -439,27 +439,6 @@ CREATE TABLE `t1` ( ) TYPE=MyISAM; -/*!40000 ALTER TABLE `t1` DISABLE KEYS */; -LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES (''); -UNLOCK TABLES; -/*!40000 ALTER TABLE `t1` ENABLE KEYS */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,MYSQL323' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -DROP TABLE IF EXISTS `t1`; -CREATE TABLE `t1` ( - `a` char(10) default NULL -) TYPE=MyISAM; - - /*!40000 ALTER TABLE `t1` DISABLE KEYS */; LOCK TABLES `t1` WRITE; INSERT INTO `t1` VALUES (''); diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 255ae50a8ca..9ea5c1e58b5 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -148,7 +148,14 @@ drop database mysqldump_test_db; CREATE TABLE t1 (a CHAR(10)); INSERT INTO t1 VALUES (_latin1 ''); --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments test t1 ---exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --compatible=mysql323 test t1 +# +# Bug#8063: make test mysqldump [ fail ] +# We cannot tes this command because its output depends +# on --default-character-set incompiled into "mysqldump" program. +# If the future we can move this command into a separate test with +# checking that "mysqldump" is compiled with "latin1" +# +#--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --compatible=mysql323 test t1 --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --compatible=mysql323 --default-character-set=cp850 test t1 --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=cp850 --compatible=mysql323 test t1 --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 test t1 From 85f94ce9926fda357626ec5a58937ae58873cad2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 12:45:49 +0100 Subject: [PATCH 17/26] ndb - bug#8876 third and final solution ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: lqh to forward abort within ng --- ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index b30da54479b..03a0590b6e2 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -5923,11 +5923,17 @@ int Dbtc::releaseAndAbort(Signal* signal) UintR TnoLoops = tcConnectptr.p->noOfNodes; apiConnectptr.p->counter++; + bool prevAlive = false; for (Uint32 Ti = 0; Ti < TnoLoops ; Ti++) { localHostptr.i = tcConnectptr.p->tcNodedata[Ti]; ptrCheckGuard(localHostptr, chostFilesize, hostRecord); if (localHostptr.p->hostStatus == HS_ALIVE) { jam(); + if (prevAlive) { + // if previous is alive, its LQH forwards abort to this node + jam(); + continue; + } /* ************< */ /* ABORT < */ /* ************< */ @@ -5937,6 +5943,7 @@ int Dbtc::releaseAndAbort(Signal* signal) signal->theData[2] = apiConnectptr.p->transid[0]; signal->theData[3] = apiConnectptr.p->transid[1]; sendSignal(tblockref, GSN_ABORT, signal, 4, JBB); + prevAlive = true; } else { jam(); signal->theData[0] = tcConnectptr.i; @@ -5945,6 +5952,7 @@ int Dbtc::releaseAndAbort(Signal* signal) signal->theData[3] = localHostptr.i; signal->theData[4] = ZFALSE; sendSignal(cownref, GSN_ABORTED, signal, 5, JBB); + prevAlive = false; }//if }//for return 1; From 66d2d13a8e3e70e54d92fc6686601b72f3bd2464 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 17:38:58 +0300 Subject: [PATCH 18/26] Fix for bug#8740: Server crash at start on Solaris 9 (64 bit) --- sql/log.cc | 2 +- sql/mysqld.cc | 2 +- sql/sql_class.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 5d77197a9b9..d5c7cd5464f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2457,7 +2457,7 @@ void sql_print_information(const char *format, ...) static const char tc_log_magic[]={(char) 254, 0x23, 0x05, 0x74}; -uint opt_tc_log_size=TC_LOG_MIN_SIZE; +ulong opt_tc_log_size= TC_LOG_MIN_SIZE; ulong tc_log_max_pages_used=0, tc_log_page_size=0, tc_log_page_waits=0, tc_log_cur_pages_used=0; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ce70b05761a..2a466af52e9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4566,7 +4566,7 @@ Disable with --skip-isam.", REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.", (gptr*) &opt_tc_log_size, (gptr*) &opt_tc_log_size, 0, GET_ULONG, - REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ~0, 0, TC_LOG_PAGE_SIZE, 0}, + REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ~0L, 0, TC_LOG_PAGE_SIZE, 0}, {"log-update", OPT_UPDATE_LOG, "The update log is deprecated since version 5.0, is replaced by the binary \ log and this option justs turns on --log-bin instead.", diff --git a/sql/sql_class.h b/sql/sql_class.h index ff30faf1150..e88205568c2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -45,7 +45,7 @@ extern const char **errmesg; #define TC_LOG_PAGE_SIZE 8192 #define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE) -extern uint opt_tc_log_size; +extern ulong opt_tc_log_size; extern ulong tc_log_max_pages_used; extern ulong tc_log_page_size; extern ulong tc_log_page_waits; From 2860a7723e8df63022c0f7a5aa3ab52996c798ed Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 17:38:59 +0300 Subject: [PATCH 19/26] Fixes for bug#8115 "Server Crash with prepared statement" and bug#8849 "problem with insert statement with table alias's": make equality propagation work in stored procedures and prepared statements. Equality propagation can change AND/OR structure of ON expressions, so the fix is to provide each execution of PS/SP with it's own copy of AND/OR tree. We have been doing that already for WHERE clauses, now ON clauses are also copied. mysql-test/r/ps.result: Bug#8115: test results fixed. mysql-test/r/sp.result: Bug#8849: test results fixed. mysql-test/t/ps.test: A test case for Bug#8115 "Server Crash with prepared statement". mysql-test/t/sp.test: A test case for Bug#8849 "problem with insert statement with table alias's". sql/item_cmpfunc.cc: Comment a parse tree transformation. sql/item_cmpfunc.h: Comment how Item_equal works with PS/SP. sql/mysql_priv.h: Add declaration for init_stmt_after_parse. sql/sp_head.cc: Call init_stmt_after_parse in restore_lex(), which is used to grab TABLE_LIST and SELECT_LEX list of a parsed substatement of stored procedure. This is a necessary post-init step which must be done for any statement which can be executed many times. sql/sql_prepare.cc: Implement init_stmt_after_parse() which prepares AND/OR structure of all ON expressions and WHERE clauses of a statement for copying. sql/sql_select.cc: Implementation of equality propagation inspected with regard to prepared statements and stored procedures. We now restore AND/OR structure of every ON expression in addition to AND/OR structure of WHERE clauses when reexecuting a PS/SP. sql/table.h: Add declaration for TABLE::prep_on_expr. --- mysql-test/r/ps.result | 25 +++++++++++++++++++++ mysql-test/r/sp.result | 38 ++++++++++++++++++++++++++++++++ mysql-test/t/ps.test | 33 ++++++++++++++++++++++++++++ mysql-test/t/sp.test | 49 ++++++++++++++++++++++++++++++++++++++++++ sql/item_cmpfunc.cc | 23 ++++++++++++++------ sql/item_cmpfunc.h | 6 ++++++ sql/mysql_priv.h | 1 + sql/sp_head.cc | 1 + sql/sql_prepare.cc | 35 +++++++++++++++++++++++------- sql/sql_select.cc | 39 ++++++++++++++++++++++----------- sql/table.h | 9 ++++++++ 11 files changed, 232 insertions(+), 27 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 51fadd48184..5b638fd58ab 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -499,3 +499,28 @@ SELECT FOUND_ROWS(); FOUND_ROWS() 2 deallocate prepare stmt; +create table t1 (a char(3) not null, b char(3) not null, +c char(3) not null, primary key (a, b, c)); +create table t2 like t1; +prepare stmt from +"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) + where t1.a=1"; +execute stmt; +a +execute stmt; +a +execute stmt; +a +prepare stmt from +"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from +(t1 left outer join t2 on t2.a=? and t1.b=t2.b) +left outer join t2 t3 on t3.a=? where t1.a=?"; +set @a:=1, @b:=1, @c:=1; +execute stmt using @a, @b, @c; +a b c a b c +execute stmt using @a, @b, @c; +a b c a b c +execute stmt using @a, @b, @c; +a b c a b c +deallocate prepare stmt; +drop table t1,t2; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 24045bae430..803cb89cecf 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -2542,3 +2542,41 @@ drop procedure bug7992| drop table t3| drop table t1; drop table t2; +CREATE TABLE t1 ( +lpitnumber int(11) default NULL, +lrecordtype int(11) default NULL +); +CREATE TABLE t2 ( +lbsiid int(11) NOT NULL default '0', +ltradingmodeid int(11) NOT NULL default '0', +ltradingareaid int(11) NOT NULL default '0', +csellingprice decimal(19,4) default NULL, +PRIMARY KEY (lbsiid,ltradingmodeid,ltradingareaid) +); +CREATE TABLE t3 ( +lbsiid int(11) NOT NULL default '0', +ltradingareaid int(11) NOT NULL default '0', +PRIMARY KEY (lbsiid,ltradingareaid) +); +CREATE PROCEDURE bug8849() +begin +insert into t3 +( +t3.lbsiid, +t3.ltradingareaid +) +select distinct t1.lpitnumber, t2.ltradingareaid +from +t2 join t1 on +t1.lpitnumber = t2.lbsiid +and t1.lrecordtype = 1 +left join t2 as price01 on +price01.lbsiid = t2.lbsiid and +price01.ltradingmodeid = 1 and +t2.ltradingareaid = price01.ltradingareaid; +end| +call bug8849(); +call bug8849(); +call bug8849(); +drop procedure bug8849; +drop tables t1,t2,t3; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index b65226dae6d..1af84119b79 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -507,3 +507,36 @@ SELECT FOUND_ROWS(); execute stmt; SELECT FOUND_ROWS(); deallocate prepare stmt; + +# +# Bug#8115: equality propagation and prepared statements +# + +create table t1 (a char(3) not null, b char(3) not null, + c char(3) not null, primary key (a, b, c)); +create table t2 like t1; + +# reduced query +prepare stmt from + "select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) + where t1.a=1"; +execute stmt; +execute stmt; +execute stmt; + +# original query +prepare stmt from +"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from +(t1 left outer join t2 on t2.a=? and t1.b=t2.b) +left outer join t2 t3 on t3.a=? where t1.a=?"; + +set @a:=1, @b:=1, @c:=1; + +execute stmt using @a, @b, @c; +execute stmt using @a, @b, @c; +execute stmt using @a, @b, @c; + +deallocate prepare stmt; + +drop table t1,t2; + diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 439ace881d1..69bdeb7a059 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3086,3 +3086,52 @@ delimiter ;| drop table t1; drop table t2; +# +# Bug#8849: rolling back changes to AND/OR structure of ON and WHERE clauses +# in SP +# + +CREATE TABLE t1 ( + lpitnumber int(11) default NULL, + lrecordtype int(11) default NULL +); + +CREATE TABLE t2 ( + lbsiid int(11) NOT NULL default '0', + ltradingmodeid int(11) NOT NULL default '0', + ltradingareaid int(11) NOT NULL default '0', + csellingprice decimal(19,4) default NULL, + PRIMARY KEY (lbsiid,ltradingmodeid,ltradingareaid) +); + +CREATE TABLE t3 ( + lbsiid int(11) NOT NULL default '0', + ltradingareaid int(11) NOT NULL default '0', + PRIMARY KEY (lbsiid,ltradingareaid) +); + +delimiter |; +CREATE PROCEDURE bug8849() +begin + insert into t3 + ( + t3.lbsiid, + t3.ltradingareaid + ) + select distinct t1.lpitnumber, t2.ltradingareaid + from + t2 join t1 on + t1.lpitnumber = t2.lbsiid + and t1.lrecordtype = 1 + left join t2 as price01 on + price01.lbsiid = t2.lbsiid and + price01.ltradingmodeid = 1 and + t2.ltradingareaid = price01.ltradingareaid; +end| +delimiter ;| + +call bug8849(); +call bug8849(); +call bug8849(); +drop procedure bug8849; +drop tables t1,t2,t3; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index dae5f0fc0c6..c0cb0704852 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2289,6 +2289,21 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (check_stack_overrun(thd, buff)) return TRUE; // Fatal error flag is set! + /* + The following optimization reduces the depth of an AND-OR tree. + E.g. a WHERE clause like + F1 AND (F2 AND (F2 AND F4)) + is parsed into a tree with the same nested structure as defined + by braces. This optimization will transform such tree into + AND (F1, F2, F3, F4). + Trees of OR items are flattened as well: + ((F1 OR F2) OR (F3 OR F4)) => OR (F1, F2, F3, F4) + Items for removed AND/OR levels will dangle until the death of the + entire statement. + The optimization is currently prepared statements and stored procedures + friendly as it doesn't allocate any memory and its effects are durable + (i.e. do not depend on PS/SP arguments). + */ while ((item=li++)) { table_map tmp_table_map; @@ -3265,6 +3280,7 @@ Item_equal::Item_equal(Item *c, Item_field *f) const_item= c; } + Item_equal::Item_equal(Item_equal *item_equal) : Item_bool_func(), eval_item(0), cond_false(0) { @@ -3301,12 +3317,7 @@ void Item_equal::add(Item_field *f) uint Item_equal::members() { - uint count= 0; - List_iterator_fast li(fields); - Item_field *item; - while ((item= li++)) - count++; - return count; + return fields.elements; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 212a3dd4501..5a87635a4dc 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1095,6 +1095,12 @@ public: predicates that can not be used to access tables in the investigated plan for those, obtained by substitution of some fields for equal fields, that can be used. + + Prepared Statements/Stored Procedures note: instances of class + Item_equal are created only at the time a PS/SP is executed and + are deleted in the end of execution. All changes made to these + objects need not be registered in the list of changes of the parse + tree and do not harm PS/SP re-execution. */ class Item_equal: public Item_bool_func diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index eb7ab7131dd..97331d3c1a6 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -805,6 +805,7 @@ void mysql_stmt_free(THD *thd, char *packet); void mysql_stmt_reset(THD *thd, char *packet); void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length); void reset_stmt_for_execute(THD *thd, LEX *lex); +void init_stmt_after_parse(THD*, LEX*); /* sql_error.cc */ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 06669e398ec..ad527d39d21 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -819,6 +819,7 @@ sp_head::restore_lex(THD *thd) LEX *sublex= thd->lex; LEX *oldlex= (LEX *)m_lex.pop(); + init_stmt_after_parse(thd, sublex); if (! oldlex) return; // Nothing to restore diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 7da5c13e18a..d1594edc3f9 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1809,20 +1809,33 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, else { stmt->setup_set_params(); - SELECT_LEX *sl= stmt->lex->all_selects_list; - /* - Save WHERE clause pointers, because they may be changed during query - optimisation. - */ - for (; sl; sl= sl->next_select_in_list()) - sl->prep_where= sl->where; + init_stmt_after_parse(thd, stmt->lex); stmt->state= Item_arena::PREPARED; } DBUG_RETURN(!stmt); } -/* Reinit statement before execution */ +/* + Init PS/SP specific parse tree members. +*/ + +void init_stmt_after_parse(THD *thd, LEX *lex) +{ + SELECT_LEX *sl= lex->all_selects_list; + /* + Save WHERE clause pointers, because they may be changed during query + optimisation. + */ + for (; sl; sl= sl->next_select_in_list()) + sl->prep_where= sl->where; + + for (TABLE_LIST *table= lex->query_tables; table; table= table->next_global) + table->prep_on_expr= table->on_expr; +} + + +/* Reinit prepared statement/stored procedure before execution */ void reset_stmt_for_execute(THD *thd, LEX *lex) { @@ -1883,6 +1896,12 @@ void reset_stmt_for_execute(THD *thd, LEX *lex) tables->table= 0; if (tables->nested_join) tables->nested_join->counter= 0; + + if (tables->prep_on_expr) + { + tables->on_expr= tables->prep_on_expr->copy_andor_structure(thd); + tables->on_expr->cleanup(); + } } lex->current_select= &lex->select_lex; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e886c658444..76d8ec1740a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6192,9 +6192,9 @@ finish: For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)]) and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]). For b=2 it will be called with *cond_equal=(ptr(CE),[]) - and will transform *cond_equal into (ptr(CE,[Item_equal(2,a,b,c)]). + and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]). For f=e it will be called with *cond_equal=(ptr(CE), []) - and will transform *cond_equal into (ptr(CE,[Item_equal(f,e)]). + and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]). NOTES Now only fields that have the same type defintions (verified by @@ -6463,6 +6463,11 @@ static COND *build_equal_items_for_cond(COND *cond, */ while ((item= li++)) { + /* + PS/SP note: we can safely remove a node from AND-OR + structure here because it's restored before each + re-execution of any prepared statement/stored procedure. + */ if (check_equality(item, &cond_equal)) li.remove(); } @@ -6501,6 +6506,11 @@ static COND *build_equal_items_for_cond(COND *cond, if ((new_item = build_equal_items_for_cond(item, inherited))!= item) { /* This replacement happens only for standalone equalities */ + /* + This is ok with PS/SP as the replacement is done for + arguments of an AND/OR item, which are restored for each + execution of PS/SP. + */ li.replace(new_item); } } @@ -6636,10 +6646,12 @@ static COND *build_equal_items(THD *thd, COND *cond, Item *expr; List *join_list= table->nested_join ? &table->nested_join->join_list : NULL; - expr= build_equal_items(thd, table->on_expr, inherited, join_list, - &table->cond_equal); - if (expr != table->on_expr) - thd->change_item_tree(&table->on_expr, expr); + /* + We can modify table->on_expr because its old value will + be restored before re-execution of PS/SP. + */ + table->on_expr= build_equal_items(thd, table->on_expr, inherited, + join_list, &table->cond_equal); } } } @@ -6866,10 +6878,14 @@ static COND* substitute_for_best_equal_field(COND *cond, while ((item= li++)) { Item *new_item =substitute_for_best_equal_field(item, cond_equal, - table_join_idx); + table_join_idx); + /* + This works OK with PS/SP re-execution as changes are made to + the arguments of AND/OR items only + */ if (new_item != item) li.replace(new_item); - } + } if (and_level) { @@ -7198,7 +7214,7 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) */ expr= simplify_joins(join, &nested_join->join_list, table->on_expr, FALSE); - table->on_expr= expr; + table->prep_on_expr= table->on_expr= expr; } nested_join->used_tables= (table_map) 0; nested_join->not_null_tables=(table_map) 0; @@ -7238,7 +7254,7 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) } else conds= table->on_expr; - table->on_expr= 0; + table->prep_on_expr= table->on_expr= 0; } } @@ -7319,10 +7335,7 @@ optimize_cond(JOIN *join, COND *conds, List *join_list, DBUG_ENTER("optimize_cond"); if (!conds) - { *cond_value= Item::COND_TRUE; - select->prep_where= 0; - } else { /* diff --git a/sql/table.h b/sql/table.h index 5ab1f900195..4306d3733c4 100644 --- a/sql/table.h +++ b/sql/table.h @@ -339,6 +339,15 @@ typedef struct st_table_list char *db, *alias, *table_name, *schema_table_name; char *option; /* Used by cache index */ Item *on_expr; /* Used with outer join */ + /* + The scturcture of ON expression presented in the member above + can be changed during certain optimizations. This member + contains a snapshot of AND-OR structure of the ON expression + made after permanent transformations of the parse tree, and is + used to restore ON clause before every reexecution of a prepared + statement or stored procedure. + */ + Item *prep_on_expr; COND_EQUAL *cond_equal; /* Used with outer join */ struct st_table_list *natural_join; /* natural join on this table*/ /* ... join ... USE INDEX ... IGNORE INDEX */ From 5a9efeedf17f78b1917d9ed751764208063c0f09 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 16:01:39 +0100 Subject: [PATCH 20/26] Ensure that '*.disabled' files are truly optional, so that their non-existence will not cause "make" to fail. mysql-test/Makefile.am: Files of the '*.disabled' pattern may exist, but need not. So it is important to ignore command failures arising from this pattern not finding any matches - whereas files of the other types must be present. --- mysql-test/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index a749d2bd4d1..6bcd0715ccd 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -45,7 +45,8 @@ mysql_test_run_new_SOURCES= mysql_test_run_new.c my_manage.c my_create_tables.c dist-hook: mkdir -p $(distdir)/t $(distdir)/r $(distdir)/include \ $(distdir)/std_data - $(INSTALL_DATA) $(srcdir)/t/*.test $(srcdir)/t/*.disabled $(distdir)/t + $(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t + -$(INSTALL_DATA) $(srcdir)/t/*.disabled $(distdir)/t $(INSTALL_DATA) $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t $(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.result.es $(srcdir)/r/*.require $(distdir)/r @@ -63,7 +64,7 @@ install-data-local: $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir) $(INSTALL_DATA) $(srcdir)/t/*.test $(DESTDIR)$(testdir)/t - $(INSTALL_DATA) $(srcdir)/t/*.disabled $(DESTDIR)$(testdir)/t + -$(INSTALL_DATA) $(srcdir)/t/*.disabled $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.opt $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.sh $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.slave-mi $(DESTDIR)$(testdir)/t From 969be90f71894240a048e26c8ea7d0cbbb5d888b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 17:20:05 +0200 Subject: [PATCH 21/26] os0file.c: AIX 5.1 after security patch ML7 seems to contain a bug that instead of EEXIST it sets errno to 0 if a file creation fails because the file already exists. Work around that bug by interpreting errno 0 in AIX as EEXIST. innobase/os/os0file.c: AIX 5.1 after security patch ML7 seems to contain a bug that instead of EEXIST it sets errno to 0 if a file creation fails because the file already exists. Work around that bug by interpreting errno 0 in AIX as EEXIST. --- innobase/os/os0file.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index cadf1c0385f..334452e09ae 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -291,6 +291,15 @@ os_file_get_last_error(void) return(OS_FILE_NOT_FOUND); } else if (err == EEXIST) { return(OS_FILE_ALREADY_EXISTS); +#ifdef UNIV_AIX + } else if (err == 0) { + fprintf(stderr, +"InnoDB: errno is 0. Since AIX 5.1 after security patch ML7 erroneously\n" +"InnoDB: sets errno to 0 when it should be EEXIST, we assume that the real\n" +"InnoDB: error here was EEXIST.\n"); + + return(OS_FILE_ALREADY_EXISTS); +#endif } else { return(100 + err); } From afc8527360149323c2f2d34633ec67d10135b224 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 17:46:56 +0200 Subject: [PATCH 22/26] srv0start.c: Work around the AIX 5.1 ML7 patch problem in errno at a higher level, in srv0start.c os0file.c: Revert the AIX patch here innobase/os/os0file.c: Revert the AIX patch here innobase/srv/srv0start.c: Work around the AIX 5.1 ML7 patch problem in errno at a higher level, in srv0start.c --- innobase/os/os0file.c | 9 --------- innobase/srv/srv0start.c | 19 +++++++++++++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 334452e09ae..cadf1c0385f 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -291,15 +291,6 @@ os_file_get_last_error(void) return(OS_FILE_NOT_FOUND); } else if (err == EEXIST) { return(OS_FILE_ALREADY_EXISTS); -#ifdef UNIV_AIX - } else if (err == 0) { - fprintf(stderr, -"InnoDB: errno is 0. Since AIX 5.1 after security patch ML7 erroneously\n" -"InnoDB: sets errno to 0 when it should be EEXIST, we assume that the real\n" -"InnoDB: error here was EEXIST.\n"); - - return(OS_FILE_ALREADY_EXISTS); -#endif } else { return(100 + err); } diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 9baa86234a0..53ef97dc42b 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -540,7 +540,14 @@ open_or_create_log_file( files[i] = os_file_create(name, OS_FILE_CREATE, OS_FILE_NORMAL, OS_LOG_FILE, &ret); if (ret == FALSE) { - if (os_file_get_last_error() != OS_FILE_ALREADY_EXISTS) { + if (os_file_get_last_error() != OS_FILE_ALREADY_EXISTS +#ifdef UNIV_AIX + /* AIX 5.1 after security patch ML7 may have errno set + to 0 here, which causes our function to return 100; + work around that AIX problem */ + && os_file_get_last_error() != 100 +#endif + ) { fprintf(stderr, "InnoDB: Error in creating or opening %s\n", name); @@ -712,7 +719,15 @@ open_or_create_data_files( if (ret == FALSE) { if (srv_data_file_is_raw_partition[i] != SRV_OLD_RAW && os_file_get_last_error() != - OS_FILE_ALREADY_EXISTS) { + OS_FILE_ALREADY_EXISTS +#ifdef UNIV_AIX + /* AIX 5.1 after security patch ML7 may have + errno set to 0 here, which causes our function + to return 100; work around that AIX problem */ + && os_file_get_last_error() != 100 +#endif + ) { + fprintf(stderr, "InnoDB: Error in creating or opening %s\n", name); From 560968258f615959419102de6d86707545c69655 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 18:00:34 +0200 Subject: [PATCH 23/26] srv0start.c: Work around the AIX 5.1 security patch ML7 problem in errno when it should be EEXIST innobase/srv/srv0start.c: Work around the AIX 5.1 security patch ML7 problem in errno when it should be EEXIST --- innobase/srv/srv0start.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index fe05f07df21..44cf645f170 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -568,7 +568,14 @@ open_or_create_log_file( files[i] = os_file_create(name, OS_FILE_CREATE, OS_FILE_NORMAL, OS_LOG_FILE, &ret); if (ret == FALSE) { - if (os_file_get_last_error(FALSE) != OS_FILE_ALREADY_EXISTS) { + if (os_file_get_last_error(FALSE) != OS_FILE_ALREADY_EXISTS +#ifdef UNIV_AIX + /* AIX 5.1 after security patch ML7 may have errno set + to 0 here, which causes our function to return 100; + work around that AIX problem */ + && os_file_get_last_error(FALSE) != 100 +#endif + ) { fprintf(stderr, "InnoDB: Error in creating or opening %s\n", name); @@ -728,7 +735,14 @@ open_or_create_data_files( OS_FILE_NORMAL, OS_DATA_FILE, &ret); if (ret == FALSE && os_file_get_last_error(FALSE) != - OS_FILE_ALREADY_EXISTS) { + OS_FILE_ALREADY_EXISTS +#ifdef UNIV_AIX + /* AIX 5.1 after security patch ML7 may have + errno set to 0 here, which causes our function + to return 100; work around that AIX problem */ + && os_file_get_last_error(FALSE) != 100 +#endif + ) { fprintf(stderr, "InnoDB: Error in creating or opening %s\n", name); From c7fdbffa0d3d28baaf18caef9c5d7de0fd7d1570 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 19:20:16 +0300 Subject: [PATCH 24/26] Fix for bug #8164: subquery with INFORMATION_SCHEMA.COLUMNS, 100 % CPU --- mysql-test/r/information_schema.result | 7 +++++++ mysql-test/t/information_schema.test | 9 +++++++++ sql/sql_show.cc | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 121de940560..8e49a3df4c8 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -631,3 +631,10 @@ TABLES UPDATE_TIME datetime TABLES CHECK_TIME datetime ROUTINES CREATED datetime ROUTINES LAST_ALTERED datetime +SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES A +WHERE NOT EXISTS +(SELECT * FROM INFORMATION_SCHEMA.COLUMNS B +WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA +AND A.TABLE_NAME = B.TABLE_NAME); +COUNT(*) +0 diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 86d7bad76bc..9ff0b1fdf61 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -400,3 +400,12 @@ information_schema.columns where data_type = 'longtext'; select table_name, column_name, data_type from information_schema.columns where data_type = 'datetime'; + +# +# Bug #8164 subquery with INFORMATION_SCHEMA.COLUMNS, 100 % CPU +# +SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES A +WHERE NOT EXISTS +(SELECT * FROM INFORMATION_SCHEMA.COLUMNS B + WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA + AND A.TABLE_NAME = B.TABLE_NAME); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1339b5e5ed0..7a4ee9f5de3 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1649,6 +1649,10 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table) strlen(item_field->field_name), 0))) return 0; } + if (item->type() == Item::SUBSELECT_ITEM && + !item->const_item()) + return 0; + return 1; } From 92895d00527f62a57ed569f85df01dbf4f0db9c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 12:36:27 -0800 Subject: [PATCH 25/26] Fix symlink test to avoid filenames with paths mysql-test/r/symlink.result: Update test results mysql-test/t/symlink.test: Fix test to avoid filenames including path in results --- mysql-test/r/symlink.result | 2 -- mysql-test/t/symlink.test | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 50210d82c69..26612ec81fd 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -84,14 +84,12 @@ t1 CREATE TABLE `t1` ( `b` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; -create table t1 (i int) data directory = "/home/jimw/my/mysql-4.1-8707/mysql-test/var/master-data/test/"; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; -create table t1 (i int) index directory = "/home/jimw/my/mysql-4.1-8707/mysql-test/var/master-data/test/"; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index b53be62861e..ddde5171200 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -120,9 +120,13 @@ drop table t1; # Test specifying DATA DIRECTORY that is the same as what would normally # have been chosen. (Bug #8707) # +disable_query_log; eval create table t1 (i int) data directory = "$MYSQL_TEST_DIR/var/master-data/test/"; +enable_query_log; show create table t1; drop table t1; +disable_query_log; eval create table t1 (i int) index directory = "$MYSQL_TEST_DIR/var/master-data/test/"; +enable_query_log; show create table t1; drop table t1; From aec0408ba9634bc15be77b8507ca8b83ff609e24 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Mar 2005 17:44:28 -0800 Subject: [PATCH 26/26] Clean up merge of fix for Bug #3309. mysql-test/r/grant2.result: Update results mysql-test/t/grant2.test: Reset sql_mode before test. sql/sql_acl.cc: Fixes to merge --- mysql-test/r/grant2.result | 1 + mysql-test/t/grant2.test | 1 + sql/sql_acl.cc | 30 +++++++++++++++++------------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index e426f0cfc08..821f67536f3 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -233,6 +233,7 @@ drop user mysqltest_B@'%'; ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql' drop user mysqltest_B@'%'; drop user mysqltest_3@localhost; +set @@sql_mode=''; create database mysqltest_1; create table mysqltest_1.t1 (i int); insert into mysqltest_1.t1 values (1),(2),(3); diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 7e2ac5b4008..3b1200f8a6e 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -247,6 +247,7 @@ drop user mysqltest_B@'%'; drop user mysqltest_3@localhost; # # Bug #3309: Test IP addresses with netmask +set @@sql_mode=''; create database mysqltest_1; create table mysqltest_1.t1 (i int); insert into mysqltest_1.t1 values (1),(2),(3); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a1d64430a01..87c83771ec8 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2122,12 +2122,12 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, { if (exact) { - if (compare_hostname(&grant_table->host, host, ip)) + if (compare_hostname(&grant_name->host, host, ip)) return grant_name; } else { - if (compare_hostname(&grant_table->host, host, ip) && + if (compare_hostname(&grant_name->host, host, ip) && (!found || found->sort < grant_name->sort)) found=grant_name; // Host ok } @@ -3178,7 +3178,7 @@ my_bool grant_init(THD *org_thd) if (check_no_resolve) { - if (hostname_requires_resolving(mem_check->host)) + if (hostname_requires_resolving(mem_check->host.hostname)) { sql_print_warning("'tables_priv' entry '%s %s@%s' " "ignored in --skip-name-resolve mode.", @@ -4057,7 +4057,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(system_charset_info, lex_user->host.str, - grant_proc->orig_host)) + grant_proc->host.hostname)) { ulong proc_access= grant_proc->privs; if (proc_access != 0) @@ -4543,19 +4543,22 @@ static int handle_grant_struct(uint struct_no, bool drop, case 1: acl_db= dynamic_element(&acl_dbs, idx, ACL_DB*); user= acl_db->user; - host= acl_db->host.hostname; + if (!(host= acl_db->host.hostname)) + host= "%"; break; case 2: grant_name= (GRANT_NAME*) hash_element(&column_priv_hash, idx); user= grant_name->user; - host= grant_name->host; + if (!(host= grant_name->host.hostname)) + host= "%"; break; case 3: grant_name= (GRANT_NAME*) hash_element(&proc_priv_hash, idx); user= grant_name->user; - host= grant_name->host; + if (!(host= grant_name->host.hostname)) + host= "%"; break; } if (! user) @@ -4610,7 +4613,8 @@ static int handle_grant_struct(uint struct_no, bool drop, case 2: case 3: grant_name->user= strdup_root(&mem, user_to->user.str); - grant_name->host= strdup_root(&mem, user_to->host.str); + update_hostname(&grant_name->host, + strdup_root(&mem, user_to->host.str)); break; } } @@ -5067,7 +5071,7 @@ bool mysql_revoke_all(THD *thd, List &list) counter); if (!(user=grant_proc->user)) user= ""; - if (!(host=grant_proc->host)) + if (!(host=grant_proc->host.hostname)) host= ""; if (!strcmp(lex_user->user.str,user) && @@ -5139,8 +5143,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name) LEX_USER lex_user; lex_user.user.str= grant_proc->user; lex_user.user.length= strlen(grant_proc->user); - lex_user.host.str= grant_proc->host; - lex_user.host.length= strlen(grant_proc->host); + lex_user.host.str= grant_proc->host.hostname; + lex_user.host.length= strlen(grant_proc->host.hostname); if (!replace_proc_table(thd,grant_proc,tables[4].table,lex_user, grant_proc->db, grant_proc->tname, ~0, 1)) { @@ -5424,7 +5428,7 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) if (!(table_access & GRANT_ACL)) is_grantable= "NO"; - strxmov(buff,"'",user,"'@'",grant_table->orig_host,"'",NullS); + strxmov(buff,"'",user,"'@'",grant_table->host.hostname,"'",NullS); if (!test_access) update_schema_privilege(table, buff, grant_table->db, grant_table->tname, 0, 0, "USAGE", 5, is_grantable); @@ -5471,7 +5475,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) is_grantable= "NO"; ulong test_access= table_access & ~GRANT_ACL; - strxmov(buff,"'",user,"'@'",grant_table->orig_host,"'",NullS); + strxmov(buff,"'",user,"'@'",grant_table->host.hostname,"'",NullS); if (!test_access) continue; else