diff options
author | serg@serg.mylan <> | 2004-11-17 18:04:36 +0100 |
---|---|---|
committer | serg@serg.mylan <> | 2004-11-17 18:04:36 +0100 |
commit | e68bd85b77ef425b69996fa83ff2d430ac172c64 (patch) | |
tree | 35f1caf73d4e61d1cb7338841a38299682005317 /sql | |
parent | 2074aeecb8a399602d5c0e9cc5770578453c0edc (diff) | |
parent | 19067008b8449df5ee7b4182300de53692fd349d (diff) | |
download | mariadb-git-e68bd85b77ef425b69996fa83ff2d430ac172c64.tar.gz |
merged
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_heap.cc | 57 | ||||
-rw-r--r-- | sql/ha_heap.h | 9 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 9 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/slave.cc | 4 | ||||
-rw-r--r-- | sql/slave.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 12 | ||||
-rw-r--r-- | sql/structs.h | 7 |
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; |