mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Post-merge fixes.
Note: One sp.test still fails (prime), and rpl_server_id2.test fails (will be fixed by guilhem ASAP). mysql-test/r/index_merge.result: Fixed syntax error (no ',' after last index in create table any more). mysql-test/r/index_merge_bdb.result: Fixed syntax error (no ',' after last index in create table any more). mysql-test/r/index_merge_innodb.result: Fixed syntax error (no ',' after last index in create table any more). mysql-test/r/index_merge_innodb2.result: Fixed syntax error (no ',' after last index in create table any more). mysql-test/r/rpl_server_id1.result: Update result after merge. mysql-test/r/sp-error.result: Update result after merge. mysql-test/r/variables.result: Update result after merge. mysql-test/t/index_merge.test: Fixed syntax error (no ',' after last index in create table any more). mysql-test/t/index_merge_bdb.test: Fixed syntax error (no ',' after last index in create table any more). mysql-test/t/index_merge_innodb.test: Fixed syntax error (no ',' after last index in create table any more). mysql-test/t/index_merge_innodb2.test: Fixed syntax error (no ',' after last index in create table any more). mysql-test/t/sp-error.test: Post-merge fix of error codes. sql/opt_range.cc: Manually merged by Monty. sql/opt_range.h: Manually merged by Monty. sql/slave.cc: Post-merge fixes with some help from Guilhem. sql/slave.h: Post-merge fixes with some help from Guilhem. sql/sp_head.cc: Got rid of warning (reordering initialization). sql/sql_parse.cc: Post-merge fix: Need to set/reset select_limit at SP CALL time as well. tests/client_test.c: Post-merge fix: key_len length in explain has changed.
This commit is contained in:
@ -2,7 +2,7 @@ drop table if exists t0, t1, t2, t3,t4;
|
||||
create table t0
|
||||
(
|
||||
key1 int not null,
|
||||
INDEX i1(key1),
|
||||
INDEX i1(key1)
|
||||
);
|
||||
alter table t0 add key2 int not null, add index i2(key2);
|
||||
alter table t0 add key3 int not null, add index i3(key3);
|
||||
@ -217,7 +217,7 @@ key3 int not null,
|
||||
index i1a (key1a, key1b),
|
||||
index i1b (key1b, key1a),
|
||||
index i2_1(key2, key2_1),
|
||||
index i2_2(key2, key2_1),
|
||||
index i2_2(key2, key2_1)
|
||||
);
|
||||
insert into t4 select key1,key1,key1 div 10, key1 % 10, key1 % 10, key1 from t0;
|
||||
select * from t4 where key1a = 3 or key1b = 4;
|
||||
|
@ -6,7 +6,7 @@ key2 int,
|
||||
filler char(200),
|
||||
filler2 char(200),
|
||||
index(key1),
|
||||
index(key2),
|
||||
index(key2)
|
||||
) engine=bdb;
|
||||
select * from t1 where (key1 >= 2 and key1 <= 10) or (pk >= 4 and pk <=8 );
|
||||
pk key1 key2 filler filler2
|
||||
|
@ -4,7 +4,7 @@ create table t1
|
||||
key1 int not null,
|
||||
key2 int not null,
|
||||
INDEX i1(key1),
|
||||
INDEX i2(key2),
|
||||
INDEX i2(key2)
|
||||
) engine=innodb;
|
||||
explain select * from t1 where key1 < 5 or key2 > 197;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
@ -6,7 +6,7 @@ key2 int,
|
||||
filler char(200),
|
||||
filler2 char(200),
|
||||
index(key1),
|
||||
index(key2),
|
||||
index(key2)
|
||||
) engine=innodb;
|
||||
select * from t1 where (key1 >= 2 and key1 <= 10) or (pk >= 4 and pk <=8 );
|
||||
pk key1 key2 filler filler2
|
||||
|
@ -10,7 +10,7 @@ stop slave;
|
||||
change master to master_port=SLAVE_PORT;
|
||||
show slave status;
|
||||
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running 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 Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
|
||||
127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 4 None 0 No NULL
|
||||
127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 95 None 0 No NULL
|
||||
start slave;
|
||||
insert into t1 values (1);
|
||||
show status like "slave_running";
|
||||
|
@ -35,7 +35,7 @@ call foo()|
|
||||
ERROR 42000: PROCEDURE foo does not exist
|
||||
drop procedure if exists foo|
|
||||
Warnings:
|
||||
Warning 1297 PROCEDURE foo does not exist
|
||||
Warning 1298 PROCEDURE foo does not exist
|
||||
show create procedure foo|
|
||||
ERROR 42000: PROCEDURE foo does not exist
|
||||
create procedure foo()
|
||||
@ -71,7 +71,7 @@ declare y int;
|
||||
set x = y;
|
||||
end|
|
||||
Warnings:
|
||||
Warning 1303 Referring to uninitialized variable y
|
||||
Warning 1304 Referring to uninitialized variable y
|
||||
drop procedure foo|
|
||||
create procedure foo()
|
||||
return 42|
|
||||
|
@ -364,7 +364,7 @@ set sql_log_bin=1;
|
||||
set sql_log_off=1;
|
||||
set sql_log_update=1;
|
||||
Warnings:
|
||||
Note 1307 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored.
|
||||
Note 1308 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored.
|
||||
set sql_low_priority_updates=1;
|
||||
set sql_max_join_size=200;
|
||||
select @@sql_max_join_size,@@max_join_size;
|
||||
|
@ -10,7 +10,7 @@ drop table if exists t0, t1, t2, t3,t4;
|
||||
create table t0
|
||||
(
|
||||
key1 int not null,
|
||||
INDEX i1(key1),
|
||||
INDEX i1(key1)
|
||||
);
|
||||
|
||||
--disable_query_log
|
||||
@ -192,7 +192,7 @@ create table t4 (
|
||||
index i1b (key1b, key1a),
|
||||
|
||||
index i2_1(key2, key2_1),
|
||||
index i2_2(key2, key2_1),
|
||||
index i2_2(key2, key2_1)
|
||||
);
|
||||
|
||||
insert into t4 select key1,key1,key1 div 10, key1 % 10, key1 % 10, key1 from t0;
|
||||
|
@ -14,7 +14,7 @@ create table t1 (
|
||||
filler char(200),
|
||||
filler2 char(200),
|
||||
index(key1),
|
||||
index(key2),
|
||||
index(key2)
|
||||
) engine=bdb;
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ create table t1
|
||||
key2 int not null,
|
||||
|
||||
INDEX i1(key1),
|
||||
INDEX i2(key2),
|
||||
INDEX i2(key2)
|
||||
) engine=innodb;
|
||||
|
||||
--disable_query_log
|
||||
|
@ -14,7 +14,7 @@ create table t1 (
|
||||
filler char(200),
|
||||
filler2 char(200),
|
||||
index(key1),
|
||||
index(key2),
|
||||
index(key2)
|
||||
) engine=innodb;
|
||||
|
||||
|
||||
|
@ -32,18 +32,18 @@ create function func1() returns int
|
||||
return 42|
|
||||
|
||||
# Can't create recursively
|
||||
--error 1295
|
||||
--error 1296
|
||||
create procedure foo()
|
||||
create procedure bar() set @x=3|
|
||||
--error 1295
|
||||
--error 1296
|
||||
create procedure foo()
|
||||
create function bar() returns double return 2.3|
|
||||
|
||||
# Already exists
|
||||
--error 1296
|
||||
--error 1297
|
||||
create procedure proc1()
|
||||
set @x = 42|
|
||||
--error 1296
|
||||
--error 1297
|
||||
create function func1() returns int
|
||||
return 42|
|
||||
|
||||
@ -51,39 +51,39 @@ drop procedure proc1|
|
||||
drop function func1|
|
||||
|
||||
# Does not exist
|
||||
--error 1297
|
||||
--error 1298
|
||||
alter procedure foo|
|
||||
--error 1297
|
||||
--error 1298
|
||||
alter function foo|
|
||||
--error 1297
|
||||
--error 1298
|
||||
drop procedure foo|
|
||||
--error 1297
|
||||
--error 1298
|
||||
drop function foo|
|
||||
--error 1297
|
||||
--error 1298
|
||||
call foo()|
|
||||
drop procedure if exists foo|
|
||||
--error 1297
|
||||
--error 1298
|
||||
show create procedure foo|
|
||||
|
||||
# LEAVE/ITERATE with no match
|
||||
--error 1300
|
||||
--error 1301
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
leave bar;
|
||||
end loop|
|
||||
--error 1300
|
||||
--error 1301
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
iterate bar;
|
||||
end loop|
|
||||
--error 1300
|
||||
--error 1301
|
||||
create procedure foo()
|
||||
foo: begin
|
||||
iterate foo;
|
||||
end|
|
||||
|
||||
# Redefining label
|
||||
--error 1301
|
||||
--error 1302
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
foo: loop
|
||||
@ -92,7 +92,7 @@ foo: loop
|
||||
end loop foo|
|
||||
|
||||
# End label mismatch
|
||||
--error 1302
|
||||
--error 1303
|
||||
create procedure foo()
|
||||
foo: loop
|
||||
set @x=2;
|
||||
@ -107,12 +107,12 @@ end|
|
||||
drop procedure foo|
|
||||
|
||||
# RETURN in FUNCTION only
|
||||
--error 1305
|
||||
--error 1306
|
||||
create procedure foo()
|
||||
return 42|
|
||||
|
||||
# Doesn't allow queries in FUNCTIONs (for now :-( )
|
||||
--error 1306
|
||||
--error 1307
|
||||
create function foo() returns int
|
||||
begin
|
||||
declare x int;
|
||||
@ -126,19 +126,19 @@ create procedure p(x int)
|
||||
create function f(x int) returns int
|
||||
return x+42|
|
||||
|
||||
--error 1310
|
||||
--error 1311
|
||||
call p()|
|
||||
--error 1310
|
||||
--error 1311
|
||||
call p(1, 2)|
|
||||
--error 1310
|
||||
--error 1311
|
||||
select f()|
|
||||
--error 1310
|
||||
--error 1311
|
||||
select f(1, 2)|
|
||||
|
||||
drop procedure p|
|
||||
drop function f|
|
||||
|
||||
--error 1311
|
||||
--error 1312
|
||||
create procedure p(val int, out res int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
@ -152,7 +152,7 @@ begin
|
||||
end if;
|
||||
end|
|
||||
|
||||
--error 1311
|
||||
--error 1312
|
||||
create procedure p(val int, out res int)
|
||||
begin
|
||||
declare x int default 0;
|
||||
@ -167,7 +167,7 @@ begin
|
||||
end if;
|
||||
end|
|
||||
|
||||
--error 1312
|
||||
--error 1313
|
||||
create function f(val int) returns int
|
||||
begin
|
||||
declare x int;
|
||||
@ -185,12 +185,12 @@ begin
|
||||
end if;
|
||||
end|
|
||||
|
||||
--error 1313
|
||||
--error 1314
|
||||
select f(10)|
|
||||
|
||||
drop function f|
|
||||
|
||||
--error 1314
|
||||
--error 1315
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for insert into test.t1 values ("foo", 42);
|
||||
@ -199,7 +199,7 @@ begin
|
||||
close c;
|
||||
end|
|
||||
|
||||
--error 1315
|
||||
--error 1316
|
||||
create procedure p()
|
||||
begin
|
||||
declare x int;
|
||||
@ -209,7 +209,7 @@ begin
|
||||
close c;
|
||||
end|
|
||||
|
||||
--error 1316
|
||||
--error 1317
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from test.t;
|
||||
@ -231,7 +231,7 @@ begin
|
||||
open c;
|
||||
close c;
|
||||
end|
|
||||
--error 1317
|
||||
--error 1318
|
||||
call p()|
|
||||
drop procedure p|
|
||||
|
||||
@ -243,11 +243,11 @@ begin
|
||||
close c;
|
||||
close c;
|
||||
end|
|
||||
--error 1318
|
||||
--error 1319
|
||||
call p()|
|
||||
drop procedure p|
|
||||
|
||||
--error 1297
|
||||
--error 1298
|
||||
alter procedure bar3 sql security invoker|
|
||||
--error 1059
|
||||
alter procedure bar3 name
|
||||
@ -261,7 +261,7 @@ drop table if exists t1|
|
||||
create table t1 (val int, x float)|
|
||||
insert into t1 values (42, 3.1), (19, 1.2)|
|
||||
|
||||
--error 1319
|
||||
--error 1320
|
||||
create procedure p()
|
||||
begin
|
||||
declare x int;
|
||||
@ -281,7 +281,7 @@ begin
|
||||
fetch c into x;
|
||||
close c;
|
||||
end|
|
||||
--error 1320
|
||||
--error 1321
|
||||
call p()|
|
||||
drop procedure p|
|
||||
|
||||
@ -296,34 +296,34 @@ begin
|
||||
fetch c into x, y, z;
|
||||
close c;
|
||||
end|
|
||||
--error 1320
|
||||
--error 1321
|
||||
call p()|
|
||||
drop procedure p|
|
||||
|
||||
--error 1322
|
||||
--error 1323
|
||||
create procedure p(in x int, x char(10))
|
||||
begin
|
||||
end|
|
||||
--error 1322
|
||||
--error 1323
|
||||
create function p(x int, x char(10))
|
||||
begin
|
||||
end|
|
||||
|
||||
--error 1323
|
||||
--error 1324
|
||||
create procedure p()
|
||||
begin
|
||||
declare x float;
|
||||
declare x int;
|
||||
end|
|
||||
|
||||
--error 1324
|
||||
--error 1325
|
||||
create procedure p()
|
||||
begin
|
||||
declare c condition for 1064;
|
||||
declare c condition for 1065;
|
||||
end|
|
||||
|
||||
--error 1325
|
||||
--error 1326
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
@ -331,18 +331,18 @@ begin
|
||||
end|
|
||||
|
||||
# USE is not allowed
|
||||
--error 1328
|
||||
--error 1329
|
||||
create procedure u()
|
||||
use sptmp|
|
||||
|
||||
# Enforced standard order of declarations
|
||||
--error 1329
|
||||
--error 1330
|
||||
create procedure p()
|
||||
begin
|
||||
declare c cursor for select * from t1;
|
||||
declare x int;
|
||||
end|
|
||||
--error 1329
|
||||
--error 1330
|
||||
create procedure p()
|
||||
begin
|
||||
declare x int;
|
||||
@ -350,7 +350,7 @@ begin
|
||||
declare foo condition for sqlstate '42S99';
|
||||
end|
|
||||
|
||||
--error 1330
|
||||
--error 1331
|
||||
create procedure p()
|
||||
begin
|
||||
declare x int;
|
||||
@ -375,13 +375,13 @@ drop procedure bug1965|
|
||||
#
|
||||
# BUG#1966
|
||||
#
|
||||
--error 1319
|
||||
--error 1320
|
||||
select 1 into a|
|
||||
|
||||
#
|
||||
# BUG#336
|
||||
#
|
||||
--error 1327
|
||||
--error 1328
|
||||
create procedure bug336(id char(16))
|
||||
begin
|
||||
declare x int;
|
||||
@ -391,7 +391,7 @@ end|
|
||||
#
|
||||
# BUG#1654
|
||||
#
|
||||
--error 1306
|
||||
--error 1307
|
||||
create function bug1654()
|
||||
returns int
|
||||
return (select sum(t.data) from test.t2 t)|
|
||||
@ -429,7 +429,7 @@ begin
|
||||
fetch c1 into v1;
|
||||
end|
|
||||
|
||||
--error 1318
|
||||
--error 1319
|
||||
call bug2259()|
|
||||
drop procedure bug2259|
|
||||
|
||||
@ -485,7 +485,7 @@ begin
|
||||
end case;
|
||||
return 2;
|
||||
end|
|
||||
--error 1331
|
||||
--error 1332
|
||||
select bug3287()|
|
||||
drop function bug3287|
|
||||
|
||||
@ -496,7 +496,7 @@ when 0 then
|
||||
when 1 then
|
||||
insert into test.t1 values (x, 1.1);
|
||||
end case|
|
||||
--error 1331
|
||||
--error 1332
|
||||
call bug3287(2)|
|
||||
drop procedure bug3287|
|
||||
|
||||
|
348
sql/opt_range.cc
348
sql/opt_range.cc
@ -177,11 +177,11 @@ public:
|
||||
if (maybe_null && *min_value)
|
||||
{
|
||||
**min_key=1;
|
||||
bzero(*min_key+1,length);
|
||||
bzero(*min_key+1,length-1);
|
||||
}
|
||||
else
|
||||
memcpy(*min_key,min_value,length+(int) maybe_null);
|
||||
(*min_key)+= length+(int) maybe_null;
|
||||
memcpy(*min_key,min_value,length);
|
||||
(*min_key)+= length;
|
||||
}
|
||||
if (!(max_flag & NO_MAX_RANGE) &&
|
||||
!(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
|
||||
@ -189,18 +189,18 @@ public:
|
||||
if (maybe_null && *max_value)
|
||||
{
|
||||
**max_key=1;
|
||||
bzero(*max_key+1,length);
|
||||
bzero(*max_key+1,length-1);
|
||||
}
|
||||
else
|
||||
memcpy(*max_key,max_value,length+(int) maybe_null);
|
||||
(*max_key)+= length+(int) maybe_null;
|
||||
memcpy(*max_key,max_value,length);
|
||||
(*max_key)+= length;
|
||||
}
|
||||
}
|
||||
|
||||
void store_min_key(KEY_PART *key,char **range_key, uint *range_key_flag)
|
||||
{
|
||||
SEL_ARG *key_tree= first();
|
||||
key_tree->store(key[key_tree->part].part_length,
|
||||
key_tree->store(key[key_tree->part].store_length,
|
||||
range_key,*range_key_flag,range_key,NO_MAX_RANGE);
|
||||
*range_key_flag|= key_tree->min_flag;
|
||||
if (key_tree->next_key_part &&
|
||||
@ -213,7 +213,7 @@ public:
|
||||
void store_max_key(KEY_PART *key,char **range_key, uint *range_key_flag)
|
||||
{
|
||||
SEL_ARG *key_tree= last();
|
||||
key_tree->store(key[key_tree->part].part_length,
|
||||
key_tree->store(key[key_tree->part].store_length,
|
||||
range_key, NO_MIN_RANGE, range_key,*range_key_flag);
|
||||
(*range_key_flag)|= key_tree->max_flag;
|
||||
if (key_tree->next_key_part &&
|
||||
@ -959,6 +959,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
||||
MEM_ROOT *old_root,alloc;
|
||||
SEL_TREE *tree;
|
||||
KEY_PART *key_parts;
|
||||
KEY *key_info;
|
||||
PARAM param;
|
||||
|
||||
/* set up parameter that is passed to all functions */
|
||||
@ -985,24 +986,26 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
||||
old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
|
||||
my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
|
||||
|
||||
for (idx=0 ; idx < head->keys ; idx++)
|
||||
key_info= head->key_info;
|
||||
for (idx=0 ; idx < head->keys ; idx++, key_info++)
|
||||
{
|
||||
KEY_PART_INFO *key_part_info;
|
||||
if (!keys_to_use.is_set(idx))
|
||||
continue;
|
||||
KEY *key_info= &head->key_info[idx];
|
||||
if (key_info->flags & HA_FULLTEXT)
|
||||
continue; // ToDo: ft-keys in non-ft ranges, if possible SerG
|
||||
|
||||
param.key[param.keys]=key_parts;
|
||||
for (uint part=0 ; part < key_info->key_parts ; part++,key_parts++)
|
||||
key_part_info= key_info->key_part;
|
||||
for (uint part=0 ; part < key_info->key_parts ;
|
||||
part++, key_parts++, key_part_info++)
|
||||
{
|
||||
key_parts->key=param.keys;
|
||||
key_parts->part=part;
|
||||
key_parts->part_length= key_info->key_part[part].length;
|
||||
key_parts->field= key_info->key_part[part].field;
|
||||
key_parts->null_bit= key_info->key_part[part].null_bit;
|
||||
if (key_parts->field->type() == FIELD_TYPE_BLOB)
|
||||
key_parts->part_length+=HA_KEY_BLOB_LENGTH;
|
||||
key_parts->key= param.keys;
|
||||
key_parts->part= part;
|
||||
key_parts->length= key_part_info->length;
|
||||
key_parts->store_length= key_part_info->store_length;
|
||||
key_parts->field= key_part_info->field;
|
||||
key_parts->null_bit= key_part_info->null_bit;
|
||||
key_parts->image_type =
|
||||
(key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW;
|
||||
}
|
||||
@ -1348,7 +1351,7 @@ static int get_index_merge_params(PARAM *param, key_map& needed_reg,
|
||||
else
|
||||
{
|
||||
double n_blocks=
|
||||
ceil((double)(longlong)param->table->file->data_file_length / IO_SIZE);
|
||||
ceil((double) ((longlong)param->table->file->data_file_length / IO_SIZE));
|
||||
double busy_blocks=
|
||||
n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, (double) records_for_unique));
|
||||
|
||||
@ -1776,18 +1779,26 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
||||
DBUG_RETURN(0); // Can only optimize strings
|
||||
|
||||
offset=maybe_null;
|
||||
length=key_part->part_length;
|
||||
if (field->type() == FIELD_TYPE_BLOB)
|
||||
length=key_part->store_length;
|
||||
|
||||
if (length != key_part->length + maybe_null)
|
||||
{
|
||||
offset+=HA_KEY_BLOB_LENGTH;
|
||||
field_length=key_part->part_length-HA_KEY_BLOB_LENGTH;
|
||||
/* key packed with length prefix */
|
||||
offset+= HA_KEY_BLOB_LENGTH;
|
||||
field_length= length - HA_KEY_BLOB_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (length < field_length)
|
||||
length=field_length; // Only if overlapping key
|
||||
if (unlikely(length < field_length))
|
||||
{
|
||||
/*
|
||||
This can only happen in a table created with UNIREG where one key
|
||||
overlaps many fields
|
||||
*/
|
||||
length= field_length;
|
||||
}
|
||||
else
|
||||
field_length=length;
|
||||
field_length= length;
|
||||
}
|
||||
length+=offset;
|
||||
if (!(min_str= (char*) alloc_root(param->mem_root, length*2)))
|
||||
@ -1800,7 +1811,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
||||
res->ptr(), res->length(),
|
||||
((Item_func_like*)(param->cond))->escape,
|
||||
wild_one, wild_many,
|
||||
field_length,
|
||||
field_length-maybe_null,
|
||||
min_str+offset, max_str+offset,
|
||||
&min_length, &max_length);
|
||||
if (like_error) // Can't optimize with LIKE
|
||||
@ -1838,13 +1849,13 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
||||
if (field->key_type() == HA_KEYTYPE_VARTEXT)
|
||||
copies= 2;
|
||||
str= str2= (char*) alloc_root(param->mem_root,
|
||||
(key_part->part_length+maybe_null)*copies+1);
|
||||
(key_part->store_length)*copies+1);
|
||||
if (!str)
|
||||
DBUG_RETURN(0);
|
||||
if (maybe_null)
|
||||
*str= (char) field->is_real_null(); // Set to 1 if null
|
||||
field->get_key_image(str+maybe_null,key_part->part_length,
|
||||
field->charset(),key_part->image_type);
|
||||
field->get_key_image(str+maybe_null, key_part->length,
|
||||
field->charset(), key_part->image_type);
|
||||
if (copies == 2)
|
||||
{
|
||||
/*
|
||||
@ -1853,16 +1864,17 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
||||
all rows between 'X' and 'X ...'
|
||||
*/
|
||||
uint length= uint2korr(str+maybe_null);
|
||||
str2= str+ key_part->part_length + maybe_null;
|
||||
str2= str+ key_part->store_length;
|
||||
/* remove end space */
|
||||
while (length > 0 && str[length+HA_KEY_BLOB_LENGTH+maybe_null-1] == ' ')
|
||||
length--;
|
||||
int2store(str+maybe_null, length);
|
||||
/* Create key that is space filled */
|
||||
memcpy(str2, str, length + HA_KEY_BLOB_LENGTH + maybe_null);
|
||||
bfill(str2+ length+ HA_KEY_BLOB_LENGTH +maybe_null,
|
||||
key_part->part_length-length - HA_KEY_BLOB_LENGTH, ' ');
|
||||
int2store(str2+maybe_null, key_part->part_length - HA_KEY_BLOB_LENGTH);
|
||||
my_fill_8bit(field->charset(),
|
||||
str2+ length+ HA_KEY_BLOB_LENGTH +maybe_null,
|
||||
key_part->length-length, ' ');
|
||||
int2store(str2+maybe_null, key_part->length);
|
||||
}
|
||||
if (!(tree=new SEL_ARG(field,str,str2)))
|
||||
DBUG_RETURN(0); // out of memory
|
||||
@ -3055,7 +3067,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
|
||||
uint tmp_min_flag,tmp_max_flag,keynr;
|
||||
char *tmp_min_key=min_key,*tmp_max_key=max_key;
|
||||
|
||||
key_tree->store(param->key[idx][key_tree->part].part_length,
|
||||
key_tree->store(param->key[idx][key_tree->part].store_length,
|
||||
&tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
|
||||
uint min_key_length= (uint) (tmp_min_key- param->min_key);
|
||||
uint max_key_length= (uint) (tmp_max_key- param->max_key);
|
||||
@ -3152,9 +3164,20 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree,
|
||||
{
|
||||
QUICK_RANGE_SELECT *quick;
|
||||
DBUG_ENTER("get_quick_select");
|
||||
if ((quick=new QUICK_RANGE_SELECT(param->thd, param->table,
|
||||
param->real_keynr[idx],test(parent_alloc),
|
||||
parent_alloc)))
|
||||
|
||||
|
||||
|
||||
if (param->table->key_info[param->real_keynr[idx]].flags & HA_SPATIAL)
|
||||
quick=new QUICK_RANGE_SELECT_GEOM(param->thd, param->table,
|
||||
param->real_keynr[idx],
|
||||
test(parent_alloc),
|
||||
parent_alloc);
|
||||
else
|
||||
quick=new QUICK_RANGE_SELECT(param->thd, param->table,
|
||||
param->real_keynr[idx],
|
||||
test(parent_alloc), parent_alloc);
|
||||
|
||||
if (quick)
|
||||
{
|
||||
if (quick->error ||
|
||||
get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
|
||||
@ -3194,7 +3217,7 @@ get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
|
||||
return 1;
|
||||
}
|
||||
char *tmp_min_key=min_key,*tmp_max_key=max_key;
|
||||
key_tree->store(key[key_tree->part].part_length,
|
||||
key_tree->store(key[key_tree->part].store_length,
|
||||
&tmp_min_key,min_key_flag,&tmp_max_key,max_key_flag);
|
||||
|
||||
if (key_tree->next_key_part &&
|
||||
@ -3314,19 +3337,17 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
|
||||
{
|
||||
for (const char *end=key+length ;
|
||||
key < end;
|
||||
key+= key_part++->part_length)
|
||||
key+= key_part++->store_length)
|
||||
{
|
||||
if (key_part->null_bit)
|
||||
{
|
||||
if (*key++)
|
||||
if (key_part->null_bit && *key)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Create a QUICK RANGE based on a key
|
||||
Create a QUICK RANGE based on a key
|
||||
****************************************************************************/
|
||||
|
||||
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
|
||||
@ -3370,9 +3391,8 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
|
||||
{
|
||||
key_part->part=part;
|
||||
key_part->field= key_info->key_part[part].field;
|
||||
key_part->part_length= key_info->key_part[part].length;
|
||||
if (key_part->field->type() == FIELD_TYPE_BLOB)
|
||||
key_part->part_length+=HA_KEY_BLOB_LENGTH;
|
||||
key_part->length= key_info->key_part[part].length;
|
||||
key_part->store_length= key_info->key_part[part].store_length;
|
||||
key_part->null_bit= key_info->key_part[part].null_bit;
|
||||
}
|
||||
if (insert_dynamic(&quick->ranges,(gptr)&range))
|
||||
@ -3539,117 +3559,88 @@ int QUICK_RANGE_SELECT::get_next()
|
||||
for (;;)
|
||||
{
|
||||
int result;
|
||||
key_range start_key, end_key;
|
||||
if (range)
|
||||
{ // Already read through key
|
||||
result=((range->flag & (EQ_RANGE | GEOM_FLAG)) ?
|
||||
file->index_next_same(record, (byte*) range->min_key,
|
||||
range->min_length) :
|
||||
file->index_next(record));
|
||||
|
||||
if (!result)
|
||||
{
|
||||
if ((range->flag & GEOM_FLAG) || !cmp_next(*cur_range))
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
else if (result != HA_ERR_END_OF_FILE)
|
||||
// Already read through key
|
||||
result= file->read_range_next(test(range->flag & EQ_RANGE));
|
||||
if (result != HA_ERR_END_OF_FILE)
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
if (!cur_range)
|
||||
range= *(cur_range= (QUICK_RANGE**)ranges.buffer);
|
||||
range= *(cur_range= (QUICK_RANGE**) ranges.buffer);
|
||||
else
|
||||
range=
|
||||
(cur_range == ((QUICK_RANGE**)ranges.buffer + ranges.elements - 1))?
|
||||
NULL: *(++cur_range);
|
||||
(cur_range == ((QUICK_RANGE**) ranges.buffer + ranges.elements - 1)) ?
|
||||
(QUICK_RANGE*) 0 : *(++cur_range);
|
||||
|
||||
if (!range)
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
|
||||
if (range->flag & GEOM_FLAG)
|
||||
{
|
||||
if ((result = file->index_read(record,
|
||||
(byte*) (range->min_key),
|
||||
range->min_length,
|
||||
(ha_rkey_function)(range->flag ^
|
||||
GEOM_FLAG))))
|
||||
{
|
||||
if (result != HA_ERR_KEY_NOT_FOUND)
|
||||
DBUG_RETURN(result);
|
||||
range=0; // Not found, to next range
|
||||
continue;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if (range->flag & NO_MIN_RANGE) // Read first record
|
||||
{
|
||||
int local_error;
|
||||
if ((local_error=file->index_first(record)))
|
||||
DBUG_RETURN(local_error); // Empty table
|
||||
if (cmp_next(range) == 0)
|
||||
DBUG_RETURN(0);
|
||||
range=0; // No matching records; go to next range
|
||||
continue;
|
||||
}
|
||||
if ((result = file->index_read(record,
|
||||
(byte*) (range->min_key +
|
||||
test(range->flag & GEOM_FLAG)),
|
||||
range->min_length,
|
||||
(range->flag & NEAR_MIN) ?
|
||||
HA_READ_AFTER_KEY:
|
||||
start_key.key= (const byte*) range->min_key;
|
||||
start_key.length= range->min_length;
|
||||
start_key.flag= ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
|
||||
(range->flag & EQ_RANGE) ?
|
||||
HA_READ_KEY_EXACT :
|
||||
HA_READ_KEY_OR_NEXT)))
|
||||
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
|
||||
end_key.key= (const byte*) range->max_key;
|
||||
end_key.length= range->max_length;
|
||||
/*
|
||||
We use READ_AFTER_KEY here because if we are reading on a key
|
||||
prefix we want to find all keys with this prefix
|
||||
*/
|
||||
end_key.flag= (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
|
||||
HA_READ_AFTER_KEY);
|
||||
|
||||
{
|
||||
if (result != HA_ERR_KEY_NOT_FOUND)
|
||||
DBUG_RETURN(result);
|
||||
range=0; // Not found, to next range
|
||||
continue;
|
||||
}
|
||||
if (cmp_next(range) == 0)
|
||||
{
|
||||
result= file->read_range_first(range->min_length ? &start_key : 0,
|
||||
range->max_length ? &end_key : 0,
|
||||
sorted);
|
||||
if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
|
||||
range=0; // Stop searching
|
||||
DBUG_RETURN(0); // Found key is in range
|
||||
}
|
||||
range=0; // To next range
|
||||
|
||||
if (result != HA_ERR_END_OF_FILE)
|
||||
DBUG_RETURN(result);
|
||||
range=0; // No matching rows; go to next range
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Compare if found key is over max-value
|
||||
Returns 0 if key <= range->max_key
|
||||
*/
|
||||
/* Get next for geometrical indexes */
|
||||
|
||||
int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg)
|
||||
int QUICK_RANGE_SELECT_GEOM::get_next()
|
||||
{
|
||||
if (range_arg->flag & NO_MAX_RANGE)
|
||||
return 0; /* key can't be to large */
|
||||
DBUG_ENTER("QUICK_RANGE_SELECT_GEOM::get_next");
|
||||
|
||||
KEY_PART *key_part=key_parts;
|
||||
for (char *key=range_arg->max_key, *end=key+range_arg->max_length;
|
||||
key < end;
|
||||
key+= key_part++->part_length)
|
||||
for (;;)
|
||||
{
|
||||
int cmp;
|
||||
if (key_part->null_bit)
|
||||
int result;
|
||||
if (range)
|
||||
{
|
||||
if (*key++)
|
||||
{
|
||||
if (!key_part->field->is_null())
|
||||
return 1;
|
||||
continue;
|
||||
// Already read through key
|
||||
result= file->index_next_same(record, (byte*) range->min_key,
|
||||
range->min_length);
|
||||
if (result != HA_ERR_END_OF_FILE)
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
else if (key_part->field->is_null())
|
||||
return 0;
|
||||
|
||||
if (!cur_range)
|
||||
range= *(cur_range= (QUICK_RANGE**) ranges.buffer);
|
||||
else
|
||||
range=
|
||||
(cur_range == ((QUICK_RANGE**) ranges.buffer + ranges.elements - 1)) ?
|
||||
(QUICK_RANGE*) 0 : *(++cur_range);
|
||||
|
||||
if (!range)
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
|
||||
|
||||
result= file->index_read(record,
|
||||
(byte*) range->min_key,
|
||||
range->min_length,
|
||||
(ha_rkey_function)(range->flag ^ GEOM_FLAG));
|
||||
if (result != HA_ERR_KEY_NOT_FOUND)
|
||||
DBUG_RETURN(result);
|
||||
range=0; // Not found, to next range
|
||||
}
|
||||
if ((cmp=key_part->field->key_cmp((byte*) key, key_part->part_length)) < 0)
|
||||
return 0;
|
||||
if (cmp > 0)
|
||||
return 1;
|
||||
}
|
||||
return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
|
||||
}
|
||||
|
||||
|
||||
@ -3833,6 +3824,47 @@ int QUICK_SELECT_DESC::get_next()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Compare if found key is over max-value
|
||||
Returns 0 if key <= range->max_key
|
||||
*/
|
||||
|
||||
int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg)
|
||||
{
|
||||
if (range_arg->flag & NO_MAX_RANGE)
|
||||
return 0; /* key can't be to large */
|
||||
|
||||
KEY_PART *key_part=key_parts;
|
||||
uint store_length;
|
||||
|
||||
for (char *key=range_arg->max_key, *end=key+range_arg->max_length;
|
||||
key < end;
|
||||
key+= store_length, key_part++)
|
||||
{
|
||||
int cmp;
|
||||
store_length= key_part->store_length;
|
||||
if (key_part->null_bit)
|
||||
{
|
||||
if (*key)
|
||||
{
|
||||
if (!key_part->field->is_null())
|
||||
return 1;
|
||||
continue;
|
||||
}
|
||||
else if (key_part->field->is_null())
|
||||
return 0;
|
||||
key++; // Skip null byte
|
||||
store_length--;
|
||||
}
|
||||
if ((cmp=key_part->field->key_cmp((byte*) key, key_part->length)) < 0)
|
||||
return 0;
|
||||
if (cmp > 0)
|
||||
return 1;
|
||||
}
|
||||
return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Returns 0 if found key is inside range (found key >= range->min_key).
|
||||
*/
|
||||
@ -3843,15 +3875,18 @@ int QUICK_RANGE_SELECT::cmp_prev(QUICK_RANGE *range_arg)
|
||||
return 0; /* key can't be to small */
|
||||
|
||||
KEY_PART *key_part = key_parts;
|
||||
uint store_length;
|
||||
|
||||
for (char *key = range_arg->min_key, *end = key + range_arg->min_length;
|
||||
key < end;
|
||||
key += key_part++->part_length)
|
||||
key += store_length, key_part++)
|
||||
{
|
||||
int cmp;
|
||||
store_length= key_part->store_length;
|
||||
if (key_part->null_bit)
|
||||
{
|
||||
// this key part allows null values; NULL is lower than everything else
|
||||
if (*key++)
|
||||
if (*key)
|
||||
{
|
||||
// the range is expecting a null value
|
||||
if (!key_part->field->is_null())
|
||||
@ -3860,9 +3895,11 @@ int QUICK_RANGE_SELECT::cmp_prev(QUICK_RANGE *range_arg)
|
||||
}
|
||||
else if (key_part->field->is_null())
|
||||
return 1; // null -- outside the range
|
||||
key++;
|
||||
store_length--;
|
||||
}
|
||||
if ((cmp = key_part->field->key_cmp((byte*) key,
|
||||
key_part->part_length)) > 0)
|
||||
key_part->length)) > 0)
|
||||
return 0;
|
||||
if (cmp < 0)
|
||||
return 1;
|
||||
@ -3890,23 +3927,20 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
|
||||
bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
|
||||
uint used_key_parts)
|
||||
{
|
||||
uint offset,end;
|
||||
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++->part_length)
|
||||
offset+= key_part++->store_length)
|
||||
{
|
||||
uint null_length=test(key_part->null_bit);
|
||||
if (!memcmp((char*) range_arg->min_key+offset,
|
||||
(char*) range_arg->max_key+offset,
|
||||
key_part->part_length + null_length))
|
||||
{
|
||||
offset+=null_length;
|
||||
key_part->store_length))
|
||||
continue;
|
||||
}
|
||||
if (null_length && range_arg->min_key[offset])
|
||||
|
||||
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;
|
||||
@ -3948,33 +3982,34 @@ static void
|
||||
print_key(KEY_PART *key_part,const char *key,uint used_length)
|
||||
{
|
||||
char buff[1024];
|
||||
const char *key_end= key+used_length;
|
||||
String tmp(buff,sizeof(buff),&my_charset_bin);
|
||||
uint store_length;
|
||||
|
||||
for (uint length=0;
|
||||
length < used_length ;
|
||||
length+=key_part->part_length, key+=key_part->part_length, key_part++)
|
||||
for (; key < key_end; key+=store_length, key_part++)
|
||||
{
|
||||
Field *field=key_part->field;
|
||||
if (length != 0)
|
||||
fputc('/',DBUG_FILE);
|
||||
Field *field= key_part->field;
|
||||
store_length= key_part->store_length;
|
||||
|
||||
if (field->real_maybe_null())
|
||||
{
|
||||
length++; // null byte is not in part_length
|
||||
if (*key++)
|
||||
if (*key)
|
||||
{
|
||||
fwrite("NULL",sizeof(char),4,DBUG_FILE);
|
||||
continue;
|
||||
}
|
||||
key++; // Skip null byte
|
||||
store_length--;
|
||||
}
|
||||
field->set_key_image((char*) key,key_part->part_length -
|
||||
((field->type() == FIELD_TYPE_BLOB) ?
|
||||
HA_KEY_BLOB_LENGTH : 0),
|
||||
field->charset());
|
||||
field->val_str(&tmp,&tmp);
|
||||
field->set_key_image((char*) key, key_part->length, field->charset());
|
||||
field->val_str(&tmp);
|
||||
fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
|
||||
if (key+store_length < key_end)
|
||||
fputc('/',DBUG_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void print_quick_sel_imerge(QUICK_INDEX_MERGE_SELECT *quick,
|
||||
const key_map *needed_reg)
|
||||
{
|
||||
@ -3994,6 +4029,7 @@ static void print_quick_sel_imerge(QUICK_INDEX_MERGE_SELECT *quick,
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void print_quick_sel_range(QUICK_RANGE_SELECT *quick,
|
||||
const key_map *needed_reg)
|
||||
{
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
|
||||
typedef struct st_key_part {
|
||||
uint16 key,part,part_length;
|
||||
uint16 key,part, store_length, length;
|
||||
uint8 null_bit;
|
||||
Field *field;
|
||||
Field::imagetype image_type;
|
||||
@ -74,6 +74,7 @@ class QUICK_RANGE :public Sql_alloc {
|
||||
class QUICK_SELECT_I
|
||||
{
|
||||
public:
|
||||
bool sorted;
|
||||
ha_rows records; /* estimate of # of records to be retrieved */
|
||||
double read_time; /* time to perform this retrieval */
|
||||
TABLE *head;
|
||||
@ -170,6 +171,17 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class QUICK_RANGE_SELECT_GEOM: public QUICK_RANGE_SELECT
|
||||
{
|
||||
public:
|
||||
QUICK_RANGE_SELECT_GEOM(THD *thd, TABLE *table, uint index_arg,
|
||||
bool no_alloc, MEM_ROOT *parent_alloc)
|
||||
:QUICK_RANGE_SELECT(thd, table, index_arg, no_alloc, parent_alloc)
|
||||
{};
|
||||
virtual int get_next();
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
|
||||
|
||||
|
37
sql/slave.cc
37
sql/slave.cc
@ -464,13 +464,12 @@ void init_slave_skip_errors(const char* arg)
|
||||
}
|
||||
|
||||
|
||||
void st_relay_log_info::inc_group_relay_log_pos(ulonglong val,
|
||||
ulonglong log_pos,
|
||||
bool skip_lock)
|
||||
void st_relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
|
||||
bool skip_lock=0)
|
||||
{
|
||||
if (!skip_lock)
|
||||
pthread_mutex_lock(&data_lock);
|
||||
inc_event_relay_log_pos(val);
|
||||
inc_event_relay_log_pos();
|
||||
group_relay_log_pos= event_relay_log_pos;
|
||||
strmake(group_relay_log_name,event_relay_log_name,
|
||||
sizeof(group_relay_log_name)-1);
|
||||
@ -487,6 +486,28 @@ void st_relay_log_info::inc_group_relay_log_pos(ulonglong val,
|
||||
not advance as it should on the non-transactional slave (it advances by
|
||||
big leaps, whereas it should advance by small leaps).
|
||||
*/
|
||||
/*
|
||||
In 4.x we used the event's len to compute the positions here. This is
|
||||
wrong if the event was 3.23/4.0 and has been converted to 5.0, because
|
||||
then the event's len is not what is was in the master's binlog, so this
|
||||
will make a wrong group_master_log_pos (yes it's a bug in 3.23->4.0
|
||||
replication: Exec_master_log_pos is wrong). Only way to solve this is to
|
||||
have the original offset of the end of the event the relay log. This is
|
||||
what we do in 5.0: log_pos has become "end_log_pos" (because the real use
|
||||
of log_pos in 4.0 was to compute the end_log_pos; so better to store
|
||||
end_log_pos instead of begin_log_pos.
|
||||
If we had not done this fix here, the problem would also have appeared
|
||||
when the slave and master are 5.0 but with different event length (for
|
||||
example the slave is more recent than the master and features the event
|
||||
UID). It would give false MASTER_POS_WAIT, false Exec_master_log_pos in
|
||||
SHOW SLAVE STATUS, and so the user would do some CHANGE MASTER using this
|
||||
value which would lead to badly broken replication.
|
||||
Even the relay_log_pos will be corrupted in this case, because the len is
|
||||
the relay log is not "val".
|
||||
With the end_log_pos solution, we avoid computations involving lengthes.
|
||||
*/
|
||||
DBUG_PRINT("info", ("log_pos=%lld group_master_log_pos=%lld",
|
||||
log_pos,group_master_log_pos));
|
||||
if (log_pos) // 3.23 binlogs don't have log_posx
|
||||
{
|
||||
#if MYSQL_VERSION_ID < 50000
|
||||
@ -500,10 +521,10 @@ void st_relay_log_info::inc_group_relay_log_pos(ulonglong val,
|
||||
Yes this is a hack but it's just to make 3.23->4.x replication work;
|
||||
3.23->5.0 replication is working much better.
|
||||
*/
|
||||
group_master_log_pos= log_pos + val -
|
||||
group_master_log_pos= log_pos -
|
||||
(mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0);
|
||||
#else
|
||||
group_master_log_pos= log_pos+ val;
|
||||
group_master_log_pos= log_pos;
|
||||
#endif /* MYSQL_VERSION_ID < 5000 */
|
||||
}
|
||||
pthread_cond_broadcast(&data_cond);
|
||||
@ -2540,13 +2561,13 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
|
||||
goto err;
|
||||
}
|
||||
|
||||
int cmp_result;
|
||||
|
||||
/* The "compare and wait" main loop */
|
||||
while (!thd->killed &&
|
||||
init_abort_pos_wait == abort_pos_wait &&
|
||||
slave_running)
|
||||
{
|
||||
bool pos_reached;
|
||||
int cmp_result= 0;
|
||||
|
||||
/*
|
||||
group_master_log_name can be "", if we are just after a fresh
|
||||
|
@ -283,12 +283,14 @@ typedef struct st_relay_log_info
|
||||
until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
|
||||
}
|
||||
|
||||
inline void inc_event_relay_log_pos(ulonglong val)
|
||||
inline void inc_event_relay_log_pos()
|
||||
{
|
||||
event_relay_log_pos+= val;
|
||||
event_relay_log_pos= future_event_relay_log_pos;
|
||||
}
|
||||
|
||||
void inc_group_relay_log_pos(ulonglong val, ulonglong log_pos, bool skip_lock=0);
|
||||
void inc_group_relay_log_pos(ulonglong log_pos,
|
||||
bool skip_lock=0);
|
||||
|
||||
int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
|
||||
longlong timeout);
|
||||
void close_temporary_tables();
|
||||
|
@ -206,8 +206,8 @@ sp_head::operator delete(void *ptr, size_t size)
|
||||
}
|
||||
|
||||
sp_head::sp_head()
|
||||
: Sql_alloc(), m_has_return(FALSE), m_simple_case(FALSE),
|
||||
m_multi_results(FALSE), m_free_list(NULL), m_returns_cs(NULL)
|
||||
: Sql_alloc(), m_returns_cs(NULL), m_has_return(FALSE), m_simple_case(FALSE),
|
||||
m_multi_results(FALSE), m_free_list(NULL)
|
||||
{
|
||||
DBUG_ENTER("sp_head::sp_head");
|
||||
|
||||
|
@ -3434,6 +3434,7 @@ unsent_create_error:
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
st_sp_security_context save_ctx;
|
||||
#endif
|
||||
ha_rows select_limit;
|
||||
uint smrx;
|
||||
LINT_INIT(smrx);
|
||||
|
||||
@ -3468,9 +3469,12 @@ unsent_create_error:
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_change_security_context(thd, sp, &save_ctx);
|
||||
#endif
|
||||
select_limit= thd->variables.select_limit;
|
||||
thd->variables.select_limit= HA_POS_ERROR;
|
||||
|
||||
res= sp->execute_procedure(thd, &lex->value_list);
|
||||
|
||||
thd->variables.select_limit= select_limit;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
sp_restore_security_context(thd, sp, &save_ctx);
|
||||
#endif
|
||||
|
@ -6976,7 +6976,7 @@ static void test_explain_bug()
|
||||
"","","",NAME_LEN,0);
|
||||
|
||||
verify_prepare_field(result,6,"key_len","",MYSQL_TYPE_VAR_STRING,
|
||||
"","","",NAME_LEN*32,0);
|
||||
"","","",NAME_LEN*64,0);
|
||||
|
||||
verify_prepare_field(result,7,"ref","",MYSQL_TYPE_VAR_STRING,
|
||||
"","","",NAME_LEN*16,0);
|
||||
|
Reference in New Issue
Block a user