Commit 57e4a7f5 authored by unknown's avatar unknown

Merge perch.ndb.mysql.com:/home/jonas/src/mysql-5.0

into  perch.ndb.mysql.com:/home/jonas/src/50-jonas

parents 12e4d6a2 32d7b5c8
......@@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
AM_INIT_AUTOMAKE(mysql, 5.0.21)
AM_INIT_AUTOMAKE(mysql, 5.0.22)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
......@@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
NDB_VERSION_BUILD=21
NDB_VERSION_BUILD=22
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
......
......@@ -617,7 +617,7 @@ dict_load_indexes(
break;
}
if (rec_get_deleted_flag(rec, table->comp)) {
if (rec_get_deleted_flag(rec, 0)) {
dict_load_report_deleted_index(table->name,
ULINT_UNDEFINED);
......
drop table if exists t1;
drop table if exists t1, t2;
select 1 in (1,2,3);
1 in (1,2,3)
1
......@@ -225,3 +225,104 @@ a
46
DROP VIEW v1;
DROP TABLE t1;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, filler char(200), key(a));
insert into t2 select C.a*2, 'no' from t1 A, t1 B, t1 C;
insert into t2 select C.a*2+1, 'yes' from t1 C;
explain
select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 5 NULL 12 Using where
select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
a filler
1 yes
3 yes
5 yes
7 yes
9 yes
11 yes
13 yes
15 yes
17 yes
19 yes
explain select * from t2 force index(a) where a NOT IN (2,2,2,2,2,2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 5 NULL 912 Using where
explain select * from t2 force index(a) where a <> 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 5 NULL 912 Using where
drop table t2;
create table t2 (a datetime, filler char(200), key(a));
insert into t2 select '2006-04-25 10:00:00' + interval C.a minute,
'no' from t1 A, t1 B, t1 C where C.a % 2 = 0;
insert into t2 select '2006-04-25 10:00:00' + interval C.a*2+1 minute,
'yes' from t1 C;
explain
select * from t2 where a NOT IN (
'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00',
'2006-04-25 10:06:00', '2006-04-25 10:08:00');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 9 NULL 18 Using where
select * from t2 where a NOT IN (
'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00',
'2006-04-25 10:06:00', '2006-04-25 10:08:00');
a filler
2006-04-25 10:01:00 yes
2006-04-25 10:03:00 yes
2006-04-25 10:05:00 yes
2006-04-25 10:07:00 yes
2006-04-25 10:09:00 yes
2006-04-25 10:11:00 yes
2006-04-25 10:13:00 yes
2006-04-25 10:15:00 yes
2006-04-25 10:17:00 yes
2006-04-25 10:19:00 yes
drop table t2;
create table t2 (a varchar(10), filler char(200), key(a));
insert into t2 select 'foo', 'no' from t1 A, t1 B;
insert into t2 select 'barbar', 'no' from t1 A, t1 B;
insert into t2 select 'bazbazbaz', 'no' from t1 A, t1 B;
insert into t2 values ('fon', '1'), ('fop','1'), ('barbaq','1'),
('barbas','1'), ('bazbazbay', '1'),('zz','1');
explain select * from t2 where a not in('foo','barbar', 'bazbazbaz');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 13 NULL 7 Using where
drop table t2;
create table t2 (a decimal(10,5), filler char(200), key(a));
insert into t2 select 345.67890, 'no' from t1 A, t1 B;
insert into t2 select 43245.34, 'no' from t1 A, t1 B;
insert into t2 select 64224.56344, 'no' from t1 A, t1 B;
insert into t2 values (0, '1'), (22334.123,'1'), (33333,'1'),
(55555,'1'), (77777, '1');
explain
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 7 NULL 7 Using where
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
a filler
0.00000 1
22334.12300 1
33333.00000 1
55555.00000 1
77777.00000 1
drop table t2;
create table t2 (a int, key(a), b int);
insert into t2 values (1,1),(2,2);
set @cnt= 1;
set @str="update t2 set b=1 where a not in (";
select count(*) from (
select @str:=concat(@str, @cnt:=@cnt+1, ",")
from t1 A, t1 B, t1 C, t1 D) Z;
count(*)
10000
set @str:=concat(@str, "10000)");
select substr(@str, 1, 50);
substr(@str, 1, 50)
update t2 set b=1 where a not in (2,3,4,5,6,7,8,9,
prepare s from @str;
execute s;
deallocate prepare s;
set @str=NULL;
drop table t2;
drop table t1;
drop table if exists t1;
......@@ -2606,7 +2606,7 @@ create view v2 as select * from v1;
drop table t1;
rename table v2 to t1;
select * from v1;
ERROR HY000: `test`.`v1` contain view recursion
ERROR HY000: `test`.`v1` contains view recursion
drop view t1, v1;
create table t1 (a int);
create function f1() returns int
......
# Initialise
--disable_warnings
drop table if exists t1;
drop table if exists t1, t2;
--enable_warnings
#
# test of IN (NULL)
......@@ -128,3 +128,95 @@ SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
# BUG#15872: Excessive memory consumption of range analysis of NOT IN
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (a int, filler char(200), key(a));
insert into t2 select C.a*2, 'no' from t1 A, t1 B, t1 C;
insert into t2 select C.a*2+1, 'yes' from t1 C;
explain
select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
explain select * from t2 force index(a) where a NOT IN (2,2,2,2,2,2);
explain select * from t2 force index(a) where a <> 2;
drop table t2;
#
# Repeat the test for DATETIME
#
create table t2 (a datetime, filler char(200), key(a));
insert into t2 select '2006-04-25 10:00:00' + interval C.a minute,
'no' from t1 A, t1 B, t1 C where C.a % 2 = 0;
insert into t2 select '2006-04-25 10:00:00' + interval C.a*2+1 minute,
'yes' from t1 C;
explain
select * from t2 where a NOT IN (
'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00',
'2006-04-25 10:06:00', '2006-04-25 10:08:00');
select * from t2 where a NOT IN (
'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00',
'2006-04-25 10:06:00', '2006-04-25 10:08:00');
drop table t2;
#
# Repeat the test for CHAR(N)
#
create table t2 (a varchar(10), filler char(200), key(a));
insert into t2 select 'foo', 'no' from t1 A, t1 B;
insert into t2 select 'barbar', 'no' from t1 A, t1 B;
insert into t2 select 'bazbazbaz', 'no' from t1 A, t1 B;
insert into t2 values ('fon', '1'), ('fop','1'), ('barbaq','1'),
('barbas','1'), ('bazbazbay', '1'),('zz','1');
explain select * from t2 where a not in('foo','barbar', 'bazbazbaz');
drop table t2;
#
# Repeat for DECIMAL
#
create table t2 (a decimal(10,5), filler char(200), key(a));
insert into t2 select 345.67890, 'no' from t1 A, t1 B;
insert into t2 select 43245.34, 'no' from t1 A, t1 B;
insert into t2 select 64224.56344, 'no' from t1 A, t1 B;
insert into t2 values (0, '1'), (22334.123,'1'), (33333,'1'),
(55555,'1'), (77777, '1');
explain
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
drop table t2;
# Try a very big IN-list
create table t2 (a int, key(a), b int);
insert into t2 values (1,1),(2,2);
set @cnt= 1;
set @str="update t2 set b=1 where a not in (";
select count(*) from (
select @str:=concat(@str, @cnt:=@cnt+1, ",")
from t1 A, t1 B, t1 C, t1 D) Z;
set @str:=concat(@str, "10000)");
select substr(@str, 1, 50);
prepare s from @str;
execute s;
deallocate prepare s;
set @str=NULL;
drop table t2;
drop table t1;
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
# These files are to be modified ONLY BY INNOBASE guys. #
# #
# Use innodb_mysql.[test|result] files instead. #
# #
# If nevertheless you need to make some changes here, please, forward #
# your commit message To: dev@innodb.com Cc: dev-innodb@mysql.com #
# (otherwise your changes may be erased). #
# #
#######################################################################
-- source include/have_innodb.inc
#
......
-- source include/have_innodb.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
......@@ -74,7 +74,7 @@ public:
/**
* Constructor / Destructor
*/
SocketServer(int maxSessions = 32);
SocketServer(unsigned maxSessions = ~(unsigned)0);
~SocketServer();
/**
......
......@@ -105,10 +105,10 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
}
{
struct sockaddr addr;
struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
int r= getpeername(sockfd, &addr, &addrlen);
m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr;
int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
m_connect_address= (&addr)->sin_addr;
}
bool res = connect_server_impl(sockfd);
......@@ -198,10 +198,10 @@ Transporter::connect_client(NDB_SOCKET_TYPE sockfd) {
}
{
struct sockaddr addr;
struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
int r= getpeername(sockfd, &addr, &addrlen);
m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr;
int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
m_connect_address= (&addr)->sin_addr;
}
bool res = connect_client_impl(sockfd);
......
......@@ -27,7 +27,7 @@
#define DEBUG(x) ndbout << x << endl;
SocketServer::SocketServer(int maxSessions) :
SocketServer::SocketServer(unsigned maxSessions) :
m_sessions(10),
m_services(5)
{
......@@ -136,7 +136,7 @@ SocketServer::setup(SocketServer::Service * service,
}
DBUG_PRINT("info",("bound to %u",ntohs(servaddr.sin_port)));
if (listen(sock, m_maxSessions) == -1){
if (listen(sock, m_maxSessions > 32 ? 32 : m_maxSessions) == -1){
DBUG_PRINT("error",("listen() - %d - %s",
errno, strerror(errno)));
NDB_CLOSE_SOCKET(sock);
......
......@@ -210,9 +210,13 @@ Configuration::Configuration()
m_config_retriever= 0;
m_clusterConfig= 0;
m_clusterConfigIter= 0;
m_logLevel= 0;
}
Configuration::~Configuration(){
if (opt_connect_str)
free(_connectString);
if(_programName != NULL)
free(_programName);
......@@ -225,6 +229,10 @@ Configuration::~Configuration(){
if (m_config_retriever) {
delete m_config_retriever;
}
if(m_logLevel) {
delete m_logLevel;
}
}
void
......
......@@ -451,9 +451,9 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
return;
}
struct sockaddr addr;
struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
int r = getpeername(m_socket, &addr, &addrlen);
int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen);
if (r != 0 ) {
m_output->println(cmd);
m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r);
......@@ -465,7 +465,7 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){
BaseString error_string;
if (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype,
&addr, &addrlen, error_string)){
(struct sockaddr*)&addr, &addrlen, error_string)){
const char *alias;
const char *str;
alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)
......
......@@ -1991,6 +1991,16 @@ bool Item_decimal::eq(const Item *item, bool binary_cmp) const
}
void Item_decimal::set_decimal_value(my_decimal *value_par)
{
my_decimal2decimal(value_par, &decimal_value);
decimals= (uint8) decimal_value.frac;
unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
String *Item_float::val_str(String *str)
{
// following assert is redundant, because fixed=1 assigned in constructor
......
......@@ -1442,6 +1442,7 @@ public:
}
uint decimal_precision() const { return decimal_value.precision(); }
bool eq(const Item *, bool binary_cmp) const;
void set_decimal_value(my_decimal *value_par);
};
......
......@@ -623,15 +623,17 @@ public:
/* Functions to handle the optimized IN */
/* A vector of values of some type */
class in_vector :public Sql_alloc
{
protected:
public:
char *base;
uint size;
qsort2_cmp compare;
CHARSET_INFO *collation;
uint count;
public:
uint used_count;
in_vector() {}
in_vector(uint elements,uint element_length,qsort2_cmp cmp_func,
......@@ -647,6 +649,32 @@ public:
qsort2(base,used_count,size,compare,collation);
}
int find(Item *item);
/*
Create an instance of Item_{type} (e.g. Item_decimal) constant object
which type allows it to hold an element of this vector without any
conversions.
The purpose of this function is to be able to get elements of this
vector in form of Item_xxx constants without creating Item_xxx object
for every array element you get (i.e. this implements "FlyWeight" pattern)
*/
virtual Item* create_item() { return NULL; }
/*
Store the value at position #pos into provided item object
SYNOPSIS
value_to_item()
pos Index of value to store
item Constant item to store value into. The item must be of the same
type that create_item() returns.
*/
virtual void value_to_item(uint pos, Item *item) { }
/* Compare values number pos1 and pos2 for equality */
bool compare_elems(uint pos1, uint pos2)
{
return test(compare(collation, base + pos1*size, base + pos2*size));
}
};
class in_string :public in_vector
......@@ -658,6 +686,16 @@ public:
~in_string();
void set(uint pos,Item *item);
byte *get_value(Item *item);
Item* create_item()
{
return new Item_string(collation);
}
void value_to_item(uint pos, Item *item)
{
String *str=((String*) base)+pos;
Item_string *to= (Item_string*)item;
to->str_value= *str;
}
};
class in_longlong :public in_vector
......@@ -667,6 +705,19 @@ public:
in_longlong(uint elements);
void set(uint pos,Item *item);
byte *get_value(Item *item);
Item* create_item()
{
/*
We're created a signed INT, this may not be correct in
general case (see BUG#19342).
*/
return new Item_int((longlong)0);
}
void value_to_item(uint pos, Item *item)
{
((Item_int*)item)->value= ((longlong*)base)[pos];
}
};
class in_double :public in_vector
......@@ -676,6 +727,15 @@ public:
in_double(uint elements);
void set(uint pos,Item *item);
byte *get_value(Item *item);
Item *create_item()
{
return new Item_float(0.0);
}
void value_to_item(uint pos, Item *item)
{
((Item_float*)item)->value= ((double*) base)[pos];
}
};
class in_decimal :public in_vector
......@@ -685,6 +745,16 @@ public:
in_decimal(uint elements);
void set(uint pos, Item *item);
byte *get_value(Item *item);
Item *create_item()
{
return new Item_decimal(0, FALSE);
}
void value_to_item(uint pos, Item *item)
{
my_decimal *dec= ((my_decimal *)base) + pos;
Item_decimal *item_dec= (Item_decimal*)item;
item_dec->set_decimal_value(dec);
}
};
......@@ -864,12 +934,13 @@ public:
class Item_func_in :public Item_func_opt_neg
{
public:
Item_result cmp_type;
in_vector *array;
cmp_item *in_item;
bool have_null;
DTCollation cmp_collation;
public:
Item_func_in(List<Item> &list)
:Item_func_opt_neg(list), array(0), in_item(0), have_null(0)
{
......
......@@ -3501,17 +3501,92 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
if (inv)
{
tree= get_ne_mm_tree(param, cond_func, field,
func->arguments()[1], func->arguments()[1],
cmp_type);
if (tree)
/*
We get here for conditions like "t.keypart NOT IN (....)".
If the IN-list contains only constants (and func->array is an ordered
array of them), we construct the appropriate SEL_ARG tree manually,
because constructing it using the range analyzer (as
AND_i( t.keypart != c_i)) will cause lots of memory to be consumed
(see BUG#15872).
*/
if (func->array && func->cmp_type != ROW_RESULT)
{
Item **arg, **end;
for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
arg < end ; arg++)
/*
Create one Item_type constant object. We'll need it as
get_mm_parts only accepts constant values wrapped in Item_Type
objects.
We create the Item on param->mem_root which points to
per-statement mem_root (while thd->mem_root is currently pointing
to mem_root local to range optimizer).
*/
MEM_ROOT *tmp_root= param->mem_root;
param->thd->mem_root= param->old_root;
Item *value_item= func->array->create_item();
param->thd->mem_root= tmp_root;
if (!value_item)
break;
/* Get a SEL_TREE for "-inf < X < c_0" interval */
func->array->value_to_item(0, value_item);
tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
value_item, cmp_type);
if (!tree)
break;
#define NOT_IN_IGNORE_THRESHOLD 1000
SEL_TREE *tree2;
if (func->array->count < NOT_IN_IGNORE_THRESHOLD)
{
for (uint i=1; i < func->array->count; i++)
{
if (func->array->compare_elems(i, i-1))
{
/* Get a SEL_TREE for "-inf < X < c_i" interval */
func->array->value_to_item(i, value_item);
tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
value_item, cmp_type);
/* Change all intervals to be "c_{i-1} < X < c_i" */
for (uint idx= 0; idx < param->keys; idx++)
{
SEL_ARG *new_interval;
if ((new_interval= tree2->keys[idx]))
{
SEL_ARG *last_val= tree->keys[idx]->last();
new_interval->min_value= last_val->max_value;
new_interval->min_flag= NEAR_MIN;
}
}
tree= tree_or(param, tree, tree2);
}
}
}
else
func->array->value_to_item(func->array->count - 1, value_item);
/*
Get the SEL_TREE for the last "c_last < X < +inf" interval
(value_item cotains c_last already)
*/
tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
value_item, cmp_type);
tree= tree_or(param, tree, tree2);
}
else
{
tree= get_ne_mm_tree(param, cond_func, field,
func->arguments()[1], func->arguments()[1],
cmp_type);
if (tree)
{
tree= tree_and(param, tree, get_ne_mm_tree(param, cond_func, field,
*arg, *arg, cmp_type));
Item **arg, **end;
for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
arg < end ; arg++)
{
tree= tree_and(param, tree, get_ne_mm_tree(param, cond_func, field,
*arg, *arg, cmp_type));
}
}
}
}
......
......@@ -5614,4 +5614,4 @@ ER_SP_NO_AGGREGATE 42000
ER_MAX_PREPARED_STMT_COUNT_REACHED 42000
eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)"
ER_VIEW_RECURSIVE
eng "`%-.64s`.`%-.64s` contain view recursion"
eng "`%-.64s`.`%-.64s` contains view recursion"
......@@ -1006,13 +1006,20 @@ static int check_connection(THD *thd)
*passwd++ : strlen(passwd);
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
db + passwd_len + 1 : 0;
uint db_len= db ? strlen(db) : 0;
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
{
inc_host_errors(&thd->remote.sin_addr);
return ER_HANDSHAKE_ERROR;
}
/* Since 4.1 all database names are stored in utf8 */
if (db)
{
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
system_charset_info,
db, strlen(db),
db, db_len,
thd->charset(), &dummy_errors)]= 0;
db= db_buff;
}
......@@ -1589,7 +1596,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
char *db, *tbl_name;
uint db_len= *(uchar*) packet;
if (db_len >= packet_length || db_len > NAME_LEN)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
}
uint tbl_len= *(uchar*) (packet + db_len + 1);
if (db_len+tbl_len+2 > packet_length || tbl_len > NAME_LEN)
{
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
break;
}
statistic_increment(thd->status_var.com_other, &LOCK_status);
thd->enable_slow_log= opt_log_slow_admin_statements;
......
......@@ -659,6 +659,7 @@ fi
%attr(755, root, root) %{_bindir}/ndb_desc
%attr(755, root, root) %{_bindir}/ndb_show_tables
%attr(755, root, root) %{_bindir}/ndb_test_platform
%attr(755, root, root) %{_bindir}/ndb_config
%files ndb-extra
%defattr(-,root,root,0755)
......
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