Merge from mysql-5.1.

This commit is contained in:
Alexander Nozdrin 2009-10-19 17:17:08 +04:00
commit 3251065aef
60 changed files with 1540 additions and 274 deletions

View file

@ -217,12 +217,16 @@ ENDIF(WITHOUT_DYNAMIC_PLUGINS)
FILE(GLOB STORAGE_SUBDIRS storage/*)
FOREACH(SUBDIR ${STORAGE_SUBDIRS})
FILE(RELATIVE_PATH DIRNAME ${PROJECT_SOURCE_DIR}/storage ${SUBDIR})
STRING(TOUPPER ${DIRNAME} ENGINE)
STRING(TOLOWER ${DIRNAME} ENGINE_LOWER)
IF (EXISTS ${SUBDIR}/CMakeLists.txt)
# Check MYSQL_STORAGE_ENGINE macro is present
FILE(STRINGS ${SUBDIR}/CMakeLists.txt HAVE_STORAGE_ENGINE REGEX MYSQL_STORAGE_ENGINE)
IF(HAVE_STORAGE_ENGINE)
# Extract name of engine from HAVE_STORAGE_ENGINE
STRING(REGEX REPLACE ".*MYSQL_STORAGE_ENGINE\\((.*\)\\).*"
"\\1" ENGINE_NAME ${HAVE_STORAGE_ENGINE})
STRING(TOUPPER ${ENGINE_NAME} ENGINE)
STRING(TOLOWER ${ENGINE_NAME} ENGINE_LOWER)
SET(ENGINE_BUILD_TYPE "DYNAMIC")
# Read plug.in to find out if a plugin is mandatory and whether it supports
# build as shared library (dynamic).
@ -248,6 +252,7 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${ENGINE_LOWER})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
SET (${ENGINE}_DIR ${DIRNAME})
ENDIF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
ENDIF(EXISTS ${SUBDIR}/plug.in)

View file

@ -6775,8 +6775,10 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
MYSQL_STMT *stmt;
DYNAMIC_STRING ds_prepare_warnings;
DYNAMIC_STRING ds_execute_warnings;
ulonglong affected_rows;
DBUG_ENTER("run_query_stmt");
DBUG_PRINT("query", ("'%-.60s'", query));
LINT_INIT(affected_rows);
/*
Init a new stmt if it's not already one created for this connection
@ -6911,9 +6913,6 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
Need to grab affected rows information before getting
warnings here
*/
ulonglong affected_rows;
LINT_INIT(affected_rows);
if (!disable_info)
affected_rows= mysql_affected_rows(mysql);

View file

@ -720,7 +720,6 @@ extern int wild_compare(const char *str,const char *wildstr,
extern WF_PACK *wf_comp(char * str);
extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
extern void wf_end(struct wild_file_pack *buffer);
extern size_t strip_sp(char * str);
extern my_bool array_append_string_unique(const char *str,
const char **array, size_t size);
extern void get_date(char * to,int timeflag,time_t use_time);

View file

@ -90,10 +90,11 @@ ENDFOREACH(rpath)
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
INCLUDE(${CMAKE_SOURCE_DIR}/storage/${ENGINE_LIB}/CMakeLists.txt)
STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
SET(ENGINE_DIR ${${ENGINE_LIB_UPPER}_DIR})
INCLUDE(${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/CMakeLists.txt)
FOREACH(rpath ${${ENGINE_LIB_UPPER}_SOURCES})
SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${ENGINE_LIB}/${rpath})
SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/${rpath})
ENDFOREACH(rpath)
ENDFOREACH(ENGINE_LIB)
@ -155,6 +156,14 @@ ADD_LIBRARY(mysqlserver STATIC ${LIBMYSQLD_SOURCES})
ADD_DEPENDENCIES(mysqlserver GenServerSource GenError)
TARGET_LINK_LIBRARIES(mysqlserver)
# Add any additional libraries requested by engine(s)
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
IF(${ENGINE_LIB_UPPER}_LIBS)
TARGET_LINK_LIBRARIES(mysqlserver ${${ENGINE_LIB_UPPER}_LIBS})
ENDIF(${ENGINE_LIB_UPPER}_LIBS)
ENDFOREACH(ENGINE_LIB)
ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def)
ADD_DEPENDENCIES(libmysqld mysqlserver)
TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32)

View file

@ -270,3 +270,42 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE TABLE test.t2 SELECT * FROM test.t1;
USE test;
DROP TABLES t1, t2;
#
# Bug#46640
# This test verifies if the server_id stored in the "format
# description BINLOG statement" will override the server_id
# of the server executing the statements.
#
connect (fresh,localhost,root,,test);
connection fresh;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY);
# Format description event, with server_id = 10;
BINLOG '
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
';
# What server_id is logged for a statement? Should be our own, not the
# one from the format description event.
INSERT INTO t1 VALUES (1);
# INSERT INTO t1 VALUES (2), with server_id=20. Check that this is logged
# with our own server id, not the 20 from the BINLOG statement.
BINLOG '
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
';
# Show binlog events to check that server ids are correct.
--replace_column 1 # 2 # 5 #
--replace_regex /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
SHOW BINLOG EVENTS;
DROP TABLE t1;
disconnect fresh;

View file

@ -321,3 +321,11 @@ Vv
Xx
YyÝýỲỳỴỵỶỷỸỹ
drop table t1;
Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20
set names latin1;
show collation like 'latin1_test';
Collation Charset Id Default Compiled Sortlen
latin1_test latin1 99 Yes 1
select "foo" = "foo " collate latin1_test;
"foo" = "foo " collate latin1_test
1

View file

@ -1477,3 +1477,47 @@ COUNT(*)
SET SQL_MODE=default;
DROP TABLE t1;
End of 5.0 tests
#
# BUG#47280 - strange results from count(*) with order by multiple
# columns without where/group
#
#
# Initialize test
#
CREATE TABLE t1 (
pk INT NOT NULL,
i INT,
PRIMARY KEY (pk)
);
INSERT INTO t1 VALUES (1,11),(2,12),(3,13);
#
# Start test
# All the following queries shall return 1 record
#
# Masking all correct values {11...13} for column i in this result.
SELECT MAX(pk) as max, i
FROM t1
ORDER BY max;
max i
3 #
EXPLAIN
SELECT MAX(pk) as max, i
FROM t1
ORDER BY max;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary
# Only 11 is correct for collumn i in this result
SELECT MAX(pk) as max, i
FROM t1
WHERE pk<2
ORDER BY max;
max i
1 11
#
# Cleanup
#
DROP TABLE t1;
End of 5.1 tests

View file

@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by

View file

@ -2271,4 +2271,32 @@ checksum table t3;
Table Checksum
test.t3 326284887
drop table t1,t2,t3;
CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
(6,'0'),(7,'0');
INSERT INTO t1 SELECT a+10,b FROM t1;
INSERT INTO t1 SELECT a+20,b FROM t1;
INSERT INTO t1 SELECT a+40,b FROM t1;
INSERT INTO t1 SELECT a+80,b FROM t1;
INSERT INTO t1 SELECT a+160,b FROM t1;
INSERT INTO t1 SELECT a+320,b FROM t1;
INSERT INTO t1 SELECT a+640,b FROM t1;
INSERT INTO t1 SELECT a+1280,b FROM t1;
INSERT INTO t1 SELECT a+2560,b FROM t1;
INSERT INTO t1 SELECT a+5120,b FROM t1;
SET myisam_sort_buffer_size=4;
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair error myisam_sort_buffer_size is too small
test.t1 repair warning Number of rows changed from 0 to 7168
test.t1 repair status OK
SET myisam_repair_threads=2;
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair error myisam_sort_buffer_size is too small
test.t1 repair warning Number of rows changed from # to 7168
test.t1 repair status OK
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
End of 5.1 tests

View file

@ -1557,3 +1557,34 @@ a
2001
1991
DROP TABLE t1;
#
# Bug #43029: FORCE INDEX FOR ORDER BY is ignored when join buffering
# is used
#
CREATE TABLE t1 (a INT, b INT, KEY (a));
INSERT INTO t1 VALUES (0, NULL), (1, NULL), (2, NULL), (3, NULL);
INSERT INTO t1 SELECT a+4, b FROM t1;
INSERT INTO t1 SELECT a+8, b FROM t1;
CREATE TABLE t2 (a INT, b INT);
INSERT INTO t2 VALUES (0,NULL), (1,NULL), (2,NULL), (3,NULL), (4,NULL);
INSERT INTO t2 SELECT a+4, b FROM t2;
# shouldn't have "using filesort"
EXPLAIN
SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 2 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 10
# should have "using filesort"
EXPLAIN
SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
# should have "using filesort"
EXPLAIN
SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
DROP TABLE t1, t2;
End of 5.1 tests

View file

@ -50,6 +50,21 @@ t1 CREATE TABLE `t1` (
PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM,
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
DROP TABLE t1;
create table t1 (a int, b int, key(a))
partition by list (a)
( partition p0 values in (1),
partition p1 values in (2));
insert into t1 values (1,1),(2,1),(2,2),(2,3);
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
show indexes from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A 1 NULL NULL YES BTREE
drop table t1;
CREATE TABLE t1 (a INT, FOREIGN KEY (a) REFERENCES t0 (a))
ENGINE=MyISAM
PARTITION BY HASH (a);

View file

@ -0,0 +1,22 @@
DROP TABLE IF EXISTS `t1`;
# Bug#46922: crash when adding partitions and open_files_limit is reached
CREATE TABLE t1 (a INT PRIMARY KEY)
ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1;
INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
# if the bug exists, then crash will happen here
ALTER TABLE t1 ADD PARTITION PARTITIONS 511;
ERROR HY000: Out of resources when opening file '<partition file>' (Errcode: 24)
SELECT * FROM t1;
a
1
10
11
2
3
4
5
6
7
8
9
DROP TABLE t1;

View file

@ -1219,3 +1219,182 @@ explain select * from t2 where a=1000 and b<11;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref a a 5 const 502 Using where
drop table t1, t2;
CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
CREATE TABLE t3( a INT, b INT, KEY( a, b ) );
INSERT INTO t1( a, b )
VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7);
INSERT INTO t2( a, b )
VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1),
( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1),
(11, 1), (12, 1), (13, 1), (14, 1), (15, 1),
(16, 1), (17, 1), (18, 1), (19, 1), (20, 1);
INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1;
INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1;
INSERT INTO t2 SELECT -1, -1 FROM t2;
INSERT INTO t2 SELECT -1, -1 FROM t2;
INSERT INTO t2 SELECT -1, -1 FROM t2;
INSERT INTO t3
VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
(6, 0), (7, 0), (8, 0), (9, 0), (10, 0);
INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
SELECT * FROM t1 WHERE
3 <= a AND a < 5 OR
5 < a AND b = 3 OR
3 <= a;
a b
5 0
9 7
EXPLAIN
SELECT * FROM t1 WHERE
3 <= a AND a < 5 OR
5 < a AND b = 3 OR
3 <= a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE
3 <= a AND a < 5 OR
5 <= a AND b = 3 OR
3 <= a;
a b
5 0
9 7
EXPLAIN
SELECT * FROM t1 WHERE
3 <= a AND a < 5 OR
5 <= a AND b = 3 OR
3 <= a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
5 <= a AND b = 3 OR
3 <= a;
a b
5 0
9 7
EXPLAIN
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
5 <= a AND b = 3 OR
3 <= a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
3 <= a;
a b
5 0
9 7
EXPLAIN
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
3 <= a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
SELECT * FROM t2 WHERE
5 <= a AND a < 10 AND b = 1 OR
15 <= a AND a < 20 AND b = 3
OR
1 <= a AND b = 1;
a b
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1
14 1
15 1
15 3
16 1
16 3
17 1
17 3
18 1
18 3
19 1
19 3
20 1
EXPLAIN
SELECT * FROM t2 WHERE
5 <= a AND a < 10 AND b = 1 OR
15 <= a AND a < 20 AND b = 3
OR
1 <= a AND b = 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
SELECT * FROM t2 WHERE
5 <= a AND a < 10 AND b = 2 OR
15 <= a AND a < 20 AND b = 3
OR
1 <= a AND b = 1;
a b
1 1
2 1
3 1
4 1
5 1
5 2
6 1
6 2
7 1
7 2
8 1
8 2
9 1
9 2
10 1
11 1
12 1
13 1
14 1
15 1
15 3
16 1
16 3
17 1
17 3
18 1
18 3
19 1
19 3
20 1
EXPLAIN
SELECT * FROM t2 WHERE
5 <= a AND a < 10 AND b = 2 OR
15 <= a AND a < 20 AND b = 3
OR
1 <= a AND b = 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
SELECT * FROM t3 WHERE
5 <= a AND a < 10 AND b = 3 OR
a < 5 OR
a < 10;
a b
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
EXPLAIN
SELECT * FROM t3 WHERE
5 <= a AND a < 10 AND b = 3 OR
a < 5 OR
a < 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index
DROP TABLE t1, t2, t3;

View file

@ -749,6 +749,16 @@ bin(a1)
110000111111111
110001011111111
drop table t1bit7, t2bit7;
#
# Bug42803: Field_bit does not have unsigned_flag field,
# can lead to bad memory access
#
CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b));
INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0);
EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 2 NULL 4 Using where; Using index; Using filesort
DROP TABLE t1;
End of 5.0 tests
create table t1(a bit(7));
insert into t1 values(0x40);

View file

@ -68,4 +68,17 @@
</charset>
<charset name="latin1">
<family>Western</family>
<description>cp1252 West European</description>
<alias>csisolatin1</alias>
<alias>iso-8859-1</alias>
<alias>iso-ir-100</alias>
<alias>iso_8859-1</alias>
<alias>iso_8859-1:1987</alias>
<alias>l1</alias>
<alias>latin1</alias>
<collation name="latin1_test" id="99" order="test"/>
</charset>
</charsets>

View file

@ -0,0 +1,135 @@
<?xml version='1.0' encoding="utf-8"?>
<charsets>
<copyright>
Copyright (C) 2009 Sun Microsystems, Inc
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</copyright>
<charset name="latin1">
<ctype>
<map>
00
20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
</map>
</ctype>
<lower>
<map>
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
</map>
</lower>
<upper>
<map>
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF
</map>
</upper>
<unicode>
<map>
0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F
0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F
0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F
0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F
0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F
0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F
0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F
20AC 0081 201A 0192 201E 2026 2020 2021 02C6 2030 0160 2039 0152 008D 017D 008F
0090 2018 2019 201C 201D 2022 2013 2014 02DC 2122 0161 203A 0153 009D 017E 0178
00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF
00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF
00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF
00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF
00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF
00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF
</map>
</unicode>
<collation name="latin1_test">
<map>
00 01 02 03 37 2D 2E 2F 16 05 25 0B 0C 0D 0E 0F
10 11 12 13 3C 3D 32 26 18 19 3F 27 1C 1D 1E 1F
40 4F 7F 7B 5B 6C 50 7D 4D 5D 5C 4E 6B 60 4B 61
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 7A 5E 4C 7E 6E 6F
7C C1 C2 C3 C4 C5 C6 C7 C8 C9 D1 D2 D3 D4 D5 D6
D7 D8 D9 E2 E3 E4 E5 E6 E7 E8 E9 4A E0 5A 5F 6D
79 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96
97 98 99 A2 A3 A4 A5 A6 A7 A8 A9 C0 6A D0 A1 07
20 21 22 23 24 15 06 17 28 29 2A 2B 2C 09 0A 1B
30 31 1A 33 34 35 36 08 38 39 3A 3B 04 14 3E E1
41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57
58 59 62 63 64 65 66 67 68 69 70 71 72 73 74 75
76 77 78 80 8A 8B 8C 8D 8E 8F 90 9A 9B 9C 9D 9E
9F A0 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7
B8 B9 BA BB BC BD BE BF CA CB CC CD CE CF DA DB
DC DD DE DF EA EB EC ED EE EF FA FB FC FD FE FF
</map>
</collation>
</charset>
</charsets>

View file

@ -1309,3 +1309,27 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE TABLE test.t2 SELECT * FROM test.t1;
USE test;
DROP TABLES t1, t2;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY);
BINLOG '
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
';
INSERT INTO t1 VALUES (1);
BINLOG '
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
';
SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info
# # Format_desc 1 # Server ver: #, Binlog ver: #
# # Query 1 # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY)
# # Query 1 # BEGIN
# # Table_map 1 # table_id: # (test.t1)
# # Write_rows 1 # table_id: # flags: STMT_END_F
# # Query 1 # COMMIT
# # Query 1 # BEGIN
# # Table_map 1 # table_id: # (test.t1)
# # Write_rows 1 # table_id: # flags: STMT_END_F
# # Query 1 # COMMIT
DROP TABLE t1;

View file

@ -0,0 +1,161 @@
Verbose statements from : write-partial-row.binlog
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
stmt
### INSERT INTO mysql.ndb_apply_status
### SET
### @1=1
### @2=25769803786
### @3=''
### @4=0
### @5=0
### INSERT INTO test.ba
### SET
### @1=3
### @2=3
### @3=3
### INSERT INTO test.ba
### SET
### @1=1
### @2=1
### @3=1
### INSERT INTO test.ba
### SET
### @1=2
### @2=2
### @3=2
### INSERT INTO test.ba
### SET
### @1=4
### @2=4
### @3=4
### INSERT INTO test.ba
### SET
### @1=4
### @3=40
### DELETE FROM test.ba
### WHERE
### @1=2
drop table raw_binlog_rows;
Verbose statements from : write-full-row.binlog
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
stmt
### INSERT INTO mysql.ndb_apply_status
### SET
### @1=2
### @2=25769803786
### @3=''
### @4=0
### @5=0
### INSERT INTO test.ba
### SET
### @1=3
### @2=3
### @3=3
### INSERT INTO test.ba
### SET
### @1=1
### @2=1
### @3=1
### INSERT INTO test.ba
### SET
### @1=2
### @2=2
### @3=2
### INSERT INTO test.ba
### SET
### @1=4
### @2=4
### @3=4
### INSERT INTO test.ba
### SET
### @1=4
### @2=4
### @3=40
### DELETE FROM test.ba
### WHERE
### @1=2
drop table raw_binlog_rows;
Verbose statements from : update-partial-row.binlog
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
stmt
### INSERT INTO mysql.ndb_apply_status
### SET
### @1=3
### @2=25769803786
### @3=''
### @4=0
### @5=0
### INSERT INTO test.ba
### SET
### @1=3
### @2=3
### @3=3
### INSERT INTO test.ba
### SET
### @1=1
### @2=1
### @3=1
### INSERT INTO test.ba
### SET
### @1=2
### @2=2
### @3=2
### INSERT INTO test.ba
### SET
### @1=4
### @2=4
### @3=4
### UPDATE test.ba
### WHERE
### @1=4
### @3=4
### SET
### @1=4
### @3=40
### DELETE FROM test.ba
### WHERE
### @1=2
drop table raw_binlog_rows;
Verbose statements from : update-full-row.binlog
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
stmt
### INSERT INTO mysql.ndb_apply_status
### SET
### @1=4
### @2=25769803786
### @3=''
### @4=0
### @5=0
### INSERT INTO test.ba
### SET
### @1=3
### @2=3
### @3=3
### INSERT INTO test.ba
### SET
### @1=1
### @2=1
### @3=1
### INSERT INTO test.ba
### SET
### @1=2
### @2=2
### @3=2
### INSERT INTO test.ba
### SET
### @1=4
### @2=4
### @3=4
### UPDATE test.ba
### WHERE
### @1=4
### @2=4
### @3=4
### SET
### @1=4
### @2=4
### @3=40
### DELETE FROM test.ba
### WHERE
### @1=2
drop table raw_binlog_rows;

View file

@ -784,3 +784,24 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE TABLE test.t2 SELECT * FROM test.t1;
USE test;
DROP TABLES t1, t2;
RESET MASTER;
CREATE TABLE t1 (a INT PRIMARY KEY);
BINLOG '
3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
';
INSERT INTO t1 VALUES (1);
BINLOG '
3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
';
SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info
# # Format_desc 1 # Server ver: #, Binlog ver: #
# # Query 1 # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY)
# # Query 1 # use `test`; INSERT INTO t1 VALUES (1)
# # Query 1 # BEGIN
# # Table_map 1 # table_id: # (test.t1)
# # Write_rows 1 # table_id: # flags: STMT_END_F
# # Query 1 # COMMIT
DROP TABLE t1;

Binary file not shown.

View file

@ -0,0 +1,86 @@
########################################################
# Test mysqlbinlog command with Ndb produced Binlog
# variants
#
# WHAT
# ====
# This test aims to check that the mysqlbinlog --verbose
# command can output binlogs in 4 format variants, currently
# used by Ndb
#
# 1) Updates logged as write_row events
# Only primary key and updated columns included in the
# event
# 2) Updates logged as write_row_events
# All columns included in the event
# 3) Updates logged as update_row events
# Only primary key and updated columns included in the
# event
# 4) Updates logged as update_row events
# All columns included in the event
#
# Format variant (1) is the Ndb default.
# Bug#47323 resulted in binlogs generated in format (1)
# being incorrectly parsed by the mysqlbinlog --verbose
# option
#
# HOW
# ===
# Row-based binlog files in each format have been
# captured from an Ndb cluster
# These are output using the mysqlbinlog --verbose
# tool and the output is checked.
#
########################################################
# We require binlog_format_row as we're independent of binlog format
# and there's no point running the same test 3 times
-- source include/have_binlog_format_row.inc
--disable_query_log
--let $binlog_file=write-partial-row.binlog
--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
create table raw_binlog_rows (txt varchar(1000));
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
--enable_query_log
--echo Verbose statements from : $binlog_file
# Output --verbose lines, with extra Windows CR's trimmed
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
drop table raw_binlog_rows;
--disable_query_log
--let $binlog_file=write-full-row.binlog
--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
create table raw_binlog_rows (txt varchar(1000));
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
--enable_query_log
--echo Verbose statements from : $binlog_file
# Output --verbose lines, with extra Windows CR's trimmed
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
drop table raw_binlog_rows;
--disable_query_log
--let $binlog_file=update-partial-row.binlog
--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
create table raw_binlog_rows (txt varchar(1000));
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
--enable_query_log
--echo Verbose statements from : $binlog_file
# Output --verbose lines, with extra Windows CR's trimmed
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
drop table raw_binlog_rows;
--disable_query_log
--let $binlog_file=update-full-row.binlog
--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
create table raw_binlog_rows (txt varchar(1000));
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
--enable_query_log
--echo Verbose statements from : $binlog_file
# Output --verbose lines, with extra Windows CR's trimmed
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
drop table raw_binlog_rows;

View file

@ -94,15 +94,24 @@ DROP TABLE t1;
SET GLOBAL log_warnings = @old_log_warnings;
let LOG_ERROR= `SELECT @@GLOBAL.log_error`;
let $log_error_= `SELECT @@GLOBAL.log_error`;
if(!`select LENGTH('$log_error_')`)
{
# MySQL Server on windows is started with --console and thus
# does not know the location of its .err log, use default location
let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
}
# Assign env variable LOG_ERROR
let LOG_ERROR=$log_error_;
--echo # Count the number of times the "Unsafe" message was printed
--echo # to the error log.
perl;
$log_error= $ENV{'LOG_ERROR'};
use strict;
my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set";
open(FILE, "$log_error") or die("Unable to open $log_error: $!\n");
$count = () = grep(/Bug#46265/g,<FILE>);
my $count = () = grep(/Bug#46265/g,<FILE>);
print "Occurrences: $count\n";
close(FILE);
EOF

View file

@ -86,3 +86,8 @@ select hex(c1) as h, c1 from t1 order by c1, h;
select group_concat(hex(c1) order by hex(c1)) from t1 group by c1;
select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1;
drop table t1;
--echo Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20
set names latin1;
show collation like 'latin1_test';
select "foo" = "foo " collate latin1_test;

View file

@ -1006,3 +1006,51 @@ DROP TABLE t1;
###
--echo End of 5.0 tests
--echo #
--echo # BUG#47280 - strange results from count(*) with order by multiple
--echo # columns without where/group
--echo #
--echo #
--echo # Initialize test
--echo #
CREATE TABLE t1 (
pk INT NOT NULL,
i INT,
PRIMARY KEY (pk)
);
INSERT INTO t1 VALUES (1,11),(2,12),(3,13);
--echo #
--echo # Start test
--echo # All the following queries shall return 1 record
--echo #
--echo
--echo # Masking all correct values {11...13} for column i in this result.
--replace_column 2 #
SELECT MAX(pk) as max, i
FROM t1
ORDER BY max;
--echo
EXPLAIN
SELECT MAX(pk) as max, i
FROM t1
ORDER BY max;
--echo
--echo # Only 11 is correct for collumn i in this result
SELECT MAX(pk) as max, i
FROM t1
WHERE pk<2
ORDER BY max;
--echo #
--echo # Cleanup
--echo #
DROP TABLE t1;
--echo End of 5.1 tests

View file

@ -1518,5 +1518,33 @@ CREATE TABLE t3 select * from t1;
checksum table t3;
drop table t1,t2,t3;
#
# BUG#47073 - valgrind errs, corruption,failed repair of partition,
# low myisam_sort_buffer_size
#
CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
(6,'0'),(7,'0');
INSERT INTO t1 SELECT a+10,b FROM t1;
INSERT INTO t1 SELECT a+20,b FROM t1;
INSERT INTO t1 SELECT a+40,b FROM t1;
INSERT INTO t1 SELECT a+80,b FROM t1;
INSERT INTO t1 SELECT a+160,b FROM t1;
INSERT INTO t1 SELECT a+320,b FROM t1;
INSERT INTO t1 SELECT a+640,b FROM t1;
INSERT INTO t1 SELECT a+1280,b FROM t1;
INSERT INTO t1 SELECT a+2560,b FROM t1;
INSERT INTO t1 SELECT a+5120,b FROM t1;
SET myisam_sort_buffer_size=4;
REPAIR TABLE t1;
SET myisam_repair_threads=2;
# May report different values depending on threads activity.
--replace_regex /changed from [0-9]+/changed from #/
REPAIR TABLE t1;
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
--echo End of 5.1 tests

View file

@ -1402,3 +1402,35 @@ SELECT DISTINCT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 0, 9;
SELECT DISTINCT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 0, 9;
DROP TABLE t1;
--echo #
--echo # Bug #43029: FORCE INDEX FOR ORDER BY is ignored when join buffering
--echo # is used
--echo #
CREATE TABLE t1 (a INT, b INT, KEY (a));
INSERT INTO t1 VALUES (0, NULL), (1, NULL), (2, NULL), (3, NULL);
INSERT INTO t1 SELECT a+4, b FROM t1;
INSERT INTO t1 SELECT a+8, b FROM t1;
CREATE TABLE t2 (a INT, b INT);
INSERT INTO t2 VALUES (0,NULL), (1,NULL), (2,NULL), (3,NULL), (4,NULL);
INSERT INTO t2 SELECT a+4, b FROM t2;
--echo # shouldn't have "using filesort"
EXPLAIN
SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
--echo # should have "using filesort"
EXPLAIN
SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
--echo # should have "using filesort"
EXPLAIN
SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
DROP TABLE t1, t2;
--echo End of 5.1 tests

View file

@ -61,6 +61,19 @@ SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
#
# Bug#44059: rec_per_key on empty partition gives weird optimiser results
#
create table t1 (a int, b int, key(a))
partition by list (a)
( partition p0 values in (1),
partition p1 values in (2));
insert into t1 values (1,1),(2,1),(2,2),(2,3);
show indexes from t1;
analyze table t1;
show indexes from t1;
drop table t1;
#
# Bug#36001: Partitions: spelling and using some error messages
#

View file

@ -0,0 +1 @@
--open-files-limit=5 --max_connections=2 --table_open_cache=1

View file

@ -0,0 +1,26 @@
--source include/have_partition.inc
--disable_warnings
DROP TABLE IF EXISTS `t1`;
--enable_warnings
# On some platforms the lowest possible open_files_limit is too high...
let $max_open_files_limit= `SELECT @@open_files_limit > 511`;
if ($max_open_files_limit)
{
skip Need open_files_limit to be lower than 512;
}
#
--echo # Bug#46922: crash when adding partitions and open_files_limit is reached
#
CREATE TABLE t1 (a INT PRIMARY KEY)
ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1;
INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
--echo # if the bug exists, then crash will happen here
--replace_regex /file '.*'/file '<partition file>'/
--error 23
ALTER TABLE t1 ADD PARTITION PARTITIONS 511;
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;

View file

@ -1046,3 +1046,128 @@ explain select * from t2 where a=1000 and b<11;
drop table t1, t2;
#
# Bug#42846: wrong result returned for range scan when using covering index
#
CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
CREATE TABLE t3( a INT, b INT, KEY( a, b ) );
INSERT INTO t1( a, b )
VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7);
INSERT INTO t2( a, b )
VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1),
( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1),
(11, 1), (12, 1), (13, 1), (14, 1), (15, 1),
(16, 1), (17, 1), (18, 1), (19, 1), (20, 1);
INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1;
INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1;
# To make range scan compelling to the optimizer
INSERT INTO t2 SELECT -1, -1 FROM t2;
INSERT INTO t2 SELECT -1, -1 FROM t2;
INSERT INTO t2 SELECT -1, -1 FROM t2;
INSERT INTO t3
VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
(6, 0), (7, 0), (8, 0), (9, 0), (10, 0);
# To make range scan compelling to the optimizer
INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
#
# Problem#1 Test queries. Will give missing results unless Problem#1 is fixed.
# With one exception, they are independent of Problem#2.
#
SELECT * FROM t1 WHERE
3 <= a AND a < 5 OR
5 < a AND b = 3 OR
3 <= a;
EXPLAIN
SELECT * FROM t1 WHERE
3 <= a AND a < 5 OR
5 < a AND b = 3 OR
3 <= a;
# Query below: Tests both Problem#1 and Problem#2 (EXPLAIN differs as well)
SELECT * FROM t1 WHERE
3 <= a AND a < 5 OR
5 <= a AND b = 3 OR
3 <= a;
EXPLAIN
SELECT * FROM t1 WHERE
3 <= a AND a < 5 OR
5 <= a AND b = 3 OR
3 <= a;
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
5 <= a AND b = 3 OR
3 <= a;
EXPLAIN
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
5 <= a AND b = 3 OR
3 <= a;
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
3 <= a;
EXPLAIN
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
3 <= a;
#
# Problem#2 Test queries.
# These queries will give missing results if Problem#1 is fixed.
# But Problem#1 also hides this bug.
#
SELECT * FROM t2 WHERE
5 <= a AND a < 10 AND b = 1 OR
15 <= a AND a < 20 AND b = 3
OR
1 <= a AND b = 1;
EXPLAIN
SELECT * FROM t2 WHERE
5 <= a AND a < 10 AND b = 1 OR
15 <= a AND a < 20 AND b = 3
OR
1 <= a AND b = 1;
SELECT * FROM t2 WHERE
5 <= a AND a < 10 AND b = 2 OR
15 <= a AND a < 20 AND b = 3
OR
1 <= a AND b = 1;
EXPLAIN
SELECT * FROM t2 WHERE
5 <= a AND a < 10 AND b = 2 OR
15 <= a AND a < 20 AND b = 3
OR
1 <= a AND b = 1;
SELECT * FROM t3 WHERE
5 <= a AND a < 10 AND b = 3 OR
a < 5 OR
a < 10;
EXPLAIN
SELECT * FROM t3 WHERE
5 <= a AND a < 10 AND b = 3 OR
a < 5 OR
a < 10;
DROP TABLE t1, t2, t3;

View file

@ -397,6 +397,17 @@ insert into t2bit7 values (b'110011011111111');
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
drop table t1bit7, t2bit7;
--echo #
--echo # Bug42803: Field_bit does not have unsigned_flag field,
--echo # can lead to bad memory access
--echo #
CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b));
INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0);
EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2;
DROP TABLE t1;
--echo End of 5.0 tests
#

View file

@ -29,7 +29,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c
mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c
mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c
mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_strip.c mf_arr_appstr.c mf_tempdir.c
mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_arr_appstr.c mf_tempdir.c
mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c
my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chsize.c
my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c

View file

@ -35,7 +35,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
my_error.c errors.c my_div.c my_messnc.c \
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
my_symlink.c my_symlink2.c \
mf_pack.c mf_unixpath.c mf_strip.c mf_arr_appstr.c \
mf_pack.c mf_unixpath.c mf_arr_appstr.c \
mf_wcomp.c mf_wfile.c my_gethwaddr.c \
mf_qsort.c mf_qsort2.c mf_sort.c \
ptr_cmp.c mf_radix.c queues.c my_getncpus.c \

View file

@ -1,45 +0,0 @@
/* Copyright (C) 2000 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* T|mmer en str{ng p{ slut_space */
#include "mysys_priv.h"
/*
strip_sp(char * str)
Strips end-space from string and returns new length.
*/
size_t strip_sp(register char * str)
{
reg2 char * found;
reg3 char * start;
start=found=str;
while (*str)
{
if (*str != ' ')
{
while (*++str && *str != ' ') {};
if (!*str)
return (size_t) (str-start); /* Return stringlength */
}
found=str;
while (*++str == ' ') {};
}
*found= '\0'; /* Stripp at first space */
return (size_t) (found-start);
} /* strip_sp */

View file

@ -18,7 +18,7 @@ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUT
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
SET(REGEX_SOURCES debug.c regcomp.c regerror.c regexec.c regfree.c reginit.c split.c)
SET(REGEX_SOURCES regcomp.c regerror.c regexec.c regfree.c reginit.c)
IF(NOT SOURCE_SUBLIBS)
ADD_LIBRARY(regex ${REGEX_SOURCES})

View file

@ -1280,10 +1280,10 @@ void ha_partition::cleanup_new_partition(uint part_count)
m_file= m_added_file;
m_added_file= NULL;
external_lock(ha_thd(), F_UNLCK);
/* delete_table also needed, a bit more complex */
close();
m_added_file= m_file;
m_file= save_m_file;
}
DBUG_VOID_RETURN;
@ -5011,8 +5011,9 @@ int ha_partition::info(uint flag)
If the handler doesn't support statistics, it should set all of the
above to 0.
We will allow the first handler to set the rec_per_key and use
this as an estimate on the total table.
We first scans through all partitions to get the one holding most rows.
We will then allow the handler with the most rows to set
the rec_per_key and use this as an estimate on the total table.
max_data_file_length: Maximum data file length
We ignore it, is only used in
@ -5024,14 +5025,33 @@ int ha_partition::info(uint flag)
ref_length: We set this to the value calculated
and stored in local object
create_time: Creation time of table
Set by first handler
So we calculate these constants by using the variables on the first
handler.
So we calculate these constants by using the variables from the
handler with most rows.
*/
handler *file;
handler *file, **file_array;
ulonglong max_records= 0;
uint32 i= 0;
uint32 handler_instance= 0;
file= m_file[0];
file_array= m_file;
do
{
file= *file_array;
/* Get variables if not already done */
if (!(flag & HA_STATUS_VARIABLE) ||
!bitmap_is_set(&(m_part_info->used_partitions),
(file_array - m_file)))
file->info(HA_STATUS_VARIABLE);
if (file->stats.records > max_records)
{
max_records= file->stats.records;
handler_instance= i;
}
i++;
} while (*(++file_array));
file= m_file[handler_instance];
file->info(HA_STATUS_CONST);
stats.create_time= file->stats.create_time;
ref_length= m_ref_length;

View file

@ -1852,6 +1852,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
{
const uchar *value0= value;
const uchar *null_bits= value;
uint null_bit_index= 0;
char typestr[64]= "";
value+= (m_width + 7) / 8;
@ -1860,7 +1861,8 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
for (size_t i= 0; i < td->size(); i ++)
{
int is_null= (null_bits[i / 8] >> (i % 8)) & 0x01;
int is_null= (null_bits[null_bit_index / 8]
>> (null_bit_index % 8)) & 0x01;
if (bitmap_is_set(cols_bitmap, i) == 0)
continue;
@ -1897,6 +1899,8 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
}
my_b_printf(file, "\n");
null_bit_index++;
}
return value - value0;
}
@ -3855,6 +3859,7 @@ bool Format_description_log_event::write(IO_CACHE* file)
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
{
int ret= 0;
DBUG_ENTER("Format_description_log_event::do_apply_event");
#ifdef USING_TRANSACTIONS
@ -3896,17 +3901,21 @@ int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
0, then 96, then jump to first really asked event (which is
>96). So this is ok.
*/
DBUG_RETURN(Start_log_event_v3::do_apply_event(rli));
ret= Start_log_event_v3::do_apply_event(rli);
}
DBUG_RETURN(0);
if (!ret)
{
/* Save the information describing this binlog */
delete rli->relay_log.description_event_for_exec;
const_cast<Relay_log_info *>(rli)->relay_log.description_event_for_exec= this;
}
DBUG_RETURN(ret);
}
int Format_description_log_event::do_update_pos(Relay_log_info *rli)
{
/* save the information describing this binlog */
delete rli->relay_log.description_event_for_exec;
rli->relay_log.description_event_for_exec= this;
if (server_id == (uint32) ::server_id)
{
/*
@ -7502,6 +7511,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
thd->reset_current_stmt_binlog_row_based();
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
thd->is_slave_error= 1;
DBUG_RETURN(error);
}
/*
This code would ideally be placed in do_update_pos() instead, but
@ -7530,6 +7540,14 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
}
if (get_flags(STMT_END_F))
if (error= rows_event_stmt_cleanup(rli, thd))
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
get_type_str(), m_table->s->db.str,
m_table->s->table_name.str);
DBUG_RETURN(error);
}
@ -7628,33 +7646,19 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
if (get_flags(STMT_END_F))
{
if ((error= rows_event_stmt_cleanup(rli, thd)) == 0)
{
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
rli->stmt_done(log_pos, when);
/*
Clear any errors pushed in thd->net.last_err* if for example "no key
found" (as this is allowed). This is a safety measure; apparently
those errors (e.g. when executing a Delete_rows_log_event of a
non-existing row, like in rpl_row_mystery22.test,
thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
do not become visible. We still prefer to wipe them out.
*/
thd->clear_error();
}
else
{
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
get_type_str(), m_table->s->db.str,
m_table->s->table_name.str);
}
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
rli->stmt_done(log_pos, when);
/*
Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in
thd->net.last_err* are allowed. Examples of errors are "key not
found", which is produced in the test case rpl_row_conflicts.test
*/
thd->clear_error();
}
else
{

View file

@ -1814,7 +1814,56 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
}
DBUG_RETURN(0);
if (get_flags(STMT_END_F))
{
/*
This is the end of a statement or transaction, so close (and
unlock) the tables we opened when processing the
Table_map_log_event starting the statement.
OBSERVER. This will clear *all* mappings, not only those that
are open for the table. There is not good handle for on-close
actions for tables.
NOTE. Even if we have no table ('table' == 0) we still need to be
here, so that we increase the group relay log position. If we didn't, we
could have a group relay log position which lags behind "forever"
(assume the last master's transaction is ignored by the slave because of
replicate-ignore rules).
*/
thd->binlog_flush_pending_rows_event(true);
/*
If this event is not in a transaction, the call below will, if some
transactional storage engines are involved, commit the statement into
them and flush the pending event to binlog.
If this event is in a transaction, the call will do nothing, but a
Xid_log_event will come next which will, if some transactional engines
are involved, commit the transaction and flush the pending event to the
binlog.
*/
if (error= ha_autocommit_or_rollback(thd, 0))
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
get_type_str(), m_table->s->db.str,
m_table->s->table_name.str);
/*
Now what if this is not a transactional engine? we still need to
flush the pending event to the binlog; we did it with
thd->binlog_flush_pending_rows_event(). Note that we imitate
what is done for real queries: a call to
ha_autocommit_or_rollback() (sometimes only if involves a
transactional engine), and a call to be sure to have the pending
event flushed.
*/
thd->reset_current_stmt_binlog_row_based();
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
}
DBUG_RETURN(error);
}
@ -1844,71 +1893,18 @@ Old_rows_log_event::do_update_pos(Relay_log_info *rli)
if (get_flags(STMT_END_F))
{
/*
This is the end of a statement or transaction, so close (and
unlock) the tables we opened when processing the
Table_map_log_event starting the statement.
OBSERVER. This will clear *all* mappings, not only those that
are open for the table. There is not good handle for on-close
actions for tables.
NOTE. Even if we have no table ('table' == 0) we still need to be
here, so that we increase the group relay log position. If we didn't, we
could have a group relay log position which lags behind "forever"
(assume the last master's transaction is ignored by the slave because of
replicate-ignore rules).
*/
thd->binlog_flush_pending_rows_event(true);
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
rli->stmt_done(log_pos, when);
/*
If this event is not in a transaction, the call below will, if some
transactional storage engines are involved, commit the statement into
them and flush the pending event to binlog.
If this event is in a transaction, the call will do nothing, but a
Xid_log_event will come next which will, if some transactional engines
are involved, commit the transaction and flush the pending event to the
binlog.
Clear any errors in thd->net.last_err*. It is not known if this is
needed or not. It is believed that any errors that may exist in
thd->net.last_err* are allowed. Examples of errors are "key not
found", which is produced in the test case rpl_row_conflicts.test
*/
error= ha_autocommit_or_rollback(thd, 0);
/*
Now what if this is not a transactional engine? we still need to
flush the pending event to the binlog; we did it with
thd->binlog_flush_pending_rows_event(). Note that we imitate
what is done for real queries: a call to
ha_autocommit_or_rollback() (sometimes only if involves a
transactional engine), and a call to be sure to have the pending
event flushed.
*/
thd->reset_current_stmt_binlog_row_based();
rli->cleanup_context(thd, 0);
if (error == 0)
{
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
*/
rli->stmt_done(log_pos, when);
/*
Clear any errors pushed in thd->net.client_last_err* if for
example "no key found" (as this is allowed). This is a safety
measure; apparently those errors (e.g. when executing a
Delete_rows_log_event_old of a non-existing row, like in
rpl_row_mystery22.test, thd->net.last_error = "Can't
find record in 't1'" and last_errno=1032) do not become
visible. We still prefer to wipe them out.
*/
thd->clear_error();
}
else
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
get_type_str(), m_table->s->db.str,
m_table->s->table_name.str);
thd->clear_error();
}
else
{

View file

@ -2435,6 +2435,7 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
table->tablenr= tablenr;
table->map= (table_map) 1 << tablenr;
table->force_index= table_list->force_index;
table->force_index_order= table->force_index_group= 0;
table->covering_keys= table->s->keys_for_keyread;
table->merge_keys.clear_all();
}

View file

@ -773,7 +773,6 @@ extern int wild_compare(const char *str,const char *wildstr,
extern WF_PACK *wf_comp(char * str);
extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
extern void wf_end(struct wild_file_pack *buffer);
extern size_t strip_sp(char * str);
extern my_bool array_append_string_unique(const char *str,
const char **array, size_t size);
extern void get_date(char * to,int timeflag,time_t use_time);

View file

@ -5876,6 +5876,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
if (type == Item_func::LT_FUNC && (value->val_int() > 0))
type = Item_func::LE_FUNC;
else if (type == Item_func::GT_FUNC &&
(field->type() != FIELD_TYPE_BIT) &&
!((Field_num*)field)->unsigned_flag &&
!((Item_int*)value)->unsigned_flag &&
(value->val_int() < 0))
@ -5913,7 +5914,9 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
*/
if (field->result_type() == INT_RESULT &&
value->result_type() == INT_RESULT &&
((Field_num*)field)->unsigned_flag && !((Item_int*)value)->unsigned_flag)
((field->type() == FIELD_TYPE_BIT ||
((Field_num *) field)->unsigned_flag) &&
!((Item_int*) value)->unsigned_flag))
{
longlong item_val= value->val_int();
if (item_val < 0)
@ -6509,6 +6512,63 @@ get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1)
}
/**
Combine two range expression under a common OR. On a logical level, the
transformation is key_or( expr1, expr2 ) => expr1 OR expr2.
Both expressions are assumed to be in the SEL_ARG format. In a logic sense,
theformat is reminiscent of DNF, since an expression such as the following
( 1 < kp1 < 10 AND p1 ) OR ( 10 <= kp2 < 20 AND p2 )
where there is a key consisting of keyparts ( kp1, kp2, ..., kpn ) and p1
and p2 are valid SEL_ARG expressions over keyparts kp2 ... kpn, is a valid
SEL_ARG condition. The disjuncts appear ordered by the minimum endpoint of
the first range and ranges must not overlap. It follows that they are also
ordered by maximum endpoints. Thus
( 1 < kp1 <= 2 AND ( kp2 = 2 OR kp2 = 3 ) ) OR kp1 = 3
Is a a valid SER_ARG expression for a key of at least 2 keyparts.
For simplicity, we will assume that expr2 is a single range predicate,
i.e. on the form ( a < x < b AND ... ). It is easy to generalize to a
disjunction of several predicates by subsequently call key_or for each
disjunct.
The algorithm iterates over each disjunct of expr1, and for each disjunct
where the first keypart's range overlaps with the first keypart's range in
expr2:
If the predicates are equal for the rest of the keyparts, or if there are
no more, the range in expr2 has its endpoints copied in, and the SEL_ARG
node in expr2 is deallocated. If more ranges became connected in expr1, the
surplus is also dealocated. If they differ, two ranges are created.
- The range leading up to the overlap. Empty if endpoints are equal.
- The overlapping sub-range. May be the entire range if they are equal.
Finally, there may be one more range if expr2's first keypart's range has a
greater maximum endpoint than the last range in expr1.
For the overlapping sub-range, we recursively call key_or. Thus in order to
compute key_or of
(1) ( 1 < kp1 < 10 AND 1 < kp2 < 10 )
(2) ( 2 < kp1 < 20 AND 4 < kp2 < 20 )
We create the ranges 1 < kp <= 2, 2 < kp1 < 10, 10 <= kp1 < 20. For the
first one, we simply hook on the condition for the second keypart from (1)
: 1 < kp2 < 10. For the second range 2 < kp1 < 10, key_or( 1 < kp2 < 10, 4
< kp2 < 20 ) is called, yielding 1 < kp2 < 20. For the last range, we reuse
the range 4 < kp2 < 20 from (2) for the second keypart. The result is thus
( 1 < kp1 <= 2 AND 1 < kp2 < 10 ) OR
( 2 < kp1 < 10 AND 1 < kp2 < 20 ) OR
( 10 <= kp1 < 20 AND 4 < kp2 < 20 )
*/
static SEL_ARG *
key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
{
@ -6660,7 +6720,21 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
key1=key1->tree_delete(save);
}
last->copy_min(tmp);
if (last->copy_min(key2) || last->copy_max(key2))
bool full_range= last->copy_min(key2);
if (!full_range)
{
if (last->next && key2->cmp_max_to_min(last->next) >= 0)
{
last->max_value= last->next->min_value;
if (last->next->min_flag & NEAR_MIN)
last->max_flag&= ~NEAR_MAX;
else
last->max_flag|= NEAR_MAX;
}
else
full_range= last->copy_max(key2);
}
if (full_range)
{ // Full range
key1->free_tree();
for (; key2 ; key2=key2->next)
@ -6670,8 +6744,6 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
return 0;
}
}
key2=key2->next;
continue;
}
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)

View file

@ -97,7 +97,8 @@ static ulonglong get_exact_record_count(TABLE_LIST *tables)
@note
This function is only called for queries with sum functions and no
GROUP BY part.
GROUP BY part. This means that the result set shall contain a single
row only
@retval
0 no errors

View file

@ -2082,8 +2082,7 @@ static int has_temporary_error(THD *thd)
@retval 2 No error calling ev->apply_event(), but error calling
ev->update_pos().
*/
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
bool skip)
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
{
int exec_res= 0;
@ -2128,38 +2127,34 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
ev->when= my_time(0);
ev->thd = thd; // because up to this point, ev->thd == 0
if (skip)
{
int reason= ev->shall_skip(rli);
if (reason == Log_event::EVENT_SKIP_COUNT)
--rli->slave_skip_counter;
pthread_mutex_unlock(&rli->data_lock);
if (reason == Log_event::EVENT_SKIP_NOT)
exec_res= ev->apply_event(rli);
#ifndef DBUG_OFF
/*
This only prints information to the debug trace.
TODO: Print an informational message to the error log?
*/
static const char *const explain[] = {
// EVENT_SKIP_NOT,
"not skipped",
// EVENT_SKIP_IGNORE,
"skipped because event should be ignored",
// EVENT_SKIP_COUNT
"skipped because event skip counter was non-zero"
};
DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
thd->options & OPTION_BEGIN ? 1 : 0,
rli->get_flag(Relay_log_info::IN_STMT)));
DBUG_PRINT("skip_event", ("%s event was %s",
ev->get_type_str(), explain[reason]));
#endif
}
else
int reason= ev->shall_skip(rli);
if (reason == Log_event::EVENT_SKIP_COUNT)
--rli->slave_skip_counter;
pthread_mutex_unlock(&rli->data_lock);
if (reason == Log_event::EVENT_SKIP_NOT)
exec_res= ev->apply_event(rli);
#ifndef DBUG_OFF
/*
This only prints information to the debug trace.
TODO: Print an informational message to the error log?
*/
static const char *const explain[] = {
// EVENT_SKIP_NOT,
"not skipped",
// EVENT_SKIP_IGNORE,
"skipped because event should be ignored",
// EVENT_SKIP_COUNT
"skipped because event skip counter was non-zero"
};
DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
thd->options & OPTION_BEGIN ? 1 : 0,
rli->get_flag(Relay_log_info::IN_STMT)));
DBUG_PRINT("skip_event", ("%s event was %s",
ev->get_type_str(), explain[reason]));
#endif
DBUG_PRINT("info", ("apply_event error = %d", exec_res));
if (exec_res == 0)
{
@ -2278,7 +2273,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
delete ev;
DBUG_RETURN(1);
}
exec_res= apply_event_and_update_pos(ev, thd, rli, TRUE);
exec_res= apply_event_and_update_pos(ev, thd, rli);
/*
Format_description_log_event should not be deleted because it will be

View file

@ -190,8 +190,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
void set_slave_thread_options(THD* thd);
void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
void rotate_relay_log(Master_info* mi);
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
bool skip);
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
pthread_handler_t handle_slave_io(void *arg);
pthread_handler_t handle_slave_sql(void *arg);

View file

@ -2305,7 +2305,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in)
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
table->null_row= table->maybe_null= table->force_index= 0;
table->null_row= table->maybe_null= 0;
table->force_index= table->force_index_order= table->force_index_group= 0;
table->status=STATUS_NO_RECORD;
DBUG_RETURN(FALSE);
}
@ -2963,7 +2964,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
table->null_row= table->maybe_null= table->force_index= 0;
table->null_row= table->maybe_null= 0;
table->force_index= table->force_index_order= table->force_index_group= 0;
table->status=STATUS_NO_RECORD;
table->insert_values= 0;
table->fulltext_searched= 0;

View file

@ -56,17 +56,20 @@ void mysql_client_binlog_statement(THD* thd)
Format_description_event.
*/
my_bool have_fd_event= TRUE;
if (!thd->rli_fake)
int err;
Relay_log_info *rli;
rli= thd->rli_fake;
if (!rli)
{
thd->rli_fake= new Relay_log_info;
rli= thd->rli_fake= new Relay_log_info;
#ifdef HAVE_purify
thd->rli_fake->is_fake= TRUE;
rli->is_fake= TRUE;
#endif
have_fd_event= FALSE;
}
if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec)
if (rli && !rli->relay_log.description_event_for_exec)
{
thd->rli_fake->relay_log.description_event_for_exec=
rli->relay_log.description_event_for_exec=
new Format_description_log_event(4);
have_fd_event= FALSE;
}
@ -78,16 +81,16 @@ void mysql_client_binlog_statement(THD* thd)
/*
Out of memory check
*/
if (!(thd->rli_fake &&
thd->rli_fake->relay_log.description_event_for_exec &&
if (!(rli &&
rli->relay_log.description_event_for_exec &&
buf))
{
my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
goto end;
}
thd->rli_fake->sql_thd= thd;
thd->rli_fake->no_storage= TRUE;
rli->sql_thd= thd;
rli->no_storage= TRUE;
for (char const *strptr= thd->lex->comment.str ;
strptr < thd->lex->comment.str + thd->lex->comment.length ; )
@ -170,8 +173,7 @@ void mysql_client_binlog_statement(THD* thd)
}
ev= Log_event::read_log_event(bufptr, event_len, &error,
thd->rli_fake->relay_log.
description_event_for_exec);
rli->relay_log.description_event_for_exec);
DBUG_PRINT("info",("binlog base64 err=%s", error));
if (!ev)
@ -209,18 +211,10 @@ void mysql_client_binlog_statement(THD* thd)
reporting.
*/
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
if (apply_event_and_update_pos(ev, thd, thd->rli_fake, FALSE))
{
delete ev;
/*
TODO: Maybe a better error message since the BINLOG statement
now contains several events.
*/
my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
goto end;
}
err= ev->apply_event(rli);
#else
err= 0;
#endif
/*
Format_description_log_event should not be deleted because it
will be used to read info about the relay log's format; it
@ -228,8 +222,17 @@ void mysql_client_binlog_statement(THD* thd)
i.e. when this thread terminates.
*/
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
delete ev;
delete ev;
ev= 0;
if (err)
{
/*
TODO: Maybe a better error message since the BINLOG statement
now contains several events.
*/
my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
goto end;
}
}
}
@ -238,7 +241,7 @@ void mysql_client_binlog_statement(THD* thd)
my_ok(thd);
end:
thd->rli_fake->clear_tables_to_lock();
rli->clear_tables_to_lock();
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
DBUG_VOID_RETURN;
}

View file

@ -2647,7 +2647,32 @@ public:
MI_COLUMNDEF *recinfo,*start_recinfo;
KEY *keyinfo;
ha_rows end_write_records;
uint field_count,sum_func_count,func_count;
/**
Number of normal fields in the query, including those referred to
from aggregate functions. Hence, "SELECT `field1`,
SUM(`field2`) from t1" sets this counter to 2.
@see count_field_types
*/
uint field_count;
/**
Number of fields in the query that have functions. Includes both
aggregate functions (e.g., SUM) and non-aggregates (e.g., RAND).
Also counts functions referred to from aggregate functions, i.e.,
"SELECT SUM(RAND())" sets this counter to 2.
@see count_field_types
*/
uint func_count;
/**
Number of fields in the query that have aggregate functions. Note
that the optimizer may choose to optimize away these fields by
replacing them with constants, in which case sum_func_count will
need to be updated.
@see opt_sum_query, count_field_types
*/
uint sum_func_count;
uint hidden_field_count;
uint group_parts,group_length,group_null_parts;
uint quick_group;

View file

@ -6330,6 +6330,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->table_name_length=table->table.length;
ptr->lock_type= lock_type;
ptr->updating= test(table_options & TL_OPTION_UPDATING);
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->derived= table->sel;

View file

@ -647,8 +647,11 @@ JOIN::prepare(Item ***rref_pointer_array,
this->group= group_list != 0;
unit= unit_arg;
if (tmp_table_param.sum_func_count && !group_list)
implicit_grouping= TRUE;
#ifdef RESTRICTED_GROUP
if (sum_func_count && !group_list && (func_count || field_count))
if (implicit_grouping)
{
my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
goto err;
@ -884,15 +887,23 @@ JOIN::optimize()
}
#endif
/* Optimize count(*), min() and max() */
if (tables_list && tmp_table_param.sum_func_count && ! group_list)
/*
Try to optimize count(*), min() and max() to const fields if
there is implicit grouping (aggregate functions but no
group_list). In this case, the result set shall only contain one
row.
*/
if (tables_list && implicit_grouping)
{
int res;
/*
opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
to the WHERE conditions,
or 1 if all items were resolved,
or 1 if all items were resolved (optimized away),
or 0, or an error number HA_ERR_...
If all items were resolved by opt_sum_query, there is no need to
open any tables.
*/
if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
{
@ -1234,13 +1245,22 @@ JOIN::optimize()
(!group_list && tmp_table_param.sum_func_count))
order=0;
// Can't use sort on head table if using row cache
// Can't use sort on head table if using join buffering
if (full_join)
{
if (group_list)
simple_group=0;
if (order)
simple_order=0;
TABLE *stable= (sort_by_table == (TABLE *) 1 ?
join_tab[const_tables].table : sort_by_table);
/*
FORCE INDEX FOR ORDER BY can be used to prevent join buffering when
sorting on the first table.
*/
if (!stable || !stable->force_index_order)
{
if (group_list)
simple_group= 0;
if (order)
simple_order= 0;
}
}
/*
@ -2018,7 +2038,8 @@ JOIN::exec()
count_field_types(select_lex, &curr_join->tmp_table_param,
*curr_all_fields, 0);
if (curr_join->group || curr_join->tmp_table_param.sum_func_count ||
if (curr_join->group || curr_join->implicit_grouping ||
curr_join->tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP)))
{
if (make_group_fields(this, curr_join))
@ -10805,6 +10826,12 @@ Next_select_func setup_end_select_func(JOIN *join)
}
else
{
/*
Choose method for presenting result to user. Use end_send_group
if the query requires grouping (has a GROUP BY clause and/or one or
more aggregate functions). Use end_send if the query should not
be grouped.
*/
if ((join->sort_and_group ||
(join->procedure && join->procedure->flags & PROC_GROUP)) &&
!tmp_tbl->precomputed_group_by)

View file

@ -278,7 +278,14 @@ public:
TABLE **table,**all_tables,*sort_by_table;
uint tables,const_tables;
uint send_group_parts;
bool sort_and_group,first_record,full_join,group, no_field_update;
/**
Indicates that grouping will be performed on the result set during
query execution. This field belongs to query execution.
@see make_group_fields, alloc_group_fields, JOIN::exec
*/
bool sort_and_group;
bool first_record,full_join,group, no_field_update;
bool do_send_rows;
/**
TRUE when we want to resume nested loop iterations when
@ -357,6 +364,8 @@ public:
simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
to other tables than the first non-constant table in the JOIN.
It's also set if ORDER/GROUP BY is empty.
Used for deciding for or against using a temporary table to compute
GROUP/ORDER BY.
*/
bool simple_order, simple_group;
/**
@ -426,6 +435,7 @@ public:
tables= 0;
const_tables= 0;
join_list= 0;
implicit_grouping= FALSE;
sort_and_group= 0;
first_record= 0;
do_send_rows= 1;
@ -531,6 +541,11 @@ public:
select_lex == unit->fake_select_lex));
}
private:
/**
TRUE if the query contains an aggregate function but has no GROUP
BY clause.
*/
bool implicit_grouping;
bool make_simple_join(JOIN *join, TABLE *tmp_table);
};

View file

@ -4638,7 +4638,8 @@ Item_subselect *TABLE_LIST::containing_subselect()
(TABLE_LIST::index_hints). Using the information in this tagged list
this function sets the members st_table::keys_in_use_for_query,
st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by,
st_table::force_index and st_table::covering_keys.
st_table::force_index, st_table::force_index_order,
st_table::force_index_group and st_table::covering_keys.
Current implementation of the runtime does not allow mixing FORCE INDEX
and USE INDEX, so this is checked here. Then the FORCE INDEX list
@ -4766,14 +4767,28 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl)
}
/* process FORCE INDEX as USE INDEX with a flag */
if (!index_order[INDEX_HINT_FORCE].is_clear_all())
{
tbl->force_index_order= TRUE;
index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
}
if (!index_group[INDEX_HINT_FORCE].is_clear_all())
{
tbl->force_index_group= TRUE;
index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
}
/*
TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) and
create tbl->force_index_join instead.
Then use the correct force_index_XX instead of the global one.
*/
if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
!index_order[INDEX_HINT_FORCE].is_clear_all() ||
!index_group[INDEX_HINT_FORCE].is_clear_all())
tbl->force_index_group || tbl->force_index_order)
{
tbl->force_index= TRUE;
index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
}
/* apply USE INDEX */

View file

@ -752,6 +752,18 @@ struct st_table {
bytes, it would take up 4.
*/
my_bool force_index;
/**
Flag set when the statement contains FORCE INDEX FOR ORDER BY
See TABLE_LIST::process_index_hints().
*/
my_bool force_index_order;
/**
Flag set when the statement contains FORCE INDEX FOR GROUP BY
See TABLE_LIST::process_index_hints().
*/
my_bool force_index_group;
my_bool distinct,const_table,no_rows;
/**

View file

@ -1088,22 +1088,6 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool do_optimize)
ha_rows rows= file->state->records;
DBUG_ENTER("ha_myisam::repair");
/*
Normally this method is entered with a properly opened table. If the
repair fails, it can be repeated with more elaborate options. Under
special circumstances it can happen that a repair fails so that it
closed the data file and cannot re-open it. In this case file->dfile
is set to -1. We must not try another repair without an open data
file. (Bug #25289)
*/
if (file->dfile == -1)
{
sql_print_information("Retrying repair of: '%s' failed. "
"Please try REPAIR EXTENDED or myisamchk",
table->s->path.str);
DBUG_RETURN(HA_ADMIN_FAILED);
}
param.db_name= table->s->db.str;
param.table_name= table->alias;
param.tmpfile_createflag = O_RDWR | O_TRUNC;

View file

@ -2561,8 +2561,9 @@ err:
VOID(my_close(new_file,MYF(0)));
VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
MYF(MY_WME)));
if (info->dfile == new_file)
info->dfile= -1;
if (info->dfile == new_file) /* Retry with key cache */
if (unlikely(mi_open_datafile(info, share, name, -1)))
param->retry_repair= 0; /* Safety */
}
mi_mark_crashed_on_repair(info);
}
@ -3095,8 +3096,9 @@ err:
VOID(my_close(new_file,MYF(0)));
VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
MYF(MY_WME)));
if (info->dfile == new_file)
info->dfile= -1;
if (info->dfile == new_file) /* Retry with key cache */
if (unlikely(mi_open_datafile(info, share, name, -1)))
param->retry_repair= 0; /* Safety */
}
mi_mark_crashed_on_repair(info);
}

View file

@ -788,7 +788,11 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
cleanup:
close_cached_file(to_file); /* This holds old result */
if (to_file == t_file)
{
*t_file=t_file2; /* Copy result file */
t_file->current_pos= &t_file->write_pos;
t_file->current_end= &t_file->write_end;
}
DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
} /* merge_many_buff */

View file

@ -7,6 +7,8 @@
# Remarks:
# ${engine}_SOURCES variable containing source files to produce the library must set before
# calling this macro
# ${engine}_LIBS variable containing extra libraries to link with may be set
MACRO(MYSQL_STORAGE_ENGINE engine)
IF(NOT SOURCE_SUBLIBS)
@ -22,6 +24,9 @@ IF(NOT SOURCE_SUBLIBS)
#Create static library. The name of the library is <storage_engine>.lib
ADD_LIBRARY(${libname} ${${engine}_SOURCES})
ADD_DEPENDENCIES(${libname} GenError)
IF(${engine}_LIBS)
TARGET_LINK_LIBRARIES(${libname} ${${engine}_LIBS})
ENDIF(${engine}_LIBS)
MESSAGE("build ${engine} as static library")
ELSEIF(${ENGINE_BUILD_TYPE} STREQUAL "DYNAMIC")
ADD_DEFINITIONS(-DMYSQL_DYNAMIC_PLUGIN)
@ -30,6 +35,9 @@ IF(NOT SOURCE_SUBLIBS)
SET(dyn_libname ha_${libname})
ADD_LIBRARY(${dyn_libname} SHARED ${${engine}_SOURCES})
TARGET_LINK_LIBRARIES (${dyn_libname} mysqld)
IF(${engine}_LIBS)
TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS})
ENDIF(${engine}_LIBS)
MESSAGE("build ${engine} as DLL")
ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
ENDIF(NOT SOURCE_SUBLIBS)

View file

@ -185,8 +185,8 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, size_t a_length,
}
for (end= a + a_length-length; a < end ; a++)
{
if (map[*a] != ' ')
return (map[*a] < ' ') ? -swap : swap;
if (map[*a] != map[' '])
return (map[*a] < map[' ']) ? -swap : swap;
}
}
return res;