Commit 9b512475 authored by unknown's avatar unknown

Merge bk-internal:/home/bk/mysql-5.0

into serg.mylan:/usr/home/serg/Abk/mysql-5.0


Makefile.am:
  Auto merged
client/mysqladmin.cc:
  Auto merged
configure.in:
  Auto merged
include/my_global.h:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
parents d3d56609 21eed96b
......@@ -50,6 +50,8 @@ dlenev@build.mysql.com
dlenev@jabberwock.localdomain
dlenev@mysql.com
ejonore@mc03.ndb.mysql.com
evgen@moonbone.(none)
evgen@moonbone.local
gbichot@production.mysql.com
gbichot@quadita2.mysql.com
gbichot@quadxeon.mysql.com
......
......@@ -102,5 +102,10 @@ tags:
test:
cd mysql-test; ./mysql-test-run && ./mysql-test-run --ps-protocol
test-force:
cd mysql-test; \
mysql-test-run --force ;\
mysql-test-run --ps-protocol --force
# Don't update the files from bitkeeper
%::SCCS/s.%
......@@ -727,7 +727,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
void (*func) (MYSQL_RES*, MYSQL_ROW, uint);
new_line = 1;
if (mysql_query(mysql, "show status") ||
if (mysql_query(mysql, "show /*!50002 GLOBAL */ status") ||
!(res = mysql_store_result(mysql)))
{
my_printf_error(0, "unable to show status; error: '%s'", MYF(ME_BELL),
......
......@@ -646,8 +646,8 @@ m4_define([_AC_PROG_CXX_EXIT_DECLARATION],
'void exit (int);' \
'#include <stdlib.h>'
do
_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <stdlib.h>
$ac_declaration],
_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$ac_declaration
@%:@include <stdlib.h>],
[exit (42);])],
[],
[continue])
......
......@@ -1805,6 +1805,9 @@ If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try
again]);
fi
fi
AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include <sys/types.h>])
AC_CHECK_TYPES([size_t], [], [], [#include <stdio.h>])
MYSQL_PTHREAD_YIELD
######################################################################
......
......@@ -106,20 +106,33 @@ functions */
/* Type information */
#if defined(__EMX__) || !defined(HAVE_UINT)
#undef HAVE_UINT
#define HAVE_UINT
typedef unsigned short ushort;
typedef unsigned int uint;
#endif /* defined(__EMX__) || !defined(HAVE_UINT) */
typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
typedef __int64 longlong;
#ifndef HAVE_SIGSET_T
typedef int sigset_t;
#endif
#define longlong_defined
/* off_t should not be __int64 because of conflicts in header files;
Use my_off_t or os_off_t instead */
/*
off_t should not be __int64 because of conflicts in header files;
Use my_off_t or os_off_t instead
*/
#ifndef HAVE_OFF_T
typedef long off_t;
#endif
typedef __int64 os_off_t;
#ifdef _WIN64
typedef UINT_PTR rf_SetTimer;
#else
#ifndef HAVE_SIZE_T
typedef unsigned int size_t;
#endif
typedef uint rf_SetTimer;
#endif
......
......@@ -414,6 +414,8 @@ int __void__;
#endif
#if defined(__EMX__) || !defined(HAVE_UINT)
#undef HAVE_UINT
#define HAVE_UINT
typedef unsigned int uint;
typedef unsigned short ushort;
#endif
......
......@@ -128,3 +128,20 @@ t2.value64=t1.value64;
value64 value32 value64 value32
9223372036854775807 2 9223372036854775807 4
drop table t1, t2;
create table t1 select 1 as 'a';
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(1) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 select 9223372036854775809 as 'a';
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(19) unsigned NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t1;
a
9223372036854775809
drop table t1;
......@@ -4,12 +4,11 @@ CAST(1-2 AS UNSIGNED)
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
-1
select CONVERT('-1',UNSIGNED);
CONVERT('-1',UNSIGNED)
18446744073709551615
select CAST('10 ' as unsigned integer);
CAST('10 ' as unsigned integer)
10
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '10 '
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
cast(-5 as unsigned) | 1 cast(-5 as unsigned) & -1
18446744073709551611 18446744073709551611
......@@ -100,6 +99,41 @@ select 10E+0+'a';
10
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'a'
select cast('18446744073709551616' as unsigned);
cast('18446744073709551616' as unsigned)
18446744073709551615
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '18446744073709551616'
select cast('18446744073709551616' as signed);
cast('18446744073709551616' as signed)
-1
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '18446744073709551616'
select cast('9223372036854775809' as signed);
cast('9223372036854775809' as signed)
-9223372036854775807
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select cast('-1' as unsigned);
cast('-1' as unsigned)
18446744073709551615
Warnings:
Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select cast('abc' as signed);
cast('abc' as signed)
0
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'abc'
select cast('1a' as signed);
cast('1a' as signed)
1
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '1a'
select cast('' as signed);
cast('' as signed)
0
Warnings:
Warning 1292 Truncated incorrect INTEGER value: ''
set names binary;
select cast(_latin1'test' as char character set latin2);
cast(_latin1'test' as char character set latin2)
......@@ -255,6 +289,39 @@ timediff(cast('2004-12-30 12:00:00' as time), '12:00:00')
select timediff(cast('1 12:00:00' as time), '12:00:00');
timediff(cast('1 12:00:00' as time), '12:00:00')
24:00:00
select cast(18446744073709551615 as unsigned);
cast(18446744073709551615 as unsigned)
18446744073709551615
select cast(18446744073709551615 as signed);
cast(18446744073709551615 as signed)
-1
select cast('18446744073709551615' as unsigned);
cast('18446744073709551615' as unsigned)
18446744073709551615
select cast('18446744073709551615' as signed);
cast('18446744073709551615' as signed)
-1
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select cast('9223372036854775807' as signed);
cast('9223372036854775807' as signed)
9223372036854775807
select cast(concat('184467440','73709551615') as unsigned);
cast(concat('184467440','73709551615') as unsigned)
18446744073709551615
select cast(concat('184467440','73709551615') as signed);
cast(concat('184467440','73709551615') as signed)
-1
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select cast(repeat('1',20) as unsigned);
cast(repeat('1',20) as unsigned)
11111111111111111111
select cast(repeat('1',20) as signed);
cast(repeat('1',20) as signed)
-7335632962598440505
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select cast('1.2' as decimal(3,2));
cast('1.2' as decimal(3,2))
1.20
......
drop table if exists t1;
create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=innodb;
select * from t1;
c1 c2 stamp
......
......@@ -182,3 +182,44 @@ coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4)
set session @honk=99;
set one_shot @honk=99;
ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @first_var= cast(NULL as signed integer);
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` bigint(20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` bigint(20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @first_var= concat(NULL);
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @first_var=1;
set @first_var= cast(NULL as CHAR);
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` longtext
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
......@@ -104,3 +104,13 @@ t2.value64=t1.value64;
drop table t1, t2;
#
# Test of CREATE ... SELECT and unsigned integers
#
create table t1 select 1 as 'a';
show create table t1;
drop table t1;
create table t1 select 9223372036854775809 as 'a';
show create table t1;
select * from t1;
drop table t1;
......@@ -4,7 +4,6 @@
select CAST(1-2 AS UNSIGNED);
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
select CONVERT('-1',UNSIGNED);
select CAST('10 ' as unsigned integer);
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
......@@ -34,6 +33,15 @@ select 10+'a';
select 10.0+cast('a' as decimal);
select 10E+0+'a';
# out-of-range cases
select cast('18446744073709551616' as unsigned);
select cast('18446744073709551616' as signed);
select cast('9223372036854775809' as signed);
select cast('-1' as unsigned);
select cast('abc' as signed);
select cast('1a' as signed);
select cast('' as signed);
#
# Character set convertion
#
......@@ -132,6 +140,22 @@ select timediff(cast('2004-12-30 12:00:00' as time), '12:00:00');
# Still we should not throw away "days" part of time value
select timediff(cast('1 12:00:00' as time), '12:00:00');
#
# Bug #7036: Casting from string to unsigned would cap value of result at
# maximum signed value instead of maximum unsigned value
#
select cast(18446744073709551615 as unsigned);
select cast(18446744073709551615 as signed);
select cast('18446744073709551615' as unsigned);
select cast('18446744073709551615' as signed);
select cast('9223372036854775807' as signed);
select cast(concat('184467440','73709551615') as unsigned);
select cast(concat('184467440','73709551615') as signed);
select cast(repeat('1',20) as unsigned);
select cast(repeat('1',20) as signed);
#decimal-related additions
select cast('1.2' as decimal(3,2));
select 1e18 * cast('1.2' as decimal(3,2));
......
......@@ -2,6 +2,10 @@
# embedded server ignores 'delayed', so skip this
-- source include/not_embedded.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
#
# Bug #1078
#
......
......@@ -119,3 +119,29 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
set session @honk=99;
--error 1382
set one_shot @honk=99;
#
# Bug #6598: problem with cast(NULL as signed integer);
#
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
drop table t1;
set @first_var= cast(NULL as signed integer);
create table t1 select @first_var;
show create table t1;
drop table t1;
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
drop table t1;
set @first_var= concat(NULL);
create table t1 select @first_var;
show create table t1;
drop table t1;
set @first_var=1;
set @first_var= cast(NULL as CHAR);
create table t1 select @first_var;
show create table t1;
drop table t1;
......@@ -409,6 +409,56 @@ static int search_default_file(Process_option_func opt_handler,
}
/*
Skip over keyword and get argument after keyword
SYNOPSIS
get_argument()
keyword Include directive keyword
kwlen Length of keyword
ptr Pointer to the keword in the line under process
line line number
RETURN
0 error
# Returns pointer to the argument after the keyword.
*/
static char *get_argument(const char *keyword, uint kwlen,
char *ptr, char *name, uint line)
{
char *end;
/* Skip over "include / includedir keyword" and following whitespace */
for (ptr+= kwlen - 1;
my_isspace(&my_charset_latin1, ptr[0]);
ptr++)
{}
/*
Trim trailing whitespace from directory name
The -1 below is for the newline added by fgets()
Note that my_isspace() is true for \r and \n
*/
for (end= ptr + strlen(ptr) - 1;
my_isspace(&my_charset_latin1, *(end - 1));
end--)
{}
end[0]= 0; /* Cut off end space */
/* Print error msg if there is nothing after !include* directive */
if (end <= ptr)
{
fprintf(stderr,
"error: Wrong '!%s' directive in config file: %s at line %d\n",
keyword, name, line);
return 0;
}
return ptr;
}
/*
Open a configuration file (if exists) and read given options from it
......@@ -497,40 +547,34 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
continue;
/* Configuration File Directives */
if ((*ptr == '!') && (recursion_level < max_recursion_level))
if ((*ptr == '!'))
{
if (recursion_level >= max_recursion_level)
{
for (end= ptr + strlen(ptr) - 1;
my_isspace(&my_charset_latin1, *(end - 1));
end--)
{}
end[0]= 0;
fprintf(stderr,
"Warning: skipping '%s' directive as maximum include"
"recursion level was reached in file %s at line %d\n",
ptr, name, line);
continue;
}
/* skip over `!' and following whitespace */
for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
if ((!strncmp(ptr, includedir_keyword, sizeof(includedir_keyword) - 1))
&& my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
if ((!strncmp(ptr, includedir_keyword,
sizeof(includedir_keyword) - 1)) &&
my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
{
/* skip over "includedir" and following whitespace */
for (ptr+= sizeof(includedir_keyword) - 1;
my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
/* trim trailing whitespace from directory name */
end= ptr + strlen(ptr) - 1;
/* fgets() stores the newline character in the buffer */
if ((end[0] == '\n') || (end[0] == '\r') ||
my_isspace(&my_charset_latin1, end[0]))
{
for (; my_isspace(&my_charset_latin1, *(end - 1)); end--)
{}
end[0]= 0;
}
/* print error msg if there is nothing after !includedir directive */
if (end == ptr)
{
fprintf(stderr,
"error: Wrong !includedir directive in config "
"file: %s at line %d\n",
name,line);
goto err;
}
if (!(ptr= get_argument(includedir_keyword,
sizeof(includedir_keyword),
ptr, name, line)))
goto err;
if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
goto err;
......@@ -559,28 +603,13 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
my_dirend(search_dir);
}
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1))
&& my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword) - 1]))
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) &&
my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword)-1]))
{
/* skip over `include' and following whitespace */
for (ptr+= sizeof(include_keyword) - 1;
my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
/* trim trailing whitespace from filename */
end= ptr + strlen(ptr) - 1;
for (; my_isspace(&my_charset_latin1, *(end - 1)) ; end--)
{}
end[0]= 0;
if (end == ptr)
{
fprintf(stderr,
"error: Wrong !include directive in config "
"file: %s at line %d\n",
name,line);
goto err;
}
if (!(ptr= get_argument(include_keyword,
sizeof(include_keyword), ptr,
name, line)))
goto err;
search_default_file_with_ext(opt_handler, handler_ctx, "", "", ptr,
recursion_level + 1);
......@@ -588,14 +617,6 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
continue;
}
else
if (recursion_level >= max_recursion_level)
{
fprintf(stderr,
"warning: skipping !include directive as maximum include"
"recursion level was reached in file %s at line %d\n",
name, line);
}
if (*ptr == '[') /* Group name */
{
......
......@@ -1025,8 +1025,8 @@ static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count)
for a too long time (this time is determined by parameter age_threshold).
*/
static inline void unreg_request(KEY_CACHE *keycache,
BLOCK_LINK *block, int at_end)
static void unreg_request(KEY_CACHE *keycache,
BLOCK_LINK *block, int at_end)
{
if (! --block->requests)
{
......@@ -1045,10 +1045,13 @@ static inline void unreg_request(KEY_CACHE *keycache,
}
link_block(keycache, block, hot, (my_bool)at_end);
block->last_hit_time= keycache->keycache_time;
if (++keycache->keycache_time - keycache->used_ins->last_hit_time >
keycache->keycache_time++;
block= keycache->used_ins;
/* Check if we should link a hot block to the warm block */
if (block && keycache->keycache_time - block->last_hit_time >
keycache->age_threshold)
{
block= keycache->used_ins;
unlink_block(keycache, block);
link_block(keycache, block, 0, 0);
if (block->temperature != BLOCK_WARM)
......
......@@ -118,6 +118,7 @@ public:
String *val_int_as_str(String *val_buffer, my_bool unsigned_flag);
virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); }
virtual Item_result cast_to_int_type () const { return result_type(); }
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
static Item_result result_merge_type(enum_field_types);
bool eq(Field *field)
......@@ -1216,6 +1217,7 @@ public:
}
enum_field_types type() const { return FIELD_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum Item_result cast_to_int_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
......
......@@ -185,9 +185,10 @@ enum db_type ha_checktype(enum db_type database_type)
thd= current_thd;
return ((enum db_type) thd->variables.table_type != DB_TYPE_UNKNOWN ?
(enum db_type) thd->variables.table_type :
(enum db_type) global_system_variables.table_type !=
DB_TYPE_UNKNOWN ?
(enum db_type) global_system_variables.table_type : DB_TYPE_MYISAM);
((enum db_type) global_system_variables.table_type !=
DB_TYPE_UNKNOWN ?
(enum db_type) global_system_variables.table_type : DB_TYPE_MYISAM)
);
} /* ha_checktype */
......
......@@ -177,7 +177,14 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors)
&tmp_errno)))
{
DBUG_PRINT("error",("gethostbyname_r returned %d",tmp_errno));
add_wrong_ip(in);
/*
Don't cache responses when the DSN server is down, as otherwise
transient DNS failure may leave any number of clients (those
that attempted to connect during the outage) unable to connect
indefinitely.
*/
if (tmp_errno == HOST_NOT_FOUND || tmp_error == NO_DATA)
add_wrong_ip(in);
my_gethostbyname_r_free();
DBUG_RETURN(0);
}
......
......@@ -302,7 +302,8 @@ public:
{ return save_in_field(field, 1); }
virtual bool send(Protocol *protocol, String *str);
virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type () const { return REAL_RESULT; }
virtual Item_result result_type() const { return REAL_RESULT; }
virtual Item_result cast_to_int_type() const { return result_type(); }
virtual enum_field_types field_type() const;
virtual enum Type type() const =0;
/* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */
......@@ -738,6 +739,10 @@ public:
{
return field->result_type();
}
Item_result cast_to_int_type() const
{
return field->cast_to_int_type();
}
enum_field_types field_type() const
{
return field->type();
......
......@@ -904,6 +904,58 @@ void Item_func_signed::print(String *str)
}
longlong Item_func_signed::val_int_from_str(int *error)
{
char buff[MAX_FIELD_WIDTH], *end;
String tmp(buff,sizeof(buff), &my_charset_bin), *res;
longlong value;
/*
For a string result, we must first get the string and then convert it
to a longlong
*/
if (!(res= args[0]->val_str(&tmp)))
{
null_value= 1;
*error= 0;
return 0;
}
null_value= 0;
end= (char*) res->ptr()+ res->length();
value= my_strtoll10(res->ptr(), &end, error);
if (*error > 0 || end != res->ptr()+ res->length())
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
res->c_ptr());
return value;
}
longlong Item_func_signed::val_int()
{
longlong value;
int error;
if (args[0]->cast_to_int_type() != STRING_RESULT)
{
value= args[0]->val_int();
null_value= args[0]->null_value;
return value;
}
value= val_int_from_str(&error);
if (value < 0 && error == 0)
{
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
"Cast to signed converted positive out-of-range integer to "
"it's negative complement");
}
return value;
}
void Item_func_unsigned::print(String *str)
{
str->append("cast(", 5);
......@@ -913,6 +965,27 @@ void Item_func_unsigned::print(String *str)
}
longlong Item_func_unsigned::val_int()
{
longlong value;
int error;
if (args[0]->cast_to_int_type() != STRING_RESULT)
{
value= args[0]->val_int();
null_value= args[0]->null_value;
return value;
}
value= val_int_from_str(&error);
if (error < 0)
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
"Cast to unsigned converted negative integer to it's "
"positive complement");
return value;
}
String *Item_decimal_typecast::val_str(String *str)
{
my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
......@@ -3271,7 +3344,8 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
from the argument if the argument is NULL
and the variable has previously been initialized.
*/
if (!entry->collation.collation || !args[0]->null_value)
null_item= (args[0]->type() == NULL_ITEM);
if (!entry->collation.collation || !null_item)
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
cached_result_type= args[0]->result_type();
......@@ -3315,8 +3389,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
if (entry->value && entry->value != pos)
my_free(entry->value,MYF(0));
entry->value=0;
entry->length=0;
entry->value= 0;
entry->length= 0;
}
else
{
......@@ -3355,9 +3429,9 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
if (type == DECIMAL_RESULT)
((my_decimal*)entry->value)->fix_buffer_pointer();
entry->length= length;
entry->type=type;
entry->collation.set(cs, dv);
}
entry->type=type;
return 0;
}
......@@ -3366,6 +3440,12 @@ bool
Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type,
CHARSET_INFO *cs, Derivation dv)
{
/*
If we set a variable explicitely to NULL then keep the old
result type of the variable
*/
if ((null_value= args[0]->null_value) && null_item)
type= entry->type; // Don't change type of item
if (::update_hash(entry, (null_value= args[0]->null_value),
ptr, length, type, cs, dv))
{
......
......@@ -262,12 +262,8 @@ public:
null_value= args[0]->null_value;
return tmp;
}
longlong val_int()
{
longlong tmp= args[0]->val_int();
null_value= args[0]->null_value;
return tmp;
}
longlong val_int();
longlong val_int_from_str(int *error);
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=0; }
void print(String *str);
......@@ -281,6 +277,7 @@ public:
const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=1; }
longlong val_int();
void print(String *str);
};
......@@ -1071,6 +1068,7 @@ class Item_func_set_user_var :public Item_func
char buffer[MAX_FIELD_WIDTH];
String value;
my_decimal decimal_buff;
bool null_item;
union
{
longlong vint;
......
......@@ -820,7 +820,7 @@ bool Protocol_simple::store_long(longlong from)
#endif
char buff[20];
return net_store_data((char*) buff,
(uint) (int10_to_str((int)from,buff, (from <0)?-10:10)-buff));
(uint) (int10_to_str((long int)from,buff, (from <0)?-10:10)-buff));
}
......
......@@ -89,7 +89,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
}
if (values.elements != table->s->fields)
{
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
return -1;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
......@@ -112,7 +112,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
int res;
if (fields.elements != values.elements)
{
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
return -1;
}
......
......@@ -2223,7 +2223,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
my_pthread_setprio(pthread_self(), QUERY_PRIOR);
thd->protocol= &thd->protocol_prep; // Switch to binary protocol
(void) stmt->cursor->fetch(num_rows);
stmt->cursor->fetch(num_rows);
thd->protocol= &thd->protocol_simple; // Use normal protocol
if (!(specialflag & SPECIAL_NO_PRIOR))
......
This diff is collapsed.
......@@ -91,7 +91,15 @@ enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF,
class JOIN;
typedef int (*Next_select_func)(JOIN *,struct st_join_table *,bool);
enum enum_nested_loop_state
{
NESTED_LOOP_KILLED= -2, NESTED_LOOP_ERROR= -1,
NESTED_LOOP_OK= 0, NESTED_LOOP_NO_MORE_ROWS= 1,
NESTED_LOOP_QUERY_LIMIT= 3, NESTED_LOOP_CURSOR_LIMIT= 4
};
typedef enum_nested_loop_state
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
typedef int (*Read_record_func)(struct st_join_table *tab);
......@@ -162,6 +170,11 @@ class JOIN :public Sql_alloc
uint send_group_parts;
bool sort_and_group,first_record,full_join,group, no_field_update;
bool do_send_rows;
/*
TRUE when we want to resume nested loop iterations when
fetching data from a cursor
*/
bool resume_nested_loop;
table_map const_table_map,found_const_table_map,outer_join;
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
/*
......@@ -263,6 +276,7 @@ class JOIN :public Sql_alloc
sort_and_group= 0;
first_record= 0;
do_send_rows= 1;
resume_nested_loop= FALSE;
send_records= 0;
found_records= 0;
fetch_limit= HA_POS_ERROR;
......@@ -374,7 +388,7 @@ public:
void reset_thd(THD *thd);
int open(JOIN *join);
int fetch(ulong num_rows);
void fetch(ulong num_rows);
void reset() { join= 0; }
bool is_open() const { return join != 0; }
void close();
......
......@@ -685,6 +685,9 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values
while ((field=it++))
{
/*
regfield don't have to be deleted as it's allocated with sql_alloc()
*/
Field *regfield=make_field((char*) buff+field->offset,field->length,
null_pos,
null_count & 7,
......@@ -696,7 +699,8 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
field->interval,
field->field_name,
&table);
DBUG_ASSERT(regfield);
if (!regfield)
goto err; // End of memory
if (!(field->flags & NOT_NULL_FLAG))
null_count++;
......@@ -730,7 +734,6 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO)),system_charset_info);
else
regfield->reset();
delete regfield;
}
/* Fill not used startpos */
......
#!/usr/bin/perl -w
#
# This is a test for a key cache bug (bug #10167)
# To expose the bug mysqld should be started with --key-buffer-size=64K
#
$opt_loop_count=100000; # Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use DBI;
use Getopt::Long;
use Benchmark;
package main;
$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=0;
$opt_host=$opt_user=$opt_password=""; $opt_db="test";
GetOptions("host=s","db=s","loop-count=i","skip-create","skip-in",
"skip-delete","verbose","fast-insert","lock-tables","debug","fast",
"force","user=s","password=s") || die "Aborted";
$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$opt_force=undef; # Ignore warnings from these
$firsttable = "bench_f1";
$secondtable = "bench_f2";
$kill_file= "/tmp/mysqltest_index_corrupt.$$";
####
#### Start timeing and start test
####
$start_time=new Benchmark;
if (!$opt_skip_create)
{
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$dbh->do("drop table if exists $firsttable, $secondtable");
print "Creating tables in $opt_db\n";
$dbh->do("create table $firsttable (
c_pollid INTEGER NOT NULL,
c_time BIGINT NOT NULL,
c_data DOUBLE NOT NULL,
c_error INTEGER NOT NULL,
c_warning INTEGER NOT NULL,
c_okay INTEGER NOT NULL,
c_unknown INTEGER NOT NULL,
c_rolled_up BIT NOT NULL,
INDEX t_mgmt_hist_r_i1 (c_pollid),
INDEX t_mgmt_hist_r_i2 (c_time),
INDEX t_mgmt_hist_r_i3 (c_rolled_up))") or die $DBI::errstr;
$dbh->do("create table $secondtable (
c_pollid INTEGER NOT NULL,
c_min_time BIGINT NOT NULL,
c_max_time BIGINT NOT NULL,
c_min_data DOUBLE NOT NULL,
c_max_data DOUBLE NOT NULL,
c_avg_data DOUBLE NOT NULL,
c_error INTEGER NOT NULL,
c_warning INTEGER NOT NULL,
c_okay INTEGER NOT NULL,
c_unknown INTEGER NOT NULL,
c_rolled_up BIT NOT NULL,
INDEX t_mgmt_hist_d_i1 (c_pollid),
INDEX t_mgmt_hist_d_i2 (c_min_time),
INDEX t_mgmt_hist_d_i3 (c_max_time),
INDEX t_mgmt_hist_d_i4 (c_rolled_up))") or die $DBI::errstr;
$dbh->disconnect; $dbh=0; # Close handler
}
$|= 1; # Autoflush
####
#### Start the tests
####
print "Running tests\n";
insert_in_bench() if (($pid=fork()) == 0); $work{$pid}="insert";
select_from_bench() if (($pid=fork()) == 0); $work{$pid}="insert-select;
delete_from_bench() if (($pid=fork()) == 0); $work{$pid}="delete";
$errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
if (!$opt_skip_delete && !$errors)
{
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$dbh->do("drop table $firsttable, $secondtable");
}
print ($errors ? "Test failed\n" :"Test ok\n");
$end_time=new Benchmark;
print "Total time: " .
timestr(timediff($end_time, $start_time),"noc") . "\n";
unlink $kill_file;
exit(0);
#
# Insert records in the two tables
#
sub insert_in_bench
{
my ($dbh,$rows,$found,$i);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($rows= 1; $rows <= $opt_loop_count ; $rows++)
{
$c_pollid = sprintf("%d",rand 1000);
$c_time = sprintf("%d",rand 100000);
$c_data = rand 1000000;
$test = rand 1;
$c_error=0;
$c_warning=0;
$c_okay=0;
$c_unknown=0;
if ($test < .8) {
$c_okay=1;
} elsif ($test <.9) {
$c_error=1;
} elsif ($test <.95) {
$c_warning=1;
} else {
$c_unknown=1;
}
$statement = "INSERT INTO $firsttable (c_pollid, c_time, c_data, c_error
, c_warning, c_okay, c_unknown, c_rolled_up) ".
"VALUES ($c_pollid,$c_time,$c_data,$c_error,$c_warning,$c_okay,$c_unknown,0)";
$cursor = $dbh->prepare($statement);
$cursor->execute();
$cursor->finish();
}
$dbh->disconnect; $dbh=0;
print "insert_in_bench: Inserted $rows rows\n";
# Kill other threads
open(KILLFILE, "> $kill_file");
close(KILLFILE);
exit(0);
}
sub select_from_bench
{
my ($dbh,$rows,$cursor);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($rows= 1; $rows < $opt_loop_count ; $rows++)
{
$t_value = rand 100000;
$t_value2 = $t_value+10000;
$statement = "INSERT INTO $secondtable (c_pollid, c_min_time, c_max_time
, c_min_data, c_max_data, c_avg_data, c_error, c_warning, c_okay, c_unknown, c_rolled_up) SELECT c_pollid, MIN(c_time), MAX(c_time), MIN(c_data), MAX(c_data), AVG(c_data), SUM(c_error), SUM(c_warning), SUM(c_okay), SUM(c_unknown), 0 FROM $firsttable WHERE (c_time>=$t_value) AND (c_time<$t_value2) AND (c_rolled_up=0) GROUP BY c_pollid";
$cursor = $dbh->prepare($statement);
$cursor->execute();
$cursor->finish();
sleep 1;
if (-e $kill_file)
{
last;
}
}
print "select_from_bench: insert-select executed $rows times\n";
exit(0);
}
sub delete_from_bench
{
my ($dbh,$row, $t_value, $t2_value, $statement, $cursor);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($rows= 1; $rows < $opt_loop_count ; $rows++)
{
$t_value = rand 50000;
$t2_value = $t_value + 50001;
$statement = "DELETE FROM $firsttable WHERE (c_time>$t_value) AND (c_time<$t2_value)";
$cursor = $dbh->prepare($statement);
$cursor->execute();
$cursor->finish();
sleep 10;
if (-e $kill_file)
{
last;
}
}
print "delete: delete executed $rows times\n";
exit(0);
}
......@@ -7046,6 +7046,7 @@ static void test_set_option()
bug #89 (reported by mark@mysql.com)
*/
#ifndef EMBEDDED_LIBRARY
static void test_prepare_grant()
{
int rc;
......@@ -7138,7 +7139,7 @@ static void test_prepare_grant()
}
}
#endif
/*
Test a crash when invalid/corrupted .frm is used in the
......@@ -12597,7 +12598,7 @@ static void test_bug8330()
const char *stmt_text;
MYSQL_STMT *stmt[2];
int i, rc;
char *query= "select a,b from t1 where a=?";
const char *query= "select a,b from t1 where a=?";
MYSQL_BIND bind[2];
long lval[2];
......@@ -12788,7 +12789,7 @@ static void test_bug8722()
}
MYSQL_STMT *open_cursor(char *query)
MYSQL_STMT *open_cursor(const char *query)
{
int rc;
const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
......@@ -12854,6 +12855,59 @@ static void test_bug9159()
myquery(rc);
}
/* Crash when opening a cursor to a query with DISTICNT and no key */
static void test_bug9520()
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
char a[6];
ulong a_len;
int rc, row_count= 0;
myheader("test_bug9520");
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
" primary key (a, b, c))");
rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
" ('a', 'b', 'c'), ('k', 'l', 'm')");
myquery(rc);
stmt= open_cursor("select distinct b from t1");
/*
Not crashes with:
stmt= open_cursor("select distinct a from t1");
*/
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
bzero(bind, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].buffer= (char*) a;
bind[0].buffer_length= sizeof(a);
bind[0].length= &a_len;
mysql_stmt_bind_result(stmt, bind);
while (!(rc= mysql_stmt_fetch(stmt)))
row_count++;
DIE_UNLESS(rc == MYSQL_NO_DATA);
printf("Fetched %d rows\n", row_count);
DBUG_ASSERT(row_count == 3);
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop table t1");
myquery(rc);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
......@@ -13079,6 +13133,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug8722", test_bug8722 },
{ "test_bug8880", test_bug8880 },
{ "test_bug9159", test_bug9159 },
{ "test_bug9520", test_bug9520 },
{ 0, 0 }
};
......
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