Commit 9b027c04 authored by unknown's avatar unknown

Merge mysql.com:/home/jonas/src/mysql-4.1

into mysql.com:/home/jonas/src/mysql-4.1-ndb


sql/ha_ndbcluster.cc:
  Auto merged
parents 27a19225 92dce374
......@@ -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: <bk.mysql-$VERSION>
From: $FROM
To: $TO
Subject: bk commit - $VERSION tree ($CHANGESET)$BUG
Subject: bk commit - $VERSION tree ($CHANGESET)${BUG}${WL}
EOF
bk changes -v -r+
......
......@@ -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;
......@@ -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;
......@@ -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;
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;
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;
......@@ -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;
......@@ -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;
###############################################
# #
# 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;
###############################################
# #
# 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;
......@@ -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();
......
......@@ -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();
......
......@@ -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),
......
......@@ -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");
......
......@@ -1244,6 +1244,7 @@ operator<<(NdbOut& out, const LogLevel & ll)
for(size_t i = 0; i<LogLevel::LOGLEVEL_CATEGORIES; i++)
out << ll.getLogLevel((LogLevel::EventCategory)i) << " ";
out << "]";
return out;
}
void
......
......@@ -779,7 +779,9 @@ main(void){
template class Vector<NdbScanFilterImpl::State>;
#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
......@@ -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;
......
......@@ -144,6 +144,7 @@ class Item {
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);
......
......@@ -544,6 +544,23 @@ class Statement: public Item_arena
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 @@ class THD :public ilink,
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;
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment