diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index a1b6b819e63..3f347e4c596 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -21,6 +21,7 @@ then CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet` BUG=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Bb][Uu][Gg] *# *\([0-9][0-9]*\).*$/ BUG#\1/p'` +WL=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Ww][Ll] *# *\([0-9][0-9]*\).*$/ WL#\1/p'` if [ "$BUG" = "" ] then @@ -37,7 +38,7 @@ fi List-ID: From: $FROM To: $TO -Subject: bk commit - $VERSION tree ($CHANGESET)$BUG +Subject: bk commit - $VERSION tree ($CHANGESET)${BUG}${WL} EOF bk changes -v -r+ diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc index 7567a0ca362..84e60657876 100644 --- a/mysql-test/include/have_ndb.inc +++ b/mysql-test/include/have_ndb.inc @@ -2,6 +2,6 @@ disable_query_log; show variables like "have_ndbcluster"; enable_query_log; -connect (server1,127.0.0.1,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); -connect (server2,127.0.0.1,root,,test,$MASTER_MYPORT1,$MASTER_MYSOCK1); -connection server1; +#connect (server1,127.0.0.1,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); +#connect (server2,127.0.0.1,root,,test,$MASTER_MYPORT1,$MASTER_MYSOCK1); +#connection server1; diff --git a/mysql-test/r/ndb_lock.result b/mysql-test/r/ndb_lock.result index 56661913e22..b8c2c58aac4 100644 --- a/mysql-test/r/ndb_lock.result +++ b/mysql-test/r/ndb_lock.result @@ -28,3 +28,38 @@ x y 2 two 3 three commit; +drop table t1; +create table t1 (pk integer not null primary key, u int not null, o int not null, +unique(u), key(o)) engine = ndb; +insert into t1 values (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5); +lock tables t1 write; +delete from t1 where pk = 1; +unlock tables; +select * from t1 order by pk; +pk u o +2 2 2 +3 3 3 +4 4 4 +5 5 5 +insert into t1 values (1,1,1); +lock tables t1 write; +delete from t1 where u = 1; +unlock tables; +select * from t1 order by pk; +pk u o +2 2 2 +3 3 3 +4 4 4 +5 5 5 +insert into t1 values (1,1,1); +lock tables t1 write; +delete from t1 where o = 1; +unlock tables; +select * from t1 order by pk; +pk u o +2 2 2 +3 3 3 +4 4 4 +5 5 5 +insert into t1 values (1,1,1); +drop table t1; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index c10cb7bb25a..df5fa5fe999 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -318,3 +318,21 @@ execute stmt; a drop table t1; deallocate prepare stmt; +create table t1 (a int, b int); +insert into t1 (a, b) values (1,1), (1,2), (2,1), (2,2); +prepare stmt from +"explain select * from t1 where t1.a=2 and t1.a=t1.b and t1.b > 1 + ?"; +set @v=5; +execute stmt using @v; +id select_type table type possible_keys key key_len ref rows Extra +- - - - - - - - NULL Impossible WHERE +set @v=0; +execute stmt using @v; +id select_type table type possible_keys key key_len ref rows Extra +- - - - - - - - 4 Using where +set @v=5; +execute stmt using @v; +id select_type table type possible_keys key key_len ref rows Extra +- - - - - - - - NULL Impossible WHERE +drop table t1; +deallocate prepare stmt; diff --git a/mysql-test/r/ps_10nestset.result b/mysql-test/r/ps_10nestset.result new file mode 100644 index 00000000000..10f0a741b54 --- /dev/null +++ b/mysql-test/r/ps_10nestset.result @@ -0,0 +1,68 @@ +use test; +drop table if exists personnel; +Warnings: +Note 1051 Unknown table 'personnel' +create table personnel ( +id INTEGER AUTO_INCREMENT PRIMARY KEY, +emp CHAR(10) NOT NULL, +salary DECIMAL(6,2) NOT NULL, +l INTEGER NOT NULL, +r INTEGER NOT NULL); +prepare st_ins from 'insert into personnel set emp = ?, salary = ?, l = ?, r = ?'; +set @arg_nam= 'Jerry'; +set @arg_sal= 1000; +set @arg_l= 1; +set @arg_r= 12; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Bert'; +set @arg_sal= 900; +set @arg_l= 2; +set @arg_r= 3; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Chuck'; +set @arg_sal= 900; +set @arg_l= 4; +set @arg_r= 11; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Donna'; +set @arg_sal= 800; +set @arg_l= 5; +set @arg_r= 6; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Eddie'; +set @arg_sal= 700; +set @arg_l= 7; +set @arg_r= 8; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Fred'; +set @arg_sal= 600; +set @arg_l= 9; +set @arg_r= 10; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +select * from personnel; +id emp salary l r +1 Jerry 1000.00 1 12 +2 Bert 900.00 2 3 +3 Chuck 900.00 4 11 +4 Donna 800.00 5 6 +5 Eddie 700.00 7 8 +6 Fred 600.00 9 10 +prepare st_raise_base from 'update personnel set salary = salary * ( 1 + ? ) where r - l = 1'; +prepare st_raise_mgr from 'update personnel set salary = salary + ? where r - l > 1'; +set @arg_percent= .10; +set @arg_amount= 100; +execute st_raise_base using @arg_percent; +execute st_raise_mgr using @arg_amount; +execute st_raise_base using @arg_percent; +execute st_raise_mgr using @arg_amount; +execute st_raise_base using @arg_percent; +execute st_raise_mgr using @arg_amount; +select * from personnel; +id emp salary l r +1 Jerry 1300.00 1 12 +2 Bert 1197.90 2 3 +3 Chuck 1200.00 4 11 +4 Donna 1064.80 5 6 +5 Eddie 931.70 7 8 +6 Fred 798.60 9 10 +drop table personnel; diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result new file mode 100644 index 00000000000..2aa0df6a431 --- /dev/null +++ b/mysql-test/r/ps_11bugs.result @@ -0,0 +1,21 @@ +use test; +drop table if exists test_select; +Warnings: +Note 1051 Unknown table 'test_select' +CREATE TABLE test_select(session_id char(9) NOT NULL); +INSERT INTO test_select VALUES ("abc"); +SELECT * FROM test_select; +session_id +abc +prepare st_1180 from 'SELECT * FROM test_select WHERE ?="1111" and session_id = "abc"'; +set @arg1= 'abc'; +execute st_1180 using @arg1; +session_id +set @arg1= '1111'; +execute st_1180 using @arg1; +session_id +abc +set @arg1= 'abc'; +execute st_1180 using @arg1; +session_id +drop table test_select; diff --git a/mysql-test/t/ndb_lock.test b/mysql-test/t/ndb_lock.test index c0389dced44..39a8655b972 100644 --- a/mysql-test/t/ndb_lock.test +++ b/mysql-test/t/ndb_lock.test @@ -39,3 +39,32 @@ commit; connection con2; select * from t1 order by x; commit; + +drop table t1; + +### +# Bug#6020 +create table t1 (pk integer not null primary key, u int not null, o int not null, + unique(u), key(o)) engine = ndb; +insert into t1 values (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5); + +lock tables t1 write; +delete from t1 where pk = 1; +unlock tables; +select * from t1 order by pk; +insert into t1 values (1,1,1); + +lock tables t1 write; +delete from t1 where u = 1; +unlock tables; +select * from t1 order by pk; +insert into t1 values (1,1,1); + +lock tables t1 write; +delete from t1 where o = 1; +unlock tables; +select * from t1 order by pk; +insert into t1 values (1,1,1); + +drop table t1; + diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 42f6d4d0f64..76c7fb7c2e7 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -342,4 +342,25 @@ execute stmt; drop table t1; deallocate prepare stmt; +# +# Test case for Bug#6042 "constants propogation works only once (prepared +# statements): check that the query plan changes whenever we change +# placeholder value. +# +create table t1 (a int, b int); +insert into t1 (a, b) values (1,1), (1,2), (2,1), (2,2); +prepare stmt from +"explain select * from t1 where t1.a=2 and t1.a=t1.b and t1.b > 1 + ?"; +--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - +set @v=5; +execute stmt using @v; +--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - +set @v=0; +execute stmt using @v; +--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - +set @v=5; +execute stmt using @v; +drop table t1; +deallocate prepare stmt; + diff --git a/mysql-test/t/ps_10nestset.test b/mysql-test/t/ps_10nestset.test new file mode 100644 index 00000000000..2c6009af9de --- /dev/null +++ b/mysql-test/t/ps_10nestset.test @@ -0,0 +1,63 @@ +############################################### +# # +# Prepared Statements test on # +# "nested sets" representing hierarchies # +# # +############################################### + +# Source: http://kris.koehntopp.de/artikel/sql-self-references (dated 1999) +# Source: http://dbmsmag.com/9603d06.html (dated 1996) + +use test; + +drop table if exists personnel; + +# "Nested Set": This table represents an employee list with a hierarchy tree. +# The tree is not modeled by "parent" links but rather by showing the "left" +# and "right" border of any person's "region". By convention, "l" < "r". +# As it is a tree, these "regions" of two persons A and B are either disjoint, +# or A's region is completely contained in B's (B is A's boss), or vice versa. +# See the references for more info. + +create table personnel ( + id INTEGER AUTO_INCREMENT PRIMARY KEY, + emp CHAR(10) NOT NULL, + salary DECIMAL(6,2) NOT NULL, + l INTEGER NOT NULL, + r INTEGER NOT NULL); + +prepare st_ins from 'insert into personnel set emp = ?, salary = ?, l = ?, r = ?'; + +# Initial employee list: +# Jerry ( Bert ( ) Chuck ( Donna ( ) Eddie ( ) Fred ( ) ) ) +set @arg_nam= 'Jerry'; set @arg_sal= 1000; set @arg_l= 1; set @arg_r= 12; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Bert'; set @arg_sal= 900; set @arg_l= 2; set @arg_r= 3; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Chuck'; set @arg_sal= 900; set @arg_l= 4; set @arg_r= 11; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Donna'; set @arg_sal= 800; set @arg_l= 5; set @arg_r= 6; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Eddie'; set @arg_sal= 700; set @arg_l= 7; set @arg_r= 8; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; +set @arg_nam= 'Fred'; set @arg_sal= 600; set @arg_l= 9; set @arg_r= 10; +execute st_ins using @arg_nam, @arg_sal, @arg_l, @arg_r ; + +select * from personnel; + +# Three successive raises, each one is 100 units for managers, 10 percent for others. +prepare st_raise_base from 'update personnel set salary = salary * ( 1 + ? ) where r - l = 1'; +prepare st_raise_mgr from 'update personnel set salary = salary + ? where r - l > 1'; +let $1= 3; +set @arg_percent= .10; +set @arg_amount= 100; +while ($1) +{ + execute st_raise_base using @arg_percent; + execute st_raise_mgr using @arg_amount; + dec $1; +} + +select * from personnel; + +drop table personnel; diff --git a/mysql-test/t/ps_11bugs.test b/mysql-test/t/ps_11bugs.test new file mode 100644 index 00000000000..53afc8b5a78 --- /dev/null +++ b/mysql-test/t/ps_11bugs.test @@ -0,0 +1,32 @@ +############################################### +# # +# Prepared Statements # +# re-testing bug DB entries # +# # +############################################### + +use test; + +# bug#1180: optimized away part of WHERE clause cause incorect prepared satatement results + +drop table if exists test_select; + +CREATE TABLE test_select(session_id char(9) NOT NULL); +INSERT INTO test_select VALUES ("abc"); +SELECT * FROM test_select; + +prepare st_1180 from 'SELECT * FROM test_select WHERE ?="1111" and session_id = "abc"'; + +# Must not find a row +set @arg1= 'abc'; +execute st_1180 using @arg1; + +# Now, it should find one row +set @arg1= '1111'; +execute st_1180 using @arg1; + +# Back to non-matching +set @arg1= 'abc'; +execute st_1180 using @arg1; + +drop table test_select; diff --git a/ndb/include/kernel/LogLevel.hpp b/ndb/include/kernel/LogLevel.hpp index 52c2f70cda8..be0627c98a8 100644 --- a/ndb/include/kernel/LogLevel.hpp +++ b/ndb/include/kernel/LogLevel.hpp @@ -64,7 +64,7 @@ public: /** * No of categories */ -#define _LOGLEVEL_CATEGORIES (CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1); +#define _LOGLEVEL_CATEGORIES (CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1) static const Uint32 LOGLEVEL_CATEGORIES = _LOGLEVEL_CATEGORIES; void clear(); diff --git a/ndb/include/util/version.h b/ndb/include/util/version.h index a82ae4b8b52..5459e44b818 100644 --- a/ndb/include/util/version.h +++ b/ndb/include/util/version.h @@ -30,7 +30,7 @@ extern "C" { Uint32 makeVersion(Uint32 major, Uint32 minor, Uint32 build); - char* getVersionString(Uint32 version, char * status); + const char* getVersionString(Uint32 version, const char * status); void ndbPrintVersion(); Uint32 ndbGetOwnVersion(); diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c index b8408c7f201..e2515b243b1 100644 --- a/ndb/src/common/util/version.c +++ b/ndb/src/common/util/version.c @@ -35,7 +35,7 @@ Uint32 makeVersion(Uint32 major, Uint32 minor, Uint32 build) { } -char * getVersionString(Uint32 version, char * status) { +const char * getVersionString(Uint32 version, const char * status) { char buff[100]; if (status && status[0] != 0) snprintf(buff, sizeof(buff), diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 9629c5e8904..bff7f9be0e6 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -2373,7 +2373,7 @@ ConfigInfo::getAlias(const char * section) const { bool ConfigInfo::verify(const Properties * section, const char* fname, Uint64 value) const { - Uint64 min, max; min = max + 1; + Uint64 min, max; min = getInfoInt(section, fname, "Min"); max = getInfoInt(section, fname, "Max"); diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 684c10dbd4d..5242237a638 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -1244,6 +1244,7 @@ operator<<(NdbOut& out, const LogLevel & ll) for(size_t i = 0; i; #if __SUNPRO_CC != 0x560 +#ifndef _FORTEC_ template int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, Uint32); template int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, Uint64); #endif +#endif diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 0e535a689dd..2234c128346 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -829,7 +829,7 @@ void ha_ndbcluster::release_metadata() int ha_ndbcluster::get_ndb_lock_type(enum thr_lock_type type) { - if (type == TL_WRITE_ALLOW_WRITE) + if (type >= TL_WRITE_ALLOW_WRITE) return NdbOperation::LM_Exclusive; else if (uses_blob_value(retrieve_all_fields)) return NdbOperation::LM_Read; @@ -1163,7 +1163,7 @@ inline int ha_ndbcluster::next_result(byte *buf) If this an update or delete, call nextResult with false to process any records already cached in NdbApi */ - bool contact_ndb= m_lock.type != TL_WRITE_ALLOW_WRITE; + bool contact_ndb= m_lock.type < TL_WRITE_ALLOW_WRITE; do { DBUG_PRINT("info", ("Call nextResult, contact_ndb: %d", contact_ndb)); /* @@ -2749,6 +2749,9 @@ THR_LOCK_DATA **ha_ndbcluster::store_lock(THD *thd, /* If we are not doing a LOCK TABLE, then allow multiple writers */ + /* Since NDB does not currently have table locks + this is treated as a ordinary lock */ + if ((lock_type >= TL_WRITE_ALLOW_WRITE && lock_type <= TL_WRITE) && !thd->in_lock_tables) lock_type= TL_WRITE_ALLOW_WRITE; diff --git a/sql/item.h b/sql/item.h index c17aabf797c..68fa013647c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -144,6 +144,7 @@ public: DBUG_ENTER("Item::cleanup"); DBUG_PRINT("info", ("Type: %d", (int)type())); fixed=0; + marker= 0; DBUG_VOID_RETURN; } virtual void make_field(Send_field *field); diff --git a/sql/sql_class.h b/sql/sql_class.h index aaa81fbe165..50b0c566c89 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -544,6 +544,23 @@ public: Points to the query associated with this statement. It's const, but we need to declare it char * because all table handlers are written in C and need to point to it. + + Note that (A) if we set query = NULL, we must at the same time set + query_length = 0, and protect the whole operation with the + LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a + non-NULL value if its previous value is NULL. We do not need to protect + operation (B) with any mutex. To avoid crashes in races, if we do not + know that thd->query cannot change at the moment, one should print + thd->query like this: + (1) reserve the LOCK_thread_count mutex; + (2) check if thd->query is NULL; + (3) if not NULL, then print at most thd->query_length characters from + it. We will see the query_length field as either 0, or the right value + for it. + Assuming that the write and read of an n-bit memory field in an n-bit + computer is atomic, we can avoid races in the above way. + This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB + STATUS. */ char *query; uint32 query_length; // current query length @@ -684,24 +701,6 @@ public: struct rand_struct rand; // used for authentication struct system_variables variables; // Changeable local variables pthread_mutex_t LOCK_delete; // Locked before thd is deleted - /* - Note that (A) if we set query = NULL, we must at the same time set - query_length = 0, and protect the whole operation with the - LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a - non-NULL value if its previous value is NULL. We do not need to protect - operation (B) with any mutex. To avoid crashes in races, if we do not - know that thd->query cannot change at the moment, one should print - thd->query like this: - (1) reserve the LOCK_thread_count mutex; - (2) check if thd->query is NULL; - (3) if not NULL, then print at most thd->query_length characters from - it. We will see the query_length field as either 0, or the right value - for it. - Assuming that the write and read of an n-bit memory field in an n-bit - computer is atomic, we can avoid races in the above way. - This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB - STATUS. - */ /* all prepared statements and cursors of this connection */ Statement_map stmt_map; /*