summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2006-02-02 18:17:18 +0300
committerunknown <konstantin@mysql.com>2006-02-02 18:17:18 +0300
commit95a3509a6637699fdcc26d7042013778c5e55d08 (patch)
tree336ed0f3ebd53f06d2b14904f4fd937b5fe487c6 /sql
parent9b3e6c27b0615270042cff92c88cb338ded9b69f (diff)
parent1e686ae7702d297cc9fd261c42864653f4fdd7b3 (diff)
downloadmariadb-git-95a3509a6637699fdcc26d7042013778c5e55d08.tar.gz
Merge mysql.com:/opt/local/work/mysql-4.1-root
into mysql.com:/opt/local/work/mysql-5.0-root BitKeeper/deleted/.del-rpl_ignore_table.result: Delete: mysql-test/r/rpl_ignore_table.result BitKeeper/deleted/.del-rpl_multi_update4.result: Delete: mysql-test/r/rpl_multi_update4.result BitKeeper/deleted/.del-rpl_ignore_table-slave.opt: Delete: mysql-test/t/rpl_ignore_table-slave.opt BitKeeper/deleted/.del-rpl_ignore_table.test: Delete: mysql-test/t/rpl_ignore_table.test BitKeeper/deleted/.del-rpl_multi_update4-slave.opt: Delete: mysql-test/t/rpl_multi_update4-slave.opt BitKeeper/deleted/.del-disabled.def: Auto merged BitKeeper/deleted/.del-rpl_multi_update4.test: Delete: mysql-test/t/rpl_multi_update4.test heap/hp_create.c: Auto merged mysql-test/r/date_formats.result: Auto merged mysql-test/r/myisam.result: Auto merged mysql-test/r/update.result: Auto merged mysql-test/t/date_formats.test: Auto merged mysql-test/t/heap.test: Auto merged mysql-test/t/kill.test: Auto merged mysql-test/t/update.test: Auto merged ndb/include/mgmapi/mgmapi_config_parameters.h: Auto merged ndb/test/ndbapi/testBlobs.cpp: Auto merged sql/sql_base.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_select.h: Auto merged configure.in: Manual merge. libmysql/libmysql.c: Manual merge. mysql-test/r/heap.result: Manual merge. mysql-test/r/heap_hash.result: Manual merge. mysql-test/r/kill.result: Manual merge. sql/ha_heap.cc: Manual merge. sql/ha_heap.h: Manual merge. sql/item_timefunc.cc: Manual merge. sql/sql_class.cc: Manual merge. sql/sql_parse.cc: Manual merge. sql/sql_update.cc: Manual merge. tests/mysql_client_test.c: Manual merge.
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_heap.cc56
-rw-r--r--sql/ha_heap.h2
-rw-r--r--sql/item_timefunc.cc4
-rw-r--r--sql/sql_class.cc3
-rw-r--r--sql/sql_select.cc14
-rw-r--r--sql/sql_select.h11
-rw-r--r--sql/sql_update.cc14
7 files changed, 86 insertions, 18 deletions
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 98cc96db707..2a989a71edc 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -53,7 +53,7 @@ handlerton heap_hton= {
ha_heap::ha_heap(TABLE *table_arg)
:handler(&heap_hton, table_arg), file(0), records_changed(0),
- key_stats_ok(0)
+ key_stats_version(0)
{}
@@ -104,7 +104,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
ha_heap::info(), which is always called before key statistics are
used.
*/
- key_stats_ok= FALSE;
+ key_stat_version= file->s->key_stat_version-1;
}
return (file ? 0 : 1);
}
@@ -151,14 +151,21 @@ void ha_heap::update_key_stats()
continue;
if (key->algorithm != HA_KEY_ALG_BTREE)
{
- ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
- key->rec_per_key[key->key_parts-1]=
- hash_buckets ? file->s->records/hash_buckets : 0;
+ if (key->flags & HA_NOSAME)
+ key->rec_per_key[key->key_parts-1]= 1;
+ else
+ {
+ ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
+ uint no_records= hash_buckets ? file->s->records/hash_buckets : 2;
+ if (no_records < 2)
+ no_records= 2;
+ key->rec_per_key[key->key_parts-1]= no_records;
+ }
}
}
records_changed= 0;
/* At the end of update_key_stats() we can proudly claim they are OK. */
- key_stats_ok= TRUE;
+ key_stat_version= file->s->key_stat_version;
}
@@ -173,7 +180,13 @@ int ha_heap::write_row(byte * buf)
res= heap_write(file,buf);
if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
file->s->records))
- key_stats_ok= FALSE;
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ file->s->key_stat_version++;
+ }
return res;
}
@@ -186,7 +199,13 @@ int ha_heap::update_row(const byte * old_data, byte * new_data)
res= heap_update(file,old_data,new_data);
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
file->s->records)
- key_stats_ok= FALSE;
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ file->s->key_stat_version++;
+ }
return res;
}
@@ -197,7 +216,13 @@ int ha_heap::delete_row(const byte * buf)
res= heap_delete(file,buf);
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
- key_stats_ok= FALSE;
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ file->s->key_stat_version++;
+ }
return res;
}
@@ -324,7 +349,7 @@ void ha_heap::info(uint flag)
have to update the key statistics. Hoping that a table lock is now
in place.
*/
- if (! key_stats_ok)
+ if (key_stat_version != file->s->key_stat_version)
update_key_stats();
}
@@ -337,7 +362,13 @@ int ha_heap::delete_all_rows()
{
heap_clear(file);
if (table->s->tmp_table == NO_TMP_TABLE)
- key_stats_ok= FALSE;
+ {
+ /*
+ We can perform this safely since only one writer at the time is
+ allowed on the table.
+ */
+ file->s->key_stat_version++;
+ }
return 0;
}
@@ -497,6 +528,9 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
max_key->flag != HA_READ_AFTER_KEY)
return HA_POS_ERROR; // Can only use exact keys
+ if (records <= 1)
+ return records;
+
/* Assert that info() did run. We need current statistics here. */
DBUG_ASSERT(key_stats_ok);
return key->rec_per_key[key->key_parts-1];
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index 7c4227e952c..e2816abf0b6 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -29,7 +29,7 @@ class ha_heap: public handler
key_map btree_keys;
/* number of records changed since last statistics update */
uint records_changed;
- bool key_stats_ok;
+ uint key_stat_version;
public:
ha_heap(TABLE *table);
~ha_heap() {}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 61449d3c671..17f25b49bcc 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -3023,9 +3023,9 @@ void Item_func_str_to_date::fix_length_and_dec()
cached_field_type= MYSQL_TYPE_STRING;
max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
cached_timestamp_type= MYSQL_TIMESTAMP_NONE;
- if ((const_item= args[1]->const_item()))
+ format= args[1]->val_str(&format_str);
+ if (!args[1]->null_value && (const_item= args[1]->const_item()))
{
- format= args[1]->val_str(&format_str);
cached_format_type= get_date_time_result_type(format->ptr(),
format->length());
switch (cached_format_type) {
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index ca86c077a3a..b3709235d8b 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1816,11 +1816,14 @@ bool select_dumpvar::send_eof()
void TMP_TABLE_PARAM::init()
{
+ DBUG_ENTER("TMP_TABLE_PARAM::init");
+ DBUG_PRINT("enter", ("this: 0x%lx", (ulong)this));
field_count= sum_func_count= func_count= hidden_field_count= 0;
group_parts= group_length= group_null_parts= 0;
quick_group= 1;
table_charset= 0;
precomputed_group_by= 0;
+ DBUG_VOID_RETURN;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 63d46934555..732956b63a6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -6016,6 +6016,20 @@ void JOIN::cleanup(bool full)
problems in free_elements() as some of the elements are then deleted.
*/
tmp_table_param.copy_funcs.empty();
+ /*
+ If we have tmp_join and 'this' JOIN is not tmp_join and
+ tmp_table_param.copy_field's of them are equal then we have to remove
+ pointer to tmp_table_param.copy_field from tmp_join, because it qill
+ be removed in tmp_table_param.cleanup().
+ */
+ if (tmp_join &&
+ tmp_join != this &&
+ tmp_join->tmp_table_param.copy_field ==
+ tmp_table_param.copy_field)
+ {
+ tmp_join->tmp_table_param.copy_field=
+ tmp_join->tmp_table_param.save_copy_field= 0;
+ }
tmp_table_param.cleanup();
}
DBUG_VOID_RETURN;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 4aa238641e5..9046398faaf 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -285,7 +285,14 @@ class JOIN :public Sql_alloc
{
init(thd_arg, fields_arg, select_options_arg, result_arg);
}
-
+
+ JOIN(JOIN &join)
+ :fields_list(join.fields_list)
+ {
+ init(join.thd, join.fields_list, join.select_options,
+ join.result);
+ }
+
void init(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
select_result *result_arg)
{
@@ -332,7 +339,7 @@ class JOIN :public Sql_alloc
all_fields= fields_arg;
fields_list= fields_arg;
bzero((char*) &keyuse,sizeof(keyuse));
- tmp_table_param.copy_field=0;
+ tmp_table_param.init();
tmp_table_param.end_write_records= HA_POS_ERROR;
rollup.state= ROLLUP::STATE_NONE;
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 2ff8a4bc244..d319167b61d 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -308,7 +308,6 @@ int mysql_update(THD *thd,
SORT_FIELD *sortorder;
ha_rows examined_rows;
- used_index= MAX_KEY; // For call to init_read_record()
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL));
if (!(sortorder=make_unireg_sortorder(order, &length)) ||
@@ -339,10 +338,21 @@ int mysql_update(THD *thd,
if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
DISK_BUFFER_SIZE, MYF(MY_WME)))
goto err;
-
+
/* If quick select is used, initialize it before retrieving rows. */
if (select && select->quick && select->quick->reset())
goto err;
+
+ /*
+ When we get here, we have one of the following options:
+ A. used_index == MAX_KEY
+ This means we should use full table scan, and start it with
+ init_read_record call
+ B. used_index != MAX_KEY
+ B.1 quick select is used, start the scan with init_read_record
+ B.2 quick select is not used, this is full index scan (with LIMIT)
+ Full index scan must be started with init_read_record_idx
+ */
if (used_index == MAX_KEY || (select && select->quick))
init_read_record(&info,thd,table,select,0,1);
else