summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2006-02-08 23:53:45 +0300
committerunknown <konstantin@mysql.com>2006-02-08 23:53:45 +0300
commitea6aba52c1919d7cdb1344cc67efe5f89df2006a (patch)
tree7d495dc3bafe88ef93bc51491f32afbb3efca087 /sql
parent2dc19ba63c94e3dc4d79e30b9825b6ff03c05ac3 (diff)
parentcf4b6ee4c01ca9e002511ad221872b4182b910fa (diff)
downloadmariadb-git-ea6aba52c1919d7cdb1344cc67efe5f89df2006a.tar.gz
Merge mysql.com:/home/kostja/mysql/tmp_merge
into mysql.com:/home/kostja/mysql/mysql-5.1-merge configure.in: Auto merged include/heap.h: Auto merged libmysql/libmysql.c: Auto merged mysql-test/r/date_formats.result: Auto merged mysql-test/t/date_formats.test: Auto merged sql/ha_heap.cc: Auto merged sql/ha_heap.h: Auto merged sql/item_timefunc.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_select.h: Auto merged storage/heap/hp_create.c: Auto merged storage/ndb/include/mgmapi/mgmapi_config_parameters.h: Auto merged storage/ndb/test/ndbapi/testBlobs.cpp: Auto merged sql/sql_update.cc: Manual merge tests/mysql_client_test.c: SCCS merged
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_heap.cc56
-rw-r--r--sql/ha_heap.h2
-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.cc17
6 files changed, 87 insertions, 16 deletions
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index c520a4e88d4..446e9f2a6eb 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -73,7 +73,7 @@ static handler *heap_create_handler(TABLE_SHARE *table)
ha_heap::ha_heap(TABLE_SHARE *table_arg)
:handler(&heap_hton, table_arg), file(0), records_changed(0),
- key_stats_ok(0)
+ key_stats_version(0)
{}
@@ -124,7 +124,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);
}
@@ -171,14 +171,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;
}
@@ -193,7 +200,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;
}
@@ -206,7 +219,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;
}
@@ -217,7 +236,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;
}
@@ -344,7 +369,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();
}
@@ -357,7 +382,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;
}
@@ -524,6 +555,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 909b36f975b..9b9b7f90d90 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_SHARE *table);
~ha_heap() {}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5833842f660..e68bcb9e281 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1862,11 +1862,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 be6bfa2f5ed..c5aca91c9e9 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -6064,6 +6064,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 523182d96cd..4f93a4aa996 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -286,7 +286,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)
{
@@ -333,7 +340,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 d6bf01f5a25..b1abf2c0777 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -331,7 +331,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)) ||
@@ -362,7 +361,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 quick select is used, initialize it before retrieving rows. */
if (select && select->quick && select->quick->reset())
goto err;