summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorserg@serg.mylan <>2004-11-17 18:04:36 +0100
committerserg@serg.mylan <>2004-11-17 18:04:36 +0100
commite68bd85b77ef425b69996fa83ff2d430ac172c64 (patch)
tree35f1caf73d4e61d1cb7338841a38299682005317 /sql
parent2074aeecb8a399602d5c0e9cc5770578453c0edc (diff)
parent19067008b8449df5ee7b4182300de53692fd349d (diff)
downloadmariadb-git-e68bd85b77ef425b69996fa83ff2d430ac172c64.tar.gz
merged
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_heap.cc57
-rw-r--r--sql/ha_heap.h9
-rw-r--r--sql/ha_innodb.cc9
-rw-r--r--sql/ha_ndbcluster.cc2
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/slave.cc4
-rw-r--r--sql/slave.h2
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_yacc.yy12
-rw-r--r--sql/structs.h7
10 files changed, 84 insertions, 28 deletions
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 1c8967c1a34..f2f27e17ef9 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -30,6 +30,18 @@
const char **ha_heap::bas_ext() const
{ static const char *ext[1]= { NullS }; return ext; }
+/*
+ Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
+ rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records
+ have been inserted/updated/deleted. delete_all_rows() and table flush cause
+ immediate update.
+
+ NOTE
+ hash index statistics must be updated when number of table records changes
+ from 0 to non-zero value and vice versa. Otherwise records_in_range may
+ erroneously return 0 and 'range' may miss records.
+*/
+#define HEAP_STATS_UPDATE_THRESHOLD 10
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
@@ -48,6 +60,8 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
/* Initialize variables for the opened table */
set_keys_for_scanning();
+ if (table->tmp_table == NO_TMP_TABLE)
+ update_key_stats();
}
return (file ? 0 : 1);
}
@@ -84,28 +98,58 @@ void ha_heap::set_keys_for_scanning(void)
}
}
+void ha_heap::update_key_stats()
+{
+ for (uint i= 0; i < table->keys; i++)
+ {
+ KEY *key=table->key_info+i;
+ 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;
+ }
+ }
+ records_changed= 0;
+}
+
int ha_heap::write_row(byte * buf)
{
+ int res;
statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0])
update_auto_increment();
- return heap_write(file,buf);
+ res= heap_write(file,buf);
+ if (!res && table->tmp_table == NO_TMP_TABLE &&
+ ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
+ update_key_stats();
+ return res;
}
int ha_heap::update_row(const byte * old_data, byte * new_data)
{
- statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
+ int res;
+ statistic_increment(ha_update_count,&LOCK_status);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
- return heap_update(file,old_data,new_data);
+ res= heap_update(file,old_data,new_data);
+ if (!res && table->tmp_table == NO_TMP_TABLE &&
+ ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
+ update_key_stats();
+ return res;
}
int ha_heap::delete_row(const byte * buf)
{
+ int res;
statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
- return heap_delete(file,buf);
+ res= heap_delete(file,buf);
+ if (!res && table->tmp_table == NO_TMP_TABLE &&
+ ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
+ update_key_stats();
+ return res;
}
int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
@@ -236,6 +280,8 @@ int ha_heap::extra(enum ha_extra_function operation)
int ha_heap::delete_all_rows()
{
heap_clear(file);
+ if (table->tmp_table == NO_TMP_TABLE)
+ update_key_stats();
return 0;
}
@@ -393,7 +439,8 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key,
min_key->flag != HA_READ_KEY_EXACT ||
max_key->flag != HA_READ_AFTER_KEY)
return HA_POS_ERROR; // Can only use exact keys
- return 10; // Good guess
+ else
+ return key->rec_per_key[key->key_parts-1];
}
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index e469a676b65..8b44695df07 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -27,9 +27,10 @@ class ha_heap: public handler
{
HP_INFO *file;
key_map btree_keys;
-
- public:
- ha_heap(TABLE *table): handler(table), file(0) {}
+ /* number of records changed since last statistics update */
+ uint records_changed;
+public:
+ ha_heap(TABLE *table): handler(table), file(0), records_changed(0) {}
~ha_heap() {}
const char *table_type() const { return "HEAP"; }
const char *index_type(uint inx)
@@ -97,4 +98,6 @@ class ha_heap: public handler
HEAP_PTR ptr2=*(HEAP_PTR*)ref2;
return ptr1 < ptr2? -1 : (ptr1 > ptr2? 1 : 0);
}
+private:
+ void update_key_stats();
};
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 3ee7c323cb3..567f4b834dd 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -1508,17 +1508,14 @@ innobase_close_connection(
*****************************************************************************/
/********************************************************************
-This function is not relevant since we store the tables and indexes
-into our own tablespace, not as files, whose extension this function would
-give. */
+Gives the file extension of an InnoDB single-table tablespace. */
const char**
ha_innobase::bas_ext() const
/*========================*/
- /* out: file extension strings, currently not
- used */
+ /* out: file extension string */
{
- static const char* ext[] = {".InnoDB", NullS};
+ static const char* ext[] = {".ibd", NullS};
return(ext);
}
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 17aaaf20fa2..8fb0a131f5d 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -144,7 +144,7 @@ static int ndb_to_mysql_error(const NdbError *err)
// Push the NDB error message as warning
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
- err->code, err->message, "NDB");
+ err->code, err->message, "NDB");
return err->code;
}
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 4455be53c5d..1f4a1e0f431 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -269,7 +269,7 @@ Item_func::Item_func(THD *thd, Item_func *item)
Sets as a side effect the following class variables:
maybe_null Set if any argument may return NULL
with_sum_func Set if any of the arguments contains a sum function
- used_table_cache Set to union of the arguments used table
+ used_tables_cache Set to union of the tables used by arguments
str_value.charset If this is a string function, set this to the
character set for the first argument.
diff --git a/sql/slave.cc b/sql/slave.cc
index 34785f1a18f..04ab4830312 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1150,7 +1150,7 @@ bool net_request_file(NET* net, const char* fname)
}
-const char *rewrite_db(const char* db, uint *new_len)
+const char *rewrite_db(const char* db, uint32 *new_len)
{
if (replicate_rewrite_db.is_empty() || !db)
return db;
@@ -1161,7 +1161,7 @@ const char *rewrite_db(const char* db, uint *new_len)
{
if (!strcmp(tmp->key, db))
{
- *new_len= strlen(tmp->val);
+ *new_len= (uint32)strlen(tmp->val);
return tmp->val;
}
}
diff --git a/sql/slave.h b/sql/slave.h
index 34e3e20ce06..e73c81a1e6f 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -508,7 +508,7 @@ int add_table_rule(HASH* h, const char* table_spec);
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec);
void init_table_rule_hash(HASH* h, bool* h_inited);
void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited);
-const char *rewrite_db(const char* db, uint *new_db_len);
+const char *rewrite_db(const char* db, uint32 *new_db_len);
const char *print_slave_db_safe(const char *db);
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
void skip_load_data_infile(NET* net);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a95be3c1d62..cd56f04267c 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4651,7 +4651,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
- SET uses tot_length.
*/
void calculate_interval_lengths(THD *thd, TYPELIB *interval,
- uint *max_length, uint *tot_length)
+ uint32 *max_length, uint32 *tot_length)
{
const char **pos;
uint *len;
@@ -4663,7 +4663,7 @@ void calculate_interval_lengths(THD *thd, TYPELIB *interval,
*len= (uint) strip_sp((char*) *pos);
uint length= cs->cset->numchars(cs, *pos, *pos + *len);
*tot_length+= length;
- set_if_bigger(*max_length, length);
+ set_if_bigger(*max_length, (uint32)length);
}
}
@@ -4994,7 +4994,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
if (new_field->pack_length > 4)
new_field->pack_length=8;
new_field->interval=interval;
- uint dummy_max_length;
+ uint32 dummy_max_length;
calculate_interval_lengths(thd, interval,
&dummy_max_length, &new_field->length);
new_field->length+= (interval->count - 1);
@@ -5024,7 +5024,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
new_field->interval=interval;
new_field->pack_length=interval->count < 256 ? 1 : 2; // Should be safe
- uint dummy_tot_length;
+ uint32 dummy_tot_length;
calculate_interval_lengths(thd, interval,
&new_field->length, &dummy_tot_length);
set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b2afd9f313e..14086514ff7 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2750,6 +2750,9 @@ type:
| BINARY '(' NUM ')' { Lex->length=$3.str;
Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_STRING; }
+ | BINARY { Lex->length= (char*) "1";
+ Lex->charset=&my_charset_bin;
+ $$=FIELD_TYPE_STRING; }
| varchar '(' NUM ')' opt_binary { Lex->length=$3.str;
$$=FIELD_TYPE_VAR_STRING; }
| nvarchar '(' NUM ')' { Lex->length=$3.str;
@@ -5413,11 +5416,12 @@ do: DO_SYM
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_DO;
- if (!(lex->insert_list = new List_item))
- YYABORT;
+ mysql_init_select(lex);
+ }
+ expr_list
+ {
+ Lex->insert_list= $3;
}
- values
- {}
;
/*
diff --git a/sql/structs.h b/sql/structs.h
index cc053e2e2fd..4f0044e4f82 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -89,7 +89,12 @@ typedef struct st_key {
enum ha_key_alg algorithm;
KEY_PART_INFO *key_part;
char *name; /* Name of key */
- ulong *rec_per_key; /* Key part distribution */
+ /*
+ Array of AVG(#records with the same field value) for 1st ... Nth key part.
+ 0 means 'not known'.
+ For temporary heap tables this member is NULL.
+ */
+ ulong *rec_per_key;
union {
int bdb_return_if_eq;
} handler;