summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2003-04-23 21:52:16 +0300
committerunknown <monty@narttu.mysql.fi>2003-04-23 21:52:16 +0300
commit7032486889f42b3f18b4a0a5be6cb97b74790ea8 (patch)
treeacef6d0c7b21d3c5a8a9cdc9c5f1eb4f1774857b /sql
parent35459cb7f38e2f9b56a8d00cbc05c631c7e235f0 (diff)
downloadmariadb-git-7032486889f42b3f18b4a0a5be6cb97b74790ea8.tar.gz
Fixes for valgrind
Added optimzation for clustered index Fixed bug in UPDATE ... ORDER BY Fixed handling of UPDATE ... LIMIT BitKeeper/deleted/.del-.cvsignore~7e29af89a3559f4c: Delete: Images/.cvsignore BitKeeper/deleted/.del-README~d5a4e7ca3a2e87a9: Delete: repl-tests/README BitKeeper/deleted/.del-run-all-tests~4deb6479a13e4568: Delete: repl-tests/run-all-tests BitKeeper/deleted/.del-run.test~3dc5b9bd1e9feea5: Delete: repl-tests/test-repl-alter/run.test BitKeeper/deleted/.del-run.test~4020771cff278f14: Delete: repl-tests/test-bad-query/run.test BitKeeper/deleted/.del-run.test~452f2b66537404a8: Delete: repl-tests/test-dump/run.test BitKeeper/deleted/.del-run.test~b1f0c1f96554df8: Delete: repl-tests/test-auto-inc/run.test BitKeeper/deleted/.del-table-dump-check.master~e13afeb8c79264b5: Delete: repl-tests/test-dump/table-dump-check.master BitKeeper/deleted/.del-table-dump-select.master~744acb955e33f3db: Delete: repl-tests/test-dump/table-dump-select.master BitKeeper/deleted/.del-x.master~29a93ed7956c8693: Delete: repl-tests/test-auto-inc/x.master BitKeeper/deleted/.del-x.master~3b248cbac9abda2b: Delete: repl-tests/test-bad-query/x.master BitKeeper/deleted/.del-foo-dump-master.master~b49ae6bec1e918ee: Delete: repl-tests/test-repl/foo-dump-master.master BitKeeper/deleted/.del-foo-dump-slave.master~f16ed20457d59be9: Delete: repl-tests/test-repl/foo-dump-slave.master BitKeeper/deleted/.del-repl-timestamp.master.reject~3492d2b74b413771: Delete: repl-tests/test-repl-ts/repl-timestamp.master.reject BitKeeper/deleted/.del-repl-timestamp.master~4b7782da5cc13161: Delete: repl-tests/test-repl-ts/repl-timestamp.master BitKeeper/deleted/.del-run.test~a1e32ea1e4253af4: Delete: repl-tests/test-repl/run.test BitKeeper/deleted/.del-run.test~ce5e626c91b760ec: Delete: repl-tests/test-repl-ts/run.test BitKeeper/deleted/.del-sum-wlen-master.master~1a5ea625c79e978: Delete: repl-tests/test-repl/sum-wlen-master.master BitKeeper/deleted/.del-sum-wlen-slave.master~f016d98833433084: Delete: repl-tests/test-repl/sum-wlen-slave.master BitKeeper/deleted/.del-test.master~5829e7b3770179db: Delete: repl-tests/test-repl-alter/test.master BitKeeper/deleted/.del-master-slave.inc~6775f6ae10137c39: Delete: repl-tests/include/master-slave.inc include/my_global.h: Fix for purify/valgrind myisam/mi_info.c: Updated comment mysql-test/r/group_by.result: New test results mysql-test/r/innodb.result: New test results mysql-test/r/join_outer.result: New test results mysql-test/r/multi_update.result: New test results mysql-test/r/null_key.result: New test results mysql-test/r/update.result: New test results mysql-test/t/group_by.test: Added extra explain to 'suspicious' test. mysql-test/t/innodb.test: Added test for UPDATE ... ORDER BY mysql-test/t/join_outer.test: Changed test to be repeatable mysql-test/t/multi_update.test: Slight change of test to catch more bugs mysql-test/t/update.test: Better test for UPDATE ... ORDER BY sql/field.cc: Simple optimization sql/ha_heap.h: Added optimzation for clustered index sql/ha_innodb.cc: Added optimzation for clustered index sql/ha_innodb.h: Added optimzation for clustered index sql/handler.h: Added optimzation for clustered index sql/item_sum.cc: Removed some usage of current_thd sql/mysqld.cc: Fix bug when compiling for purify/valgrind sql/opt_range.cc: Added optimzation for clustered index sql/records.cc: Fixed comment sql/sql_list.h: Fixed comment sql/sql_select.cc: Removed some usage of current_thd sql/sql_select.h: Removed some usage of current_thd sql/sql_union.cc: Removed some usage of current_thd sql/sql_update.cc: Fixed bug in UPDATE ... ORDER BY Fixed handling of UPDATE ... LIMIT support-files/my-huge.cnf.sh: Added default size for query cache support-files/my-large.cnf.sh: Added default size for query cache
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc2
-rw-r--r--sql/ha_heap.h5
-rw-r--r--sql/ha_innodb.cc29
-rw-r--r--sql/ha_innodb.h1
-rw-r--r--sql/handler.h3
-rw-r--r--sql/item_sum.cc5
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/opt_range.cc12
-rw-r--r--sql/records.cc2
-rw-r--r--sql/sql_list.h2
-rw-r--r--sql/sql_select.cc24
-rw-r--r--sql/sql_select.h4
-rw-r--r--sql/sql_union.cc3
-rw-r--r--sql/sql_update.cc145
14 files changed, 146 insertions, 93 deletions
diff --git a/sql/field.cc b/sql/field.cc
index ce5e240aba8..eb7d3dc5686 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -3322,11 +3322,11 @@ bool Field_newdate::get_date(TIME *ltime,bool fuzzydate)
if (is_null())
return 1;
uint32 tmp=(uint32) uint3korr(ptr);
- bzero((char*) ltime,sizeof(*ltime));
ltime->day= tmp & 31;
ltime->month= (tmp >> 5) & 15;
ltime->year= (tmp >> 9);
ltime->time_type=TIMESTAMP_DATE;
+ ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
}
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index 504f5262bf3..31126111d9d 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -54,8 +54,9 @@ class ha_heap: public handler
uint max_keys() const { return MAX_KEY; }
uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return HA_MAX_REC_LENGTH; }
- virtual double scan_time() { return (double) (records+deleted) / 20.0+10; }
- virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
+ double scan_time() { return (double) (records+deleted) / 20.0+10; }
+ double read_time(uint index, uint ranges, ha_rows rows)
+ { return (double) rows / 20.0+1; }
virtual bool fast_key_read() { return 1;}
int open(const char *name, int mode, uint test_if_locked);
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index ea8eaf6653e..b7b72426053 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -3501,10 +3501,8 @@ ha_innobase::records_in_range(
/*************************************************************************
Gives an UPPER BOUND to the number of rows in a table. This is used in
-filesort.cc and the upper bound must hold. TODO: Since the number of
-rows in a table may change after this function is called, we still may
-get a 'Sort aborted' error in filesort.cc of MySQL. The ultimate fix is to
-improve the algorithm of filesort.cc. */
+filesort.cc and its better if the upper bound hold.
+*/
ha_rows
ha_innobase::estimate_number_of_rows(void)
@@ -3570,6 +3568,29 @@ ha_innobase::scan_time()
return((double) (prebuilt->table->stat_clustered_index_size));
}
+/*
+ Calculate the time it takes to read a set of ranges through and index
+ This enables us to optimise reads for clustered indexes.
+*/
+
+double ha_innobase::read_time(uint index, uint ranges, ha_rows rows)
+{
+ ha_rows total_rows;
+ double time_for_scan;
+ if (index != table->primary_key)
+ return handler::read_time(index, ranges, rows); // Not clustered
+ if (rows <= 2)
+ return (double) rows;
+ /*
+ Assume that the read is proportional to scan time for all rows + one
+ seek per range.
+ */
+ time_for_scan= scan_time();
+ if ((total_rows= estimate_number_of_rows()) < rows)
+ return time_for_scan;
+ return (ranges + (double) rows / (double) total_rows * time_for_scan);
+}
+
/*************************************************************************
Returns statistics information of the table to the MySQL interpreter,
in various fields of the handle object. */
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 8031fa0aa29..f7aa1d3b277 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -118,6 +118,7 @@ class ha_innobase: public handler
void initialize(void);
int close(void);
double scan_time();
+ double read_time(uint index, uint ranges, ha_rows rows);
int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data);
diff --git a/sql/handler.h b/sql/handler.h
index 8f1d00f64b5..72a05d7ebee 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -227,7 +227,8 @@ public:
void change_table_ptr(TABLE *table_arg) { table=table_arg; }
virtual double scan_time()
{ return ulonglong2double(data_file_length) / IO_SIZE + 1; }
- virtual double read_time(ha_rows rows) { return rows2double(rows); }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+ { return rows2double(ranges+rows); }
virtual bool fast_key_read() { return 0;}
virtual key_map keys_to_use_for_scanning() { return 0; }
virtual bool has_transactions(){ return 0;}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 3a513505913..d88894d4fb4 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1066,7 +1066,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
int Item_sum_count_distinct::tree_to_myisam()
{
- if (create_myisam_from_heap(table, tmp_table_param,
+ if (create_myisam_from_heap(current_thd, table, tmp_table_param,
HA_ERR_RECORD_FILE_FULL, 1) ||
tree_walk(&tree, (tree_walk_action)&dump_leaf, (void*)this,
left_root_right))
@@ -1120,7 +1120,8 @@ bool Item_sum_count_distinct::add()
if (error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE)
{
- if (create_myisam_from_heap(table, tmp_table_param, error,1))
+ if (create_myisam_from_heap(current_thd, table, tmp_table_param, error,
+ 1))
return 1; // Not a table_is_full error
}
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 24e343017e2..4c2bda6e1d6 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -42,7 +42,7 @@
#define MAIN_THD
#define SIGNAL_THD
-#ifdef PURIFY
+#ifdef HAVE_purify
#define IF_PURIFY(A,B) (A)
#else
#define IF_PURIFY(A,B) (B)
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index aeeabb7d29c..cc45e18e54c 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -284,7 +284,7 @@ typedef struct st_qsel_param {
KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY];
MEM_ROOT *mem_root;
table_map prev_tables,read_tables,current_table;
- uint baseflag,keys,max_key_part;
+ uint baseflag, keys, max_key_part, range_count;
uint real_keynr[MAX_KEY];
char min_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH],
max_key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
@@ -710,8 +710,10 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
(double) keys_per_block);
}
else
- found_read_time= head->file->read_time(found_records)+
- (double) found_records / TIME_FOR_COMPARE;
+ found_read_time= (head->file->read_time(keynr,
+ param.range_count,
+ found_records)+
+ (double) found_records / TIME_FOR_COMPARE);
if (read_time > found_read_time)
{
read_time=found_read_time;
@@ -2113,11 +2115,12 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree)
if (!tree)
DBUG_RETURN(HA_POS_ERROR); // Can't use it
+ param->max_key_part=0;
+ param->range_count=0;
if (tree->type == SEL_ARG::IMPOSSIBLE)
DBUG_RETURN(0L); // Impossible select. return
if (tree->type != SEL_ARG::KEY_RANGE || tree->part != 0)
DBUG_RETURN(HA_POS_ERROR); // Don't use tree
- param->max_key_part=0;
records=check_quick_keys(param,idx,tree,param->min_key,0,param->max_key,0);
if (records != HA_POS_ERROR)
{
@@ -2185,6 +2188,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
}
keynr=param->real_keynr[idx];
+ param->range_count++;
if (!tmp_min_flag && ! tmp_max_flag &&
(uint) key_tree->part+1 == param->table->key_info[keynr].key_parts &&
(param->table->key_info[keynr].flags & HA_NOSAME) &&
diff --git a/sql/records.cc b/sql/records.cc
index 22c4d54550c..fd46506203f 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -15,7 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* Functions to read, write and lock records */
+/* Functions for easy reading of records, possible through a cache */
#include "mysql_priv.h"
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 542eef623f0..bbda93d32f5 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 96de43ae55c..14b567b86c5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1829,7 +1829,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
{
ha_rows rec;
double tmp;
- THD *thd= current_thd;
+ THD *thd= join->thd;
if (!rest_tables)
{
@@ -1960,7 +1960,10 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
if (table->quick_keys & ((key_map) 1 << key))
records= (double) table->quick_rows[key];
else
- records= (double) s->records/rec; // quick_range couldn't use key!
+ {
+ /* quick_range couldn't use key! */
+ records= (double) s->records/rec;
+ }
}
else
{
@@ -4306,12 +4309,11 @@ free_tmp_table(THD *thd, TABLE *entry)
* If a HEAP table gets full, create a MyISAM table and copy all rows to this
*/
-bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
- bool ignore_last_dupp_key_error)
+bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
+ int error, bool ignore_last_dupp_key_error)
{
TABLE new_table;
const char *save_proc_info;
- THD *thd=current_thd;
int write_err;
DBUG_ENTER("create_myisam_from_heap");
@@ -5318,7 +5320,8 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (error == HA_ERR_FOUND_DUPP_KEY ||
error == HA_ERR_FOUND_DUPP_UNIQUE)
goto end;
- if (create_myisam_from_heap(table, &join->tmp_table_param, error,1))
+ if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
+ error,1))
DBUG_RETURN(-1); // Not a table_is_full error
table->uniques=0; // To ensure rows are the same
}
@@ -5395,7 +5398,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
copy_funcs(join->tmp_table_param.items_to_copy);
if ((error=table->file->write_row(table->record[0])))
{
- if (create_myisam_from_heap(table, &join->tmp_table_param, error, 0))
+ if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
+ error, 0))
DBUG_RETURN(-1); // Not a table_is_full error
/* Change method to update rows */
table->file->index_init(0);
@@ -5489,8 +5493,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if ((error=table->file->write_row(table->record[0])))
{
- if (create_myisam_from_heap(table, &join->tmp_table_param,
- error, 0))
+ if (create_myisam_from_heap(join->thd, table,
+ &join->tmp_table_param, error, 0))
DBUG_RETURN(-1); // Not a table_is_full error
}
else
@@ -6019,7 +6023,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
int error;
ulong reclength,offset;
uint field_count;
- THD *thd= current_thd;
+ THD *thd= join->thd;
DBUG_ENTER("remove_duplicates");
entry->reginfo.lock_type=TL_WRITE;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 332778aafe6..5c987e74163 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -195,8 +195,8 @@ void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,List<Item> &fields);
void copy_fields(TMP_TABLE_PARAM *param);
void copy_funcs(Item **func_ptr);
-bool create_myisam_from_heap(TABLE *table, TMP_TABLE_PARAM *param, int error,
- bool ignore_last_dupp_error);
+bool create_myisam_from_heap(THD *Thd, TABLE *table, TMP_TABLE_PARAM *param,
+ int error, bool ignore_last_dupp_error);
/* functions from opt_sum.cc */
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index faa106d4f42..e7afa7fbd23 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -262,7 +262,8 @@ bool select_union::send_data(List<Item> &values)
fill_record(table->field,values);
if ((write_record(table,&info)))
{
- if (create_myisam_from_heap(table, tmp_table_param, info.last_errno, 0))
+ if (create_myisam_from_heap(thd, table, tmp_table_param, info.last_errno,
+ 0))
return 1;
}
return 0;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 709f88726de..653b16a45e9 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -66,7 +66,10 @@ int mysql_update(THD *thd,
TABLE *table;
SQL_SELECT *select;
READ_RECORD info;
+ TABLE_LIST tables;
+ List<Item> all_fields;
DBUG_ENTER("mysql_update");
+
LINT_INIT(used_index);
LINT_INIT(timestamp_query_id);
@@ -80,8 +83,13 @@ int mysql_update(THD *thd,
table->quick_keys=0;
want_privilege=table->grant.want_privilege;
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
- if (setup_tables(table_list) || setup_conds(thd,table_list,&conds)
- || setup_ftfuncs(thd))
+
+ bzero((char*) &tables,sizeof(tables)); // For ORDER BY
+ tables.table = table;
+
+ if (setup_tables(table_list) || setup_conds(thd,table_list,&conds) ||
+ setup_order(thd, &tables, all_fields, all_fields, order) ||
+ setup_ftfuncs(thd))
DBUG_RETURN(-1); /* purecov: inspected */
old_used_keys=table->used_keys; // Keys used in WHERE
@@ -159,13 +167,6 @@ int mysql_update(THD *thd,
matching rows before updating the table!
*/
table->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE);
- IO_CACHE tempfile;
- if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
- DISK_BUFFER_SIZE, MYF(MY_WME)))
- {
- delete select; /* purecov: inspected */
- DBUG_RETURN(-1);
- }
if (old_used_keys & ((key_map) 1 << used_index))
{
table->key_read=1;
@@ -174,81 +175,97 @@ int mysql_update(THD *thd,
if (order)
{
+ /*
+ Doing an ORDER BY; Let filesort find and sort the rows we are going
+ to update
+ */
uint length;
SORT_FIELD *sortorder;
- TABLE_LIST tables;
List<Item> fields;
- List<Item> all_fields;
ha_rows examined_rows;
- bzero((char*) &tables,sizeof(tables));
- tables.table = table;
-
table->io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL));
- if (setup_order(thd, &tables, fields, all_fields, order) ||
- !(sortorder=make_unireg_sortorder(order, &length)) ||
+ if (!(sortorder=make_unireg_sortorder(order, &length)) ||
(table->found_records = filesort(table, sortorder, length,
- (SQL_SELECT *) 0, 0L,
- HA_POS_ERROR, &examined_rows))
- == HA_POS_ERROR)
+ select, 0L,
+ limit, &examined_rows)) ==
+ HA_POS_ERROR)
{
delete select;
+ free_io_cache(table);
DBUG_RETURN(-1);
}
+ /*
+ Filesort has already found and selected the rows we want to update,
+ so we don't need the where clause
+ */
+ delete select;
+ select= 0;
}
-
- init_read_record(&info,thd,table,select,0,1);
- thd->proc_info="Searching rows for update";
-
- while (!(error=info.read_record(&info)) && !thd->killed)
+ else
{
- if (!(select && select->skipp_record()))
+ /*
+ We are doing a search on a key that is updated. In this case
+ we go trough the matching rows, save a pointer to them and
+ update these in a separate loop based on the pointer.
+ */
+
+ IO_CACHE tempfile;
+ if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
+ DISK_BUFFER_SIZE, MYF(MY_WME)))
{
- table->file->position(table->record[0]);
- if (my_b_write(&tempfile,table->file->ref,
- table->file->ref_length))
+ delete select; /* purecov: inspected */
+ DBUG_RETURN(-1);
+ }
+
+ init_read_record(&info,thd,table,select,0,1);
+ thd->proc_info="Searching rows for update";
+ uint tmp_limit= limit;
+ while (!(error=info.read_record(&info)) && !thd->killed)
+ {
+ if (!(select && select->skipp_record()))
{
- error=1; /* purecov: inspected */
- break; /* purecov: inspected */
+ table->file->position(table->record[0]);
+ if (my_b_write(&tempfile,table->file->ref,
+ table->file->ref_length))
+ {
+ error=1; /* purecov: inspected */
+ break; /* purecov: inspected */
+ }
+ if (!--limit && using_limit)
+ break;
}
}
+ end_read_record(&info);
+ /* Change select to use tempfile */
+ if (select)
+ {
+ delete select->quick;
+ if (select->free_cond)
+ delete select->cond;
+ select->quick=0;
+ select->cond=0;
+ }
else
{
- if (!(test_flags & 512)) /* For debugging */
- {
- DBUG_DUMP("record",(char*) table->record[0],table->reclength);
- }
+ select= new SQL_SELECT;
+ select->head=table;
+ }
+ if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
+ error=1; /* purecov: inspected */
+ select->file=tempfile; // Read row ptrs from this file
+ if (error >= 0)
+ {
+ delete select;
+ DBUG_RETURN(-1);
}
}
- end_read_record(&info);
if (table->key_read)
{
table->key_read=0;
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
- /* Change select to use tempfile */
- if (select)
- {
- delete select->quick;
- if (select->free_cond)
- delete select->cond;
- select->quick=0;
- select->cond=0;
- }
- else
- {
- select= new SQL_SELECT;
- select->head=table;
- }
- if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
- error=1; /* purecov: inspected */
- select->file=tempfile; // Read row ptrs from this file
- if (error >= 0)
- {
- delete select;
- DBUG_RETURN(-1);
- }
}
if (handle_duplicates == DUP_IGNORE)
@@ -275,11 +292,6 @@ int mysql_update(THD *thd,
(byte*) table->record[0])))
{
updated++;
- if (!--limit && using_limit)
- {
- error= -1;
- break;
- }
}
else if (handle_duplicates != DUP_IGNORE ||
error != HA_ERR_FOUND_DUPP_KEY)
@@ -289,11 +301,17 @@ int mysql_update(THD *thd,
break;
}
}
+ if (!--limit && using_limit)
+ {
+ error= -1; // Simulate end of file
+ break;
+ }
}
else
table->file->unlock_row();
}
end_read_record(&info);
+ free_io_cache(table); // If ORDER BY
thd->proc_info="end";
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
transactional_table= table->file->has_transactions();
@@ -741,7 +759,8 @@ bool multi_update::send_data(List<Item> &not_used_values)
(error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE))
{
- if (create_myisam_from_heap(table, tmp_table_param + offset, error, 1))
+ if (create_myisam_from_heap(thd, table, tmp_table_param + offset,
+ error, 1))
{
do_update=0;
DBUG_RETURN(1); // Not a table_is_full error