#At file:///home/thek/Development/cpp/mysqlbzr/mysql-5.1-bugteam/
2707 Kristofer Pettersson 2008-07-21 [merge]
Auto merge
modified:
client/mysql.cc
mysql-test/include/mix1.inc
mysql-test/r/client_xml.result
mysql-test/r/innodb_mysql.result
mysql-test/r/mysql.result
mysql-test/suite/rpl/r/rpl_server_id1.result
mysql-test/suite/rpl/r/rpl_temporary.result
mysql-test/suite/rpl/t/disabled.def
mysql-test/suite/rpl/t/rpl_server_id1.test
mysql-test/suite/rpl/t/rpl_temporary.test
mysql-test/t/client_xml.test
mysql-test/t/mysql_delimiter.sql
mysys/default.c
sql/event_db_repository.cc
sql/events.cc
sql/filesort.cc
sql/mysql_priv.h
sql/opt_range.cc
sql/opt_range.h
sql/records.cc
sql/sql_acl.cc
sql/sql_delete.cc
sql/sql_help.cc
sql/sql_plugin.cc
sql/sql_select.cc
sql/sql_servers.cc
sql/sql_table.cc
sql/sql_udf.cc
sql/sql_update.cc
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc 2008-06-25 09:44:55 +0000
+++ b/client/mysql.cc 2008-07-18 12:00:45 +0000
@@ -2101,6 +2101,37 @@ static bool add_line(String &buffer,char
continue;
}
}
+ else if (!*ml_comment && !*in_string &&
+ (end_of_line - pos) >= 10 &&
+ !my_strnncoll(charset_info, (uchar*) pos, 10,
+ (const uchar*) "delimiter ", 10))
+ {
+ // Flush previously accepted characters
+ if (out != line)
+ {
+ buffer.append(line, (uint32) (out - line));
+ out= line;
+ }
+
+ // Flush possible comments in the buffer
+ if (!buffer.is_empty())
+ {
+ if (com_go(&buffer, 0) > 0) // < 0 is not fatal
+ DBUG_RETURN(1);
+ buffer.length(0);
+ }
+
+ /*
+ Delimiter wants the get rest of the given line as argument to
+ allow one to change ';' to ';;' and back
+ */
+ buffer.append(pos);
+ if (com_delimiter(&buffer, pos) > 0)
+ DBUG_RETURN(1);
+
+ buffer.length(0);
+ break;
+ }
else if (!*ml_comment && !*in_string && is_prefix(pos, delimiter))
{
// Found a statement. Continue parsing after the delimiter
=== modified file 'mysql-test/include/mix1.inc'
--- a/mysql-test/include/mix1.inc 2008-06-17 14:12:21 +0000
+++ b/mysql-test/include/mix1.inc 2008-07-17 15:51:24 +0000
@@ -1103,6 +1103,24 @@ set @my_innodb_commit_concurrency=@@glob
set global innodb_commit_concurrency=0;
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
+#
+# Bug #37830: ORDER BY ASC/DESC - no difference
+#
+
+CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
+ ENGINE=InnoDB;
+
+INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
+INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
+
+# should be range access
+EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+
+# should produce '8 7 6 5 4' for a
+SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY
=== modified file 'mysql-test/r/client_xml.result'
--- a/mysql-test/r/client_xml.result 2008-04-30 13:28:19 +0000
+++ b/mysql-test/r/client_xml.result 2008-07-18 12:00:45 +0000
@@ -1,5 +1,6 @@
set @old_concurrent_insert= @@global.concurrent_insert;
set @@global.concurrent_insert= 0;
+drop table if exists t1;
create table t1 (
`a&b` int,
`a<b` int,
=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result 2008-06-17 14:12:21 +0000
+++ b/mysql-test/r/innodb_mysql.result 2008-07-17 15:51:24 +0000
@@ -1362,6 +1362,21 @@ set global innodb_autoextend_increment=@
set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
set global innodb_commit_concurrency=0;
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
+CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
+ENGINE=InnoDB;
+INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
+INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
+EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1_b PRIMARY 4 NULL 8 Using where
+SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
+a b c
+8 1 1
+7 1 1
+6 1 1
+5 1 1
+4 1 1
+DROP TABLE t1;
End of 5.0 tests
CREATE TABLE `t2` (
`k` int(11) NOT NULL auto_increment,
=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result 2008-06-25 09:44:55 +0000
+++ b/mysql-test/r/mysql.result 2008-07-18 12:00:45 +0000
@@ -38,8 +38,6 @@ t2
t3
Tables_in_test
t1
-delimiter
-1
_
Test delimiter : from command line
a
=== modified file 'mysql-test/suite/rpl/r/rpl_server_id1.result'
--- a/mysql-test/suite/rpl/r/rpl_server_id1.result 2008-02-20 21:18:01 +0000
+++ b/mysql-test/suite/rpl/r/rpl_server_id1.result 2008-07-18 11:53:16 +0000
@@ -9,42 +9,5 @@ stop slave;
change master to master_port=SLAVE_PORT;
start slave;
*** must be having the replicate-same-server-id IO thread error ***
-show slave status;
-Slave_IO_State
-Master_Host 127.0.0.1
-Master_User root
-Master_Port SLAVE_PORT
-Connect_Retry 1
-Master_Log_File
-Read_Master_Log_Pos 4
-Relay_Log_File slave-relay-bin.000001
-Relay_Log_Pos 4
-Relay_Master_Log_File
-Slave_IO_Running No
-Slave_SQL_Running #
-Replicate_Do_DB
-Replicate_Ignore_DB
-Replicate_Do_Table
-Replicate_Ignore_Table #
-Replicate_Wild_Do_Table
-Replicate_Wild_Ignore_Table #
-Last_Errno #
-Last_Error #
-Skip_Counter 0
-Exec_Master_Log_Pos 0
-Relay_Log_Space 106
-Until_Condition None
-Until_Log_File
-Until_Log_Pos 0
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master NULL
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno 1593
-Last_IO_Error Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).
-Last_SQL_Errno #
-Last_SQL_Error #
+Slave_IO_Errno= 1593
+Slave_IO_Error= Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).
=== modified file 'mysql-test/suite/rpl/r/rpl_temporary.result'
--- a/mysql-test/suite/rpl/r/rpl_temporary.result 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_temporary.result 2008-07-18 08:20:55 +0000
@@ -76,9 +76,9 @@ drop table t1,t2;
create temporary table t3 (f int);
create temporary table t4 (f int);
create table t5 (f int);
-select id from information_schema.processlist where command='Binlog Dump' into @id;
-kill @id;
+stop slave;
insert into t5 select * from t4;
+start slave;
select * from t5 /* must be 1 after reconnection */;
f
drop temporary table t4;
=== modified file 'mysql-test/suite/rpl/t/disabled.def'
--- a/mysql-test/suite/rpl/t/disabled.def 2008-06-19 10:39:48 +0000
+++ b/mysql-test/suite/rpl/t/disabled.def 2008-07-18 11:53:16 +0000
@@ -12,4 +12,4 @@
rpl_redirect : Failure is sporadic and and the test is superfluous (mats)
rpl_innodb_bug28430 : Failure on Solaris Bug #36793
-rpl_server_id1 : Bug #36818 rpl_server_id1 fails expecting slave has stopped (azundris)
+
=== modified file 'mysql-test/suite/rpl/t/rpl_server_id1.test'
--- a/mysql-test/suite/rpl/t/rpl_server_id1.test 2008-05-20 15:14:03 +0000
+++ b/mysql-test/suite/rpl/t/rpl_server_id1.test 2008-07-18 11:53:16 +0000
@@ -10,17 +10,15 @@ reset master;
# replicate ourselves
stop slave;
-source include/wait_for_slave_to_stop.inc;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval change master to master_port=$SLAVE_MYPORT;
start slave;
+let $slave_param= Last_IO_Errno;
+let $slave_param_value= 1593;
+source include/wait_for_slave_param.inc;
--echo *** must be having the replicate-same-server-id IO thread error ***
-
-source include/wait_for_slave_io_to_stop.inc;
-
---replace_result $SLAVE_MYPORT SLAVE_PORT
---replace_column 12 # 16 # 19 # 20 # 18 # 37 # 38 #
-query_vertical show slave status;
-
-# End of 4.1 tests
+let $last_io_errno= query_get_value("show slave status", Last_IO_Errno, 1);
+let $last_io_error= query_get_value("show slave status", Last_IO_Error, 1);
+echo Slave_IO_Errno= $last_io_errno;
+echo Slave_IO_Error= $last_io_error;
=== modified file 'mysql-test/suite/rpl/t/rpl_temporary.test'
--- a/mysql-test/suite/rpl/t/rpl_temporary.test 2008-03-12 12:07:35 +0000
+++ b/mysql-test/suite/rpl/t/rpl_temporary.test 2008-07-18 08:20:55 +0000
@@ -138,20 +138,21 @@ sync_slave_with_master;
#
# Bug#17284 erroneous temp table cleanup on slave
+# The test targets at verifying that reconnected slave
+# retained the former session's temporary tables
#
-
connection master;
create temporary table t4 (f int);
create table t5 (f int);
sync_slave_with_master;
+# connection slave
+stop slave; # to prepare for reconnecting w/o waiting for timeout
connection master;
-# find dumper's $id
-select id from information_schema.processlist where command='Binlog Dump' into @id;
-kill @id; # to stimulate reconnection by slave w/o timeout
insert into t5 select * from t4;
save_master_pos;
connection slave;
+start slave;
sync_with_master;
select * from t5 /* must be 1 after reconnection */;
=== modified file 'mysql-test/t/client_xml.test'
--- a/mysql-test/t/client_xml.test 2008-04-30 13:28:19 +0000
+++ b/mysql-test/t/client_xml.test 2008-07-18 12:00:45 +0000
@@ -6,6 +6,9 @@
# the data is actually in the table).
set @old_concurrent_insert= @@global.concurrent_insert;
set @@global.concurrent_insert= 0;
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
# Test of the xml output of the 'mysql' and 'mysqldump' clients -- makes
# sure that basic encoding issues are handled properly
=== modified file 'mysql-test/t/mysql_delimiter.sql'
--- a/mysql-test/t/mysql_delimiter.sql 2008-06-25 09:44:55 +0000
+++ b/mysql-test/t/mysql_delimiter.sql 2008-07-18 12:00:45 +0000
@@ -61,12 +61,6 @@ show tables//
delimiter ; # Reset delimiter
#
-# Bug #33812: mysql client incorrectly parsing DELIMITER
-#
-select a as delimiter from t1
-delimiter ; # Reset delimiter
-
-#
# Bug #36244: MySQL CLI doesn't recognize standalone -- as comment
# before DELIMITER statement
#
=== modified file 'mysys/default.c'
--- a/mysys/default.c 2008-07-02 15:54:54 +0000
+++ b/mysys/default.c 2008-07-18 12:00:45 +0000
@@ -1026,7 +1026,7 @@ static const char *my_get_module_parent(
{
char *last= NULL;
char *end;
- if (!GetModuleFileName(NULL, buf, size))
+ if (!GetModuleFileName(NULL, buf, (DWORD) size))
return NULL;
end= strend(buf);
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2008-02-07 10:47:39 +0000
+++ b/sql/event_db_repository.cc 2008-07-15 17:46:02 +0000
@@ -452,7 +452,7 @@ Event_db_repository::table_scan_all_for_
READ_RECORD read_record_info;
DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s");
- init_read_record(&read_record_info, thd, event_table, NULL, 1, 0);
+ init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE);
/*
rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE,
@@ -925,7 +925,7 @@ Event_db_repository::drop_events_by_fiel
DBUG_VOID_RETURN;
/* only enabled events are in memory, so we go now and delete the rest */
- init_read_record(&read_record_info, thd, table, NULL, 1, 0);
+ init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE);
while (!ret && !(read_record_info.read_record(&read_record_info)) )
{
char *et_field= get_field(thd->mem_root, table->field[field]);
=== modified file 'sql/events.cc'
--- a/sql/events.cc 2008-05-09 07:43:02 +0000
+++ b/sql/events.cc 2008-07-15 17:46:02 +0000
@@ -1149,7 +1149,7 @@ Events::load_events_from_db(THD *thd)
DBUG_RETURN(TRUE);
}
- init_read_record(&read_record_info, thd, table, NULL, 0, 1);
+ init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE);
while (!(read_record_info.read_record(&read_record_info)))
{
Event_queue_element *et;
=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc 2008-07-24 13:41:55 +0000
+++ b/sql/filesort.cc 2008-07-17 18:26:55 +0000
@@ -410,6 +410,56 @@ static uchar *read_buffpek_from_file(IO_
DBUG_RETURN(tmp);
}
+#ifndef DBUG_OFF
+/*
+ Print a text, SQL-like record representation into dbug trace.
+
+ Note: this function is a work in progress: at the moment
+ - column read bitmap is ignored (can print garbage for unused columns)
+ - there is no quoting
+*/
+static void dbug_print_record(TABLE *table, bool print_rowid)
+{
+ char buff[1024];
+ Field **pfield;
+ String tmp(buff,sizeof(buff),&my_charset_bin);
+ DBUG_LOCK_FILE;
+
+ fprintf(DBUG_FILE, "record (");
+ for (pfield= table->field; *pfield ; pfield++)
+ fprintf(DBUG_FILE, "%s%s", (*pfield)->field_name, (pfield[1])? ", ":"");
+ fprintf(DBUG_FILE, ") = ");
+
+ fprintf(DBUG_FILE, "(");
+ for (pfield= table->field; *pfield ; pfield++)
+ {
+ Field *field= *pfield;
+
+ if (field->is_null())
+ fwrite("NULL", sizeof(char), 4, DBUG_FILE);
+
+ if (field->type() == MYSQL_TYPE_BIT)
+ (void) field->val_int_as_str(&tmp, 1);
+ else
+ field->val_str(&tmp);
+
+ fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
+ if (pfield[1])
+ fwrite(", ", sizeof(char), 2, DBUG_FILE);
+ }
+ fprintf(DBUG_FILE, ")");
+ if (print_rowid)
+ {
+ fprintf(DBUG_FILE, " rowid ");
+ for (uint i=0; i < table->file->ref_length; i++)
+ {
+ fprintf(DBUG_FILE, "%x", (uchar)table->file->ref[i]);
+ }
+ }
+ fprintf(DBUG_FILE, "\n");
+ DBUG_UNLOCK_FILE;
+}
+#endif
/**
Search after sort_keys and write them into tempfile.
@@ -488,13 +538,10 @@ static ha_rows find_all_keys(SORTPARAM *
current_thd->variables.read_buff_size);
}
- READ_RECORD read_record_info;
if (quick_select)
{
if (select->quick->reset())
DBUG_RETURN(HA_POS_ERROR);
- init_read_record(&read_record_info, current_thd, select->quick->head,
- select, 1, 1);
}
/* Remember original bitmaps */
@@ -514,12 +561,13 @@ static ha_rows find_all_keys(SORTPARAM *
{
if (quick_select)
{
- if ((error= read_record_info.read_record(&read_record_info)))
+ if ((error= select->quick->get_next()))
{
error= HA_ERR_END_OF_FILE;
break;
}
file->position(sort_form->record[0]);
+ DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE););
}
else /* Not quick-select */
{
@@ -576,15 +624,7 @@ static ha_rows find_all_keys(SORTPARAM *
if (thd->is_error())
break;
}
- if (quick_select)
- {
- /*
- index_merge quick select uses table->sort when retrieving rows, so free
- resoures it has allocated.
- */
- end_read_record(&read_record_info);
- }
- else
+ if (!quick_select)
{
(void) file->extra(HA_EXTRA_NO_CACHE); /* End cacheing of records */
if (!next_pos)
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2008-07-24 13:41:55 +0000
+++ b/sql/mysql_priv.h 2008-07-17 18:26:55 +0000
@@ -2175,8 +2175,8 @@ ulonglong get_datetime_value(THD *thd, I
int test_if_number(char *str,int *res,bool allow_wildcards);
void change_byte(uchar *,uint,char,char);
void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
- SQL_SELECT *select,
- int use_record_cache, bool print_errors);
+ SQL_SELECT *select, int use_record_cache,
+ bool print_errors, bool disable_rr_cache);
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
bool print_error, uint idx);
void end_read_record(READ_RECORD *info);
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2008-07-24 13:41:55 +0000
+++ b/sql/opt_range.cc 2008-07-17 18:28:42 +0000
@@ -7936,6 +7936,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
handler *file= head->file;
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
+ /* We're going to just read rowids. */
file->extra(HA_EXTRA_KEYREAD);
head->prepare_for_position();
@@ -7994,15 +7995,17 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
}
- DBUG_PRINT("info", ("ok"));
- /* ok, all row ids are in Unique */
+ /*
+ Ok all rowids are in the Unique now. The next call will initialize
+ head->sort structure so it can be used to iterate through the rowids
+ sequence.
+ */
result= unique->get(head);
delete unique;
doing_pk_scan= FALSE;
/* index_merge currently doesn't support "using index" at all */
file->extra(HA_EXTRA_NO_KEYREAD);
- /* start table scan */
- init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1, 1);
+ init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE);
DBUG_RETURN(result);
}
@@ -8028,6 +8031,7 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
{
result= HA_ERR_END_OF_FILE;
end_read_record(&read_record);
+ free_io_cache(head);
/* All rows from Unique have been retrieved, do a clustered PK scan */
if (pk_quick_select)
{
@@ -8556,7 +8560,8 @@ bool QUICK_RANGE_SELECT::row_in_ranges()
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
uint used_key_parts_arg)
- :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
+ :QUICK_RANGE_SELECT(*q), rev_it(rev_ranges),
+ used_key_parts (used_key_parts_arg)
{
QUICK_RANGE *r;
@@ -8598,10 +8603,11 @@ int QUICK_SELECT_DESC::get_next()
int result;
if (last_range)
{ // Already read through key
- result = ((last_range->flag & EQ_RANGE)
- ? file->index_next_same(record, last_range->min_key,
- last_range->min_length) :
- file->index_prev(record));
+ result = ((last_range->flag & EQ_RANGE &&
+ used_key_parts <= head->key_info[index].key_parts) ?
+ file->index_next_same(record, last_range->min_key,
+ last_range->min_length) :
+ file->index_prev(record));
if (!result)
{
if (cmp_prev(*rev_it.ref()) == 0)
@@ -8625,7 +8631,9 @@ int QUICK_SELECT_DESC::get_next()
continue;
}
- if (last_range->flag & EQ_RANGE)
+ if (last_range->flag & EQ_RANGE &&
+ used_key_parts <= head->key_info[index].key_parts)
+
{
result = file->index_read_map(record, last_range->max_key,
last_range->max_keypart_map,
@@ -8634,6 +8642,8 @@ int QUICK_SELECT_DESC::get_next()
else
{
DBUG_ASSERT(last_range->flag & NEAR_MAX ||
+ (last_range->flag & EQ_RANGE &&
+ used_key_parts > head->key_info[index].key_parts) ||
range_reads_after_key(last_range));
result=file->index_read_map(record, last_range->max_key,
last_range->max_keypart_map,
@@ -8731,54 +8741,6 @@ bool QUICK_SELECT_DESC::range_reads_afte
}
-/* TRUE if we are reading over a key that may have a NULL value */
-
-#ifdef NOT_USED
-bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
- uint used_key_parts)
-{
- uint offset, end;
- KEY_PART *key_part = key_parts,
- *key_part_end= key_part+used_key_parts;
-
- for (offset= 0, end = min(range_arg->min_length, range_arg->max_length) ;
- offset < end && key_part != key_part_end ;
- offset+= key_part++->store_length)
- {
- if (!memcmp((char*) range_arg->min_key+offset,
- (char*) range_arg->max_key+offset,
- key_part->store_length))
- continue;
-
- if (key_part->null_bit && range_arg->min_key[offset])
- return 1; // min_key is null and max_key isn't
- // Range doesn't cover NULL. This is ok if there is no more null parts
- break;
- }
- /*
- If the next min_range is > NULL, then we can use this, even if
- it's a NULL key
- Example: SELECT * FROM t1 WHERE a = 2 AND b >0 ORDER BY a DESC,b DESC;
-
- */
- if (key_part != key_part_end && key_part->null_bit)
- {
- if (offset >= range_arg->min_length || range_arg->min_key[offset])
- return 1; // Could be null
- key_part++;
- }
- /*
- If any of the key parts used in the ORDER BY could be NULL, we can't
- use the key to sort the data.
- */
- for (; key_part != key_part_end ; key_part++)
- if (key_part->null_bit)
- return 1; // Covers null part
- return 0;
-}
-#endif
-
-
void QUICK_RANGE_SELECT::add_info_string(String *str)
{
KEY *key_info= head->key_info + index;
=== modified file 'sql/opt_range.h'
--- a/sql/opt_range.h 2007-11-06 18:57:51 +0000
+++ b/sql/opt_range.h 2008-07-17 15:51:24 +0000
@@ -686,12 +686,10 @@ public:
int get_type() { return QS_TYPE_RANGE_DESC; }
private:
bool range_reads_after_key(QUICK_RANGE *range);
-#ifdef NOT_USED
- bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
-#endif
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
List<QUICK_RANGE> rev_ranges;
List_iterator<QUICK_RANGE> rev_it;
+ uint used_key_parts;
};
=== modified file 'sql/records.cc'
--- a/sql/records.cc 2008-07-24 13:41:55 +0000
+++ b/sql/records.cc 2008-07-17 18:26:55 +0000
@@ -86,6 +86,23 @@ void init_read_record_idx(READ_RECORD *i
The temporary file is normally used when the references doesn't fit into
a properly sized memory buffer. For most small queries the references
are stored in the memory buffer.
+ SYNOPSIS
+ init_read_record()
+ info OUT read structure
+ thd Thread handle
+ table Table the data [originally] comes from.
+ select SQL_SELECT structure. We may select->quick or
+ select->file as data source
+ use_record_cache Call file->extra_opt(HA_EXTRA_CACHE,...)
+ if we're going to do sequential read and some
+ additional conditions are satisfied.
+ print_error Copy this to info->print_error
+ disable_rr_cache Don't use rr_from_cache (used by sort-union
+ index-merge which produces rowid sequences that
+ are already ordered)
+
+ DESCRIPTION
+ This function sets up reading data via one of the methods:
The temporary file is also used when performing an update where a key is
modified.
@@ -140,7 +157,8 @@ void init_read_record_idx(READ_RECORD *i
*/
void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
SQL_SELECT *select,
- int use_record_cache, bool print_error)
+ int use_record_cache, bool print_error,
+ bool disable_rr_cache)
{
IO_CACHE *tempfile;
DBUG_ENTER("init_read_record");
@@ -191,7 +209,8 @@ void init_read_record(READ_RECORD *info,
it doesn't make sense to use cache - we don't read from the table
and table->sort.io_cache is read sequentially
*/
- if (!table->sort.addon_field &&
+ if (!disable_rr_cache &&
+ !table->sort.addon_field &&
! (specialflag & SPECIAL_SAFE_MODE) &&
thd->variables.read_rnd_buff_size &&
!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2008-07-24 13:41:55 +0000
+++ b/sql/sql_acl.cc 2008-07-17 18:26:55 +0000
@@ -324,7 +324,8 @@ static my_bool acl_load(THD *thd, TABLE_
acl_cache->clear(1); // Clear locked hostname cache
init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
- init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0);
+ init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0,
+ FALSE);
table->use_all_columns();
VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50));
while (!(read_record_info.read_record(&read_record_info)))
@@ -373,7 +374,7 @@ static my_bool acl_load(THD *thd, TABLE_
end_read_record(&read_record_info);
freeze_size(&acl_hosts);
- init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0);
+ init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0,FALSE);
table->use_all_columns();
VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100));
password_length= table->field[2]->field_length /
@@ -561,7 +562,7 @@ static my_bool acl_load(THD *thd, TABLE_
end_read_record(&read_record_info);
freeze_size(&acl_users);
- init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0);
+ init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0,FALSE);
table->use_all_columns();
VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100));
while (!(read_record_info.read_record(&read_record_info)))
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2008-07-24 13:41:55 +0000
+++ b/sql/sql_delete.cc 2008-07-17 18:26:55 +0000
@@ -245,7 +245,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
DBUG_RETURN(TRUE);
}
if (usable_index==MAX_KEY)
- init_read_record(&info,thd,table,select,1,1);
+ init_read_record(&info, thd, table, select, 1, 1, FALSE);
else
init_read_record_idx(&info, thd, table, 1, usable_index);
@@ -834,7 +834,7 @@ int multi_delete::do_deletes()
}
READ_RECORD info;
- init_read_record(&info,thd,table,NULL,0,1);
+ init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
/*
Ignore any rows not found in reference tables as they may already have
been deleted by foreign key handling
=== modified file 'sql/sql_help.cc'
--- a/sql/sql_help.cc 2008-07-24 13:41:55 +0000
+++ b/sql/sql_help.cc 2008-07-17 18:26:55 +0000
@@ -186,7 +186,7 @@ int search_topics(THD *thd, TABLE *topic
int count= 0;
READ_RECORD read_record_info;
- init_read_record(&read_record_info, thd, topics, select,1,0);
+ init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE);
while (!read_record_info.read_record(&read_record_info))
{
if (!select->cond->val_int()) // Doesn't match like
@@ -226,7 +226,7 @@ int search_keyword(THD *thd, TABLE *keyw
int count= 0;
READ_RECORD read_record_info;
- init_read_record(&read_record_info, thd, keywords, select,1,0);
+ init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE);
while (!read_record_info.read_record(&read_record_info) && count<2)
{
if (!select->cond->val_int()) // Dosn't match like
@@ -350,7 +350,7 @@ int search_categories(THD *thd, TABLE *c
DBUG_ENTER("search_categories");
- init_read_record(&read_record_info, thd, categories, select,1,0);
+ init_read_record(&read_record_info, thd, categories, select,1,0,FALSE);
while (!read_record_info.read_record(&read_record_info))
{
if (select && !select->cond->val_int())
@@ -384,7 +384,7 @@ void get_all_items_for_category(THD *thd
DBUG_ENTER("get_all_items_for_category");
READ_RECORD read_record_info;
- init_read_record(&read_record_info, thd, items, select,1,0);
+ init_read_record(&read_record_info, thd, items, select,1,0,FALSE);
while (!read_record_info.read_record(&read_record_info))
{
if (!select->cond->val_int())
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2008-07-09 11:52:26 +0000
+++ b/sql/sql_plugin.cc 2008-07-15 17:46:02 +0000
@@ -1361,7 +1361,7 @@ static void plugin_load(MEM_ROOT *tmp_ro
goto end;
}
table= tables.table;
- init_read_record(&read_record_info, new_thd, table, NULL, 1, 0);
+ init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE);
table->use_all_columns();
/*
there're no other threads running yet, so we don't need a mutex.
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2008-07-24 13:41:55 +0000
+++ b/sql/sql_select.cc 2008-07-17 18:28:42 +0000
@@ -11713,7 +11713,7 @@ join_init_read_record(JOIN_TAB *tab)
if (tab->select && tab->select->quick && tab->select->quick->reset())
return 1;
init_read_record(&tab->read_record, tab->join->thd, tab->table,
- tab->select,1,1);
+ tab->select,1,1, FALSE);
return (*tab->read_record.read_record)(&tab->read_record);
}
@@ -12508,6 +12508,9 @@ part_of_refkey(TABLE *table,Field *field
@note
used_key_parts is set to correct key parts used if return value != 0
(On other cases, used_key_part may be changed)
+ Note that the value may actually be greater than the number of index
+ key parts. This can happen for storage engines that have the primary
+ key parts as a suffix for every secondary key.
@retval
1 key is ok.
@@ -12580,11 +12583,27 @@ static int test_if_order_by_key(ORDER *o
reverse=flag; // Remember if reverse
key_part++;
}
- *used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
- (uint) (key_part - table->key_info[idx].key_part);
- if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
- HA_READ_PREV))
- reverse= 0; // Index can't be used
+ if (on_primary_key)
+ {
+ uint used_key_parts_secondary= table->key_info[idx].key_parts;
+ uint used_key_parts_pk=
+ (uint) (key_part - table->key_info[table->s->primary_key].key_part);
+ *used_key_parts= used_key_parts_pk + used_key_parts_secondary;
+
+ if (reverse == -1 &&
+ (!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
+ HA_READ_PREV) ||
+ !(table->file->index_flags(table->s->primary_key,
+ used_key_parts_pk - 1, 1) & HA_READ_PREV)))
+ reverse= 0; // Index can't be used
+ }
+ else
+ {
+ *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
+ if (reverse == -1 &&
+ !(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
+ reverse= 0; // Index can't be used
+ }
DBUG_RETURN(reverse);
}
=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc 2008-03-21 08:46:01 +0000
+++ b/sql/sql_servers.cc 2008-07-15 17:46:02 +0000
@@ -182,7 +182,8 @@ static bool servers_load(THD *thd, TABLE
free_root(&mem, MYF(0));
init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
- init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0);
+ init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0,
+ FALSE);
while (!(read_record_info.read_record(&read_record_info)))
{
/* return_val is already TRUE, so no need to set */
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2008-07-24 13:41:55 +0000
+++ b/sql/sql_table.cc 2008-07-17 18:26:55 +0000
@@ -7113,7 +7113,7 @@ copy_data_between_tables(TABLE *from,TAB
/* Tell handler that we have values for all columns in the to table */
to->use_all_columns();
- init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
+ init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
if (ignore)
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->row_count= 0;
=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc 2008-07-24 13:41:55 +0000
+++ b/sql/sql_udf.cc 2008-07-17 18:26:55 +0000
@@ -152,7 +152,7 @@ void udf_init()
}
table= tables.table;
- init_read_record(&read_record_info, new_thd, table, NULL,1,0);
+ init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE);
table->use_all_columns();
while (!(error= read_record_info.read_record(&read_record_info)))
{
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2008-07-24 13:41:55 +0000
+++ b/sql/sql_update.cc 2008-07-17 18:26:55 +0000
@@ -457,7 +457,7 @@ int mysql_update(THD *thd,
*/
if (used_index == MAX_KEY || (select && select->quick))
- init_read_record(&info,thd,table,select,0,1);
+ init_read_record(&info, thd, table, select, 0, 1, FALSE);
else
init_read_record_idx(&info, thd, table, 1, used_index);
@@ -523,7 +523,7 @@ int mysql_update(THD *thd,
if (select && select->quick && select->quick->reset())
goto err;
table->file->try_semi_consistent_read(1);
- init_read_record(&info,thd,table,select,0,1);
+ init_read_record(&info, thd, table, select, 0, 1, FALSE);
updated= found= 0;
/* Generate an error when trying to set a NOT NULL field to NULL. */
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (kpettersson:2707) | Kristofer Pettersson | 21 Jul |