Commit 4d5dcac3 authored by unknown's avatar unknown

Fixed bug when sorting big files (introduced with multi-table-delete)

Changed mysql-test to use --language
Cleaned up parameters to filesort()


configure.in:
  Fixed typo
mysql-test/install_test_db.sh:
  Changed test case to use --language
mysql-test/mysql-test-run.sh:
  Changed test case to use --language
  Fixed that test names are not 'cut'-ed.
mysql-test/r/select_found.result:
  Fixed test case to make it repeatable
mysql-test/t/insert.test:
  Added test of unique key handling
mysql-test/t/order_fill_sortbuf.test:
  Cleaned up test
mysql-test/t/select_found.test:
  Fixed test case to make it repeatable
sql/filesort.cc:
  Fixed bug when sorting big files (introduced with multi-table-delete)
  cleaned up parameters.
sql/mysql_priv.h:
  Cleaned up parameters to filesort()
sql/mysqld.cc:
  Fixed typo on enum
sql/sql_delete.cc:
  Cleanup
sql/sql_select.cc:
  Cleanup
sql/sql_table.cc:
  Cleanup
sql/sql_test.cc:
  Cleanup
sql/sql_update.cc:
  Cleanup
parent 157c1bc5
...@@ -403,7 +403,7 @@ AM_PROG_CC_STDC ...@@ -403,7 +403,7 @@ AM_PROG_CC_STDC
if test "$am_cv_prog_cc_stdc" = "no" if test "$am_cv_prog_cc_stdc" = "no"
then then
AC_MSG_ERROR([MySQL requiers a ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.]) AC_MSG_ERROR([MySQL requires a ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.])
fi fi
NOINST_LDFLAGS= NOINST_LDFLAGS=
......
...@@ -30,7 +30,7 @@ else ...@@ -30,7 +30,7 @@ else
fi fi
mdata=$data/mysql mdata=$data/mysql
EXTRA_ARG=""
if test ! -x $execdir/mysqld if test ! -x $execdir/mysqld
then then
...@@ -57,9 +57,7 @@ if [ x$BINARY_DIST = x1 ] ; then ...@@ -57,9 +57,7 @@ if [ x$BINARY_DIST = x1 ] ; then
basedir=.. basedir=..
else else
basedir=. basedir=.
rm -rf share EXTRA_ARG="--language=../sql/share/english/"
mkdir share
ln -sf ../../sql/share share/mysql
fi fi
# Initialize variables # Initialize variables
...@@ -193,7 +191,7 @@ then ...@@ -193,7 +191,7 @@ then
fi fi
if $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \ if $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \
--basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb --skip-gemini << END_OF_DATA --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb --skip-gemini $EXTRA_ARG << END_OF_DATA
use mysql; use mysql;
$c_d $c_d
$i_d $i_d
......
...@@ -260,6 +260,7 @@ if [ x$SOURCE_DIST = x1 ] ; then ...@@ -260,6 +260,7 @@ if [ x$SOURCE_DIST = x1 ] ; then
MYSQL_TEST="$BASEDIR/client/mysqltest" MYSQL_TEST="$BASEDIR/client/mysqltest"
MYSQLADMIN="$BASEDIR/client/mysqladmin" MYSQLADMIN="$BASEDIR/client/mysqladmin"
MYSQL="$BASEDIR/client/mysql" MYSQL="$BASEDIR/client/mysql"
LANGUAGE="$BASEDIR/sql/share/english/"
INSTALL_DB="./install_test_db" INSTALL_DB="./install_test_db"
else else
MYSQLD="$BASEDIR/bin/mysqld" MYSQLD="$BASEDIR/bin/mysqld"
...@@ -267,6 +268,12 @@ else ...@@ -267,6 +268,12 @@ else
MYSQLADMIN="$BASEDIR/bin/mysqladmin" MYSQLADMIN="$BASEDIR/bin/mysqladmin"
MYSQL="$BASEDIR/bin/mysql" MYSQL="$BASEDIR/bin/mysql"
INSTALL_DB="./install_test_db -bin" INSTALL_DB="./install_test_db -bin"
if test -d "$BASEDIR/share/mysql/english"
then
LANGUAGE="$BASEDIR/share/mysql/english/"
else
LANGUAGE="$BASEDIR/share/english/"
fi
fi fi
# If we should run all tests cases, we will use a local server for that # If we should run all tests cases, we will use a local server for that
...@@ -478,7 +485,7 @@ start_master() ...@@ -478,7 +485,7 @@ start_master()
--socket=$MASTER_MYSOCK \ --socket=$MASTER_MYSOCK \
--log=$MASTER_MYLOG --default-character-set=latin1 \ --log=$MASTER_MYLOG --default-character-set=latin1 \
--tmpdir=$MYSQL_TMP_DIR \ --tmpdir=$MYSQL_TMP_DIR \
--language=english \ --language=$LANGUAGE \
--innodb_data_file_path=ibdata1:50M \ --innodb_data_file_path=ibdata1:50M \
$SMALL_SERVER \ $SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT" $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
...@@ -492,7 +499,7 @@ start_master() ...@@ -492,7 +499,7 @@ start_master()
--default-character-set=latin1 \ --default-character-set=latin1 \
--core \ --core \
--tmpdir=$MYSQL_TMP_DIR \ --tmpdir=$MYSQL_TMP_DIR \
--language=english \ --language=$LANGUAGE \
--innodb_data_file_path=ibdata1:50M \ --innodb_data_file_path=ibdata1:50M \
$SMALL_SERVER \ $SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT" $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT"
...@@ -548,7 +555,7 @@ start_slave() ...@@ -548,7 +555,7 @@ start_slave()
--log=$SLAVE_MYLOG --default-character-set=latin1 \ --log=$SLAVE_MYLOG --default-character-set=latin1 \
--core \ --core \
--tmpdir=$MYSQL_TMP_DIR \ --tmpdir=$MYSQL_TMP_DIR \
--language=english \ --language=$LANGUAGE \
--skip-innodb --skip-slave-start \ --skip-innodb --skip-slave-start \
--report-host=127.0.0.1 --report-user=root \ --report-host=127.0.0.1 --report-user=root \
--report-port=$SLAVE_MYPORT \ --report-port=$SLAVE_MYPORT \
...@@ -674,7 +681,7 @@ run_testcase () ...@@ -674,7 +681,7 @@ run_testcase ()
SYST=" ...." SYST=" ...."
REALT=" ...." REALT=" ...."
timestr="$USERT $SYST $REALT" timestr="$USERT $SYST $REALT"
pname=`$ECHO "$tname "|$CUT -c 1-16` pname=`$ECHO "$tname "|$CUT -c 1-24`
RES="$pname $timestr" RES="$pname $timestr"
skip_inc skip_inc
$ECHO "$RES$RES_SPACE [ skipped ]" $ECHO "$RES$RES_SPACE [ skipped ]"
...@@ -755,7 +762,7 @@ run_testcase () ...@@ -755,7 +762,7 @@ run_testcase ()
fi fi
timestr="$USERT $SYST $REALT" timestr="$USERT $SYST $REALT"
pname=`$ECHO "$tname "|$CUT -c 1-16` pname=`$ECHO "$tname "|$CUT -c 1-24`
RES="$pname $timestr" RES="$pname $timestr"
if [ $res = 0 ]; then if [ $res = 0 ]; then
......
using_big_test
1
...@@ -22,7 +22,7 @@ b ...@@ -22,7 +22,7 @@ b
FOUND_ROWS() FOUND_ROWS()
6 6
b c b c
2 1 5 3
FOUND_ROWS() FOUND_ROWS()
6 6
a b a b a b a b
......
...@@ -10,3 +10,15 @@ insert into t1 values (a+3); ...@@ -10,3 +10,15 @@ insert into t1 values (a+3);
insert into t1 values (4),(a+5); insert into t1 values (4),(a+5);
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Test of duplicate key values with packed keys
#
create table t1 (id int not null auto_increment primary key, username varchar(32) not null, unique (username));
insert into t1 values (0,"mysql");
insert into t1 values (0,"mysql ab");
insert into t1 values (0,"mysql a");
insert into t1 values (0,"r1manic");
insert into t1 values (0,"r1man");
drop table t1;
#
# This test does a create-select with ORDER BY, where there is so many
# rows MySQL needs to use a merge during the sort phase.
#
drop table if exists t1,t2; drop table if exists t1,t2;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`id` int(11) NOT NULL default '0', `id` int(11) NOT NULL default '0',
`id2` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0',
`id3` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0');
`dummy1` char(30) default NULL,
PRIMARY KEY (`id`,`id2`),
KEY `index_id3` (`id3`));
let $1=4000; let $1=4000;
while ($1) while ($1)
{ {
eval insert into t1 (id,id2,id3,dummy1) values ($1,$1,$1,'foobar'); eval insert into t1 (id,id2,id3) values ($1,$1,$1);
dec $1; dec $1;
} }
create table t2 (n int); create table t2 select id2 from t1 order by id3;
insert into t2 select id2 from t1 order by id3;
select count(*) from t2; select count(*) from t2;
drop table t1,t2; drop table t1,t2;
...@@ -13,7 +13,7 @@ select SQL_CALC_FOUND_ROWS * from t1 order by b desc limit 1; ...@@ -13,7 +13,7 @@ select SQL_CALC_FOUND_ROWS * from t1 order by b desc limit 1;
select found_rows(); select found_rows();
select SQL_CALC_FOUND_ROWS distinct b from t1 limit 1; select SQL_CALC_FOUND_ROWS distinct b from t1 limit 1;
select found_rows(); select found_rows();
select SQL_CALC_FOUND_ROWS b,count(*) as c from t1 group by b order by c limit 1; select SQL_CALC_FOUND_ROWS b,count(*) as c from t1 group by b order by c desc limit 1;
select found_rows(); select found_rows();
select SQL_CALC_FOUND_ROWS * from t1 left join t1 as t2 on (t1.b=t2.a) limit 2,1; select SQL_CALC_FOUND_ROWS * from t1 left join t1 as t2 on (t1.b=t2.a) limit 2,1;
select found_rows(); select found_rows();
......
...@@ -53,11 +53,19 @@ static int merge_index(SORTPARAM *param,uchar *sort_buffer, ...@@ -53,11 +53,19 @@ static int merge_index(SORTPARAM *param,uchar *sort_buffer,
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count); static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count);
static uint sortlength(SORT_FIELD *sortorder,uint length); static uint sortlength(SORT_FIELD *sortorder,uint length);
/* Makes a indexfil of recordnumbers of a sorted database */ /*
/* outfile is reset before data is written to it, if it wasn't Creates a set of pointers that can be used to read the rows
open a new file is opened */ in sorted order. This should be done with the functions
in records.cc
Before calling filesort, one must have done
table->file->info(HA_STATUS_VARIABLE)
The result set is stored in table->io_cache or
table->record_pointers
*/
ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length, ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
SQL_SELECT *select, ha_rows special, ha_rows max_rows, SQL_SELECT *select, ha_rows special, ha_rows max_rows,
ha_rows *examined_rows) ha_rows *examined_rows)
{ {
...@@ -69,19 +77,20 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length, ...@@ -69,19 +77,20 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
IO_CACHE tempfile,*selected_records_file,*outfile; IO_CACHE tempfile,*selected_records_file,*outfile;
SORTPARAM param; SORTPARAM param;
DBUG_ENTER("filesort"); DBUG_ENTER("filesort");
DBUG_EXECUTE("info",TEST_filesort(table,sortorder,s_length,special);); DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length,special););
#ifdef SKIPP_DBUG_IN_FILESORT #ifdef SKIPP_DBUG_IN_FILESORT
DBUG_PUSH(""); /* No DBUG here */ DBUG_PUSH(""); /* No DBUG here */
#endif #endif
outfile= table[0]->io_cache; outfile= table->io_cache;
my_b_clear(&tempfile); my_b_clear(&tempfile);
buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1; buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1; maxbuffer=1;
param.ref_length= table[0]->file->ref_length; param.ref_length= table->file->ref_length;
param.sort_length=sortlength(sortorder,s_length)+ param.ref_length; param.sort_length=sortlength(sortorder,s_length)+ param.ref_length;
param.max_rows= max_rows; param.max_rows= max_rows;
param.examined_rows=0; param.examined_rows=0;
param.unique_buff=0;
if (select && select->quick) if (select && select->quick)
{ {
...@@ -106,17 +115,14 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length, ...@@ -106,17 +115,14 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
#ifdef CAN_TRUST_RANGE #ifdef CAN_TRUST_RANGE
else if (select && select->quick && select->quick->records > 0L) else if (select && select->quick && select->quick->records > 0L)
{ {
/* Get record-count */
table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2), records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
table[0]->file->records)+EXTRA_RECORDS; table->file->records)+EXTRA_RECORDS;
selected_records_file=0; selected_records_file=0;
} }
#endif #endif
else else
{ {
table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);/* Get record-count */ records=table->file->estimate_number_of_rows();
records=table[0]->file->estimate_number_of_rows();
selected_records_file= 0; selected_records_file= 0;
} }
if (param.sort_length == param.ref_length && records > param.max_rows) if (param.sort_length == param.ref_length && records > param.max_rows)
...@@ -170,7 +176,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length, ...@@ -170,7 +176,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size); my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size);
goto err; goto err;
} }
param.sort_form= table[0]; param.sort_form= table;
param.end=(param.local_sortorder=sortorder)+s_length; param.end=(param.local_sortorder=sortorder)+s_length;
if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer, if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer,
&tempfile, selected_records_file)) == &tempfile, selected_records_file)) ==
......
...@@ -475,8 +475,7 @@ pthread_handler_decl(handle_manager, arg); ...@@ -475,8 +475,7 @@ pthread_handler_decl(handle_manager, arg);
#ifndef DBUG_OFF #ifndef DBUG_OFF
void print_where(COND *cond,const char *info); void print_where(COND *cond,const char *info);
void print_cached_tables(void); void print_cached_tables(void);
void TEST_filesort(TABLE **form,SORT_FIELD *sortorder,uint s_length, void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special);
ha_rows special);
#endif #endif
void mysql_print_status(THD *thd); void mysql_print_status(THD *thd);
/* key.cc */ /* key.cc */
...@@ -618,7 +617,7 @@ void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, ...@@ -618,7 +617,7 @@ void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
SQL_SELECT *select, SQL_SELECT *select,
int use_record_cache, bool print_errors); int use_record_cache, bool print_errors);
void end_read_record(READ_RECORD *info); void end_read_record(READ_RECORD *info);
ha_rows filesort(TABLE **form,struct st_sort_field *sortorder, uint s_length, ha_rows filesort(TABLE *form,struct st_sort_field *sortorder, uint s_length,
SQL_SELECT *select, ha_rows special,ha_rows max_rows, SQL_SELECT *select, ha_rows special,ha_rows max_rows,
ha_rows *examined_rows); ha_rows *examined_rows);
void change_double_for_sort(double nr,byte *to); void change_double_for_sort(double nr,byte *to);
......
...@@ -2479,7 +2479,7 @@ enum options { ...@@ -2479,7 +2479,7 @@ enum options {
OPT_INNODB_LOG_ARCH_DIR, OPT_INNODB_LOG_ARCH_DIR,
OPT_INNODB_LOG_ARCHIVE, OPT_INNODB_LOG_ARCHIVE,
OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
OPT_innodb_flush_method, OPT_INNODB_FLUSH_METHOD,
OPT_SAFE_SHOW_DB, OPT_SAFE_SHOW_DB,
OPT_GEMINI_SKIP, OPT_INNODB_SKIP, OPT_GEMINI_SKIP, OPT_INNODB_SKIP,
OPT_TEMP_POOL, OPT_DO_PSTACK, OPT_TX_ISOLATION, OPT_TEMP_POOL, OPT_DO_PSTACK, OPT_TX_ISOLATION,
...@@ -2545,7 +2545,7 @@ static struct option long_options[] = { ...@@ -2545,7 +2545,7 @@ static struct option long_options[] = {
{"innodb_flush_log_at_trx_commit", optional_argument, 0, {"innodb_flush_log_at_trx_commit", optional_argument, 0,
OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT}, OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT},
{"innodb_flush_method", required_argument, 0, {"innodb_flush_method", required_argument, 0,
OPT_INNODB_UNIX_FILE_FLUSH_METHOD}, OPT_INNODB_FLUSH_METHOD},
#endif #endif
{"help", no_argument, 0, '?'}, {"help", no_argument, 0, '?'},
{"init-file", required_argument, 0, (int) OPT_INIT_FILE}, {"init-file", required_argument, 0, (int) OPT_INIT_FILE},
...@@ -3703,7 +3703,7 @@ static void get_options(int argc,char **argv) ...@@ -3703,7 +3703,7 @@ static void get_options(int argc,char **argv)
case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT: case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT:
innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1; innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1;
break; break;
case OPT_INNODB_UNIX_FILE_FLUSH_METHOD: case OPT_INNODB_FLUSH_METHOD:
innobase_unix_file_flush_method=optarg; innobase_unix_file_flush_method=optarg;
break; break;
#endif /* HAVE_INNOBASE_DB */ #endif /* HAVE_INNOBASE_DB */
......
...@@ -214,7 +214,7 @@ int mysql_delete(THD *thd, ...@@ -214,7 +214,7 @@ int mysql_delete(THD *thd,
MYF(MY_FAE | MY_ZEROFILL)); MYF(MY_FAE | MY_ZEROFILL));
if (setup_order(thd, &tables, fields, all_fields, order) || if (setup_order(thd, &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) || !(sortorder=make_unireg_sortorder(order, &length)) ||
(table->found_records = filesort(&table, sortorder, length, (table->found_records = filesort(table, sortorder, length,
(SQL_SELECT *) 0, 0L, HA_POS_ERROR, (SQL_SELECT *) 0, 0L, HA_POS_ERROR,
&examined_rows)) &examined_rows))
== HA_POS_ERROR) == HA_POS_ERROR)
......
...@@ -5334,7 +5334,9 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) ...@@ -5334,7 +5334,9 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
goto err; goto err;
} }
} }
table->found_records=filesort(&table,sortorder,length, if (table->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count
table->found_records=filesort(table,sortorder,length,
select, 0L, select_limit, &examined_rows); select, 0L, select_limit, &examined_rows);
delete select; // filesort did select delete select; // filesort did select
tab->select=0; tab->select=0;
......
...@@ -1755,7 +1755,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -1755,7 +1755,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (setup_order(thd, &tables, fields, all_fields, order) || if (setup_order(thd, &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) || !(sortorder=make_unireg_sortorder(order, &length)) ||
(from->found_records = filesort(&from, sortorder, length, (from->found_records = filesort(from, sortorder, length,
(SQL_SELECT *) 0, 0L, HA_POS_ERROR, (SQL_SELECT *) 0, 0L, HA_POS_ERROR,
&examined_rows)) &examined_rows))
== HA_POS_ERROR) == HA_POS_ERROR)
......
...@@ -96,8 +96,7 @@ void print_cached_tables(void) ...@@ -96,8 +96,7 @@ void print_cached_tables(void)
} }
void TEST_filesort(TABLE **table,SORT_FIELD *sortorder,uint s_length, void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special)
ha_rows special)
{ {
char buff[256],buff2[256]; char buff[256],buff2[256];
String str(buff,sizeof(buff)),out(buff2,sizeof(buff2)); String str(buff,sizeof(buff)),out(buff2,sizeof(buff2));
......
...@@ -184,7 +184,7 @@ int mysql_update(THD *thd, ...@@ -184,7 +184,7 @@ int mysql_update(THD *thd,
MYF(MY_FAE | MY_ZEROFILL)); MYF(MY_FAE | MY_ZEROFILL));
if (setup_order(thd, &tables, fields, all_fields, order) || if (setup_order(thd, &tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) || !(sortorder=make_unireg_sortorder(order, &length)) ||
(table->found_records = filesort(&table, sortorder, length, (table->found_records = filesort(table, sortorder, length,
(SQL_SELECT *) 0, 0L, (SQL_SELECT *) 0, 0L,
HA_POS_ERROR, &examined_rows)) HA_POS_ERROR, &examined_rows))
== HA_POS_ERROR) == HA_POS_ERROR)
......
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