diff options
author | unknown <monty@mashka.mysql.fi> | 2003-09-05 17:06:36 +0300 |
---|---|---|
committer | unknown <monty@mashka.mysql.fi> | 2003-09-05 17:06:36 +0300 |
commit | 07cacdcbe73670f9d2fde0adf68f5e2472d7c6bd (patch) | |
tree | 572e3b87fc0d320cc803880aeb73ed3658a330c9 | |
parent | a65f5081ba3b326b06f9cece549d7e2e319d8aba (diff) | |
parent | 04ff15001df1cf318e45a7a7abeb30ed9e578027 (diff) | |
download | mariadb-git-07cacdcbe73670f9d2fde0adf68f5e2472d7c6bd.tar.gz |
Merge bk-internal.mysql.com:/home/bk/mysql-4.0
into mashka.mysql.fi:/home/my/mysql-4.0
-rw-r--r-- | client/mysqldump.c | 158 | ||||
-rw-r--r-- | myisam/mi_locking.c | 6 | ||||
-rw-r--r-- | myisam/mi_open.c | 9 | ||||
-rw-r--r-- | myisam/mi_update.c | 32 | ||||
-rw-r--r-- | mysql-test/r/myisam.result | 22 | ||||
-rw-r--r-- | mysql-test/t/myisam.test | 34 | ||||
-rw-r--r-- | sql/sql_acl.cc | 10 |
7 files changed, 184 insertions, 87 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index f1425faf0ed..6ef9d75249d 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -36,7 +36,7 @@ ** Added --single-transaction option 06/06/2002 by Peter Zaitsev */ -#define DUMP_VERSION "9.08" +#define DUMP_VERSION "9.09" #include <my_global.h> #include <my_sys.h> @@ -257,7 +257,7 @@ static int dump_all_tables_in_db(char *db); static int init_dumping(char *); static int dump_databases(char **); static int dump_all_databases(); -static char *quote_name(char *name, char *buff); +static char *quote_name(const char *name, char *buff, my_bool force); static void print_quoted_xml(FILE *output, char *fname, char *str, uint len); static void print_version(void) @@ -542,33 +542,43 @@ static my_bool test_if_special_chars(const char *str) return 0; } /* test_if_special_chars */ -static char *quote_name(char *name, char *buff) + +static char *quote_name(const char *name, char *buff, my_bool force) { - char *end; - if (!opt_quoted && !test_if_special_chars(name)) - return name; - buff[0]=QUOTE_CHAR; - end=strmov(buff+1,name); - end[0]=QUOTE_CHAR; - end[1]=0; + char *to= buff; + if (!force && !opt_quoted && !test_if_special_chars(name)) + return (char*) name; + *to++= QUOTE_CHAR; + while (*name) + { + if (*name == QUOTE_CHAR) + *to= QUOTE_CHAR; + *to++= *name++; + } + to[0]=QUOTE_CHAR; + to[1]=0; return buff; } /* quote_name */ /* -** getStructure -- retrievs database structure, prints out corresponding -** CREATE statement and fills out insert_pat. -** Return values: number of fields in table, 0 if error + getStructure -- retrievs database structure, prints out corresponding + CREATE statement and fills out insert_pat. + + RETURN + number of fields in table, 0 if error */ + static uint getTableStructure(char *table, char* db) { MYSQL_RES *tableRes; MYSQL_ROW row; my_bool init=0; uint numFields; - char *strpos, *table_name; + char *strpos, *result_table, *opt_quoted_table; const char *delayed; - char name_buff[NAME_LEN+3],table_buff[NAME_LEN+3]; + char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3]; + char table_buff2[NAME_LEN*2+3]; FILE *sql_file = md_result_file; DBUG_ENTER("getTableStructure"); @@ -578,7 +588,8 @@ static uint getTableStructure(char *table, char* db) fprintf(stderr, "-- Retrieving table structure for table %s...\n", table); sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", (opt_quoted || opt_keywords)); - table_name=quote_name(table,table_buff); + result_table= quote_name(table, table_buff, 1); + opt_quoted_table= quote_name(table, table_buff2, 0); if (!mysql_query(sock,insert_pat)) { /* using SHOW CREATE statement */ @@ -587,11 +598,11 @@ static uint getTableStructure(char *table, char* db) /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; - sprintf(buff,"show create table `%s`",table); + sprintf(buff,"show create table %s", result_table); if (mysql_query(sock, buff)) { - fprintf(stderr, "%s: Can't get CREATE TABLE for table '%s' (%s)\n", - my_progname, table, mysql_error(sock)); + fprintf(stderr, "%s: Can't get CREATE TABLE for table %s (%s)\n", + my_progname, result_table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -610,10 +621,10 @@ static uint getTableStructure(char *table, char* db) write_header(sql_file, db); } if (!opt_xml) - fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n", - table); + fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n", + result_table); if (opt_drop) - fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",table_name); + fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table); tableRes=mysql_store_result(sock); row=mysql_fetch_row(tableRes); @@ -621,11 +632,11 @@ static uint getTableStructure(char *table, char* db) fprintf(sql_file, "%s;\n", row[1]); mysql_free_result(tableRes); } - sprintf(insert_pat,"show fields from %s",table_name); + sprintf(insert_pat,"show fields from %s", result_table); if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock))) { - fprintf(stderr, "%s: Can't get info about table: '%s'\nerror: %s\n", - my_progname, table, mysql_error(sock)); + fprintf(stderr, "%s: Can't get info about table: %s\nerror: %s\n", + my_progname, result_table, mysql_error(sock)); if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); @@ -633,10 +644,11 @@ static uint getTableStructure(char *table, char* db) } if (cFlag) - sprintf(insert_pat, "INSERT %sINTO %s (", delayed, table_name); + sprintf(insert_pat, "INSERT %sINTO %s (", delayed, opt_quoted_table); else { - sprintf(insert_pat, "INSERT %sINTO %s VALUES ", delayed, table_name); + sprintf(insert_pat, "INSERT %sINTO %s VALUES ", delayed, + opt_quoted_table); if (!extended_insert) strcat(insert_pat,"("); } @@ -651,7 +663,7 @@ static uint getTableStructure(char *table, char* db) } init=1; if (cFlag) - strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME],name_buff)); + strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME], name_buff, 0)); } numFields = (uint) mysql_num_rows(tableRes); mysql_free_result(tableRes); @@ -661,11 +673,11 @@ static uint getTableStructure(char *table, char* db) /* fprintf(stderr, "%s: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n", my_progname, mysql_error(sock)); */ - sprintf(insert_pat,"show fields from %s",table_name); + sprintf(insert_pat,"show fields from %s", result_table); if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock))) { - fprintf(stderr, "%s: Can't get info about table: '%s'\nerror: %s\n", - my_progname, table, mysql_error(sock)); + fprintf(stderr, "%s: Can't get info about table: %s\nerror: %s\n", + my_progname, result_table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -687,17 +699,17 @@ static uint getTableStructure(char *table, char* db) write_header(sql_file, db); } if (!opt_xml) - fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n", - table); + fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n", + result_table); if (opt_drop) - fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",table_name); - fprintf(sql_file, "CREATE TABLE %s (\n", table_name); + fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",result_table); + fprintf(sql_file, "CREATE TABLE %s (\n", result_table); } if (cFlag) - sprintf(insert_pat, "INSERT %sINTO %s (", delayed, table_name); + sprintf(insert_pat, "INSERT %sINTO %s (", delayed, result_table); else { - sprintf(insert_pat, "INSERT %sINTO %s VALUES ", delayed, table_name); + sprintf(insert_pat, "INSERT %sINTO %s VALUES ", delayed, result_table); if (!extended_insert) strcat(insert_pat,"("); } @@ -715,15 +727,17 @@ static uint getTableStructure(char *table, char* db) } init=1; if (cFlag) - strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME],name_buff)); + strpos=strmov(strpos,quote_name(row[SHOW_FIELDNAME], name_buff, 0)); if (!tFlag) { if (opt_keywords) - fprintf(sql_file, " %s.%s %s", table_name, - quote_name(row[SHOW_FIELDNAME],name_buff), row[SHOW_TYPE]); + fprintf(sql_file, " %s.%s %s", result_table, + quote_name(row[SHOW_FIELDNAME],name_buff, 0), + row[SHOW_TYPE]); else fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME], - name_buff), row[SHOW_TYPE]); + name_buff, 0), + row[SHOW_TYPE]); if (row[SHOW_DEFAULT]) { fputs(" DEFAULT ", sql_file); @@ -742,11 +756,11 @@ static uint getTableStructure(char *table, char* db) /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; uint keynr,primary_key; - sprintf(buff,"show keys from %s",table_name); + sprintf(buff,"show keys from %s", result_table); if (mysql_query(sock, buff)) { - fprintf(stderr, "%s: Can't get keys for table '%s' (%s)\n", - my_progname, table, mysql_error(sock)); + fprintf(stderr, "%s: Can't get keys for table %s (%s)\n", + my_progname, result_table, mysql_error(sock)); if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); @@ -783,15 +797,15 @@ static uint getTableStructure(char *table, char* db) putc(')', sql_file); if (atoi(row[1])) /* Test if duplicate key */ /* Duplicate allowed */ - fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff)); + fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0)); else if (keynr == primary_key) fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */ else - fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff)); + fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,0)); } else putc(',', sql_file); - fputs(quote_name(row[4],name_buff), sql_file); + fputs(quote_name(row[4], name_buff, 0), sql_file); if (row[7]) fprintf(sql_file, " (%s)",row[7]); /* Sub key */ } @@ -802,23 +816,23 @@ static uint getTableStructure(char *table, char* db) /* Get MySQL specific create options */ if (create_options) { - sprintf(buff,"show table status like '%s'",table); + sprintf(buff,"show table status like %s",result_table); if (mysql_query(sock, buff)) { if (mysql_errno(sock) != ER_PARSE_ERROR) { /* If old MySQL version */ if (verbose) fprintf(stderr, - "-- Warning: Couldn't get status information for table '%s' (%s)\n", - table,mysql_error(sock)); + "-- Warning: Couldn't get status information for table %s (%s)\n", + result_table,mysql_error(sock)); } } else if (!(tableRes=mysql_store_result(sock)) || !(row=mysql_fetch_row(tableRes))) { fprintf(stderr, - "Error: Couldn't read status information for table '%s' (%s)\n", - table,mysql_error(sock)); + "Error: Couldn't read status information for table %s (%s)\n", + result_table,mysql_error(sock)); } else { @@ -902,6 +916,7 @@ static char *field_escape(char *to,const char *from,uint length) static void dumpTable(uint numFields, char *table) { char query[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; + char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table; MYSQL_RES *res; MYSQL_FIELD *field; MYSQL_ROW row; @@ -909,6 +924,8 @@ static void dumpTable(uint numFields, char *table) if (verbose) fprintf(stderr, "-- Sending SELECT query...\n"); + result_table= quote_name(table,table_buff, 1); + opt_quoted_table= quote_name(table, table_buff2, 0); if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; @@ -935,7 +952,7 @@ static void dumpTable(uint numFields, char *table) end= add_load_option(end, lines_terminated, " LINES TERMINATED BY"); *end= '\0'; - sprintf(buff," FROM %s",quote_name(table,table_buff)); + sprintf(buff," FROM %s", result_table); end= strmov(end,buff); if (where) end= strxmov(end, " WHERE ",where,NullS); @@ -948,10 +965,10 @@ static void dumpTable(uint numFields, char *table) else { if (!opt_xml) - fprintf(md_result_file,"\n--\n-- Dumping data for table '%s'\n--\n", - table); + fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n", + result_table); sprintf(query, "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s", - quote_name(table,table_buff)); + result_table); if (where) { if (!opt_xml) @@ -978,18 +995,17 @@ static void dumpTable(uint numFields, char *table) fprintf(stderr, "-- Retrieving rows...\n"); if (mysql_num_fields(res) != numFields) { - fprintf(stderr,"%s: Error in field count for table: '%s' ! Aborting.\n", - my_progname,table); + fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n", + my_progname, result_table); safe_exit(EX_CONSCHECK); return; } if (opt_disable_keys) - fprintf(md_result_file,"/*!40000 ALTER TABLE %s DISABLE KEYS */;\n", - quote_name(table, table_buff)); + fprintf(md_result_file, "\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n", + opt_quoted_table); if (opt_lock) - fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", - quote_name(table,table_buff)); + fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table); total_length=net_buffer_length; /* Force row break */ row_break=0; @@ -1017,8 +1033,8 @@ static void dumpTable(uint numFields, char *table) { if (!(field = mysql_fetch_field(res))) { - sprintf(query,"%s: Not enough fields from table '%s'! Aborting.\n", - my_progname,table); + sprintf(query,"%s: Not enough fields from table %s! Aborting.\n", + my_progname, result_table); fputs(query,stderr); safe_exit(EX_CONSCHECK); return; @@ -1142,11 +1158,11 @@ static void dumpTable(uint numFields, char *table) fflush(md_result_file); if (mysql_errno(sock)) { - sprintf(query,"%s: Error %d: %s when dumping table '%s' at row: %ld\n", + sprintf(query,"%s: Error %d: %s when dumping table %s at row: %ld\n", my_progname, mysql_errno(sock), mysql_error(sock), - table, + result_table, rownr); fputs(query,stderr); safe_exit(EX_CONSCHECK); @@ -1156,7 +1172,7 @@ static void dumpTable(uint numFields, char *table) fputs("UNLOCK TABLES;\n", md_result_file); if (opt_disable_keys) fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n", - quote_name(table,table_buff)); + opt_quoted_table); if (opt_autocommit) fprintf(md_result_file, "commit;\n"); mysql_free_result(res); @@ -1273,7 +1289,7 @@ static int dump_all_tables_in_db(char *database) { char *table; uint numrows; - char table_buff[NAME_LEN+3]; + char table_buff[NAME_LEN*2+3]; if (init_dumping(database)) return 1; @@ -1285,7 +1301,7 @@ static int dump_all_tables_in_db(char *database) init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); for (numrows=0 ; (table = getTableName(1)) ; numrows++) { - dynstr_append(&query, quote_name(table, table_buff)); + dynstr_append(&query, quote_name(table, table_buff, 1)); dynstr_append(&query, " READ /*!32311 LOCAL */,"); } if (numrows && mysql_real_query(sock, query.str, query.length-1)) @@ -1317,7 +1333,7 @@ static int dump_all_tables_in_db(char *database) static int dump_selected_tables(char *db, char **table_names, int tables) { uint numrows; - char table_buff[NAME_LEN+3]; + char table_buff[NAME_LEN*+3]; if (init_dumping(db)) return 1; @@ -1329,7 +1345,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); for (i=0 ; i < tables ; i++) { - dynstr_append(&query, quote_name(table_names[i], table_buff)); + dynstr_append(&query, quote_name(table_names[i], table_buff, 1)); dynstr_append(&query, " READ /*!32311 LOCAL */,"); } if (mysql_real_query(sock, query.str, query.length-1)) diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index 18daebffa85..a707eb294a9 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -76,6 +76,8 @@ int mi_lock_database(MI_INFO *info, int lock_type) } if (!count) { + DBUG_PRINT("info",("changed: %u w_locks: %u", + (uint) share->changed, share->w_locks)); if (share->changed && !share->w_locks) { share->state.process= share->last_process=share->this_process; @@ -352,6 +354,8 @@ int _mi_writeinfo(register MI_INFO *info, uint operation) int error,olderror; MYISAM_SHARE *share=info->s; DBUG_ENTER("_mi_writeinfo"); + DBUG_PRINT("info",("operation: %u tot_locks: %u", operation, + share->tot_locks)); error=0; if (share->tot_locks == 0) @@ -379,9 +383,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation) my_errno=olderror; } else if (operation) - { share->changed= 1; /* Mark keyfile changed */ - } DBUG_RETURN(error); } /* _mi_writeinfo */ diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 857ca1486fd..580261d8078 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -730,6 +730,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite) uchar *ptr=buff; uint i, keys= (uint) state->header.keys, key_blocks=state->header.max_block_size; + DBUG_ENTER("mi_state_info_write"); memcpy_fixed(ptr,&state->header,sizeof(state->header)); ptr+=sizeof(state->header); @@ -780,10 +781,10 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite) } if (pWrite & 1) - return my_pwrite(file,(char*) buff, (uint) (ptr-buff), 0L, - MYF(MY_NABP | MY_THREADSAFE)); - else - return my_write(file, (char*) buff, (uint) (ptr-buff), MYF(MY_NABP)); + DBUG_RETURN(my_pwrite(file,(char*) buff, (uint) (ptr-buff), 0L, + MYF(MY_NABP | MY_THREADSAFE))); + DBUG_RETURN(my_write(file, (char*) buff, (uint) (ptr-buff), + MYF(MY_NABP))); } diff --git a/myisam/mi_update.c b/myisam/mi_update.c index 1614d6ca19d..f9ed969d8b5 100644 --- a/myisam/mi_update.c +++ b/myisam/mi_update.c @@ -94,7 +94,14 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) if (_mi_ft_cmp(info,i,oldrec, newrec)) { if ((int) i == info->lastinx) + { + /* + We are changeing the index we are reading on. Mark that + the index data has changed and we need to do a full search + when doing read-next + */ key_changed|=HA_STATE_WRITTEN; + } changed|=((ulonglong) 1 << i); if (_mi_ft_update(info,i,(char*) old_key,oldrec,newrec,pos)) goto err; @@ -121,25 +128,36 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) } /* If we are running with external locking, we must update the index file - that something has changed + that something has changed. */ if (changed || !my_disable_locking) - key_changed|= HA_STATE_KEY_CHANGED; + key_changed|= HA_STATE_CHANGED; if (share->calc_checksum) { info->checksum=(*share->calc_checksum)(info,newrec); - key_changed|= HA_STATE_KEY_CHANGED; /* Must update index file */ + /* Store new checksum in index file header */ + key_changed|= HA_STATE_CHANGED; } { - /* Don't update index file if data file is not extended */ + /* + Don't update index file if data file is not extended and no status + information changed + */ MI_STATUS_INFO state; + ha_rows org_split; + my_off_t org_delete_link; + memcpy((char*) &state, (char*) info->state, sizeof(state)); + org_split= share->state.split; + org_delete_link= share->state.dellink; if ((*share->update_record)(info,pos,newrec)) goto err; if (!key_changed && - memcmp((char*) &state, (char*) info->state, sizeof(state))) - key_changed|= HA_STATE_KEY_CHANGED; /* Must update index file */ + (memcmp((char*) &state, (char*) info->state, sizeof(state)) || + org_split != share->state.split || + org_delete_link != share->state.dellink)) + key_changed|= HA_STATE_CHANGED; /* Must update index file */ } if (auto_key_changed) update_auto_increment(info,newrec); @@ -163,7 +181,7 @@ err: DBUG_PRINT("error",("key: %d errno: %d",i,my_errno)); save_errno=my_errno; if (changed) - key_changed|= HA_STATE_KEY_CHANGED; + key_changed|= HA_STATE_CHANGED; if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL) { info->errkey= (int) i; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index e78e12c01d5..3052af3499d 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -364,3 +364,25 @@ explain select * from t1 force index (a) where a=0 or a=2; table type possible_keys key key_len ref rows Extra t1 range a a 4 NULL 4 Using where drop table t1,t2; +create table t1 (a int not null auto_increment primary key, b varchar(255)); +insert into t1 (b) values (repeat('a',100)),(repeat('b',100)),(repeat('c',100)); +update t1 set b=repeat(left(b,1),200) where a=1; +delete from t1 where (a & 1)= 0; +update t1 set b=repeat('e',200) where a=1; +flush tables; +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +update t1 set b=repeat(left(b,1),255) where a between 1 and 5; +update t1 set b=repeat(left(b,1),10) where a between 32 and 43; +update t1 set b=repeat(left(b,1),2) where a between 64 and 66; +update t1 set b=repeat(left(b,1),65) where a between 67 and 70; +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +insert into t1 (b) values (repeat('z',100)); +update t1 set b="test" where left(b,1) > 'n'; +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 02c92109816..a5490153a17 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -352,3 +352,37 @@ explain select * from t1,t2 force index(c) where t1.a=t2.a; explain select * from t1 where a=0 or a=2; explain select * from t1 force index (a) where a=0 or a=2; drop table t1,t2; + +# +# Test bug when updating a split dynamic row where keys are not changed +# + +create table t1 (a int not null auto_increment primary key, b varchar(255)); +insert into t1 (b) values (repeat('a',100)),(repeat('b',100)),(repeat('c',100)); +update t1 set b=repeat(left(b,1),200) where a=1; +delete from t1 where (a & 1)= 0; +update t1 set b=repeat('e',200) where a=1; +flush tables; +check table t1; + +# +# check updating with keys +# + +disable_query_log; +let $1 = 100; +while ($1) +{ + eval insert into t1 (b) values (repeat(char(($1 & 32)+65), $1)); + dec $1; +} +enable_query_log; +update t1 set b=repeat(left(b,1),255) where a between 1 and 5; +update t1 set b=repeat(left(b,1),10) where a between 32 and 43; +update t1 set b=repeat(left(b,1),2) where a between 64 and 66; +update t1 set b=repeat(left(b,1),65) where a between 67 and 70; +check table t1; +insert into t1 (b) values (repeat('z',100)); +update t1 set b="test" where left(b,1) > 'n'; +check table t1; +drop table t1; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3b5e9983b80..b76bbe8c730 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1607,6 +1607,7 @@ class GRANT_TABLE :public Sql_alloc public: char *host,*db,*user,*tname, *hash_key; ulong privs, cols; + ulong sort; uint key_length; HASH hash_columns; GRANT_TABLE (const char *h, const char *d,const char *u, const char *t, @@ -1616,6 +1617,7 @@ public: host = strdup_root(&memex,h); db = strdup_root(&memex,d); user = strdup_root(&memex,u); + sort= get_sort(3,host,db,user); tname= strdup_root(&memex,t); if (lower_case_table_names) { @@ -1638,6 +1640,7 @@ public: user = get_field(&memex,form,2); if (!user) user=(char*) ""; + sort= get_sort(3,host,db,user); tname = get_field(&memex,form,3); if (!host || !db || !tname) { @@ -1745,9 +1748,10 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, } else { - if ((host && !wild_case_compare(host,grant_table->host)) || - (ip && !wild_case_compare(ip,grant_table->host))) - found=grant_table; // Host ok + if (((host && !wild_case_compare(host,grant_table->host)) || + (ip && !wild_case_compare(ip,grant_table->host))) && + (!found || found->sort < grant_table->sort)) + found=grant_table; } } return found; |