This commit is contained in:
unknown 2005-01-16 15:10:42 +01:00
commit 0be9922605
66 changed files with 775 additions and 401 deletions

View file

@ -754,6 +754,7 @@ ndb/examples/ndbapi_example3/ndbapi_example3
ndb/examples/ndbapi_example5/ndbapi_example5
ndb/examples/select_all/select_all
ndb/include/ndb_global.h
ndb/include/ndb_types.h
ndb/include/ndb_version.h
ndb/lib/libMGM_API.so
ndb/lib/libNDB_API.so

View file

@ -3,28 +3,27 @@
while test $# -gt 0
do
case "$1" in
--debug) EXTRA_CONFIG_FLAGS=--with-debug; shift ;;
-h | --help ) cat <<EOF; exit 0 ;;
Usage: $0 [-h|-n] [configure-options]
--debug Compile with DBUG enabled
EOF
*) echo "No such option '$1'" ; exit ;;
--debug) EXTRA_CONFIG_FLAGS=--with-debug; shift ;;
-h | --help )
echo "Usage: $0 [-h|-n] [configure-options]"
echo " --debug Compile with DBUG enabled"
exit 0 ;;
*) echo "No such option '$1'" ; exit ;;
esac
done
gmake -k clean || true
/bin/rm -f */.deps/*.P config.cache
aclocal && autoheader && aclocal && automake && autoconf
(cd bdb/dist && sh s_all)
# (cd bdb/dist && sh s_all)
(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -DHAVE_purify -DEXTRA_DEBUG -O2" CXX=gcc CXXLD=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -DHAVE_purify -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-berkeley-db --with-innodb $EXTRA_CONFIG_FLAGS
CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -DHAVE_purify -DEXTRA_DEBUG -O2" CXX=gcc CXXLD=g++ CXXFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti -DHAVE_purify -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --without-berkeley-db --with-embedded-server --with-innodb $EXTRA_CONFIG_FLAGS
gmake -j 4
cd sql ; mv mysqld mysqld-org ;
make CXXLD="purify -best-effort g++" mysqld ; mv mysqld mysqld-purify
make CXXLD="quantify -best-effort g++" mysqld ; mv mysqld mysqld-quantify
make CXXLD="purecov -best-effort g++" mysqld ; mv mysqld mysqld-purecov
gmake CXXLD="purify -best-effort g++" mysqld ; mv mysqld mysqld-purify
gmake CXXLD="quantify -best-effort g++" mysqld ; mv mysqld mysqld-quantify
gmake CXXLD="purecov -best-effort g++" mysqld ; mv mysqld mysqld-purecov
mv mysqld-org mysqld

View file

@ -265,7 +265,8 @@ if ($opt_stage <= 1)
$opt_config_options.= " --with-berkeley-db" if ($opt_bdb);
$opt_config_options.= " --with-zlib-dir=bundled" if ($opt_bundled_zlib);
$opt_config_options.= " --with-client-ldflags=-all-static" if ($opt_static_client);
$opt_config_options.= " --with-debug" if ($opt_with_debug);
$opt_config_options.= " --with-debug" if ($opt_with_debug);
$opt_config_options.= " --without-ndb-debug" if ($opt_with_debug && $opt_with_cluster);
$opt_config_options.= " --with-libwrap" if ($opt_libwrap);
$opt_config_options.= " --with-low-memory" if ($opt_with_low_memory);
$opt_config_options.= " --with-mysqld-ldflags=-all-static" if ($opt_static_server);

View file

@ -833,7 +833,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
if (argv[1][0])
{
char *pw= argv[1];
bool old= find_type(argv[0], &command_typelib, 2) == ADMIN_OLD_PASSWORD;
bool old= (find_type(argv[0], &command_typelib, 2) ==
ADMIN_OLD_PASSWORD);
#ifdef __WIN__
uint pw_len= strlen(pw);
if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'')
@ -844,21 +845,29 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
If we don't already know to use an old-style password, see what
the server is using
*/
if (!old) {
if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'")) {
if (!old)
{
if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'"))
{
my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'",
MYF(ME_BELL),mysql_error(mysql));
return -1;
} else {
}
else
{
MYSQL_RES *res= mysql_store_result(mysql);
if (!res) {
my_printf_error(0, "Could not get old_passwords setting from server; error: '%s'",
if (!res)
{
my_printf_error(0,
"Could not get old_passwords setting from "
"server; error: '%s'",
MYF(ME_BELL),mysql_error(mysql));
return -1;
}
if (!mysql_num_rows(res)) {
if (!mysql_num_rows(res))
old= 1;
} else {
else
{
MYSQL_ROW row= mysql_fetch_row(res);
old= !strncmp(row[1], "ON", 2);
}

View file

@ -154,15 +154,15 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
keyseg->flag= 0;
keyseg->null_bit= 0;
keyseg++;
init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*),
init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*),
(qsort_cmp2)keys_compare, 1, NULL, NULL);
keyinfo->delete_key= hp_rb_delete_key;
keyinfo->write_key= hp_rb_write_key;
}
else
{
init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
max_records);
keyinfo->delete_key= hp_delete_key;
keyinfo->write_key= hp_write_key;
@ -171,6 +171,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
}
share->min_records= min_records;
share->max_records= max_records;
share->max_table_size= create_info->max_table_size;
share->data_length= share->index_length= 0;
share->reclength= reclength;
share->blength= 1;

View file

@ -143,7 +143,8 @@ static byte *next_free_record_pos(HP_SHARE *info)
}
if (!(block_pos=(info->records % info->block.records_in_block)))
{
if (info->records > info->max_records && info->max_records)
if ((info->records > info->max_records && info->max_records) ||
(info->data_length + info->index_length >= info->max_table_size))
{
my_errno=HA_ERR_RECORD_FILE_FULL;
DBUG_RETURN(NULL);

View file

@ -125,8 +125,8 @@ typedef struct st_hp_keydef /* Key definition with open */
TREE rb_tree;
int (*write_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo,
const byte *record, byte *recpos);
int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo,
const byte *record, byte *recpos, int flag);
int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo,
const byte *record, byte *recpos, int flag);
uint (*get_key_length)(struct st_hp_keydef *keydef, const byte *key);
} HP_KEYDEF;
@ -135,7 +135,7 @@ typedef struct st_heap_share
HP_BLOCK block;
HP_KEYDEF *keydef;
ulong min_records,max_records; /* Params to open */
ulong data_length,index_length;
ulong data_length,index_length,max_table_size;
uint records; /* records */
uint blength; /* records rounded up to 2^n */
uint deleted; /* Deleted records in database */
@ -185,6 +185,7 @@ typedef struct st_heap_create_info
{
uint auto_key;
uint auto_key_type;
ulong max_table_size;
ulonglong auto_increment;
} HP_CREATE_INFO;

View file

@ -215,7 +215,7 @@ extern char *strstr(const char *, const char *);
extern int is_prefix(const char *, const char *);
/* Conversion routines */
double my_strtod(const char *str, char **end);
double my_strtod(const char *str, char **end, int *error);
double my_atof(const char *nptr);
extern char *llstr(longlong value,char *buff);

View file

@ -688,6 +688,7 @@ extern int init_io_cache(IO_CACHE *info,File file,uint cachesize,
extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type,
my_off_t seek_offset,pbool use_async_io,
pbool clear_cache);
extern void setup_io_cache(IO_CACHE* info);
extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count);
#ifdef THREAD
extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count);

View file

@ -165,6 +165,17 @@ dtype_is_non_binary_string_type(
return(FALSE);
}
/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
ulint
dtype_get_charset_coll_noninline(
/*=============================*/
ulint prtype) /* in: precise data type */
{
return(dtype_get_charset_coll(prtype));
}
/*************************************************************************
Forms a precise type from the < 4.1.2 format precise type plus the
charset-collation code. */

View file

@ -234,6 +234,13 @@ dtype_get_prtype(
dtype_t* type);
/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
ulint
dtype_get_charset_coll_noninline(
/*=============================*/
ulint prtype);/* in: precise data type */
/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
UNIV_INLINE
ulint
dtype_get_charset_coll(

View file

@ -456,6 +456,8 @@ struct mysql_row_templ_struct {
zero if column cannot be NULL */
ulint type; /* column type in Innobase mtype
numbers DATA_CHAR... */
ulint charset; /* MySQL charset-collation code
of the column, or zero */
ulint is_unsigned; /* if a column type is an integer
type and this field is != 0, then
it is an unsigned integer type */

View file

@ -91,12 +91,33 @@ row_mysql_store_col_in_innobase_format(
}
} else if (type == DATA_VARCHAR || type == DATA_VARMYSQL
|| type == DATA_BINARY) {
/* Remove trailing spaces. */
/* Handle UCS2 strings differently. As no new
collations will be introduced in 4.1, we hardcode the
charset-collation codes here. In 5.0, the logic will
be based on mbminlen. */
ulint cset = dtype_get_charset_coll(
dtype_get_prtype(dfield_get_type(dfield)));
ptr = row_mysql_read_var_ref(&col_len, mysql_data);
/* Remove trailing spaces */
while (col_len > 0 && ptr[col_len - 1] == ' ') {
col_len--;
}
if (cset == 35/*ucs2_general_ci*/
|| cset == 90/*ucs2_bin*/
|| (cset >= 128/*ucs2_unicode_ci*/
&& cset <= 144/*ucs2_persian_ci*/)) {
/* space=0x0020 */
/* Trim "half-chars", just in case. */
col_len &= ~1;
while (col_len >= 2 && ptr[col_len - 2] == 0x00
&& ptr[col_len - 1] == 0x20) {
col_len -= 2;
}
} else {
/* space=0x20 */
while (col_len > 0 && ptr[col_len - 1] == 0x20) {
col_len--;
}
}
} else if (type == DATA_BLOB) {
ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len);
}

View file

@ -75,6 +75,10 @@ extern dulint srv_start_lsn;
void set_panic_flag_for_netware(void);
#endif
#ifdef HAVE_DARWIN_THREADS
extern ibool srv_have_fullfsync;
#endif
extern ulint srv_sizeof_trx_t_in_ha_innodb_cc;
extern ibool srv_is_being_started;

View file

@ -1773,19 +1773,31 @@ os_file_flush(
#else
int ret;
#if defined(HAVE_DARWIN_THREADS) && defined(F_FULLFSYNC)
#if defined(HAVE_DARWIN_THREADS)
# ifndef F_FULLFSYNC
/* The following definition is from the Mac OS X 10.3 <sys/fcntl.h> */
# define F_FULLFSYNC 51 /* fsync + ask the drive to flush to the media */
# elif F_FULLFSYNC != 51
# error "F_FULLFSYNC != 51: ABI incompatibility with Mac OS X 10.3"
# endif
/* Apple has disabled fsync() for internal disk drives in OS X. That
caused corruption for a user when he tested a power outage. Let us in
OS X use a nonstandard flush method recommended by an Apple
engineer. */
ret = fcntl(file, F_FULLFSYNC, NULL);
if (ret) {
/* If we are not on a file system that supports this, then
fall back to a plain fsync. */
if (!srv_have_fullfsync) {
/* If we are not on an operating system that supports this,
then fall back to a plain fsync. */
ret = fsync(file);
} else {
ret = fcntl(file, F_FULLFSYNC, NULL);
if (ret) {
/* If we are not on a file system that supports this,
then fall back to a plain fsync. */
ret = fsync(file);
}
}
#elif HAVE_FDATASYNC
ret = fdatasync(file);

View file

@ -262,22 +262,6 @@ cmp_whole_field(
"InnoDB: comparison!\n");
}
/* MySQL does not pad the ends of strings with spaces in a
comparison. That would cause a foreign key check to fail for
non-latin1 character sets if we have different length columns.
To prevent that we remove trailing spaces here before doing
the comparison. NOTE that if we in the future map more MySQL
types to DATA_MYSQL or DATA_VARMYSQL, we have to change this
code. */
while (a_length > 0 && a[a_length - 1] == ' ') {
a_length--;
}
while (b_length > 0 && b[b_length - 1] == ' ') {
b_length--;
}
return(innobase_mysql_cmp(
(int)(type->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(type->prtype),

View file

@ -2271,9 +2271,6 @@ row_sel_field_store_in_mysql_format(
dest = row_mysql_store_var_len(dest, len);
ut_memcpy(dest, data, len);
/* Pad with trailing spaces */
memset(dest + len, ' ', col_len - len);
/* ut_ad(col_len >= len + 2); No real var implemented in
MySQL yet! */
@ -2406,7 +2403,45 @@ row_sel_store_mysql_rec(
mysql_rec + templ->mysql_col_offset,
templ->mysql_col_len, data, len,
templ->type, templ->is_unsigned);
if (templ->type == DATA_VARCHAR
|| templ->type == DATA_VARMYSQL
|| templ->type == DATA_BINARY) {
/* Pad with trailing spaces */
data = mysql_rec + templ->mysql_col_offset;
/* Handle UCS2 strings differently. As no new
collations will be introduced in 4.1, we
hardcode the charset-collation codes here.
5.0 will use a different approach. */
if (templ->charset == 35
|| templ->charset == 90
|| (templ->charset >= 128
&& templ->charset <= 144)) {
/* space=0x0020 */
ulint col_len = templ->mysql_col_len;
ut_a(!(col_len & 1));
if (len & 1) {
/* A 0x20 has been stripped
from the column.
Pad it back. */
goto pad_0x20;
}
/* Pad the rest of the string
with 0x0020 */
while (len < col_len) {
data[len++] = 0x00;
pad_0x20:
data[len++] = 0x20;
}
} else {
/* space=0x20 */
memset(data + len, 0x20,
templ->mysql_col_len - len);
}
}
/* Cleanup */
if (extern_field_heap) {
mem_heap_free(extern_field_heap);
@ -2442,8 +2477,29 @@ row_sel_store_mysql_rec(
pad_char = '\0';
}
memset(mysql_rec + templ->mysql_col_offset, pad_char,
templ->mysql_col_len);
/* Handle UCS2 strings differently. As no new
collations will be introduced in 4.1,
we hardcode the charset-collation codes here.
5.0 will use a different approach. */
if (templ->charset == 35
|| templ->charset == 90
|| (templ->charset >= 128
&& templ->charset <= 144)) {
/* There are two bytes per char, so the length
has to be an even number. */
ut_a(!(templ->mysql_col_len & 1));
data = mysql_rec + templ->mysql_col_offset;
len = templ->mysql_col_len;
/* Pad with 0x0020. */
while (len >= 2) {
*data++ = 0x00;
*data++ = 0x20;
len -= 2;
}
} else {
memset(mysql_rec + templ->mysql_col_offset,
pad_char, templ->mysql_col_len);
}
}
}

View file

@ -61,6 +61,11 @@ dulint srv_start_lsn;
/* Log sequence number at shutdown */
dulint srv_shutdown_lsn;
#ifdef HAVE_DARWIN_THREADS
# include <sys/utsname.h>
ibool srv_have_fullfsync = FALSE;
#endif
ibool srv_start_raw_disk_in_use = FALSE;
static ibool srv_start_has_been_called = FALSE;
@ -935,6 +940,28 @@ innobase_start_or_create_for_mysql(void)
ulint i;
ibool srv_file_per_table_original_value = srv_file_per_table;
mtr_t mtr;
#ifdef HAVE_DARWIN_THREADS
# ifdef F_FULLFSYNC
/* This executable has been compiled on Mac OS X 10.3 or later.
Assume that F_FULLFSYNC is available at run-time. */
srv_have_fullfsync = TRUE;
# else /* F_FULLFSYNC */
/* This executable has been compiled on Mac OS X 10.2
or earlier. Determine if the executable is running
on Mac OS X 10.3 or later. */
struct utsname utsname;
if (uname(&utsname)) {
fputs("InnoDB: cannot determine Mac OS X version!\n", stderr);
} else {
srv_have_fullfsync = strcmp(utsname.release, "7.") >= 0;
}
if (!srv_have_fullfsync) {
fputs(
"InnoDB: On Mac OS X, fsync() may be broken on internal drives,\n"
"InnoDB: making transactions unsafe!\n", stderr);
}
# endif /* F_FULLFSYNC */
#endif /* HAVE_DARWIN_THREADS */
if (sizeof(ulint) != sizeof(void*)) {
fprintf(stderr,

View file

@ -427,6 +427,9 @@ while test $# -gt 0; do
--fast)
FAST_START=1
;;
--use-old-data)
USE_OLD_DATA=1;
;;
-- ) shift; break ;;
--* ) $ECHO "Unrecognized option: $1"; exit 1 ;;
* ) break ;;
@ -773,12 +776,14 @@ report_stats () {
mysql_install_db () {
$ECHO "Removing Stale Files"
$RM -rf $MASTER_MYDDIR $MASTER_MYDDIR"1" $SLAVE_MYDDIR $MY_LOG_DIR/*
$ECHO "Installing Master Databases"
$INSTALL_DB
if [ $? != 0 ]; then
if [ -z "$USE_OLD_DATA" ]; then
$RM -rf $MASTER_MYDDIR $MASTER_MYDDIR"1"
$ECHO "Installing Master Databases"
$INSTALL_DB
if [ $? != 0 ]; then
error "Could not install master test DBs"
exit 1
exit 1
fi
fi
if [ ! -z "$USE_NDBCLUSTER" ]
then
@ -790,6 +795,7 @@ mysql_install_db () {
fi
fi
$ECHO "Installing Slave Databases"
$RM -rf $SLAVE_MYDDIR $MY_LOG_DIR/*
$INSTALL_DB -slave
if [ $? != 0 ]; then
error "Could not install slave test DBs"

View file

@ -204,7 +204,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
drop table t1;
SET SESSION storage_engine="gemini";
ERROR 42000: Unknown table engine 'gemini'
@ -216,7 +216,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
SET SESSION storage_engine=default;
drop table t1;
create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2));
@ -361,7 +361,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
drop table t1;
SET SESSION storage_engine="gemini";
ERROR 42000: Unknown table engine 'gemini'
@ -373,7 +373,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
SET SESSION storage_engine=default;
drop table t1;
create table t1(a int,b int,c int unsigned,d date,e char,f datetime,g time,h blob);

View file

@ -413,7 +413,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`c` char(10) character set utf8 default NULL,
UNIQUE KEY `a` USING HASH (`c`(1))
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f');
insert into t1 values ('aa');
ERROR 23000: Duplicate entry 'aa' for key 1
@ -449,7 +449,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`c` char(10) character set utf8 default NULL,
UNIQUE KEY `a` USING BTREE (`c`(1))
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f');
insert into t1 values ('aa');
ERROR 23000: Duplicate entry 'aa' for key 1
@ -571,7 +571,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`c` char(10) character set utf8 collate utf8_bin default NULL,
UNIQUE KEY `a` USING HASH (`c`(1))
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f');
insert into t1 values ('aa');
ERROR 23000: Duplicate entry 'aa' for key 1
@ -607,7 +607,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`c` char(10) character set utf8 collate utf8_bin default NULL,
UNIQUE KEY `a` USING BTREE (`c`(1))
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f');
insert into t1 values ('aa');
ERROR 23000: Duplicate entry 'aa' for key 1

View file

@ -457,6 +457,11 @@ group_concat(distinct b order by b)
Warnings:
Warning 1260 2 line(s) were cut by GROUP_CONCAT()
drop table t1;
CREATE TABLE t1 (id int);
SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL;
gc
NULL
DROP TABLE t1;
create table t1 (a char(3), b char(20), primary key (a, b));
insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English');
select group_concat(a) from t1 group by b;

View file

@ -107,13 +107,16 @@ timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002")
46:58:57.999999
select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002");
timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002")
-23:59:59.999999
-24:00:00.000001
select timediff("1997-12-31 23:59:59.000001","23:59:59.000001");
timediff("1997-12-31 23:59:59.000001","23:59:59.000001")
NULL
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001");
timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001")
-00:00:00.000001
select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50");
timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50")
-00:00:00.000001
select maketime(10,11,12);
maketime(10,11,12)
10:11:12
@ -185,7 +188,7 @@ f8 date YES NULL
f9 time YES NULL
select * from t1;
f1 f2 f3 f4 f5 f6 f7 f8 f9
1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -23:59:59 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59
1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59
create table test(t1 datetime, t2 time, t3 time, t4 datetime);
insert into test values
('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'),

View file

@ -266,7 +266,7 @@ t1 CREATE TABLE `t1` (
`v` varchar(10) default NULL,
`c` char(10) default NULL,
`t` varchar(50) default NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
create table t2 like t1;
show create table t2;
Table Create Table
@ -274,7 +274,7 @@ t2 CREATE TABLE `t2` (
`v` varchar(10) default NULL,
`c` char(10) default NULL,
`t` varchar(50) default NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
create table t3 select * from t1;
show create table t3;
Table Create Table
@ -282,7 +282,7 @@ t3 CREATE TABLE `t3` (
`v` varchar(10) default NULL,
`c` char(10) default NULL,
`t` varchar(50) default NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
alter table t1 modify c varchar(10);
show create table t1;
Table Create Table
@ -290,7 +290,7 @@ t1 CREATE TABLE `t1` (
`v` varchar(10) default NULL,
`c` varchar(10) default NULL,
`t` varchar(50) default NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
alter table t1 modify v char(10);
show create table t1;
Table Create Table
@ -298,7 +298,7 @@ t1 CREATE TABLE `t1` (
`v` char(10) default NULL,
`c` varchar(10) default NULL,
`t` varchar(50) default NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
alter table t1 modify t varchar(10);
Warnings:
Warning 1265 Data truncated for column 't' at row 2
@ -308,7 +308,7 @@ t1 CREATE TABLE `t1` (
`v` char(10) default NULL,
`c` varchar(10) default NULL,
`t` varchar(10) default NULL
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
select concat('*',v,'*',c,'*',t,'*') from t1;
concat('*',v,'*',c,'*',t,'*')
*+*+*+ *
@ -324,7 +324,7 @@ t1 CREATE TABLE `t1` (
KEY `v` (`v`),
KEY `c` (`c`),
KEY `t` (`t`(10))
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
select count(*) from t1;
count(*)
270
@ -559,7 +559,7 @@ t1 CREATE TABLE `t1` (
KEY `v` USING BTREE (`v`),
KEY `c` USING BTREE (`c`),
KEY `t` USING BTREE (`t`(10))
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
select count(*) from t1;
count(*)
270
@ -650,7 +650,7 @@ t1 CREATE TABLE `t1` (
KEY `v` (`v`(5)),
KEY `c` (`c`(5)),
KEY `t` (`t`(5))
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
drop table t1;
create table t1 (v varchar(65530), key(v(10)));
show create table t1;
@ -658,7 +658,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`v` varchar(65530) default NULL,
KEY `v` (`v`(10))
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
insert into t1 values(repeat('a',65530));
select length(v) from t1 where v=repeat('a',65530);
length(v)

View file

@ -478,7 +478,7 @@ character_sets CREATE TEMPORARY TABLE `character_sets` (
`DEFAULT_COLLATE_NAME` varchar(64) NOT NULL default '',
`DESCRIPTION` varchar(60) NOT NULL default '',
`MAXLEN` bigint(3) NOT NULL default '0'
) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=1818
) ENGINE=MEMORY DEFAULT CHARSET=utf8 MAX_ROWS=1818
set names latin2;
SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets;
Table Create Table
@ -487,7 +487,7 @@ character_sets CREATE TEMPORARY TABLE `character_sets` (
`DEFAULT_COLLATE_NAME` varchar(64) NOT NULL default '',
`DESCRIPTION` varchar(60) NOT NULL default '',
`MAXLEN` bigint(3) NOT NULL default '0'
) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=1818
) ENGINE=MEMORY DEFAULT CHARSET=utf8 MAX_ROWS=1818
set names latin1;
create table t1 select * from information_schema.CHARACTER_SETS
where CHARACTER_SET_NAME like "latin1";

View file

@ -1326,8 +1326,8 @@ truncate table t1;
insert into t1 (a) values (NULL),(NULL);
SELECT * from t1;
a
3
4
1
2
drop table t1;
CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) ENGINE=INNODB;
CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (`t1_id`) REFERENCES `t1`(`id 1`) ON DELETE CASCADE ) ENGINE=INNODB;
@ -1690,13 +1690,13 @@ Variable_name Value
Innodb_page_size 16384
show status like "Innodb_rows_deleted";
Variable_name Value
Innodb_rows_deleted 2078
Innodb_rows_deleted 2070
show status like "Innodb_rows_inserted";
Variable_name Value
Innodb_rows_inserted 31706
show status like "Innodb_rows_read";
Variable_name Value
Innodb_rows_read 80161
Innodb_rows_read 80153
show status like "Innodb_rows_updated";
Variable_name Value
Innodb_rows_updated 29530

View file

@ -315,57 +315,57 @@ insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (3),(4);
insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=3;
delete from t2 where b=3;
delete from t3 where a=3;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1;
delete from t2;
delete from t3;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=5;
delete from t2 where b=5;
delete from t3 where a=5;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
drop table t1, t2, t3;
create database mysqltest;
show create database mysqltest;
@ -412,7 +412,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`i` int(11) default NULL,
KEY `i` (`i`)
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (i int, KEY USING HASH (i)) ENGINE=MEMORY;
SHOW CREATE TABLE t1;
@ -420,7 +420,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`i` int(11) default NULL,
KEY `i` USING HASH (`i`)
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MEMORY;
SHOW CREATE TABLE t1;
@ -428,7 +428,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`i` int(11) default NULL,
KEY `i` USING BTREE (`i`)
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM;
SHOW CREATE TABLE t1;
@ -459,7 +459,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`i` int(11) default NULL,
KEY `i` (`i`)
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM;
SHOW CREATE TABLE t1;
@ -474,5 +474,5 @@ Table Create Table
t1 CREATE TABLE `t1` (
`i` int(11) default NULL,
KEY `i` USING BTREE (`i`)
) ENGINE=HEAP DEFAULT CHARSET=latin1
) ENGINE=MEMORY DEFAULT CHARSET=latin1
DROP TABLE t1;

View file

@ -18,7 +18,7 @@ t1 CREATE TABLE `t1` (
`email` varchar(60) character set latin2 NOT NULL default '',
PRIMARY KEY (`a`),
UNIQUE KEY `email` USING BTREE (`email`)
) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
set @@sql_mode="ansi_quotes";
show variables like 'sql_mode';
Variable_name Value
@ -31,7 +31,7 @@ t1 CREATE TABLE "t1" (
"email" varchar(60) character set latin2 NOT NULL default '',
PRIMARY KEY ("a"),
UNIQUE KEY "email" USING BTREE ("email")
) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
set @@sql_mode="no_table_options";
show variables like 'sql_mode';
Variable_name Value
@ -57,7 +57,7 @@ t1 CREATE TABLE `t1` (
`email` varchar(60) character set latin2 NOT NULL default '',
PRIMARY KEY (`a`),
UNIQUE KEY `email` (`email`)
) ENGINE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
) ENGINE=MEMORY DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
set @@sql_mode="no_field_options,mysql323,mysql40";
show variables like 'sql_mode';
Variable_name Value

View file

@ -768,7 +768,7 @@ INSERT INTO t1 VALUES (-2.2E-307,0),(+1.7E+308,+1.7E+308);
INSERT INTO t1 VALUES ('-2.2E-307',0),('+1.7E+308','+1.7E+308');
INSERT INTO t1 (col1) VALUES (-2.2E-330);
INSERT INTO t1 (col1) VALUES (+1.7E+309);
ERROR 22007: Illegal double '1.7E+309' value found during parsing
Got one of the listed errors
INSERT INTO t1 (col2) VALUES (-1.1E-3);
ERROR 22003: Out of range value adjusted for column 'col2' at row 1
INSERT INTO t1 (col1) VALUES ('+1.8E+309');

View file

@ -368,3 +368,14 @@ a+0
44
57
drop table t1;
create table t1 (a bit(3), b bit(12));
insert into t1 values (7,(1<<12)-2), (0x01,0x01ff);
select hex(a),hex(b) from t1;
hex(a) hex(b)
7 FFE
1 1FF
select hex(concat(a)),hex(concat(b)) from t1;
hex(concat(a)) hex(concat(b))
07 0FFE
01 01FF
drop table t1;

View file

@ -1,4 +1,4 @@
drop table if exists t1;
drop table if exists t1,t2;
SELECT 10,10.0,10.,.1e+2,100.0e-1;
10 10.0 10. .1e+2 100.0e-1
10 10.0 10 10 10
@ -8,6 +8,9 @@ SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000;
SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1;
1e1 1.e1 1.0e1 1e+1 1.e+1 1.0e+1 1e-1 1.e-1 1.0e-1
10 10 10 10 10 10 0.1 0.1 0.1
SELECT 0.001e+1,0.001e-1, -0.001e+01,-0.001e-01;
0.001e+1 0.001e-1 -0.001e+01 -0.001e-01
0.01 0.0001 -0.01 -0.0001
create table t1 (f1 float(24),f2 float(52));
show full columns from t1;
Field Type Collation Null Key Default Extra Privileges Comment

View file

@ -426,3 +426,13 @@ max(t)
2004-01-01 01:00:00
2004-02-01 00:00:00
drop table t1;
set sql_mode='maxdb';
create table t1 (a timestamp, b timestamp(19));
show create table t1;
Table Create Table
t1 CREATE TABLE "t1" (
"a" datetime default NULL,
"b" datetime default NULL
)
set sql_mode='';
drop table t1;

View file

@ -278,6 +278,13 @@ select group_concat(distinct b order by b) from t1 group by a;
drop table t1;
#
# bug #7769: group_concat returning null is checked in having
#
CREATE TABLE t1 (id int);
SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL;
DROP TABLE t1;
#
# Bug #6475
#

View file

@ -60,6 +60,7 @@ select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002");
select timediff("1997-12-31 23:59:59.000001","23:59:59.000001");
select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001");
select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50");
--enable_ps_protocol
select maketime(10,11,12);

View file

@ -531,7 +531,7 @@ INSERT INTO t1 VALUES (-2.2E-307,0),(+1.7E+308,+1.7E+308);
INSERT INTO t1 VALUES ('-2.2E-307',0),('+1.7E+308','+1.7E+308');
# We don't give warnings for underflow
INSERT INTO t1 (col1) VALUES (-2.2E-330);
--error 1367
--error 1367,1264
INSERT INTO t1 (col1) VALUES (+1.7E+309);
--error 1264
INSERT INTO t1 (col2) VALUES (-1.1E-3);

View file

@ -106,3 +106,12 @@ create table t1 (a bit(7), key(a));
insert into t1 values (44), (57);
select a+0 from t1;
drop table t1;
#
# Test conversion to and from strings
#
create table t1 (a bit(3), b bit(12));
insert into t1 values (7,(1<<12)-2), (0x01,0x01ff);
select hex(a),hex(b) from t1;
select hex(concat(a)),hex(concat(b)) from t1;
drop table t1;

View file

@ -3,7 +3,7 @@
# Numeric floating point.
--disable_warnings
drop table if exists t1;
drop table if exists t1,t2;
--enable_warnings
--replace_result e-0 e- e+0 e+
@ -11,6 +11,7 @@ SELECT 10,10.0,10.,.1e+2,100.0e-1;
--replace_result e-00 e-0
SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000;
SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1;
SELECT 0.001e+1,0.001e-1, -0.001e+01,-0.001e-01;
create table t1 (f1 float(24),f2 float(52));
show full columns from t1;

View file

@ -288,3 +288,15 @@ insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00')
('b', '2004-02-01 00:00:00');
select max(t) from t1 group by a;
drop table t1;
#
# Test for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB
# mode". TIMESTAMP columns should be converted DATETIME columns in MAXDB
# mode regardless of whether a display width is given.
#
set sql_mode='maxdb';
create table t1 (a timestamp, b timestamp(19));
show create table t1;
# restore default mode
set sql_mode='';
drop table t1;

View file

@ -27,7 +27,7 @@
also info->read_pos is set to info->read_end.
If called through open_cached_file(), then the temporary file will
only be created if a write exeeds the file buffer or if one calls
flush_io_cache().
my_b_flush_io_cache().
If one uses SEQ_READ_APPEND, then two buffers are allocated, one for
reading and another for writing. Reads are first done from disk and
@ -43,7 +43,7 @@ TODO:
each time the write buffer gets full and it's written to disk, we will
always do a disk read to read a part of the buffer from disk to the
read buffer.
This should be fixed so that when we do a flush_io_cache() and
This should be fixed so that when we do a my_b_flush_io_cache() and
we have been reading the write buffer, we should transfer the rest of the
write buffer to the read buffer before we start to reuse it.
*/
@ -70,9 +70,40 @@ static void my_aiowait(my_aio_result *result);
#define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1))
#define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1))
static void
init_functions(IO_CACHE* info, enum cache_type type)
/*
Setup internal pointers inside IO_CACHE
SYNOPSIS
setup_io_cache()
info IO_CACHE handler
NOTES
This is called on automaticly on init or reinit of IO_CACHE
It must be called externally if one moves or copies an IO_CACHE
object.
*/
void setup_io_cache(IO_CACHE* info)
{
/* Ensure that my_b_tell() and my_b_bytes_in_cache works */
if (info->type == WRITE_CACHE)
{
info->current_pos= &info->write_pos;
info->current_end= &info->write_end;
}
else
{
info->current_pos= &info->read_pos;
info->current_end= &info->read_end;
}
}
static void
init_functions(IO_CACHE* info)
{
enum cache_type type= info->type;
switch (type) {
case READ_NET:
/*
@ -96,17 +127,7 @@ init_functions(IO_CACHE* info, enum cache_type type)
info->write_function = _my_b_write;
}
/* Ensure that my_b_tell() and my_b_bytes_in_cache works */
if (type == WRITE_CACHE)
{
info->current_pos= &info->write_pos;
info->current_end= &info->write_end;
}
else
{
info->current_pos= &info->read_pos;
info->current_end= &info->read_end;
}
setup_io_cache(info);
}
@ -236,7 +257,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
info->end_of_file= end_of_file;
info->error=0;
info->type= type;
init_functions(info,type);
init_functions(info);
#ifdef HAVE_AIOWAIT
if (use_async_io && ! my_disable_async_io)
{
@ -339,7 +360,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
if (info->type == WRITE_CACHE && type == READ_CACHE)
info->end_of_file=my_b_tell(info);
/* flush cache if we want to reuse it */
if (!clear_cache && flush_io_cache(info))
if (!clear_cache && my_b_flush_io_cache(info,1))
DBUG_RETURN(1);
info->pos_in_file=seek_offset;
/* Better to do always do a seek */
@ -358,7 +379,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
}
info->type=type;
info->error=0;
init_functions(info,type);
init_functions(info);
#ifdef HAVE_AIOWAIT
if (use_async_io && ! my_disable_async_io &&
@ -948,7 +969,7 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count)
Buffer+=rest_length;
Count-=rest_length;
info->write_pos+=rest_length;
if (flush_io_cache(info))
if (my_b_flush_io_cache(info,1))
return 1;
if (Count >= IO_SIZE)
{ /* Fill first intern buffer */
@ -1191,6 +1212,7 @@ int end_io_cache(IO_CACHE *info)
int error=0;
IO_CACHE_CALLBACK pre_close;
DBUG_ENTER("end_io_cache");
DBUG_PRINT("enter",("cache: 0x%lx", (ulong) info));
#ifdef THREAD
/*
@ -1200,7 +1222,7 @@ int end_io_cache(IO_CACHE *info)
*/
if (info->share)
{
pthread_cond_destroy (&info->share->cond);
pthread_cond_destroy(&info->share->cond);
pthread_mutex_destroy(&info->share->mutex);
info->share=0;
}
@ -1215,7 +1237,7 @@ int end_io_cache(IO_CACHE *info)
{
info->alloced_buffer=0;
if (info->file != -1) /* File doesn't exist */
error=flush_io_cache(info);
error= my_b_flush_io_cache(info,1);
my_free((gptr) info->buffer,MYF(MY_WME));
info->buffer=info->read_pos=(byte*) 0;
}

View file

@ -245,6 +245,19 @@ static inline void mark_blocks_free(MEM_ROOT* root)
/*
Deallocate everything used by alloc_root or just move
used blocks to free list if called with MY_USED_TO_FREE
SYNOPSIS
free_root()
root Memory root
MyFlags Flags for what should be freed:
MY_MARK_BLOCKS_FREED Don't free blocks, just mark them free
MY_KEEP_PREALLOC If this is not set, then free also the
preallocated block
NOTES
One can call this function either with root block initialised with
init_alloc_root() or with a bzero()-ed block.
*/
void free_root(MEM_ROOT *root, myf MyFlags)

View file

@ -523,8 +523,10 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type)
data->prev=lock->write_wait.last;
lock->write_wait.last= &data->next;
data->cond=get_cond();
if (lock->get_status)
(*lock->get_status)(data->status_param);
/*
We don't have to do get_status here as we will do it when we change
the delayed lock to a real write lock
*/
statistic_increment(locks_immediate,&THR_LOCK_lock);
goto end;
}

View file

@ -1035,7 +1035,9 @@ int Field_decimal::store(longlong nr)
double Field_decimal::val_real(void)
{
int not_used;
return my_strntod(&my_charset_bin, ptr, field_length, NULL, &not_used);
char *end_not_used;
return my_strntod(&my_charset_bin, ptr, field_length, &end_not_used,
&not_used);
}
longlong Field_decimal::val_int(void)
@ -4432,16 +4434,18 @@ int Field_string::store(longlong nr)
double Field_string::val_real(void)
{
int not_used;
CHARSET_INFO *cs=charset();
return my_strntod(cs,ptr,field_length,(char**)0,&not_used);
char *end_not_used;
CHARSET_INFO *cs= charset();
return my_strntod(cs,ptr,field_length,&end_not_used,&not_used);
}
longlong Field_string::val_int(void)
{
int not_used;
char *end_not_used;
CHARSET_INFO *cs=charset();
return my_strntoll(cs,ptr,field_length,10,NULL,&not_used);
return my_strntoll(cs,ptr,field_length,10,&end_not_used,&not_used);
}
@ -4740,8 +4744,9 @@ int Field_varstring::store(longlong nr)
double Field_varstring::val_real(void)
{
int not_used;
char *end_not_used;
uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr);
return my_strntod(field_charset, ptr+length_bytes, length, (char**) 0,
return my_strntod(field_charset, ptr+length_bytes, length, &end_not_used,
&not_used);
}
@ -4749,9 +4754,10 @@ double Field_varstring::val_real(void)
longlong Field_varstring::val_int(void)
{
int not_used;
char *end_not_used;
uint length= length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr);
return my_strntoll(field_charset, ptr+length_bytes, length, 10, NULL,
&not_used);
return my_strntoll(field_charset, ptr+length_bytes, length, 10,
&end_not_used, &not_used);
}
@ -5343,13 +5349,16 @@ int Field_blob::store(longlong nr)
double Field_blob::val_real(void)
{
int not_used;
char *blob;
char *end_not_used, *blob;
uint32 length;
CHARSET_INFO *cs;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
return 0.0;
uint32 length=get_length(ptr);
CHARSET_INFO *cs=charset();
return my_strntod(cs,blob,length,(char**)0, &not_used);
length= get_length(ptr);
cs= charset();
return my_strntod(cs, blob, length, &end_not_used, &not_used);
}
@ -6353,11 +6362,13 @@ longlong Field_bit::val_int(void)
String *Field_bit::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
char buff[sizeof(longlong)];
uint length= min(pack_length(), sizeof(longlong));
ulonglong bits= val_int();
mi_int8store(buff,bits);
val_buffer->alloc(length);
memcpy_fixed((char*) val_buffer->ptr(), (char*) &bits, length);
memcpy_fixed((char*) val_buffer->ptr(), buff+8-length, length);
val_buffer->length(length);
val_buffer->set_charset(&my_charset_bin);
return val_buffer;

View file

@ -567,10 +567,10 @@ write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
if (!my_b_inited(tempfile) &&
open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
MYF(MY_WME)))
goto err; /* purecov: inspected */
goto err; /* purecov: inspected */
buffpek.file_pos= my_b_tell(tempfile);
if ((ha_rows) count > param->max_rows)
count=(uint) param->max_rows; /* purecov: inspected */
count=(uint) param->max_rows; /* purecov: inspected */
buffpek.count=(ha_rows) count;
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
if (my_b_write(tempfile, (byte*) *sort_keys, (uint) rec_length))
@ -841,6 +841,8 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
if (flush_io_cache(to_file))
break; /* purecov: inspected */
temp=from_file; from_file=to_file; to_file=temp;
setup_io_cache(from_file);
setup_io_cache(to_file);
*maxbuffer= (uint) (lastbuff-buffpek)-1;
}
close_cached_file(to_file); // This holds old result
@ -1173,7 +1175,12 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
else
{
sortorder->length=sortorder->field->pack_length();
if (use_strnxfrm((cs=sortorder->field->charset())))
/*
We must test cmp_type() to ensure that ENUM and SET are sorted
as numbers
*/
if (use_strnxfrm((cs=sortorder->field->charset())) &&
sortorder->field->cmp_type() == STRING_RESULT)
{
sortorder->need_strxnfrm= 1;
*multi_byte_charset= 1;

View file

@ -471,12 +471,24 @@ int ha_heap::create(const char *name, TABLE *table_arg,
KEY_PART_INFO *key_part= pos->key_part;
KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
mem_per_row+= (pos->key_length + (sizeof(char*) * 2));
keydef[key].keysegs= (uint) pos->key_parts;
keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
keydef[key].seg= seg;
keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ?
switch (pos->algorithm) {
case HA_KEY_ALG_UNDEF:
case HA_KEY_ALG_HASH:
keydef[key].algorithm= HA_KEY_ALG_HASH;
mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
break;
case HA_KEY_ALG_BTREE:
keydef[key].algorithm= HA_KEY_ALG_BTREE;
mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
break;
default:
DBUG_ASSERT(0); // cannot happen
}
keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ?
HA_KEY_ALG_HASH : pos->algorithm);
for (; key_part != key_part_end; key_part++, seg++)
@ -525,8 +537,10 @@ int ha_heap::create(const char *name, TABLE *table_arg,
hp_create_info.auto_key_type= auto_key_type;
hp_create_info.auto_increment= (create_info->auto_increment_value ?
create_info->auto_increment_value - 1 : 0);
hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row);
error= heap_create(fn_format(buff,name,"","",4+2),
keys,keydef, share->reclength,
keys, keydef, share->reclength,
(ulong) ((share->max_rows < max_rows &&
share->max_rows) ?
share->max_rows : max_rows),

View file

@ -32,7 +32,11 @@ class ha_heap: public handler
public:
ha_heap(TABLE *table): handler(table), file(0), records_changed(0) {}
~ha_heap() {}
const char *table_type() const { return "HEAP"; }
const char *table_type() const
{
return (table->in_use->variables.sql_mode & MODE_MYSQL323) ?
"HEAP" : "MEMORY";
}
const char *index_type(uint inx)
{
return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? "BTREE" :

View file

@ -2425,6 +2425,8 @@ build_template(
templ->mysql_col_len = (ulint) field->pack_length();
templ->type = get_innobase_type_from_mysql_type(field);
templ->charset = dtype_get_charset_coll_noninline(
index->table->cols[i].type.prtype);
templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG);
if (templ->type == DATA_BLOB) {

View file

@ -1290,11 +1290,12 @@ double Item_param::val_real()
return (double) value.integer;
case STRING_VALUE:
case LONG_DATA_VALUE:
{
int dummy_err;
return my_strntod(str_value.charset(), (char*) str_value.ptr(),
str_value.length(), (char**) 0, &dummy_err);
}
{
int dummy_err;
char *end_not_used;
return my_strntod(str_value.charset(), (char*) str_value.ptr(),
str_value.length(), &end_not_used, &dummy_err);
}
case TIME_VALUE:
/*
This works for example when user says SELECT ?+0.0 and supplies
@ -2545,8 +2546,9 @@ Item_num *Item_uint::neg()
Item_real::Item_real(const char *str_arg, uint length)
{
int error;
char *end;
value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end, &error);
char *end_not_used;
value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used,
&error);
if (error)
{
/*
@ -3522,12 +3524,12 @@ void Item_cache_str::store(Item *item)
double Item_cache_str::val_real()
{
DBUG_ASSERT(fixed == 1);
int err;
int err_not_used;
char *end_not_used;
if (value)
return my_strntod(value->charset(), (char*) value->ptr(),
value->length(), (char**) 0, &err);
else
return (double)0;
value->length(), &end_not_used, &err_not_used);
return (double) 0;
}

View file

@ -877,9 +877,10 @@ public:
double val_real()
{
DBUG_ASSERT(fixed == 1);
int err;
int err_not_used;
char *end_not_used;
return my_strntod(str_value.charset(), (char*) str_value.ptr(),
str_value.length(), (char**) 0, &err);
str_value.length(), &end_not_used, &err_not_used);
}
longlong val_int()
{
@ -1230,10 +1231,11 @@ public:
enum_field_types field_type() const { return cached_field_type; }
double val_real()
{
int err;
int err_not_used;
char *end_not_used;
return (null_value ? 0.0 :
my_strntod(str_value.charset(), (char*) str_value.ptr(),
str_value.length(),NULL,&err));
str_value.length(), &end_not_used, &err_not_used));
}
longlong val_int()
{

View file

@ -834,15 +834,19 @@ public:
String *val_str(String *);
double val_real()
{
int err;
String *res; res=val_str(&str_value);
return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0,&err) : 0.0;
int err_not_used;
char *end_not_used;
String *res;
res= val_str(&str_value);
return res ? my_strntod(res->charset(),(char*) res->ptr(),
res->length(), &end_not_used, &err_not_used) : 0.0;
}
longlong val_int()
{
int err;
int err_not_used;
String *res; res=val_str(&str_value);
return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,(char**) 0,&err) : (longlong) 0;
return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
(char**) 0, &err_not_used) : (longlong) 0;
}
enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec();

View file

@ -58,17 +58,19 @@ uint nr_of_decimals(const char *str)
return 0;
}
double Item_str_func::val_real()
{
DBUG_ASSERT(fixed == 1);
int err;
char buff[64];
int err_not_used;
char *end_not_used, buff[64];
String *res, tmp(buff,sizeof(buff), &my_charset_bin);
res= val_str(&tmp);
return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(),
NULL, &err) : 0.0;
return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
&end_not_used, &err_not_used) : 0.0;
}
longlong Item_str_func::val_int()
{
DBUG_ASSERT(fixed == 1);

View file

@ -591,14 +591,17 @@ void Item_sum_hybrid::clear()
double Item_sum_hybrid::val_real()
{
DBUG_ASSERT(fixed == 1);
int err;
if (null_value)
return 0.0;
switch (hybrid_type) {
case STRING_RESULT:
{
char *end_not_used;
int err_not_used;
String *res; res=val_str(&str_value);
return (res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(),
(char**) 0, &err) : 0.0);
return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
&end_not_used, &err_not_used) : 0.0);
}
case INT_RESULT:
if (unsigned_flag)
return ulonglong2double(sum_int);

View file

@ -643,16 +643,18 @@ public:
String *val_str(String *);
double val_real()
{
int err;
int err_not_used;
char *end_not_used;
String *res; res=val_str(&str_value);
return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
(char**) 0, &err) : 0.0;
&end_not_used, &err_not_used) : 0.0;
}
longlong val_int()
{
int err;
int err_not_used;
String *res; res=val_str(&str_value);
return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, (char**) 0, &err) : (longlong) 0;
return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
(char**) 0, &err_not_used) : (longlong) 0;
}
enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec();
@ -783,9 +785,10 @@ class Item_func_group_concat : public Item_sum
String *res;
char *end_ptr;
int error;
res= val_str(&str_value);
if (!(res= val_str(&str_value)))
return (longlong) 0;
end_ptr= (char*) res->ptr()+ res->length();
return res ? my_strtoll10(res->ptr(), &end_ptr, &error) : (longlong) 0;
return my_strtoll10(res->ptr(), &end_ptr, &error);
}
String* val_str(String* str);
Item *copy_or_same(THD* thd);

View file

@ -2441,36 +2441,37 @@ void Item_func_add_time::print(String *str)
/*
Calculate difference between two datetime values as seconds + microseconds.
SYNOPSIS
calc_time_diff()
l_time1 TIME/DATE/DATETIME value
l_time2 TIME/DATE/DATETIME value
l_sign Can be 1 (operation of addition)
or -1 (substraction)
seconds_out Returns count of seconds bitween
l_time1 and l_time2
microseconds_out Returns count of microseconds bitween
l_time1 and l_time2.
l_time1 - TIME/DATE/DATETIME value
l_time2 - TIME/DATE/DATETIME value
l_sign - 1 absolute values are substracted,
-1 absolute values are added.
seconds_out - Out parameter where difference between
l_time1 and l_time2 in seconds is stored.
microseconds_out- Out parameter where microsecond part of difference
between l_time1 and l_time2 is stored.
DESCRIPTION
Calculates difference in seconds(seconds_out)
and microseconds(microseconds_out)
bitween two TIME/DATE/DATETIME values.
NOTE
This function calculates difference between l_time1 and l_time2 absolute
values. So one should set l_sign and correct result if he want to take
signs into account (i.e. for TIME values).
RETURN VALUES
Rertuns sign of difference.
Returns sign of difference.
1 means negative result
0 means positive result
*/
bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign,
longlong *seconds_out, long *microseconds_out)
static bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign,
longlong *seconds_out, long *microseconds_out)
{
long days;
bool neg;
longlong seconds= *seconds_out;
long microseconds= *microseconds_out;
longlong microseconds;
/*
We suppose that if first argument is MYSQL_TIMESTAMP_TIME
@ -2487,29 +2488,20 @@ bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign,
(uint) l_time2->month,
(uint) l_time2->day));
microseconds= l_time1->second_part - l_sign*l_time2->second_part;
seconds= ((longlong) days*86400L + l_time1->hour*3600L +
l_time1->minute*60L + l_time1->second + microseconds/1000000L -
(longlong)l_sign*(l_time2->hour*3600L+l_time2->minute*60L+l_time2->second));
microseconds= ((longlong)days*86400L +
l_time1->hour*3600L + l_time1->minute*60L + l_time1->second -
(longlong)l_sign*(l_time2->hour*3600L + l_time2->minute*60L +
l_time2->second))*1000000L +
l_time1->second_part - l_sign*l_time2->second_part;
neg= 0;
if (seconds < 0)
{
seconds= -seconds;
neg= 1;
}
else if (seconds == 0 && microseconds < 0)
if (microseconds < 0)
{
microseconds= -microseconds;
neg= 1;
}
if (microseconds < 0)
{
microseconds+= 1000000L;
seconds--;
}
*seconds_out= seconds;
*microseconds_out= microseconds;
*seconds_out= microseconds/1000000L;
*microseconds_out= (long) (microseconds%1000000L);
return neg;
}
@ -2544,9 +2536,10 @@ String *Item_func_timediff::val_str(String *str)
/*
For MYSQL_TIMESTAMP_TIME only:
If both argumets are negative values and diff between them
is negative we need to swap sign as result should be positive.
is non-zero we need to swap sign to get proper result.
*/
if ((l_time2.neg == l_time1.neg) && l_time1.neg)
if ((l_time2.neg == l_time1.neg) && l_time1.neg &&
(seconds || microseconds))
l_time3.neg= 1-l_time3.neg; // Swap sign of result
calc_time_from_sec(&l_time3, (long) seconds, microseconds);
@ -2712,13 +2705,11 @@ longlong Item_func_timestamp_diff::val_int()
case INTERVAL_SECOND:
return seconds*neg;
case INTERVAL_MICROSECOND:
{
longlong max_sec= LONGLONG_MAX/1000000;
if (max_sec > seconds ||
max_sec == seconds && LONGLONG_MAX%1000000 >= microseconds)
return (longlong) (seconds*1000000L+microseconds)*neg;
goto null_date;
}
/*
In MySQL difference between any two valid datetime values
in microseconds fits into longlong.
*/
return (seconds*1000000L+microseconds)*neg;
default:
break;
}

View file

@ -831,6 +831,7 @@ void wait_for_refresh(THD *thd);
int open_tables(THD *thd, TABLE_LIST *tables, uint *counter);
int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables);
bool open_and_lock_tables(THD *thd,TABLE_LIST *tables);
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables);
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter);
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
const char *table_name, bool link_in_list);

View file

@ -59,10 +59,18 @@ public:
void set(double nr) { value=nr; }
void set(longlong nr) { value=(double) nr; }
void set(const char *str,uint length,CHARSET_INFO *cs)
{ int err; value=my_strntod(cs,(char*) str,length,(char**)0,&err); }
{
int err_not_used;
char *end_not_used;
value= my_strntod(cs,(char*) str,length, &end_not_used, &err_not_used);
}
double val_real() { return value; }
longlong val_int() { return (longlong) value; }
String *val_str(String *s) { s->set(value,decimals,default_charset()); return s; }
String *val_str(String *s)
{
s->set(value,decimals,default_charset());
return s;
}
unsigned int size_of() { return sizeof(*this);}
};
@ -98,10 +106,11 @@ public:
{ str_value.copy(str,length,cs); }
double val_real()
{
int err;
int err_not_used;
char *end_not_used;
CHARSET_INFO *cs=str_value.charset();
return my_strntod(cs, (char*) str_value.ptr(), str_value.length(),
(char**) 0, &err);
&end_not_used, &err_not_used);
}
longlong val_int()
{

View file

@ -1853,8 +1853,8 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
{
DBUG_ENTER("open_and_lock_tables");
uint counter;
DBUG_ENTER("open_and_lock_tables");
if (open_tables(thd, tables, &counter) ||
lock_tables(thd, tables, counter) ||
mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
@ -1866,6 +1866,36 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
}
/*
Open all tables in list and process derived tables
SYNOPSIS
open_normal_and_derived_tables
thd - thread handler
tables - list of tables for open&locking
RETURN
FALSE - ok
TRUE - error
NOTE
This is to be used on prepare stage when you don't read any
data from the tables.
*/
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables)
{
uint counter;
DBUG_ENTER("open_normal_and_derived_tables");
DBUG_ASSERT(!thd->fill_derived_tables());
if (open_tables(thd, tables, &counter) ||
mysql_handle_derived(thd->lex, &mysql_derived_prepare))
DBUG_RETURN(TRUE); /* purecov: inspected */
relink_tables_for_multidelete(thd); // Not really needed, but
DBUG_RETURN(0);
}
/*
Let us propagate pointers to open tables from global table list
to table lists for multi-delete

View file

@ -900,8 +900,12 @@ static bool mysql_test_insert(Prepared_statement *stmt,
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
Note that this is done without locks (should not be needed as we will not
access any data here)
If we would use locks, then we have to ensure we are not using
TL_WRITE_DELAYED as having two such locks can cause table corruption.
*/
if (open_and_lock_tables(thd, table_list))
if (open_normal_and_derived_tables(thd, table_list))
{
DBUG_RETURN(TRUE);
}

View file

@ -7823,12 +7823,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
sprintf(filename, "%s_%lx_%i", tmp_file_prefix,
current_pid, temp_pool_slot);
else // if we run out of slots or we are not using tempool
else
{
/* if we run out of slots or we are not using tempool */
sprintf(filename,"%s%lx_%lx_%x",tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
}
if (lower_case_table_names)
my_casedn_str(files_charset_info, path);
/*
No need for change table name to lower case as we are only creating
MyISAM or HEAP tables here
*/
sprintf(path, "%s%s", mysql_tmpdir, filename);
if (group)

View file

@ -948,11 +948,12 @@ frm_type_enum mysql_frm_type(char *path)
{
DBUG_RETURN(FRMTYPE_ERROR);
}
length= my_read(file, (byte*) header, 10, MYF(MY_WME));
length= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME));
my_close(file, MYF(MY_WME));
if (length == (int) MY_FILE_ERROR)
DBUG_RETURN(FRMTYPE_ERROR);
if (!strncmp(header, "TYPE=VIEW\n", 10))
if (length < (int) sizeof(header) ||
!strncmp(header, "TYPE=VIEW\n", sizeof(header)))
DBUG_RETURN(FRMTYPE_VIEW);
DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table
}

View file

@ -2793,7 +2793,7 @@ type:
| YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; }
| DATE_SYM { $$=FIELD_TYPE_DATE; }
| TIME_SYM { $$=FIELD_TYPE_TIME; }
| TIMESTAMP
| TIMESTAMP opt_len
{
if (YYTHD->variables.sql_mode & MODE_MAXDB)
$$=FIELD_TYPE_DATETIME;
@ -2806,13 +2806,6 @@ type:
$$=FIELD_TYPE_TIMESTAMP;
}
}
| TIMESTAMP '(' NUM ')'
{
LEX *lex= Lex;
lex->length= $3.str;
lex->type|= NOT_NULL_FLAG;
$$= FIELD_TYPE_TIMESTAMP;
}
| DATETIME { $$=FIELD_TYPE_DATETIME; }
| TINYBLOB { Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_TINY_BLOB; }

View file

@ -103,11 +103,11 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
O_RDONLY | O_SHARE,
MYF(0)))
< 0)
goto err_w_init;
goto err;
error= 4;
if (my_read(file,(byte*) head,64,MYF(MY_NABP)))
goto err_w_init;
goto err;
if (memcmp(head, "TYPE=", 5) == 0)
{
@ -116,9 +116,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if (db_stat & NO_ERR_ON_NEW_FRM)
DBUG_RETURN(5);
file= -1;
// caller can't process new .frm
goto err_w_init;
goto err;
}
share->blob_ptr_size= sizeof(char*);
@ -131,21 +131,21 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
share->path= strdup_root(&outparam->mem_root, name);
outparam->alias= my_strdup(alias, MYF(MY_WME));
if (!share->table_name || !share->path || !outparam->alias)
goto err_not_open;
goto err;
*fn_ext(share->table_name)='\0'; // Remove extension
*fn_ext(share->path)='\0'; // Remove extension
if (head[0] != (uchar) 254 || head[1] != 1 ||
(head[2] != FRM_VER && head[2] != FRM_VER+1 &&
! (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4)))
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
new_field_pack_flag=head[27];
new_frm_ver= (head[2] - FRM_VER);
field_pack_length= new_frm_ver < 2 ? 11 : 17;
error=3;
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
*fn_ext(index_file)='\0'; // Remove .frm extension
share->frm_version= head[2];
@ -181,7 +181,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
key_info_length= (uint) uint2korr(head+28);
VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
if (read_string(file,(gptr*) &disk_buff,key_info_length))
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
if (disk_buff[0] & 0x80)
{
share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
@ -201,7 +201,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
if (!(keyinfo = (KEY*) alloc_root(&outparam->mem_root,
n_length+uint2korr(disk_buff+4))))
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
bzero((char*) keyinfo,n_length);
outparam->key_info=keyinfo;
key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
@ -210,7 +210,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
ulong *rec_per_key;
if (!(rec_per_key= (ulong*) alloc_root(&outparam->mem_root,
sizeof(ulong*)*key_parts)))
goto err_not_open;
goto err;
for (i=0 ; i < keys ; i++, keyinfo++)
{
@ -279,7 +279,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
/* Allocate handler */
if (!(outparam->file= get_new_handler(outparam, share->db_type)))
goto err_not_open;
goto err;
error=4;
outparam->reginfo.lock_type= TL_UNLOCK;
@ -296,14 +296,14 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
share->rec_buff_length= rec_buff_length;
if (!(record= (char *) alloc_root(&outparam->mem_root,
rec_buff_length * records)))
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
share->default_values= record;
if (my_pread(file,(byte*) record, (uint) share->reclength,
(ulong) (uint2korr(head+6)+
((uint2korr(head+14) == 0xffff ?
uint4korr(head+47) : uint2korr(head+14)))),
MYF(MY_NABP)))
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
if (records == 1)
{
@ -332,12 +332,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
}
#endif
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open;
if (my_read(file,(byte*) head,288,MYF(MY_NABP)))
goto err;
if (crypted)
{
crypted->decode((char*) head+256,288-256);
if (sint2korr(head+284) != 0) // Should be 0
goto err_not_open; // Wrong password
goto err; // Wrong password
}
share->fields= uint2korr(head+258);
@ -359,13 +360,13 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
(share->fields+interval_parts+
keys+3)*sizeof(my_string)+
(n_length+int_length+com_length)))))
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
outparam->field=field_ptr;
read_length=(uint) (share->fields * field_pack_length +
pos+ (uint) (n_length+int_length+com_length));
if (read_string(file,(gptr*) &disk_buff,read_length))
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
if (crypted)
{
crypted->decode((char*) disk_buff,read_length);
@ -398,7 +399,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
uint count= (uint) (interval->count + 1) * sizeof(uint);
if (!(interval->type_lengths= (uint *) alloc_root(&outparam->mem_root,
count)))
goto err_not_open;
goto err;
for (count= 0; count < interval->count; count++)
interval->type_lengths[count]= strlen(interval->type_names[count]);
interval->type_lengths[count]= 0;
@ -459,7 +460,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
charset= &my_charset_bin;
#else
error= 4; // unsupported field type
goto err_not_open;
goto err;
#endif
}
else
@ -470,7 +471,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
{
error= 5; // Unknown or unavailable charset
errarg= (int) strpos[14];
goto err_not_open;
goto err;
}
}
if (!comment_length)
@ -543,7 +544,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if (!reg_field) // Not supported field type
{
error= 4;
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
}
reg_field->comment=comment;
if (field_type == FIELD_TYPE_BIT)
@ -616,7 +617,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
(uint) key_part->length);
#ifdef EXTRA_DEBUG
if (key_part->fieldnr > share->fields)
goto err_not_open; // sanity check
goto err; // sanity check
#endif
if (key_part->fieldnr)
{ // Should always be true !
@ -767,7 +768,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if (!(share->blob_field= save=
(uint*) alloc_root(&outparam->mem_root,
(uint) (share->blob_fields* sizeof(uint)))))
goto err_not_open;
goto err;
for (i=0, ptr= outparam->field ; *ptr ; ptr++, i++)
{
if ((*ptr)->flags & BLOB_FLAG)
@ -779,25 +780,25 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
error=2;
if (db_stat)
{
int err;
int ha_err;
unpack_filename(index_file,index_file);
if ((err=(outparam->file->
ha_open(index_file,
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
((db_stat & HA_WAIT_IF_LOCKED) ||
(specialflag & SPECIAL_WAIT_IF_LOCKED)) ?
HA_OPEN_WAIT_IF_LOCKED :
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
HA_OPEN_ABORT_IF_LOCKED :
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
if ((ha_err= (outparam->file->
ha_open(index_file,
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
((db_stat & HA_WAIT_IF_LOCKED) ||
(specialflag & SPECIAL_WAIT_IF_LOCKED)) ?
HA_OPEN_WAIT_IF_LOCKED :
(db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
HA_OPEN_ABORT_IF_LOCKED :
HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
{
/* Set a flag if the table is crashed and it can be auto. repaired */
share->crashed= ((err == HA_ERR_CRASHED_ON_USAGE) &&
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
outparam->file->auto_repair() &&
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
if (err == HA_ERR_NO_SUCH_TABLE)
if (ha_err == HA_ERR_NO_SUCH_TABLE)
{
/* The table did not exists in storage engine, use same error message
as if the .frm file didn't exist */
@ -806,10 +807,10 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
}
else
{
outparam->file->print_error(err, MYF(0));
outparam->file->print_error(ha_err, MYF(0));
error_reported= TRUE;
}
goto err_not_open; /* purecov: inspected */
goto err; /* purecov: inspected */
}
}
share->db_low_byte_first= outparam->file->low_byte_first();
@ -822,15 +823,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
#endif
DBUG_RETURN (0);
err_w_init:
/*
Avoid problem with uninitialized data
Note that we don't have to initialize outparam->s here becasue
the caller will check if the pointer exists in case of errors
*/
bzero((char*) outparam,sizeof(*outparam));
err_not_open:
err:
x_free((gptr) disk_buff);
if (file > 0)
VOID(my_close(file,MYF(MY_WME)));
@ -843,7 +836,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
outparam->file=0; // For easier errorchecking
outparam->db_stat=0;
hash_free(&share->name_hash);
free_root(&outparam->mem_root, MYF(0));
free_root(&outparam->mem_root, MYF(0)); // Safe to call on bzero'd root
my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN (error);
} /* openfrm */

View file

@ -243,9 +243,10 @@ static int my_strnncoll_cp932(CHARSET_INFO *cs __attribute__((unused)),
static int my_strnncollsp_cp932(CHARSET_INFO *cs __attribute__((unused)),
const uchar *a, uint a_length,
const uchar *b, uint b_length,
my_bool diff_end_space __attribute__((unused)))
const uchar *a, uint a_length,
const uchar *b, uint b_length,
my_bool diff_if_only_endspace_difference
__attribute__((unused)))
{
const uchar *a_end= a + a_length;
const uchar *b_end= b + b_length;

View file

@ -791,31 +791,10 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *str, uint length,
char **end, int *err)
{
char end_char;
double result;
errno= 0; /* Safety */
/*
The following define is to avoid warnings from valgrind as str[length]
may not be defined (which is not fatal in real life)
*/
#ifdef HAVE_purify
if (length == INT_MAX32)
#else
if (length == INT_MAX32 || str[length] == 0)
#endif
result= my_strtod(str, end);
else
{
end_char= str[length];
str[length]= 0;
result= my_strtod(str, end);
str[length]= end_char; /* Restore end char */
}
*err= errno;
return result;
length= 65535; /* Should be big enough */
*end= str + length;
return my_strtod(str, end, err);
}

View file

@ -926,15 +926,16 @@ bs:
return (negative ? -((longlong) res) : (longlong) res);
}
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
char *nptr, uint length,
char **endptr, int *err)
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
char *nptr, uint length,
char **endptr, int *err)
{
char buf[256];
double res;
register char *b=buf;
register const uchar *s= (const uchar*) nptr;
register const uchar *end;
const uchar *end;
my_wc_t wc;
int cnv;
@ -951,13 +952,10 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
break; /* Can't be part of double */
*b++= (char) wc;
}
*b= 0;
errno= 0;
res=my_strtod(buf, endptr);
*err= errno;
if (endptr)
*endptr=(char*) (*endptr-buf+nptr);
*endptr= b;
res= my_strtod(buf, endptr, err);
*endptr= nptr + (uint) (*endptr- buf);
return res;
}

View file

@ -2,7 +2,7 @@
An alternative implementation of "strtod()" that is both
simplier, and thread-safe.
From mit-threads as bundled with MySQL 3.23
Original code from mit-threads as bundled with MySQL 3.23
SQL:2003 specifies a number as
@ -29,6 +29,8 @@
#include "my_base.h" /* Includes errno.h */
#include "m_ctype.h"
#define MAX_DBL_EXP 308
#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232
static double scaler10[] = {
1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
};
@ -37,89 +39,154 @@ static double scaler1[] = {
};
double my_strtod(const char *str, char **end)
/*
Convert string to double (string doesn't have to be null terminated)
SYNOPSIS
my_strtod()
str String to convert
end_ptr Pointer to pointer that points to end of string
Will be updated to point to end of double.
error Will contain error number in case of error (else 0)
RETURN
value of str as double
*/
double my_strtod(const char *str, char **end_ptr, int *error)
{
double result= 0.0;
int negative, ndigits;
const char *old_str;
uint negative= 0, ndigits, dec_digits= 0, pre_zero, neg_exp= 0;
int exp= 0;
const char *old_str, *end= *end_ptr, *start_of_number;
char next_char;
my_bool overflow=0;
while (my_isspace(&my_charset_latin1, *str))
str++;
*error= 0;
if (str >= end)
goto done;
while (my_isspace(&my_charset_latin1, *str))
{
if (++str == end)
goto done;
}
start_of_number= str;
if ((negative= (*str == '-')) || *str=='+')
str++;
{
if (++str == end)
goto done; /* Could be changed to error */
}
/* Skip pre-zero for easier calculation of overflows */
while (*str == '0')
{
if (++str == end)
goto done;
start_of_number= 0; /* Found digit */
}
old_str= str;
while (my_isdigit (&my_charset_latin1, *str))
while ((next_char= *str) >= '0' && next_char <= '9')
{
result= result*10.0 + (*str - '0');
str++;
}
ndigits= str-old_str;
if (*str == '.')
{
double p10=10;
str++;
old_str= str;
while (my_isdigit (&my_charset_latin1, *str))
result= result*10.0 + (next_char - '0');
if (++str == end)
{
result+= (*str++ - '0')/p10;
p10*=10;
next_char= 0; /* Found end of string */
break;
}
ndigits+= str-old_str;
if (!ndigits) str--;
start_of_number= 0; /* Found digit */
}
if (ndigits && (*str=='e' || *str=='E'))
ndigits= (uint) (str-old_str);
pre_zero= 0;
if (next_char == '.' && str < end-1)
{
double p10= 10;
old_str= ++str;
while (my_isdigit(&my_charset_latin1, (next_char= *str)))
{
result+= (next_char - '0')/p10;
if (!result)
pre_zero++;
else
p10*= 10;
if (++str == end)
{
next_char= 0;
break;
}
}
/* If we found just '+.' or '.' then point at first character */
if (!(dec_digits= (uint) (str-old_str)) && start_of_number)
str= start_of_number; /* Point at '+' or '.' */
}
if ((next_char == 'e' || next_char == 'E') &&
dec_digits + ndigits != 0 && str < end-1)
{
int exp= 0;
int neg= 0;
const char *old_str= str++;
if ((neg= (*str == '-')) || *str == '+')
if ((neg_exp= (*str == '-')) || *str == '+')
str++;
if (!my_isdigit (&my_charset_latin1, *str))
if (str == end || !my_isdigit(&my_charset_latin1, *str))
str= old_str;
else
{
double scaler= 1.0;
while (my_isdigit (&my_charset_latin1, *str))
do
{
if (exp < 9999) /* protection against exp overflow */
if (exp < 9999) /* protec against exp overfl. */
exp= exp*10 + *str - '0';
str++;
}
if (exp >= 1000)
} while (str < end && my_isdigit(&my_charset_latin1, *str));
}
}
if ((exp= neg_exp ? exp + pre_zero : exp - pre_zero))
{
double scaler;
if (exp < 0)
{
exp= -exp;
neg_exp= 1; /* neg_exp was 0 before */
}
if (exp + ndigits >= MAX_DBL_EXP + 1 && result)
{
/*
This is not 100 % as we actually will give an owerflow for
17E307 but not for 1.7E308 but lets cut some corners to make life
simpler
*/
if (exp + ndigits > MAX_DBL_EXP + 1 ||
result >= MAX_RESULT_FOR_MAX_EXP)
{
if (neg)
result= 0.0;
else
if (neg_exp)
result= 0.0;
else
overflow= 1;
goto done;
}
while (exp >= 100)
{
scaler*= 1.0e100;
exp-= 100;
}
scaler*= scaler10[exp/10]*scaler1[exp%10];
if (neg)
result/= scaler;
else
result*= scaler;
}
scaler= 1.0;
while (exp >= 100)
{
scaler*= 1.0e100;
exp-= 100;
}
scaler*= scaler10[exp/10]*scaler1[exp%10];
if (neg_exp)
result/= scaler;
else
result*= scaler;
}
done:
if (end)
*end = (char *)str;
*end_ptr= (char*) str; /* end of number */
if (overflow || isinf(result))
{
result= DBL_MAX;
errno= EOVERFLOW;
*error= EOVERFLOW;
}
return negative ? -result : result;
@ -127,6 +194,7 @@ done:
double my_atof(const char *nptr)
{
return (my_strtod(nptr, 0));
int error;
const char *end= nptr+65535; /* Should be enough */
return (my_strtod(nptr, (char**) &end, &error));
}

View file

@ -27,7 +27,7 @@ Packager: Lenz Grimmer <build@mysql.com>
Vendor: MySQL AB
Requires: fileutils sh-utils
Provides: msqlormysql MySQL-server mysql
BuildPrereq: ncurses-devel
BuildRequires: ncurses-devel
Obsoletes: mysql
# Think about what you use here since the first step is to
@ -602,6 +602,10 @@ fi
# itself - note that they must be ordered by date (important when
# merging BK trees)
%changelog
* Fri Jan 14 2005 Lenz Grimmer <lenz@mysql.com>
- replaced obsoleted "BuildPrereq" with "BuildRequires" instead
* Thu Jan 13 2005 Lenz Grimmer <lenz@mysql.com>
- enabled the "Federated" storage engine for the max binary