Browse Source

Merge tag 'mariadb-5.5.68' into 10.0

10.0
Sergei Golubchik 5 years ago
parent
commit
c2a7dffc57
  1. 2
      VERSION
  2. 14
      client/mysqlbinlog.cc
  3. 2
      client/mysqldump.c
  4. 10
      include/queues.h
  5. 2
      mysql-test/lib/My/SafeProcess/safe_process_win.cc
  6. 2
      mysql-test/mysql-test-run.pl
  7. 52
      mysql-test/r/index_merge_myisam.result
  8. 3
      mysql-test/r/processlist_notembedded.result
  9. 19
      mysql-test/r/range.result
  10. 30
      mysql-test/r/range_innodb.result
  11. 19
      mysql-test/r/range_mrr_icp.result
  12. 2
      mysql-test/r/range_vs_index_merge.result
  13. 5
      mysql-test/suite.pm
  14. 15
      mysql-test/suite/rpl/r/rpl_conditional_comments.result
  15. 16
      mysql-test/suite/rpl/r/rpl_fail_register.result
  16. 12
      mysql-test/suite/rpl/t/rpl_conditional_comments.test
  17. 33
      mysql-test/suite/rpl/t/rpl_fail_register.test
  18. 49
      mysql-test/t/index_merge_myisam.test
  19. 9
      mysql-test/t/processlist_notembedded.test
  20. 14
      mysql-test/t/range.test
  21. 29
      mysql-test/t/range_innodb.test
  22. 12
      mysys/my_addr_resolve.c
  23. 169
      mysys/queues.c
  24. 20
      sql-common/client.c
  25. 4
      sql/event_scheduler.cc
  26. 28
      sql/opt_range.cc
  27. 34
      sql/slave.cc
  28. 2
      sql/sql_class.cc
  29. 18
      sql/sql_lex.cc
  30. 1
      sql/sql_parse.cc
  31. 1
      sql/table.cc
  32. 6
      storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
  33. 2
      support-files/rpm/my.cnf
  34. 2
      unittest/mysys/CMakeLists.txt
  35. 139
      unittest/mysys/queues-t.c
  36. 2
      win/packaging/heidisql.cmake
  37. 28
      win/packaging/heidisql.wxi.in

2
VERSION

@ -1,4 +1,4 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=0
MYSQL_VERSION_PATCH=40
MYSQL_VERSION_EXTRA=-3
MYSQL_VERSION_EXTRA=-4

14
client/mysqlbinlog.cc

@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Copyright (c) 2009, 2014, MariaDB
Copyright (c) 2009, 2020, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -155,7 +155,7 @@ enum Exit_status {
*/
static Annotate_rows_log_event *annotate_event= NULL;
void free_annotate_event()
static void free_annotate_event()
{
if (annotate_event)
{
@ -858,7 +858,7 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print_event_info->m_table_map_ignored.get_table(table_id);
bool skip_event= (ignored_map != NULL);
/*
/*
end of statement check:
i) destroy/free ignored maps
ii) if skip event
@ -869,21 +869,21 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
if (is_stmt_end)
{
/*
/*
Now is safe to clear ignored map (clear_tables will also
delete original table map events stored in the map).
*/
if (print_event_info->m_table_map_ignored.count() > 0)
print_event_info->m_table_map_ignored.clear_tables();
/*
/*
If there is a kept Annotate event and all corresponding
rbr-events were filtered away, the Annotate event was not
freed and it is just the time to do it.
*/
free_annotate_event();
free_annotate_event();
/*
/*
One needs to take into account an event that gets
filtered but was last event in the statement. If this is
the case, previous rows events that were written into

2
client/mysqldump.c

@ -32,7 +32,7 @@
** master/autocommit code by Brian Aker <brian@tangent.org>
** SSL by
** Andrei Errapart <andreie@no.spam.ee>
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
** and adapted to mysqldump 05/11/01 by Jani Tolonen
** Added --single-transaction option 06/06/2002 by Peter Zaitsev

10
include/queues.h

@ -55,7 +55,7 @@ typedef struct st_queue {
#define queue_top(queue) ((queue)->root[1])
#define queue_element(queue,index) ((queue)->root[index])
#define queue_end(queue) ((queue)->root[(queue)->elements])
#define queue_replace_top(queue) _downheap(queue, 1, (queue)->root[1])
#define queue_replace_top(queue) _downheap(queue, 1)
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
#define queue_set_max_at_top(queue, set_arg) \
(queue)->max_at_top= set_arg ? -1 : 1
@ -63,23 +63,23 @@ typedef struct st_queue {
typedef int (*queue_compare)(void *,uchar *, uchar *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
my_bool max_at_top, queue_compare compare,
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent);
int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
my_bool max_at_top, queue_compare compare,
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent);
int resize_queue(QUEUE *queue, uint max_elements);
void delete_queue(QUEUE *queue);
void queue_insert(QUEUE *queue,uchar *element);
void queue_insert(QUEUE *queue, uchar *element);
int queue_insert_safe(QUEUE *queue, uchar *element);
uchar *queue_remove(QUEUE *queue,uint idx);
void queue_replace(QUEUE *queue,uint idx);
#define queue_remove_all(queue) { (queue)->elements= 0; }
#define queue_is_full(queue) (queue->elements == queue->max_elements)
void _downheap(QUEUE *queue, uint idx, uchar *element);
void _downheap(QUEUE *queue, uint idx);
void queue_fix(QUEUE *queue);
#define is_queue_inited(queue) ((queue)->root != 0)

2
mysql-test/lib/My/SafeProcess/safe_process_win.cc

@ -206,7 +206,7 @@ int main(int argc, const char** argv )
} else {
if (strcmp(arg, "--verbose") == 0)
verbose++;
else if (strncmp(arg, "--parent-pid", 10) == 0)
else if (strncmp(arg, "--parent-pid", 12) == 0)
{
/* Override parent_pid with a value provided by user */
const char* start;

2
mysql-test/mysql-test-run.pl

@ -272,7 +272,7 @@ my $current_config_name; # The currently running config file template
our @opt_experimentals;
our $experimental_test_cases= [];
my $baseport;
our $baseport;
# $opt_build_thread may later be set from $opt_port_base
my $opt_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto";
my $opt_port_base= $ENV{'MTR_PORT_BASE'} || "auto";

52
mysql-test/r/index_merge_myisam.result

@ -1713,6 +1713,58 @@ id select_type table type possible_keys key key_len ref rows Extra
DROP TABLE t1;
set optimizer_switch= @optimizer_switch_save;
#
# MDEV-21932: ROR union with index_merge_sort_union=off
#
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into t0 select a+10 from t0;
insert into t0 select a+20 from t0;
insert into t0 select a+40 from t0;
insert into t0 select a+80 from t0;
insert into t0 select a+160 from t0;
delete from t0 where a > 300;
create table t1 (
f1 int, f2 int, f3 int, f4 int,
primary key (f1), key (f3), key(f4)
) engine=myisam;
insert into t1 select a+100, a+100, a+100, a+100 from t0;
insert into t1 VALUES (9,0,2,6), (9930,0,0,NULL);
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
set optimizer_switch='index_merge_sort_union=off';
set optimizer_switch='index_merge_union=on';
explain select * from t1
where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 3 Using union(f3,PRIMARY,f3); Using where
select * from t1
where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
f1 f2 f3 f4
9 0 2 6
insert into t1 values (52,0,1,0),(53,0,1,0);
insert into t1 values (50,0,1,0),(51,0,1,0);
insert into t1 values (48,0,1,0),(49,0,1,0);
insert into t1 values (46,0,1,0),(47,0,1,0);
insert into t1 values (44,0,1,0),(45,0,1,0);
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
explain select * from t1
where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 13 Using union(f3,PRIMARY,f3); Using where
select * from t1
where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
f1 f2 f3 f4
9 0 2 6
drop table t0,t1;
set optimizer_switch= @optimizer_switch_save;
#
# MDEV-16695: Estimate for rows of derived tables is very high when we are using index_merge union
#
create table t0

3
mysql-test/r/processlist_notembedded.result

@ -1,8 +1,9 @@
#
# MDEV-20466: SHOW PROCESSLIST truncates query text on \0 bytes
#
SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync';
SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync WAIT_FOR go';
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
FOUND /sleep/ in MDEV-20466.text
SET DEBUG_SYNC= 'now SIGNAL go';
SET DEBUG_SYNC = 'RESET';
End of 5.5 tests

19
mysql-test/r/range.result

@ -2145,6 +2145,25 @@ value1 1003560 12345
value1 1004807 12345
drop table t1;
#
# MDEV-22191: Range access is not picked when index_merge_sort_union is turned off
#
set @save_optimizer_switch=@@optimizer_switch;
set @save_optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, INDEX(a));
INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
explain
SELECT * FROM t1 WHERE a > 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 5 Using where; Using index
SELECT * FROM t1 WHERE a > 5;
a
6
7
8
9
set @@optimizer_switch=@save_optimizer_switch;
drop table t1;
#
# BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
#
CREATE TABLE t1 (pk INT PRIMARY KEY);

30
mysql-test/r/range_innodb.result

@ -37,6 +37,36 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10
1 SIMPLE t2 range a,b b 5 NULL 201 Using where; Using join buffer (flat, BNL join)
drop table t0,t1,t2;
#
# MDEV-10466: constructing an invalid SEL_ARG
#
create table t1 (
pk int, a int, b int,
primary key (pk), index idx1(b), index idx2(b)
) engine=innodb;
Warnings:
Note 1831 Duplicate index `idx2`. This is deprecated and will be disallowed in a future release.
insert into t1 values (1,6,0),(2,1,0),(3,5,2),(4,8,0);
create table t2 (c int) engine=innodb;
insert into t2 values (1),(2);
create table t3 (d int) engine=innodb;
insert into t3 values (3),(-1),(4);
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='extended_keys=on';
explain
select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 4 Using where; Using join buffer (incremental, BNL join)
select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0';
pk a b
1 6 0
set optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
#
# MDEV-6453: Assertion `inited==NONE || (inited==RND && scan)' failed in handler::ha_rnd_init(bool) with InnoDB, joins, AND/OR conditions
#
CREATE TABLE t1 (
pk INT PRIMARY KEY, f1 INT, f2 CHAR(1), f3 CHAR(1),
KEY(f1), KEY(f2)

19
mysql-test/r/range_mrr_icp.result

@ -2147,6 +2147,25 @@ value1 1003560 12345
value1 1004807 12345
drop table t1;
#
# MDEV-22191: Range access is not picked when index_merge_sort_union is turned off
#
set @save_optimizer_switch=@@optimizer_switch;
set @save_optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, INDEX(a));
INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
explain
SELECT * FROM t1 WHERE a > 5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 5 Using where; Using index
SELECT * FROM t1 WHERE a > 5;
a
6
7
8
9
set @@optimizer_switch=@save_optimizer_switch;
drop table t1;
#
# BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
#
CREATE TABLE t1 (pk INT PRIMARY KEY);

2
mysql-test/r/range_vs_index_merge.result

@ -1659,7 +1659,7 @@ SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where
1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 3 Using union(f3,PRIMARY,f3); Using where
SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );

5
mysql-test/suite.pm

@ -49,9 +49,10 @@ sub skip_combinations {
sub ipv6_ok() {
use Socket;
return 0 unless socket my $sock, PF_INET6, SOCK_STREAM, getprotobyname('tcp');
$!="";
# eval{}, if there's no Socket::sockaddr_in6 at all, old Perl installation
eval { connect $sock, sockaddr_in6(7, Socket::IN6ADDR_LOOPBACK) };
return $@ eq "";
eval { bind $sock, sockaddr_in6($::baseport, Socket::IN6ADDR_LOOPBACK) };
return $@ eq "" && $! eq ""
}
$skip{'include/check_ipv6.inc'} = 'No IPv6' unless ipv6_ok();

15
mysql-test/suite/rpl/r/rpl_conditional_comments.result

@ -65,5 +65,20 @@ include/diff_tables.inc [master:t1,slave:t1]
# comments
SELECT c1 FROM /*!999999 t1 WHEREN;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '/*!999999 t1 WHEREN' at line 1
insert t1 values (/*!50505 1 /* foo */ */ + 2);
insert t1 values (/*!999999 10 /* foo */ */ + 20);
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; insert t1 values (/*!50505 1 /* foo */ */ + 2)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; insert t1 values (/* 999999 10 (* foo *) */ + 20)
master-bin.000001 # Query # # COMMIT
select * from t1;
c1
62
3
20
DROP TABLE t1;
include/rpl_end.inc

16
mysql-test/suite/rpl/r/rpl_fail_register.result

@ -0,0 +1,16 @@
include/master-slave.inc
[connection master]
set @old_dbug=@@global.debug_dbug;
set global debug_dbug='d,fail_com_register_slave';
stop slave;
reset slave;
include/wait_for_slave_to_stop.inc
start slave;
stop slave;
include/wait_for_slave_to_stop.inc
set global debug_dbug=@old_dbug;
kill DUMP_THREAD;
show slave hosts;
Server_id Host Port Master_id
start slave;
include/rpl_end.inc

12
mysql-test/suite/rpl/t/rpl_conditional_comments.test

@ -68,7 +68,17 @@ sync_slave_with_master;
--echo # comments
--connection master
--error 1064
SELECT c1 FROM /*!999999 t1 WHEREN;
SELECT c1 FROM /*!999999 t1 WHEREN; #*/
#
# Bug#28388217 - SERVER CAN FAIL WHILE REPLICATING CONDITIONAL COMMENTS
#
insert t1 values (/*!50505 1 /* foo */ */ + 2);
insert t1 values (/*!999999 10 /* foo */ */ + 20);
source include/show_binlog_events.inc;
sync_slave_with_master;
select * from t1;
connection master;
DROP TABLE t1;
--source include/rpl_end.inc

33
mysql-test/suite/rpl/t/rpl_fail_register.test

@ -0,0 +1,33 @@
source include/have_debug.inc;
source include/have_binlog_format_mixed.inc;
source include/master-slave.inc;
connection slave;
set @old_dbug=@@global.debug_dbug;
set global debug_dbug='d,fail_com_register_slave';
stop slave;
reset slave;
source include/wait_for_slave_to_stop.inc;
start slave;
stop slave;
source include/wait_for_slave_to_stop.inc;
set global debug_dbug=@old_dbug;
connection master;
### why is that needed?
let $id=`SELECT id from information_schema.processlist where command='Binlog Dump'`;
if ($id) {
replace_result $id DUMP_THREAD;
eval kill $id;
let $wait_condition= SELECT count(*)=0 from information_schema.processlist where command='Binlog Dump';
source include/wait_condition.inc;
}
show slave hosts;
connection slave;
start slave;
source include/rpl_end.inc;

49
mysql-test/t/index_merge_myisam.test

@ -243,6 +243,55 @@ DROP TABLE t1;
set optimizer_switch= @optimizer_switch_save;
--echo #
--echo # MDEV-21932: ROR union with index_merge_sort_union=off
--echo #
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into t0 select a+10 from t0;
insert into t0 select a+20 from t0;
insert into t0 select a+40 from t0;
insert into t0 select a+80 from t0;
insert into t0 select a+160 from t0;
delete from t0 where a > 300;
create table t1 (
f1 int, f2 int, f3 int, f4 int,
primary key (f1), key (f3), key(f4)
) engine=myisam;
insert into t1 select a+100, a+100, a+100, a+100 from t0;
insert into t1 VALUES (9,0,2,6), (9930,0,0,NULL);
analyze table t1;
set optimizer_switch='index_merge_sort_union=off';
set optimizer_switch='index_merge_union=on';
let $q1=
select * from t1
where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
eval explain $q1;
eval $q1;
insert into t1 values (52,0,1,0),(53,0,1,0);
insert into t1 values (50,0,1,0),(51,0,1,0);
insert into t1 values (48,0,1,0),(49,0,1,0);
insert into t1 values (46,0,1,0),(47,0,1,0);
insert into t1 values (44,0,1,0),(45,0,1,0);
analyze table t1;
let $q2=
select * from t1
where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
eval explain $q2;
eval $q2;
drop table t0,t1;
set optimizer_switch= @optimizer_switch_save;
--echo #
--echo # MDEV-16695: Estimate for rows of derived tables is very high when we are using index_merge union
--echo #

9
mysql-test/t/processlist_notembedded.test

@ -1,6 +1,7 @@
source include/have_debug.inc;
source include/have_debug_sync.inc;
source include/not_embedded.inc;
source include/count_sessions.inc;
--echo #
--echo # MDEV-20466: SHOW PROCESSLIST truncates query text on \0 bytes
@ -10,9 +11,9 @@ connect (con1,localhost,root,,);
connection con1;
let $q= `select CONCAT("SELECT user FROM mysql.user WHERE user ='some", CHAR(0), "' or sleep (30)")`;
let $q= `select CONCAT("SELECT user FROM mysql.user WHERE user ='some", CHAR(0), "sleep'")`;
SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync';
SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync WAIT_FOR go';
--disable_query_log
--send_eval $q;
--enable_query_log
@ -27,8 +28,12 @@ let SEARCH_PATTERN=sleep;
source include/search_pattern_in_file.inc;
remove_file $MYSQLTEST_VARDIR/tmp//MDEV-20466.text;
SET DEBUG_SYNC= 'now SIGNAL go';
disconnect con1;
SET DEBUG_SYNC = 'RESET';
source include/wait_until_count_sessions.inc;
--echo End of 5.5 tests

14
mysql-test/t/range.test

@ -1719,6 +1719,20 @@ where (key1varchar='value1' AND (key2int <=1 OR key2int > 1));
select * from t1;
drop table t1;
--echo #
--echo # MDEV-22191: Range access is not picked when index_merge_sort_union is turned off
--echo #
set @save_optimizer_switch=@@optimizer_switch;
set @save_optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, INDEX(a));
INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
explain
SELECT * FROM t1 WHERE a > 5;
SELECT * FROM t1 WHERE a > 5;
set @@optimizer_switch=@save_optimizer_switch;
drop table t1;
--echo #
--echo # BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
--echo #

29
mysql-test/t/range_innodb.test

@ -46,6 +46,35 @@ explain select * from t0 left join t2 on t2.a <t0.a and t2.b between 50 and 250;
drop table t0,t1,t2;
--echo #
--echo # MDEV-10466: constructing an invalid SEL_ARG
--echo #
create table t1 (
pk int, a int, b int,
primary key (pk), index idx1(b), index idx2(b)
) engine=innodb;
insert into t1 values (1,6,0),(2,1,0),(3,5,2),(4,8,0);
create table t2 (c int) engine=innodb;
insert into t2 values (1),(2);
create table t3 (d int) engine=innodb;
insert into t3 values (3),(-1),(4);
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='extended_keys=on';
explain
select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0';
select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0';
set optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
--echo #
--echo # MDEV-6453: Assertion `inited==NONE || (inited==RND && scan)' failed in handler::ha_rnd_init(bool) with InnoDB, joins, AND/OR conditions
--echo #
CREATE TABLE t1 (
pk INT PRIMARY KEY, f1 INT, f2 CHAR(1), f3 CHAR(1),
KEY(f1), KEY(f2)

12
mysys/my_addr_resolve.c

@ -49,6 +49,18 @@ static const char *strip_path(const char *s)
static bfd *bfdh= 0;
static asymbol **symtable= 0;
#ifndef bfd_get_section_flags
#define bfd_get_section_flags(H, S) bfd_section_flags(S)
#endif /* bfd_get_section_flags */
#ifndef bfd_get_section_size
#define bfd_get_section_size(S) bfd_section_size(S)
#endif /* bfd_get_section_size */
#ifndef bfd_get_section_vma
#define bfd_get_section_vma(H, S) bfd_section_vma(S)
#endif /* bfd_get_section_vma */
/**
finds a file name, a line number, and a function name corresponding to addr.

169
mysys/queues.c

@ -70,10 +70,9 @@
*/
int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
my_bool max_at_top, int (*compare) (void *, uchar *, uchar *),
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent)
{
DBUG_ENTER("init_queue");
if ((queue->root= (uchar **) my_malloc((max_elements + 1) * sizeof(void*),
@ -109,7 +108,7 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
*/
int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
my_bool max_at_top, int (*compare) (void *, uchar *, uchar *),
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent)
{
@ -182,6 +181,28 @@ void delete_queue(QUEUE *queue)
}
static void insert_at(QUEUE *queue, uchar *element, uint idx)
{
uint next_index, offset_to_key= queue->offset_to_key;
uint offset_to_queue_pos= queue->offset_to_queue_pos;
/* max_at_top swaps the comparison if we want to order by desc */
while ((next_index= idx >> 1) > 0 &&
queue->compare(queue->first_cmp_arg,
element + offset_to_key,
queue->root[next_index] + offset_to_key) *
queue->max_at_top < 0)
{
queue->root[idx]= queue->root[next_index];
if (offset_to_queue_pos)
(*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx= next_index;
}
queue->root[idx]= element;
if (offset_to_queue_pos)
(*(uint*) (element + offset_to_queue_pos-1))= idx;
}
/*
Insert element in queue
@ -191,28 +212,10 @@ void delete_queue(QUEUE *queue)
element Element to insert
*/
void queue_insert(register QUEUE *queue, uchar *element)
void queue_insert(QUEUE *queue, uchar *element)
{
reg2 uint idx, next;
uint offset_to_queue_pos= queue->offset_to_queue_pos;
DBUG_ASSERT(queue->elements < queue->max_elements);
idx= ++queue->elements;
/* max_at_top swaps the comparison if we want to order by desc */
while (idx > 1 &&
(queue->compare(queue->first_cmp_arg,
element + queue->offset_to_key,
queue->root[(next= idx >> 1)] +
queue->offset_to_key) * queue->max_at_top) < 0)
{
queue->root[idx]= queue->root[next];
if (offset_to_queue_pos)
(*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx= next;
}
queue->root[idx]= element;
if (offset_to_queue_pos)
(*(uint*) (element+ offset_to_queue_pos-1))= idx;
insert_at(queue, element, ++queue->elements);
}
@ -230,7 +233,7 @@ void queue_insert(register QUEUE *queue, uchar *element)
2 auto_extend is 0; No insertion done
*/
int queue_insert_safe(register QUEUE *queue, uchar *element)
int queue_insert_safe(QUEUE *queue, uchar *element)
{
if (queue->elements == queue->max_elements)
@ -240,7 +243,7 @@ int queue_insert_safe(register QUEUE *queue, uchar *element)
if (resize_queue(queue, queue->max_elements + queue->auto_extent))
return 1;
}
queue_insert(queue, element);
return 0;
}
@ -259,81 +262,55 @@ int queue_insert_safe(register QUEUE *queue, uchar *element)
pointer to removed element
*/
uchar *queue_remove(register QUEUE *queue, uint idx)
uchar *queue_remove(QUEUE *queue, uint idx)
{
uchar *element;
DBUG_ASSERT(idx >= 1 && idx <= queue->elements);
DBUG_ASSERT(idx >= 1);
DBUG_ASSERT(idx <= queue->elements);
element= queue->root[idx];
_downheap(queue, idx, queue->root[queue->elements--]);
queue->root[idx]= queue->root[queue->elements--];
queue_replace(queue, idx);
return element;
}
/*
Add element to fixed position and update heap
Restores the heap property from idx down the heap
SYNOPSIS
_downheap()
queue Queue to use
idx Index of element to change
element Element to store at 'idx'
NOTE
This only works if element is >= all elements <= start_idx
*/
void _downheap(register QUEUE *queue, uint start_idx, uchar *element)
void _downheap(QUEUE *queue, uint idx)
{
uint elements,half_queue,offset_to_key, next_index, offset_to_queue_pos;
register uint idx= start_idx;
my_bool first= TRUE;
offset_to_key=queue->offset_to_key;
offset_to_queue_pos= queue->offset_to_queue_pos;
half_queue= (elements= queue->elements) >> 1;
uchar *element= queue->root[idx];
uint next_index,
elements= queue->elements,
half_queue= elements >> 1,
offset_to_key= queue->offset_to_key,
offset_to_queue_pos= queue->offset_to_queue_pos;
while (idx <= half_queue)
{
next_index=idx+idx;
next_index= idx+idx;
if (next_index < elements &&
(queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
queue->root[next_index+1]+offset_to_key) *
queue->max_at_top) > 0)
(queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
queue->root[next_index+1]+offset_to_key) *
queue->max_at_top) > 0)
next_index++;
if (first &&
(((queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
element+offset_to_key) * queue->max_at_top) >= 0)))
{
queue->root[idx]= element;
if (offset_to_queue_pos)
(*(uint*) (element + offset_to_queue_pos-1))= idx;
return;
}
first= FALSE;
queue->root[idx]= queue->root[next_index];
if (offset_to_queue_pos)
(*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx=next_index;
}
/*
Insert the element into the right position. This is the same code
as we have in queue_insert()
*/
while ((next_index= (idx >> 1)) > start_idx &&
queue->compare(queue->first_cmp_arg,
element+offset_to_key,
queue->root[next_index]+offset_to_key)*
queue->max_at_top < 0)
{
if ((queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
element+offset_to_key) * queue->max_at_top) >= 0)
break;
queue->root[idx]= queue->root[next_index];
if (offset_to_queue_pos)
(*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx= next_index;
}
queue->root[idx]= element;
queue->root[idx]=element;
if (offset_to_queue_pos)
(*(uint*) (element + offset_to_queue_pos-1))= idx;
}
@ -351,7 +328,7 @@ void queue_fix(QUEUE *queue)
{
uint i;
for (i= queue->elements >> 1; i > 0; i--)
_downheap(queue, i, queue_element(queue, i));
_downheap(queue, i);
}
@ -362,13 +339,47 @@ void queue_fix(QUEUE *queue)
queue_replace()
queue Queue to use
idx Index of element to change
element Element to store at 'idx'
NOTE
optimized for the case when the new position is close to the end of the
heap (typical for queue_remove() replacements).
*/
void queue_replace(QUEUE *queue, uint idx)
{
uchar *element= queue->root[idx];
DBUG_ASSERT(idx >= 1 && idx <= queue->elements);
queue_remove(queue, idx);
queue_insert(queue, element);
uint next_index,
elements= queue->elements,
half_queue= elements>>1,
offset_to_key= queue->offset_to_key,
offset_to_queue_pos= queue->offset_to_queue_pos;
my_bool first= TRUE;
while (idx <= half_queue)
{
next_index= idx + idx;
if (next_index < elements &&
queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
queue->root[next_index+1]+offset_to_key) *
queue->max_at_top > 0)
next_index++;
if (first &&
queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
element+offset_to_key) * queue->max_at_top >= 0)
{
queue->root[idx]= element;
if (offset_to_queue_pos)
(*(uint*) (element + offset_to_queue_pos-1))= idx;
break;
}
first= FALSE;
queue->root[idx]= queue->root[next_index];
if (offset_to_queue_pos)
(*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx=next_index;
}
insert_at(queue, element, idx);
}

20
sql-common/client.c

@ -1402,9 +1402,23 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
{
if (field - result >= fields)
goto err;
/*
If any of the row->data[] below is NULL, it can result in a
crash. Error out early as it indicates a malformed packet.
For data[0], data[1] and data[5], strmake_root will handle
NULL values.
*/
if (!row->data[2] || !row->data[3] || !row->data[4])
{
free_rows(data);
set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
DBUG_RETURN(0);
}
cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
field->name= strdup_root(alloc,(char*) row->data[1]);
field->org_table= field->table= strmake_root(alloc,(char*) row->data[0], lengths[0]);
field->name= strmake_root(alloc,(char*) row->data[1], lengths[1]);
field->length= (uint) uint3korr(row->data[2]);
field->type= (enum enum_field_types) (uchar) row->data[3][0];
@ -1429,7 +1443,7 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
field->flags|= NUM_FLAG;
if (default_value && row->data[5])
{
field->def=strdup_root(alloc,(char*) row->data[5]);
field->def= strmake_root(alloc,(char*) row->data[5], lengths[5]);
field->def_length= lengths[5];
}
else

4
sql/event_scheduler.cc

@ -1,4 +1,5 @@
/* Copyright (c) 2006, 2013, Oracle and/or its affiliates.
/* Copyright (c) 2006, 2019, Oracle and/or its affiliates.
Copyright (c) 2009, 2020, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -507,6 +508,7 @@ Event_scheduler::run(THD *thd)
DBUG_PRINT("info", ("job_data is NULL, the thread was killed"));
}
DBUG_PRINT("info", ("state=%s", scheduler_states_names[state].str));
free_root(thd->mem_root, MYF(0));
}
LOCK_DATA();

28
sql/opt_range.cc

@ -958,7 +958,7 @@ QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
uint mrr_buf_size, MEM_ROOT *alloc);
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
bool update_tbl_stats,
bool for_range_access,
double read_time);
static
TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree,
@ -5291,6 +5291,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
sizeof(TRP_RANGE*)*
n_child_scans)))
DBUG_RETURN(NULL);
/*
Collect best 'range' scan for each of disjuncts, and, while doing so,
analyze possibility of ROR scans. Also calculate some values needed by
@ -5302,7 +5303,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
{
DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
"tree in SEL_IMERGE"););
if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, read_time)))
if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE,
read_time)))
{
/*
One of index scans in this index_merge is more expensive than entire
@ -5622,9 +5624,12 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
a random order
2. the functions that estimate the cost of a range scan and an
index merge retrievals are not well calibrated
As the best range access has been already chosen it does not
make sense to evaluate the one obtained from a degenerated
index merge.
*/
trp= get_key_scans_params(param, *imerge->trees, FALSE, TRUE,
read_time);
trp= 0;
}
DBUG_RETURN(trp);
@ -7341,6 +7346,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
tree make range select for this SEL_TREE
index_read_must_be_used if TRUE, assume 'index only' option will be set
(except for clustered PK indexes)
for_range_access if TRUE the function is called to get the best range
plan for range access, not for index merge access
read_time don't create read plans with cost > read_time.
RETURN
Best range read plan
@ -7349,7 +7356,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
bool update_tbl_stats,
bool for_range_access,
double read_time)
{
uint idx;
@ -7394,9 +7401,16 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
(bool) param->table->covering_keys.is_set(keynr);
found_records= check_quick_select(param, idx, read_index_only, *key,
update_tbl_stats, &mrr_flags,
for_range_access, &mrr_flags,
&buf_size, &cost);
if (!for_range_access && !param->is_ror_scan &&
!optimizer_flag(param->thd,OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))
{
/* The scan is not a ROR-scan, just skip it */
continue;
}
if (found_records != HA_POS_ERROR && tree->index_scans &&
(index_scan= (INDEX_SCAN_INFO *)alloc_root(param->mem_root,
sizeof(INDEX_SCAN_INFO))))
@ -9482,7 +9496,7 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
if (key2->next_key_part)
{
key1->use_count--; // Incremented in and_all_keys
return and_all_keys(param, key1, key2, clone_flag);
return and_all_keys(param, key1, key2->next_key_part, clone_flag);
}
key2->use_count--; // Key2 doesn't have a tree
}

34
sql/slave.cc

@ -3860,9 +3860,6 @@ pthread_handler_t handle_slave_io(void *arg)
bool suppress_warnings;
int ret;
rpl_io_thread_info io_info;
#ifndef DBUG_OFF
uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0;
#endif
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init();
DBUG_ENTER("handle_slave_io");
@ -4043,16 +4040,7 @@ connected:
goto err;
goto connected;
}
DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_REG",
if (!retry_count_reg)
{
retry_count_reg++;
sql_print_information("Forcing to reconnect slave I/O thread");
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
reconnect_messages[SLAVE_RECON_ACT_REG]))
goto err;
goto connected;
});
DBUG_EXECUTE_IF("fail_com_register_slave", goto err;);
}
DBUG_PRINT("info",("Starting reading binary log from master"));
@ -4068,16 +4056,6 @@ connected:
goto err;
goto connected;
}
DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_DUMP",
if (!retry_count_dump)
{
retry_count_dump++;
sql_print_information("Forcing to reconnect slave I/O thread");
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
reconnect_messages[SLAVE_RECON_ACT_DUMP]))
goto err;
goto connected;
});
const char *event_buf;
mi->slave_running= MYSQL_SLAVE_RUN_READING;
@ -4095,16 +4073,6 @@ connected:
event_len= read_event(mysql, mi, &suppress_warnings);
if (check_io_slave_killed(mi, NullS))
goto err;
DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT",
if (!retry_count_event)
{
retry_count_event++;
sql_print_information("Forcing to reconnect slave I/O thread");
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
reconnect_messages[SLAVE_RECON_ACT_EVENT]))
goto err;
goto connected;
});
if (event_len == packet_error)
{

2
sql/sql_class.cc

@ -64,6 +64,7 @@
#include "sql_callback.h"
#include "lock.h"
#include "sql_connect.h"
#include "repl_failsafe.h"
/*
The following is used to initialise Table_ident with a internal
@ -1535,6 +1536,7 @@ THD::~THD()
if (rgi_slave)
rgi_slave->cleanup_after_session();
my_free(semisync_info);
unregister_slave(this, true, true);
#endif
free_root(&main_mem_root, MYF(0));

18
sql/sql_lex.cc

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
Copyright (c) 2009, 2018, MariaDB Corporation
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
Copyright (c) 2009, 2020, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -962,17 +962,27 @@ static inline uint int_token(const char *str,uint length)
*/
bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted)
{
// only one level of nested comments are allowed
DBUG_ASSERT(remaining_recursions_permitted == 0 ||
remaining_recursions_permitted == 1);
reg1 uchar c;
while (! lip->eof())
{
c= lip->yyGet();
if (remaining_recursions_permitted > 0)
if (remaining_recursions_permitted == 1)
{
if ((c == '/') && (lip->yyPeek() == '*'))
{
lip->yyUnput('('); // Replace nested "/*..." with "(*..."
lip->yySkip(); // and skip "("
lip->yySkip(); /* Eat asterisk */
consume_comment(lip, remaining_recursions_permitted-1);
if (consume_comment(lip, 0))
return true;
lip->yyUnput(')'); // Replace "...*/" with "...*)"
lip->yySkip(); // and skip ")"
continue;
}
}

1
sql/sql_parse.cc

@ -1530,7 +1530,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
general_log_print(thd, command, "Log: '%s' Pos: %lu", name, pos);
if (nlen < FN_REFLEN)
mysql_binlog_send(thd, thd->strmake(name, nlen), (my_off_t)pos, flags);
unregister_slave(thd,1,1);
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
error = TRUE;
break;

1
sql/table.cc

@ -3653,7 +3653,6 @@ bool check_column_name(const char *name)
been opened.
@param[in] table The table to check
@param[in] table_f_count Expected number of columns in the table
@param[in] table_def Expected structure of the table (column name
and type)

6
storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake

@ -205,9 +205,9 @@ if (NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang)
set_cflags_if_supported(-Wcast-align)
endif ()
## always want these in debug builds
set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror ${CMAKE_C_FLAGS_DEBUG}")
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Werror ${CMAKE_CXX_FLAGS_DEBUG}")
## never want these
set(CMAKE_C_FLAGS "-Wno-error ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "-Wno-error ${CMAKE_CXX_FLAGS}")
# pick language dialect
set(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}")

2
support-files/rpm/my.cnf

@ -5,7 +5,7 @@
[client-server]
#
# include all files from the config directory
# include *.cnf from the config directory
#
!includedir /etc/my.cnf.d

2
unittest/mysys/CMakeLists.txt

@ -14,7 +14,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring
LINK_LIBRARIES mysys)
queues LINK_LIBRARIES mysys)
MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys)
MY_ADD_TESTS(ma_dyncol

139
unittest/mysys/queues-t.c

@ -0,0 +1,139 @@
/* Copyright (c) 2020, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
#include <my_global.h>
#include <my_sys.h>
#include <my_rnd.h>
#include <queues.h>
#include "tap.h"
int cmp(void *arg __attribute__((unused)), uchar *a, uchar *b)
{
return *a < *b ? -1 : *a > *b;
}
#define rnd(R) ((uint)(my_rnd(R) * INT_MAX32))
#define el(Q,I) ((uint)*queue_element(Q, I))
my_bool verbose;
my_bool check_queue(QUEUE *queue)
{
char b[1024]={0}, *s, *e=b+sizeof(b)-2;
my_bool ok=1;
uint i;
s= b + my_snprintf(b, e-b, "%x", el(queue, 1));
for (i=2; i <= queue->elements; i++)
{
s+= my_snprintf(s, e-s, ", %x", el(queue, i));
ok &= el(queue, i) <= el(queue, i>>1);
}
if (!ok || verbose)
diag("%s", b);
return ok;
}
int main(int argc __attribute__((unused)), char *argv[])
{
QUEUE q, *queue=&q;
MY_INIT(argv[0]);
plan(19);
verbose=1;
init_queue(queue, 256, 0, 1, cmp, NULL, 0, 0);
queue_insert(queue, (uchar*)"\x99");
queue_insert(queue, (uchar*)"\x19");
queue_insert(queue, (uchar*)"\x36");
queue_insert(queue, (uchar*)"\x17");
queue_insert(queue, (uchar*)"\x12");
queue_insert(queue, (uchar*)"\x05");
queue_insert(queue, (uchar*)"\x25");
queue_insert(queue, (uchar*)"\x09");
queue_insert(queue, (uchar*)"\x15");
queue_insert(queue, (uchar*)"\x06");
queue_insert(queue, (uchar*)"\x11");
queue_insert(queue, (uchar*)"\x01");
queue_insert(queue, (uchar*)"\x04");
queue_insert(queue, (uchar*)"\x13");
queue_insert(queue, (uchar*)"\x24");
ok(check_queue(queue), "after insert");
queue_remove(queue, 5);
ok(check_queue(queue), "after remove 5th");
queue_element(queue, 1) = (uchar*)"\x01";
queue_element(queue, 2) = (uchar*)"\x10";
queue_element(queue, 3) = (uchar*)"\x04";
queue_element(queue, 4) = (uchar*)"\x09";
queue_element(queue, 5) = (uchar*)"\x13";
queue_element(queue, 6) = (uchar*)"\x03";
queue_element(queue, 7) = (uchar*)"\x08";
queue_element(queue, 8) = (uchar*)"\x07";
queue_element(queue, 9) = (uchar*)"\x06";
queue_element(queue,10) = (uchar*)"\x12";
queue_element(queue,11) = (uchar*)"\x05";
queue_element(queue,12) = (uchar*)"\x02";
queue_element(queue,13) = (uchar*)"\x11";
queue->elements= 13;
ok(!check_queue(queue), "manually filled (queue property violated)");
queue_fix(queue);
ok(check_queue(queue), "fixed");
ok(*queue_remove_top(queue) == 0x13, "remove top 13");
ok(*queue_remove_top(queue) == 0x12, "remove top 12");
ok(*queue_remove_top(queue) == 0x11, "remove top 11");
ok(*queue_remove_top(queue) == 0x10, "remove top 10");
ok(*queue_remove_top(queue) == 0x09, "remove top 9");
ok(*queue_remove_top(queue) == 0x08, "remove top 8");
ok(*queue_remove_top(queue) == 0x07, "remove top 7");
ok(*queue_remove_top(queue) == 0x06, "remove top 6");
ok(*queue_remove_top(queue) == 0x05, "remove top 5");
ok(*queue_remove_top(queue) == 0x04, "remove top 4");
ok(*queue_remove_top(queue) == 0x03, "remove top 3");
ok(*queue_remove_top(queue) == 0x02, "remove top 2");
ok(*queue_remove_top(queue) == 0x01, "remove top 1");
/* random test */
{
int i, res;
struct my_rnd_struct rand;
my_rnd_init(&rand, (ulong)(intptr)&i, (ulong)(intptr)argv);
verbose=0;
for (res= i=1; i <= 250; i++)
{
uchar *s=alloca(2);
*s= rnd(&rand) % 251;
queue_insert(queue, s);
res &= check_queue(queue);
}
ok(res, "inserted 250");
while (queue->elements)
{
queue_remove(queue, (rnd(&rand) % queue->elements) + 1);
res &= check_queue(queue);
}
ok(res, "removed 250");
}
delete_queue(queue);
my_end(0);
return exit_status();
}

2
win/packaging/heidisql.cmake

@ -1,4 +1,4 @@
SET(HEIDISQL_BASE_NAME "HeidiSQL_10.2_32_Portable")
SET(HEIDISQL_BASE_NAME "HeidiSQL_11.0_32_Portable")
SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip")
SET(HEIDISQL_URL "http://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}")
SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME})

28
win/packaging/heidisql.wxi.in

@ -33,20 +33,25 @@
<RegistryValue Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall" Name="shortcuts.heidisql" Value="1" Type="string" KeyPath="yes" />
<Shortcut Id="startmenuHeidiSQL" Directory="ShortcutFolder" Name="HeidiSQL" Target="[D.HeidiSQL]\heidisql.exe"/>
</Component>
<Component Id="component.HeidiSQL_libmysql.dll" Guid="*" Win64="no">
<File Id="heidisql.libmysql.dll" Name="libmysql.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libmysql.dll" />
</Component>
<Component Id="component.HeidiSQL_libmysql_6.1.dll" Guid="*" Win64="no">
<File Id="heidisql.libmysql_6.1.dll" Name="libmysql-6.1.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libmysql-6.1.dll" />
</Component>
<Component Id="component.HeidiSQL_libmariadb.dll" Guid="*" Win64="no">
<File Id="heidisql.libmariadb.dll" Name="libmariadb.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libmariadb.dll" />
</Component>
<Component Id="component.HeidiSQL_libeay32.dll" Guid="*" Win64="no">
<File Id="heidisql.libeay32.dll" Name="libeay32.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libeay32.dll" />
<Component Id="component.HeidiSQL_libssl_1_1.dll" Guid="*" Win64="no">
<File Id="heidisql.libssl_1_1.dll" Name="libssl-1_1.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libssl-1_1.dll" />
</Component>
<Component Id="component.HeidiSQL_libpq.dll" Guid="*" Win64="no">
<File Id="heidisql.libpq.dll" Name="libpq.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libpq.dll" />
<Component Id="component.HeidiSQL_libpq_10.dll" Guid="*" Win64="no">
<File Id="heidisql.libpq_10.dll" Name="libpq-10.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libpq-10.dll" />
</Component>
<Component Id="component.HeidiSQL_ssleay32.dll" Guid="*" Win64="no">
<File Id="heidisql.ssleay32.dll" Name="ssleay32.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\ssleay32.dll" />
<Component Id="component.HeidiSQL_libcrypto_1_1.dll" Guid="*" Win64="no">
<File Id="heidisql.libcrypto_1_1.dll" Name="libcrypto-1_1.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libcrypto-1_1.dll" />
</Component>
<Component Id="component.HeidiSQL_libintl_8.dll" Guid="*" Win64="no">
<File Id="heidisql.libintl_8.dll" Name="libintl-8.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libintl-8.dll" />
@ -54,6 +59,9 @@
<Component Id="component.HeidiSQL_libiconv_2.dll" Guid="*" Win64="no">
<File Id="heidisql.libiconv_2.dll" Name="libiconv-2.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libiconv-2.dll" />
</Component>
<Component Id="component.HeidiSQL_sqlite3.dll" Guid="*" Win64="no">
<File Id="heidisql.sqlite3.dll" Name="sqlite3.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\sqlite3.dll" />
</Component>
<Directory Id="D.HeidiSQL.plugins" Name="plugins">
<?foreach dll in $(var.pluginlist) ?>
@ -76,11 +84,13 @@
<ComponentRef Id="component.HeidiSQL_MenuShortcut"/>
<ComponentRef Id="component.HeidiSQL_libmysql.dll"/>
<ComponentRef Id="component.HeidiSQL_libmariadb.dll"/>
<ComponentRef Id="component.HeidiSQL_libeay32.dll" />
<ComponentRef Id="component.HeidiSQL_libpq.dll" />
<ComponentRef Id="component.HeidiSQL_ssleay32.dll" />
<ComponentRef Id="component.HeidiSQL_libssl_1_1.dll" />
<ComponentRef Id="component.HeidiSQL_libpq_10.dll" />
<ComponentRef Id="component.HeidiSQL_libcrypto_1_1.dll" />
<ComponentRef Id="component.HeidiSQL_libintl_8.dll" />
<ComponentRef Id="component.HeidiSQL_libiconv_2.dll" />
<ComponentRef Id="component.HeidiSQL_sqlite3.dll" />
<ComponentRef Id="component.HeidiSQL_libmysql_6.1.dll" />
<?foreach dll in $(var.pluginlist)?>
<ComponentRef Id="component.HeidiSQL_$(var.dll)" />
<?endforeach?>

Loading…
Cancel
Save