Automatic merge
This commit is contained in:
commit
c6051a4beb
@ -7719,6 +7719,7 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
|
||||
{
|
||||
uint count;
|
||||
MYSQL_RES *warn_res;
|
||||
DYNAMIC_STRING res;
|
||||
DBUG_ENTER("append_warnings");
|
||||
|
||||
if (!(count= mysql_warning_count(mysql)))
|
||||
@ -7738,11 +7739,18 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
|
||||
die("Warning count is %u but didn't get any warnings",
|
||||
count);
|
||||
|
||||
append_result(ds, warn_res);
|
||||
init_dynamic_string(&res, "", 1024, 1024);
|
||||
|
||||
append_result(&res, warn_res);
|
||||
mysql_free_result(warn_res);
|
||||
|
||||
DBUG_PRINT("warnings", ("%s", ds->str));
|
||||
DBUG_PRINT("warnings", ("%s", res.str));
|
||||
|
||||
if (display_result_sorted)
|
||||
dynstr_append_sorted(ds, &res, 0);
|
||||
else
|
||||
dynstr_append_mem(ds, res.str, res.length);
|
||||
dynstr_free(&res);
|
||||
DBUG_RETURN(count);
|
||||
}
|
||||
|
||||
|
@ -427,4 +427,16 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
|
||||
# MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2
|
||||
drop table t1;
|
||||
unlock tables;
|
||||
#
|
||||
# MDEV-6560
|
||||
# Assertion `! is_set() ' failed in Diagnostics_area::set_ok_status
|
||||
#
|
||||
CREATE TABLE t1 (col_int_nokey INT) ENGINE=InnoDB;
|
||||
CREATE OR REPLACE TEMPORARY TABLE tmp LIKE t1;
|
||||
LOCK TABLE t1 WRITE;
|
||||
CREATE OR REPLACE TABLE t1 LIKE tmp;;
|
||||
KILL QUERY 3;
|
||||
CREATE OR REPLACE TABLE t1 (a int);;
|
||||
KILL QUERY 3;
|
||||
drop table t1;
|
||||
DROP TABLE t2;
|
||||
|
51
mysql-test/r/ctype_partitions.result
Normal file
51
mysql-test/r/ctype_partitions.result
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# MDEV-6255 DUPLICATE KEY Errors on SELECT .. GROUP BY that uses temporary and filesort
|
||||
#
|
||||
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci);
|
||||
INSERT INTO t1 VALUES (0x20),(0x60),(0x6060),(0x606060);
|
||||
SELECT HEX(a) FROM t1 WHERE a=0x60;
|
||||
HEX(a)
|
||||
20
|
||||
60
|
||||
6060
|
||||
606060
|
||||
ALTER TABLE t1 PARTITION BY KEY(a) PARTITIONS 3;
|
||||
SELECT HEX(a) FROM t1 WHERE a=0x60;
|
||||
HEX(a)
|
||||
20
|
||||
60
|
||||
6060
|
||||
606060
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET koi8u COLLATE koi8u_general_ci);
|
||||
INSERT INTO t1 VALUES (0x20),(0x60),(0x6060),(0x606060);
|
||||
SELECT HEX(a) FROM t1 WHERE a=0x60;
|
||||
HEX(a)
|
||||
20
|
||||
60
|
||||
6060
|
||||
606060
|
||||
ALTER TABLE t1 PARTITION BY KEY(a) PARTITIONS 3;
|
||||
SELECT HEX(a) FROM t1 WHERE a=0x60;
|
||||
HEX(a)
|
||||
20
|
||||
60
|
||||
6060
|
||||
606060
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET cp1250 COLLATE cp1250_general_ci);
|
||||
INSERT INTO t1 VALUES (0x20),(0xA0),(0xA0A0),(0xA0A0A0);
|
||||
SELECT HEX(a) FROM t1 WHERE a=0xA0;
|
||||
HEX(a)
|
||||
20
|
||||
A0
|
||||
A0A0
|
||||
A0A0A0
|
||||
ALTER TABLE t1 PARTITION BY KEY(a) PARTITIONS 3;
|
||||
SELECT HEX(a) FROM t1 WHERE a=0xA0;
|
||||
HEX(a)
|
||||
20
|
||||
A0
|
||||
A0A0
|
||||
A0A0A0
|
||||
DROP TABLE t1;
|
@ -141,8 +141,8 @@ include/reset_master_slave.inc
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
STOP ALL SLAVES;
|
||||
Warnings:
|
||||
Note 1938 SLAVE 'slave2' stopped
|
||||
Note 1938 SLAVE 'slave1' stopped
|
||||
Note 1938 SLAVE 'slave2' stopped
|
||||
include/reset_master_slave.inc
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
include/reset_master_slave.inc
|
||||
|
@ -141,12 +141,14 @@ DROP TABLE t3;
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
--let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.tables WHERE table_name IN ("t1", "t2", "t3") AND table_schema = "test"
|
||||
--source include/wait_condition.inc
|
||||
--sorted_result
|
||||
STOP ALL SLAVES;
|
||||
--source reset_master_slave.inc
|
||||
--disconnect slave1
|
||||
|
||||
--connection slave2
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
--sorted_result
|
||||
STOP ALL SLAVES;
|
||||
--source reset_master_slave.inc
|
||||
--disconnect slave2
|
||||
|
@ -245,8 +245,8 @@ a
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
STOP ALL SLAVES;
|
||||
Warnings:
|
||||
Note 1938 SLAVE 'c2a' stopped
|
||||
Note 1938 SLAVE 'b2a' stopped
|
||||
Note 1938 SLAVE 'c2a' stopped
|
||||
SET GLOBAL slave_parallel_threads= @old_parallel;
|
||||
SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates;
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
|
@ -261,24 +261,28 @@ SELECT * FROM t1 WHERE a >= 20 ORDER BY a;
|
||||
# Clean up.
|
||||
--connection server_1
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
--sorted_result
|
||||
STOP ALL SLAVES;
|
||||
SET GLOBAL slave_parallel_threads= @old_parallel;
|
||||
SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates;
|
||||
|
||||
--connection server_2
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
--sorted_result
|
||||
STOP ALL SLAVES;
|
||||
SET GLOBAL slave_parallel_threads= @old_parallel;
|
||||
SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates;
|
||||
|
||||
--connection server_3
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
--sorted_result
|
||||
STOP ALL SLAVES;
|
||||
SET GLOBAL slave_parallel_threads= @old_parallel;
|
||||
SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates;
|
||||
|
||||
--connection server_4
|
||||
SET GLOBAL gtid_domain_id=0;
|
||||
--sorted_result
|
||||
STOP ALL SLAVES;
|
||||
SET GLOBAL slave_parallel_threads= @old_parallel;
|
||||
SET GLOBAL gtid_ignore_duplicates= @old_ignore_duplicates;
|
||||
|
@ -23,8 +23,8 @@ drop table t1;
|
||||
drop table t2;
|
||||
stop all slaves;
|
||||
Warnings:
|
||||
Note 1938 SLAVE 'master2' stopped
|
||||
Note 1938 SLAVE '' stopped
|
||||
Note 1938 SLAVE 'master2' stopped
|
||||
include/reset_master_slave.inc
|
||||
include/reset_master_slave.inc
|
||||
include/reset_master_slave.inc
|
||||
|
@ -58,6 +58,7 @@ drop table t2;
|
||||
--sync_with_master 0,'master2'
|
||||
|
||||
--connection slave
|
||||
--sorted_result
|
||||
stop all slaves;
|
||||
|
||||
--source reset_master_slave.inc
|
||||
|
31
mysql-test/suite/rpl/r/create_or_replace2.result
Normal file
31
mysql-test/suite/rpl/r/create_or_replace2.result
Normal file
@ -0,0 +1,31 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
#
|
||||
# MDEV-6525 ; Problems with CREATE OR REPLACE under lock
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
CREATE FUNCTION f1() RETURNS INT RETURN ( SELECT MAX(a) FROM t1 );
|
||||
connect con1,localhost,root,,test;
|
||||
CREATE TEMPORARY TABLE tmp (b INT) ENGINE=InnoDB;
|
||||
LOCK TABLE t1 WRITE;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
CREATE OR REPLACE TABLE t1 LIKE tmp;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
connection default;
|
||||
set session lock_wait_timeout=1;
|
||||
SELECT f1();
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
set session lock_wait_timeout=@@global.lock_wait_timeout;
|
||||
SELECT f1();
|
||||
connection con1;
|
||||
unlock tables;
|
||||
connection default;
|
||||
ERROR 42S22: Unknown column 'a' in 'field list'
|
||||
disconnect con1;
|
||||
drop function f1;
|
||||
drop table t1;
|
||||
include/rpl_end.inc
|
44
mysql-test/suite/rpl/t/create_or_replace2.test
Normal file
44
mysql-test/suite/rpl/t/create_or_replace2.test
Normal file
@ -0,0 +1,44 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_binlog_format_row_or_statement.inc
|
||||
--source include/have_metadata_lock_info.inc
|
||||
--source include/master-slave.inc
|
||||
--enable_connect_log
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-6525 ; Problems with CREATE OR REPLACE under lock
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
CREATE FUNCTION f1() RETURNS INT RETURN ( SELECT MAX(a) FROM t1 );
|
||||
|
||||
--connect (con1,localhost,root,,test)
|
||||
|
||||
CREATE TEMPORARY TABLE tmp (b INT) ENGINE=InnoDB;
|
||||
LOCK TABLE t1 WRITE;
|
||||
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
|
||||
CREATE OR REPLACE TABLE t1 LIKE tmp;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--connection default
|
||||
set session lock_wait_timeout=1;
|
||||
--error 1205
|
||||
SELECT f1();
|
||||
|
||||
set session lock_wait_timeout=@@global.lock_wait_timeout;
|
||||
--send SELECT f1()
|
||||
--connection con1
|
||||
# This is here just in case, any timeout should be ok
|
||||
--sleep 1
|
||||
unlock tables;
|
||||
--connection default
|
||||
--error 1054
|
||||
--reap
|
||||
--disconnect con1
|
||||
|
||||
# Cleanup
|
||||
drop function f1;
|
||||
drop table t1;
|
||||
--disable_connect_log
|
||||
--source include/rpl_end.inc
|
@ -332,6 +332,38 @@ select * from information_schema.metadata_lock_info;
|
||||
drop table t1;
|
||||
unlock tables;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-6560
|
||||
--echo # Assertion `! is_set() ' failed in Diagnostics_area::set_ok_status
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (col_int_nokey INT) ENGINE=InnoDB;
|
||||
|
||||
--let $con_id = `SELECT CONNECTION_ID()`
|
||||
CREATE OR REPLACE TEMPORARY TABLE tmp LIKE t1;
|
||||
LOCK TABLE t1 WRITE;
|
||||
|
||||
--connect (con1,localhost,root,,test)
|
||||
|
||||
--connection default
|
||||
--send CREATE OR REPLACE TABLE t1 LIKE tmp;
|
||||
--connection con1
|
||||
eval KILL QUERY $con_id;
|
||||
|
||||
--connection default
|
||||
--error 0,ER_QUERY_INTERRUPTED
|
||||
--reap
|
||||
--send CREATE OR REPLACE TABLE t1 (a int);
|
||||
|
||||
--connection con1
|
||||
eval KILL QUERY $con_id;
|
||||
|
||||
--connection default
|
||||
--error 0,ER_QUERY_INTERRUPTED
|
||||
--reap
|
||||
--disconnect con1
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
|
29
mysql-test/t/ctype_partitions.test
Normal file
29
mysql-test/t/ctype_partitions.test
Normal file
@ -0,0 +1,29 @@
|
||||
--source include/have_partition.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-6255 DUPLICATE KEY Errors on SELECT .. GROUP BY that uses temporary and filesort
|
||||
--echo #
|
||||
|
||||
# cp1251_ukrainian_ci: 0x20 SPACE is equal to 0x60 GRAVE ACCENT
|
||||
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci);
|
||||
INSERT INTO t1 VALUES (0x20),(0x60),(0x6060),(0x606060);
|
||||
SELECT HEX(a) FROM t1 WHERE a=0x60;
|
||||
ALTER TABLE t1 PARTITION BY KEY(a) PARTITIONS 3;
|
||||
SELECT HEX(a) FROM t1 WHERE a=0x60;
|
||||
DROP TABLE t1;
|
||||
|
||||
# koi8u_general_ci: 0x20 SPACE is equal to 0x60 GRAVE ACCENT
|
||||
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET koi8u COLLATE koi8u_general_ci);
|
||||
INSERT INTO t1 VALUES (0x20),(0x60),(0x6060),(0x606060);
|
||||
SELECT HEX(a) FROM t1 WHERE a=0x60;
|
||||
ALTER TABLE t1 PARTITION BY KEY(a) PARTITIONS 3;
|
||||
SELECT HEX(a) FROM t1 WHERE a=0x60;
|
||||
DROP TABLE t1;
|
||||
|
||||
# cp1250_general_ci: 0x20 SPACE is equal to 0xA0 NO-BREAK SPACE
|
||||
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET cp1250 COLLATE cp1250_general_ci);
|
||||
INSERT INTO t1 VALUES (0x20),(0xA0),(0xA0A0),(0xA0A0A0);
|
||||
SELECT HEX(a) FROM t1 WHERE a=0xA0;
|
||||
ALTER TABLE t1 PARTITION BY KEY(a) PARTITIONS 3;
|
||||
SELECT HEX(a) FROM t1 WHERE a=0xA0;
|
||||
DROP TABLE t1;
|
@ -412,6 +412,17 @@
|
||||
fun:__libc_start_main
|
||||
}
|
||||
|
||||
#
|
||||
# dl_init reports leaked memory in memalign on OpenSuse 12.3
|
||||
|
||||
{
|
||||
memory "loss" from _dl_init
|
||||
Memcheck:Leak
|
||||
fun:memalign
|
||||
...
|
||||
fun:call_init
|
||||
fun:_dl_init
|
||||
}
|
||||
|
||||
#
|
||||
# dlclose can allocate memory for error message, the memory will be
|
||||
|
12
sql/slave.cc
12
sql/slave.cc
@ -2230,6 +2230,7 @@ slave_killed_err:
|
||||
static bool wait_for_relay_log_space(Relay_log_info* rli)
|
||||
{
|
||||
bool slave_killed=0;
|
||||
bool ignore_log_space_limit;
|
||||
Master_info* mi = rli->mi;
|
||||
PSI_stage_info old_stage;
|
||||
THD* thd = mi->io_thd;
|
||||
@ -2245,6 +2246,11 @@ static bool wait_for_relay_log_space(Relay_log_info* rli)
|
||||
!rli->ignore_log_space_limit)
|
||||
mysql_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
|
||||
|
||||
ignore_log_space_limit= rli->ignore_log_space_limit;
|
||||
rli->ignore_log_space_limit= 0;
|
||||
|
||||
thd->EXIT_COND(&old_stage);
|
||||
|
||||
/*
|
||||
Makes the IO thread read only one event at a time
|
||||
until the SQL thread is able to purge the relay
|
||||
@ -2268,7 +2274,8 @@ static bool wait_for_relay_log_space(Relay_log_info* rli)
|
||||
thread sleeps waiting for events.
|
||||
|
||||
*/
|
||||
if (rli->ignore_log_space_limit)
|
||||
|
||||
if (ignore_log_space_limit)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
{
|
||||
@ -2290,11 +2297,8 @@ static bool wait_for_relay_log_space(Relay_log_info* rli)
|
||||
mysql_mutex_unlock(&mi->data_lock);
|
||||
rli->sql_force_rotate_relay= false;
|
||||
}
|
||||
|
||||
rli->ignore_log_space_limit= false;
|
||||
}
|
||||
|
||||
thd->EXIT_COND(&old_stage);
|
||||
DBUG_RETURN(slave_killed);
|
||||
}
|
||||
|
||||
|
@ -2925,6 +2925,7 @@ Locked_tables_list::reopen_tables(THD *thd)
|
||||
size_t reopen_count= 0;
|
||||
MYSQL_LOCK *lock;
|
||||
MYSQL_LOCK *merged_lock;
|
||||
DBUG_ENTER("Locked_tables_list::reopen_tables");
|
||||
|
||||
for (TABLE_LIST *table_list= m_locked_tables;
|
||||
table_list; table_list= table_list->next_global)
|
||||
@ -2936,7 +2937,7 @@ Locked_tables_list::reopen_tables(THD *thd)
|
||||
if (open_table(thd, table_list, thd->mem_root, &ot_ctx))
|
||||
{
|
||||
unlink_all_closed_tables(thd, 0, reopen_count);
|
||||
return TRUE;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
table_list->table->pos_in_locked_tables= table_list;
|
||||
/* See also the comment on lock type in init_locked_tables(). */
|
||||
@ -2968,11 +2969,11 @@ Locked_tables_list::reopen_tables(THD *thd)
|
||||
unlink_all_closed_tables(thd, lock, reopen_count);
|
||||
if (! thd->killed)
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
||||
return TRUE;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
thd->lock= merged_lock;
|
||||
}
|
||||
return FALSE;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4453,9 +4453,18 @@ extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
|
||||
return binlog_filter->db_ok(thd->db);
|
||||
}
|
||||
|
||||
/*
|
||||
This is similar to sqlcom_can_generate_row_events, with the expection
|
||||
that we only return 1 if we are going to generate row events in a
|
||||
transaction.
|
||||
CREATE OR REPLACE is always safe to do as this will run in it's own
|
||||
transaction.
|
||||
*/
|
||||
|
||||
extern "C" bool thd_sqlcom_can_generate_row_events(const MYSQL_THD thd)
|
||||
{
|
||||
return sqlcom_can_generate_row_events(thd);
|
||||
return (sqlcom_can_generate_row_events(thd) && thd->lex->sql_command !=
|
||||
SQLCOM_CREATE_TABLE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5029,7 +5029,10 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
|
||||
*/
|
||||
thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
|
||||
if (thd->locked_tables_list.reopen_tables(thd))
|
||||
{
|
||||
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
||||
result= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TABLE *table= pos_in_locked_tables->table;
|
||||
@ -5292,6 +5295,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
|
||||
if (res)
|
||||
{
|
||||
/* is_error() may be 0 if table existed and we generated a warning */
|
||||
res= thd->is_error();
|
||||
goto err;
|
||||
}
|
||||
@ -5374,7 +5378,10 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
*/
|
||||
thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
|
||||
if (thd->locked_tables_list.reopen_tables(thd))
|
||||
{
|
||||
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
||||
res= 1; // We got an error
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
|
@ -385,7 +385,8 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
|
||||
pos=empty;
|
||||
do
|
||||
{
|
||||
if (! hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 1))
|
||||
if (pos->hash_of_key == hash_of_key &&
|
||||
! hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 1))
|
||||
{
|
||||
DBUG_RETURN(my_errno=HA_ERR_FOUND_DUPP_KEY);
|
||||
}
|
||||
|
@ -5515,6 +5515,8 @@ static int sort_key_write(MARIA_SORT_PARAM *sort_param, const uchar *a)
|
||||
}
|
||||
if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0)
|
||||
{
|
||||
DBUG_EXECUTE("key", _ma_print_keydata(DBUG_FILE, sort_param->seg, a,
|
||||
USE_WHOLE_KEY););
|
||||
sort_info->dupp++;
|
||||
sort_info->info->cur_row.lastpos= get_record_for_key(sort_param->keyinfo,
|
||||
a);
|
||||
|
@ -288,9 +288,7 @@ void my_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
|
||||
for (; key < end ; key++)
|
||||
{
|
||||
tmp1^= (ulong) ((((uint) tmp1 & 63) + tmp2) *
|
||||
((uint) *key)) + (tmp1 << 8);
|
||||
tmp2+= 3;
|
||||
MY_HASH_ADD(tmp1, tmp2, (uint) *key);
|
||||
}
|
||||
|
||||
*nr1= tmp1;
|
||||
@ -307,9 +305,7 @@ void my_hash_sort_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
|
||||
for (; key < end ; key++)
|
||||
{
|
||||
tmp1^= (ulong) ((((uint) tmp1 & 63) + tmp2) *
|
||||
((uint) *key)) + (tmp1 << 8);
|
||||
tmp2+= 3;
|
||||
MY_HASH_ADD(tmp1, tmp2, (uint) *key);
|
||||
}
|
||||
|
||||
*nr1= tmp1;
|
||||
|
@ -691,6 +691,8 @@ void my_hash_sort_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
|
||||
ulong *nr1, ulong *nr2)
|
||||
{
|
||||
const uchar *end;
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
/*
|
||||
Remove end space. We have to do this to be able to compare
|
||||
'AE' and 'Ä' as identical
|
||||
@ -700,14 +702,14 @@ void my_hash_sort_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
|
||||
for (; key < end ; key++)
|
||||
{
|
||||
uint X= (uint) combo1map[(uint) *key];
|
||||
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * X) + (nr1[0] << 8);
|
||||
nr2[0]+=3;
|
||||
MY_HASH_ADD(m1, m2, X);
|
||||
if ((X= combo2map[*key]))
|
||||
{
|
||||
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) * X) + (nr1[0] << 8);
|
||||
nr2[0]+=3;
|
||||
MY_HASH_ADD(m1, m2, X);
|
||||
}
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -680,6 +680,8 @@ void
|
||||
my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
||||
{
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
/*
|
||||
Remove trailing spaces. We have to do this to be able to compare
|
||||
'A ' and 'A' as identical
|
||||
@ -688,10 +690,10 @@ my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
|
||||
for (; key < end ; key++)
|
||||
{
|
||||
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
||||
((uint)*key)) + (nr1[0] << 8);
|
||||
nr2[0]+=3;
|
||||
MY_HASH_ADD(m1, m2, (uint)*key);
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -306,24 +306,48 @@ void my_hash_sort_simple(CHARSET_INFO *cs,
|
||||
{
|
||||
register const uchar *sort_order=cs->sort_order;
|
||||
const uchar *end;
|
||||
ulong n1, n2;
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
uint16 space_weight= sort_order[' '];
|
||||
|
||||
/*
|
||||
Remove end space. We have to do this to be able to compare
|
||||
'A ' and 'A' as identical
|
||||
*/
|
||||
end= skip_trailing_space(key, len);
|
||||
Remove all trailing characters that are equal to space.
|
||||
We have to do this to be able to compare 'A ' and 'A' as identical.
|
||||
|
||||
If the key is long enough, cut the trailing spaces (0x20) using an
|
||||
optimized function implemented in skip_trailing_spaces().
|
||||
|
||||
"len > 16" is just some heuristic here.
|
||||
Calling skip_triling_space() for short values is not desirable,
|
||||
because its initialization block may be more expensive than the
|
||||
performance gained.
|
||||
*/
|
||||
|
||||
end= len > 16 ? skip_trailing_space(key, len) : key + len;
|
||||
|
||||
/*
|
||||
We removed all trailing characters that are binary equal to space 0x20.
|
||||
Now remove all trailing characters that have weights equal to space.
|
||||
Some 8bit simple collations may have such characters:
|
||||
- cp1250_general_ci 0xA0 NO-BREAK SPACE == 0x20 SPACE
|
||||
- cp1251_ukrainian_ci 0x60 GRAVE ACCENT == 0x20 SPACE
|
||||
- koi8u_general_ci 0x60 GRAVE ACCENT == 0x20 SPACE
|
||||
*/
|
||||
|
||||
for ( ; key < end ; )
|
||||
{
|
||||
if (sort_order[*--end] != space_weight)
|
||||
{
|
||||
end++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
n1= *nr1;
|
||||
n2= *nr2;
|
||||
for (; key < (uchar*) end ; key++)
|
||||
{
|
||||
n1^=(ulong) ((((uint) n1 & 63)+n2) *
|
||||
((uint) sort_order[(uint) *key])) + (n1 << 8);
|
||||
n2+=3;
|
||||
MY_HASH_ADD(m1, m2, (uint) sort_order[(uint) *key]);
|
||||
}
|
||||
*nr1= n1;
|
||||
*nr2= n2;
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -20873,21 +20873,45 @@ static int my_strnncollsp_uca(CHARSET_INFO *cs,
|
||||
static void my_hash_sort_uca(CHARSET_INFO *cs,
|
||||
my_uca_scanner_handler *scanner_handler,
|
||||
const uchar *s, size_t slen,
|
||||
ulong *n1, ulong *n2)
|
||||
ulong *nr1, ulong *nr2)
|
||||
{
|
||||
int s_res;
|
||||
my_uca_scanner scanner;
|
||||
|
||||
slen= cs->cset->lengthsp(cs, (char*) s, slen);
|
||||
int space_weight= my_space_weight(cs);
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
scanner_handler->init(&scanner, cs, &cs->uca->level[0], s, slen);
|
||||
|
||||
while ((s_res= scanner_handler->next(&scanner)) >0)
|
||||
{
|
||||
n1[0]^= (((n1[0] & 63)+n2[0])*(s_res >> 8))+ (n1[0] << 8);
|
||||
n2[0]+=3;
|
||||
n1[0]^= (((n1[0] & 63)+n2[0])*(s_res & 0xFF))+ (n1[0] << 8);
|
||||
n2[0]+=3;
|
||||
if (s_res == space_weight)
|
||||
{
|
||||
/* Combine all spaces to be able to skip end spaces */
|
||||
uint count= 0;
|
||||
do
|
||||
{
|
||||
count++;
|
||||
if ((s_res= scanner_handler->next(&scanner)) <= 0)
|
||||
{
|
||||
/* Skip strings at end of string */
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
while (s_res == space_weight);
|
||||
|
||||
/* Add back that has for the space characters */
|
||||
do
|
||||
{
|
||||
MY_HASH_ADD_16(m1, m2, space_weight);
|
||||
}
|
||||
while (--count != 0);
|
||||
|
||||
}
|
||||
MY_HASH_ADD_16(m1, m2, s_res);
|
||||
}
|
||||
end:
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1222,23 +1222,23 @@ my_caseup_utf16(CHARSET_INFO *cs, char *src, size_t srclen,
|
||||
|
||||
static void
|
||||
my_hash_sort_utf16(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
ulong *n1, ulong *n2)
|
||||
ulong *nr1, ulong *nr2)
|
||||
{
|
||||
my_wc_t wc;
|
||||
my_charset_conv_mb_wc mb_wc= cs->cset->mb_wc;
|
||||
int res;
|
||||
const uchar *e= s + cs->cset->lengthsp(cs, (const char *) s, slen);
|
||||
MY_UNICASE_INFO *uni_plane= cs->caseinfo;
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
while ((s < e) && (res= mb_wc(cs, &wc, (uchar *) s, (uchar *) e)) > 0)
|
||||
{
|
||||
my_tosort_utf16(uni_plane, &wc);
|
||||
n1[0]^= (((n1[0] & 63) + n2[0]) * (wc & 0xFF)) + (n1[0] << 8);
|
||||
n2[0]+= 3;
|
||||
n1[0]^= (((n1[0] & 63) + n2[0]) * (wc >> 8)) + (n1[0] << 8);
|
||||
n2[0]+= 3;
|
||||
MY_HASH_ADD_16(m1, m2, wc);
|
||||
s+= res;
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
@ -1611,12 +1611,14 @@ my_hash_sort_utf16_bin(CHARSET_INFO *cs,
|
||||
const uchar *pos, size_t len, ulong *nr1, ulong *nr2)
|
||||
{
|
||||
const uchar *end= pos + cs->cset->lengthsp(cs, (const char *) pos, len);
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
for ( ; pos < end ; pos++)
|
||||
{
|
||||
nr1[0]^= (ulong) ((((uint) nr1[0] & 63) + nr2[0]) *
|
||||
((uint)*pos)) + (nr1[0] << 8);
|
||||
nr2[0]+= 3;
|
||||
MY_HASH_ADD(m1, m2, (uint)*pos);
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
@ -2007,22 +2009,15 @@ my_caseup_utf32(CHARSET_INFO *cs, char *src, size_t srclen,
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
my_hash_add(ulong *n1, ulong *n2, uint ch)
|
||||
{
|
||||
n1[0]^= (((n1[0] & 63) + n2[0]) * (ch)) + (n1[0] << 8);
|
||||
n2[0]+= 3;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_hash_sort_utf32(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
ulong *n1, ulong *n2)
|
||||
ulong *nr1, ulong *nr2)
|
||||
{
|
||||
my_wc_t wc;
|
||||
int res;
|
||||
const uchar *e= s + slen;
|
||||
MY_UNICASE_INFO *uni_plane= cs->caseinfo;
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
/* Skip trailing spaces */
|
||||
while (e > s + 3 && e[-1] == ' ' && !e[-2] && !e[-3] && !e[-4])
|
||||
@ -2031,12 +2026,14 @@ my_hash_sort_utf32(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
while ((res= my_utf32_uni(cs, &wc, (uchar*) s, (uchar*) e)) > 0)
|
||||
{
|
||||
my_tosort_utf32(uni_plane, &wc);
|
||||
my_hash_add(n1, n2, (uint) (wc >> 24));
|
||||
my_hash_add(n1, n2, (uint) (wc >> 16) & 0xFF);
|
||||
my_hash_add(n1, n2, (uint) (wc >> 8) & 0xFF);
|
||||
my_hash_add(n1, n2, (uint) (wc & 0xFF));
|
||||
MY_HASH_ADD(m1, m2, (uint) (wc >> 24));
|
||||
MY_HASH_ADD(m1, m2, (uint) (wc >> 16) & 0xFF);
|
||||
MY_HASH_ADD(m1, m2, (uint) (wc >> 8) & 0xFF);
|
||||
MY_HASH_ADD(m1, m2, (uint) (wc & 0xFF));
|
||||
s+= res;
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
@ -2976,12 +2973,13 @@ static size_t my_caseup_ucs2(CHARSET_INFO *cs, char *src, size_t srclen,
|
||||
|
||||
|
||||
static void my_hash_sort_ucs2(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
ulong *n1, ulong *n2)
|
||||
ulong *nr1, ulong *nr2)
|
||||
{
|
||||
my_wc_t wc;
|
||||
int res;
|
||||
const uchar *e=s+slen;
|
||||
MY_UNICASE_INFO *uni_plane= cs->caseinfo;
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
while (e > s+1 && e[-1] == ' ' && e[-2] == '\0')
|
||||
e-= 2;
|
||||
@ -2989,12 +2987,11 @@ static void my_hash_sort_ucs2(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
while ((s < e) && (res=my_ucs2_uni(cs,&wc, (uchar *)s, (uchar*)e)) >0)
|
||||
{
|
||||
my_tosort_ucs2(uni_plane, &wc);
|
||||
n1[0]^= (((n1[0] & 63)+n2[0])*(wc & 0xFF))+ (n1[0] << 8);
|
||||
n2[0]+=3;
|
||||
n1[0]^= (((n1[0] & 63)+n2[0])*(wc >> 8))+ (n1[0] << 8);
|
||||
n2[0]+=3;
|
||||
MY_HASH_ADD_16(m1, m2, wc);
|
||||
s+=res;
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
@ -3312,16 +3309,17 @@ void my_hash_sort_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const uchar *key, size_t len,ulong *nr1, ulong *nr2)
|
||||
{
|
||||
const uchar *end = key + len;
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
while (end > key+1 && end[-1] == ' ' && end[-2] == '\0')
|
||||
end-= 2;
|
||||
|
||||
for (; key < (uchar*) end ; key++)
|
||||
{
|
||||
nr1[0]^=(ulong) ((((uint) nr1[0] & 63)+nr2[0]) *
|
||||
((uint)*key)) + (nr1[0] << 8);
|
||||
nr2[0]+=3;
|
||||
MY_HASH_ADD(m1, m2, (uint)*key);
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5087,12 +5087,13 @@ static size_t my_caseup_utf8(CHARSET_INFO *cs, char *src, size_t srclen,
|
||||
|
||||
|
||||
static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
ulong *n1, ulong *n2)
|
||||
ulong *nr1, ulong *nr2)
|
||||
{
|
||||
my_wc_t wc;
|
||||
int res;
|
||||
const uchar *e=s+slen;
|
||||
MY_UNICASE_INFO *uni_plane= cs->caseinfo;
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
/*
|
||||
Remove end space. We have to do this to be able to compare
|
||||
@ -5104,12 +5105,11 @@ static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
while ((s < e) && (res=my_utf8_uni(cs,&wc, (uchar *)s, (uchar*)e))>0 )
|
||||
{
|
||||
my_tosort_unicode(uni_plane, &wc, cs->state);
|
||||
n1[0]^= (((n1[0] & 63)+n2[0])*(wc & 0xFF))+ (n1[0] << 8);
|
||||
n2[0]+=3;
|
||||
n1[0]^= (((n1[0] & 63)+n2[0])*(wc >> 8))+ (n1[0] << 8);
|
||||
n2[0]+=3;
|
||||
MY_HASH_ADD_16(m1, m2, wc);
|
||||
s+=res;
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
@ -7597,22 +7597,15 @@ my_caseup_utf8mb4(CHARSET_INFO *cs, char *src, size_t srclen,
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
my_hash_add(ulong *n1, ulong *n2, uint ch)
|
||||
{
|
||||
n1[0]^= (((n1[0] & 63) + n2[0]) * (ch)) + (n1[0] << 8);
|
||||
n2[0]+= 3;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_hash_sort_utf8mb4(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
ulong *n1, ulong *n2)
|
||||
ulong *nr1, ulong *nr2)
|
||||
{
|
||||
my_wc_t wc;
|
||||
int res;
|
||||
const uchar *e= s + slen;
|
||||
MY_UNICASE_INFO *uni_plane= cs->caseinfo;
|
||||
register ulong m1= *nr1, m2= *nr2;
|
||||
|
||||
/*
|
||||
Remove end space. We do this to be able to compare
|
||||
@ -7624,8 +7617,7 @@ my_hash_sort_utf8mb4(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
while ((res= my_mb_wc_utf8mb4(cs, &wc, (uchar*) s, (uchar*) e)) > 0)
|
||||
{
|
||||
my_tosort_unicode(uni_plane, &wc, cs->state);
|
||||
my_hash_add(n1, n2, (uint) (wc & 0xFF));
|
||||
my_hash_add(n1, n2, (uint) (wc >> 8) & 0xFF);
|
||||
MY_HASH_ADD_16(m1, m2, (uint) (wc & 0xFFFF));
|
||||
if (wc > 0xFFFF)
|
||||
{
|
||||
/*
|
||||
@ -7635,10 +7627,12 @@ my_hash_sort_utf8mb4(CHARSET_INFO *cs, const uchar *s, size_t slen,
|
||||
This is useful to keep order of records in
|
||||
test results, e.g. for "SHOW GRANTS".
|
||||
*/
|
||||
my_hash_add(n1, n2, (uint) (wc >> 16) & 0xFF);
|
||||
MY_HASH_ADD(m1, m2, (uint) ((wc >> 16) & 0xFF));
|
||||
}
|
||||
s+= res;
|
||||
}
|
||||
*nr1= m1;
|
||||
*nr2= m2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,4 +100,20 @@ static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
|
||||
end--;
|
||||
return (end);
|
||||
}
|
||||
|
||||
/* Macros for hashing characters */
|
||||
|
||||
#define MY_HASH_ADD(A, B, value) \
|
||||
do { A^= (((A & 63)+B)*((value)))+ (A << 8); B+=3; } while(0)
|
||||
|
||||
#define MY_HASH_ADD_16(A, B, value) \
|
||||
do { MY_HASH_ADD(A, B, ((value) & 0xFF)) ; MY_HASH_ADD(A, B, ((value >>8 ))); } while(0)
|
||||
|
||||
/*
|
||||
This one is needed to ensure we get the exact same hash as MariaDB 5.1
|
||||
This is needed to ensure that old partitioned tables still work as before.
|
||||
*/
|
||||
#define MY_HASH_ADD_16_INV(A, B, value) \
|
||||
do { MY_HASH_ADD(A, B, ((value >> 8))) ; MY_HASH_ADD(A, B, ((value & 0xFF ))); } while(0)
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user