mirror of
https://github.com/MariaDB/server.git
synced 2026-04-21 15:55:53 +02:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.0-marvel
into janus.mylan:/usr/home/serg/Abk/mysql-5.0 heap/hp_write.c: Auto merged sql/ha_ndbcluster.cc: Auto merged
This commit is contained in:
commit
c4879fe6dd
61 changed files with 1670 additions and 438 deletions
|
|
@ -6,6 +6,6 @@ path=`dirname $0`
|
|||
extra_flags="$pentium_cflags $debug_cflags $max_cflags"
|
||||
c_warnings="$c_warnings $debug_extra_warnings"
|
||||
cxx_warnings="$cxx_warnings $debug_extra_warnings"
|
||||
extra_configs="$pentium_configs $debug_configs $max_configs"
|
||||
extra_configs="$pentium_configs $debug_configs $max_configs --with-experimental-collations"
|
||||
|
||||
. "$path/FINISH.sh"
|
||||
|
|
|
|||
|
|
@ -2529,7 +2529,8 @@ print_table_data_xml(MYSQL_RES *result)
|
|||
|
||||
tee_fputs("<?xml version=\"1.0\"?>\n\n<resultset statement=\"", PAGER);
|
||||
xmlencode_print(glob_buffer.ptr(), (int)strlen(glob_buffer.ptr()));
|
||||
tee_fputs("\">", PAGER);
|
||||
tee_fputs("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">",
|
||||
PAGER);
|
||||
|
||||
fields = mysql_fetch_fields(result);
|
||||
while ((cur = mysql_fetch_row(result)))
|
||||
|
|
|
|||
|
|
@ -429,3 +429,16 @@ then
|
|||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
|
||||
# Shall we build experimental collations
|
||||
AC_ARG_WITH(experimental-collations,
|
||||
[],
|
||||
[with_exp_coll=$withval],
|
||||
[with_exp_coll=no]
|
||||
)
|
||||
|
||||
if test "$with_exp_coll" = "yes"
|
||||
then
|
||||
AC_DEFINE([HAVE_UTF8_GENERAL_CS], [1], [certain Japanese customer])
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ insert into t1 values (1, 2, 'a&b a<b a>b');
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<resultset statement="select * from t1
|
||||
">
|
||||
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<row>
|
||||
<field name="a&b">1</field>
|
||||
<field name="a<b">2</field>
|
||||
|
|
@ -34,7 +34,7 @@ insert into t1 values (1, 2, 'a&b a<b a>b');
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<resultset statement="select count(*) from t1
|
||||
">
|
||||
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<row>
|
||||
<field name="count(*)">1</field>
|
||||
</row>
|
||||
|
|
@ -42,7 +42,7 @@ insert into t1 values (1, 2, 'a&b a<b a>b');
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<resultset statement="select 1 < 2 from dual
|
||||
">
|
||||
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<row>
|
||||
<field name="1 < 2">1</field>
|
||||
</row>
|
||||
|
|
@ -50,7 +50,7 @@ insert into t1 values (1, 2, 'a&b a<b a>b');
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<resultset statement="select 1 > 2 from dual
|
||||
">
|
||||
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<row>
|
||||
<field name="1 > 2">0</field>
|
||||
</row>
|
||||
|
|
@ -58,7 +58,7 @@ insert into t1 values (1, 2, 'a&b a<b a>b');
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<resultset statement="select 1 & 3 from dual
|
||||
">
|
||||
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<row>
|
||||
<field name="1 & 3">1</field>
|
||||
</row>
|
||||
|
|
@ -66,7 +66,7 @@ insert into t1 values (1, 2, 'a&b a<b a>b');
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<resultset statement="select null from dual
|
||||
">
|
||||
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<row>
|
||||
<field name="NULL" xsi:nil="true" />
|
||||
</row>
|
||||
|
|
|
|||
|
|
@ -2654,3 +2654,12 @@ ii 2 ii 2 İİ 4
|
|||
İİ 4 ii 2 İİ 4
|
||||
II 2 ıı 4 II 2
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
c1 text character set ucs2 collate ucs2_polish_ci NOT NULL
|
||||
) ENGINE=MyISAM;
|
||||
insert into t1 values (''),('a');
|
||||
SELECT COUNT(*), c1 FROM t1 GROUP BY c1;
|
||||
COUNT(*) c1
|
||||
1
|
||||
1 a
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
|
|
|||
|
|
@ -839,6 +839,24 @@ lily
|
|||
river
|
||||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
set names latin1;
|
||||
set character_set_connection=ucs2;
|
||||
select soundex(''),soundex('he'),soundex('hello all folks'),soundex('#3556 in bugdb');
|
||||
soundex('') soundex('he') soundex('hello all folks') soundex('#3556 in bugdb')
|
||||
H000 H4142 I51231
|
||||
select hex(soundex('')),hex(soundex('he')),hex(soundex('hello all folks')),hex(soundex('#3556 in bugdb'));
|
||||
hex(soundex('')) hex(soundex('he')) hex(soundex('hello all folks')) hex(soundex('#3556 in bugdb'))
|
||||
0048003000300030 00480034003100340032 004900350031003200330031
|
||||
select 'mood' sounds like 'mud';
|
||||
'mood' sounds like 'mud'
|
||||
1
|
||||
select hex(soundex(_ucs2 0x041004110412));
|
||||
hex(soundex(_ucs2 0x041004110412))
|
||||
0410003000300030
|
||||
select hex(soundex(_ucs2 0x00BF00C0));
|
||||
hex(soundex(_ucs2 0x00BF00C0))
|
||||
00C0003000300030
|
||||
set names latin1;
|
||||
create table t1(a blob, b text charset utf8, c text charset ucs2);
|
||||
select data_type, character_octet_length, character_maximum_length
|
||||
from information_schema.columns where table_name='t1';
|
||||
|
|
|
|||
|
|
@ -854,6 +854,18 @@ select * from t1 where soundex(a) = soundex('test');
|
|||
id a
|
||||
1 Test
|
||||
drop table t1;
|
||||
select soundex(_utf8 0xE99885E8A788E99A8FE697B6E69BB4E696B0E79A84E696B0E997BB);
|
||||
soundex(_utf8 0xE99885E8A788E99A8FE697B6E69BB4E696B0E79A84E696B0E997BB)
|
||||
阅000
|
||||
select hex(soundex(_utf8 0xE99885E8A788E99A8FE697B6E69BB4E696B0E79A84E696B0E997BB));
|
||||
hex(soundex(_utf8 0xE99885E8A788E99A8FE697B6E69BB4E696B0E79A84E696B0E997BB))
|
||||
E99885303030
|
||||
select soundex(_utf8 0xD091D092D093);
|
||||
soundex(_utf8 0xD091D092D093)
|
||||
Б000
|
||||
select hex(soundex(_utf8 0xD091D092D093));
|
||||
hex(soundex(_utf8 0xD091D092D093))
|
||||
D091303030
|
||||
SET collation_connection='utf8_general_ci';
|
||||
create table t1 select repeat('a',4000) a;
|
||||
delete from t1;
|
||||
|
|
|
|||
|
|
@ -214,3 +214,12 @@ select count(*) from t1;
|
|||
count(*)
|
||||
0
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
DELETE FROM t1 ORDER BY x;
|
||||
ERROR 42S22: Unknown column 'x' in 'order clause'
|
||||
DELETE FROM t1 ORDER BY t2.x;
|
||||
ERROR 42S22: Unknown column 't2.x' in 'order clause'
|
||||
DELETE FROM t1 ORDER BY (SELECT x);
|
||||
ERROR 42S22: Unknown column 'x' in 'field list'
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -728,3 +728,13 @@ f2 group_concat(f1)
|
|||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1
|
||||
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2
|
||||
drop table t1;
|
||||
CREATE TABLE t1(a TEXT, b CHAR(20));
|
||||
INSERT INTO t1 VALUES ("one.1","one.1"),("two.2","two.2"),("one.3","one.3");
|
||||
SELECT GROUP_CONCAT(DISTINCT UCASE(a)) FROM t1;
|
||||
GROUP_CONCAT(DISTINCT UCASE(a))
|
||||
ONE.1,TWO.2,ONE.3
|
||||
SELECT GROUP_CONCAT(DISTINCT UCASE(b)) FROM t1;
|
||||
GROUP_CONCAT(DISTINCT UCASE(b))
|
||||
ONE.1,TWO.2,ONE.3
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
|
|
|
|||
|
|
@ -730,6 +730,12 @@ point(b, b) IS NULL linestring(b) IS NULL polygon(b) IS NULL multipoint(b) IS NU
|
|||
1 1 1 1 1 1 1
|
||||
0 1 1 1 1 1 1
|
||||
drop table t1;
|
||||
CREATE TABLE t1(a POINT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
NULL
|
||||
DROP TABLE t1;
|
||||
End of 4.1 tests
|
||||
create table t1 (s1 geometry not null,s2 char(100));
|
||||
create trigger t1_bu before update on t1 for each row set new.s1 = null;
|
||||
|
|
@ -763,3 +769,14 @@ create table t1 (g geometry not null);
|
|||
insert into t1 values(default);
|
||||
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a GEOMETRY);
|
||||
CREATE VIEW v1 AS SELECT GeomFromwkb(ASBINARY(a)) FROM t1;
|
||||
CREATE VIEW v2 AS SELECT a FROM t1;
|
||||
DESCRIBE v1;
|
||||
Field Type Null Key Default Extra
|
||||
GeomFromwkb(ASBINARY(a)) geometry YES NULL
|
||||
DESCRIBE v2;
|
||||
Field Type Null Key Default Extra
|
||||
a geometry YES NULL
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -1019,4 +1019,79 @@ DROP DATABASE mysqltest2;
|
|||
DROP DATABASE mysqltest3;
|
||||
DROP DATABASE mysqltest4;
|
||||
DROP USER mysqltest_1@localhost;
|
||||
DROP DATABASE IF EXISTS mysqltest1;
|
||||
DROP DATABASE IF EXISTS mysqltest2;
|
||||
CREATE DATABASE mysqltest1;
|
||||
CREATE DATABASE mysqltest2;
|
||||
GRANT ALL PRIVILEGES ON mysqltest1.* TO mysqltest_1@localhost;
|
||||
GRANT SELECT ON mysqltest2.* TO mysqltest_1@localhost;
|
||||
CREATE PROCEDURE mysqltest1.p1() SQL SECURITY INVOKER
|
||||
SELECT 1;
|
||||
|
||||
---> connection: bug27337_con1
|
||||
CREATE TABLE t1(c INT);
|
||||
ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
|
||||
CALL mysqltest1.p1();
|
||||
1
|
||||
1
|
||||
CREATE TABLE t1(c INT);
|
||||
ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
|
||||
|
||||
---> connection: bug27337_con2
|
||||
CREATE TABLE t1(c INT);
|
||||
ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
|
||||
SHOW TABLES;
|
||||
Tables_in_mysqltest2
|
||||
|
||||
---> connection: default
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP DATABASE mysqltest2;
|
||||
DROP USER mysqltest_1@localhost;
|
||||
DROP DATABASE IF EXISTS mysqltest1;
|
||||
DROP DATABASE IF EXISTS mysqltest2;
|
||||
CREATE DATABASE mysqltest1;
|
||||
CREATE DATABASE mysqltest2;
|
||||
CREATE TABLE mysqltest1.t1(c INT);
|
||||
CREATE TABLE mysqltest2.t2(c INT);
|
||||
GRANT SELECT ON mysqltest1.t1 TO mysqltest_1@localhost;
|
||||
GRANT SELECT ON mysqltest2.t2 TO mysqltest_2@localhost;
|
||||
|
||||
---> connection: bug27337_con1
|
||||
SHOW TABLES FROM mysqltest1;
|
||||
Tables_in_mysqltest1
|
||||
t1
|
||||
PREPARE stmt1 FROM 'SHOW TABLES FROM mysqltest1';
|
||||
EXECUTE stmt1;
|
||||
Tables_in_mysqltest1
|
||||
t1
|
||||
|
||||
---> connection: bug27337_con2
|
||||
SHOW COLUMNS FROM mysqltest2.t2;
|
||||
Field Type Null Key Default Extra
|
||||
c int(11) YES NULL
|
||||
PREPARE stmt2 FROM 'SHOW COLUMNS FROM mysqltest2.t2';
|
||||
EXECUTE stmt2;
|
||||
Field Type Null Key Default Extra
|
||||
c int(11) YES NULL
|
||||
|
||||
---> connection: default
|
||||
REVOKE SELECT ON mysqltest1.t1 FROM mysqltest_1@localhost;
|
||||
REVOKE SELECT ON mysqltest2.t2 FROM mysqltest_2@localhost;
|
||||
|
||||
---> connection: bug27337_con1
|
||||
SHOW TABLES FROM mysqltest1;
|
||||
ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest1'
|
||||
EXECUTE stmt1;
|
||||
ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest1'
|
||||
|
||||
---> connection: bug27337_con2
|
||||
SHOW COLUMNS FROM mysqltest2.t2;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2'
|
||||
EXECUTE stmt2;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2'
|
||||
|
||||
---> connection: default
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP DATABASE mysqltest2;
|
||||
DROP USER mysqltest_1@localhost;
|
||||
End of 5.0 tests
|
||||
|
|
|
|||
|
|
@ -258,3 +258,81 @@ SELECT LAST_INSERT_ID();
|
|||
LAST_INSERT_ID()
|
||||
1
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` varchar(10) NOT NULL UNIQUE
|
||||
);
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test1")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test1")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
LAST_INSERT_ID()
|
||||
1
|
||||
SELECT * FROM t1;
|
||||
id f1
|
||||
1 test1
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test2")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT * FROM t1;
|
||||
id f1
|
||||
1 test1
|
||||
2 test2
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test2")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
LAST_INSERT_ID()
|
||||
2
|
||||
SELECT * FROM t1;
|
||||
id f1
|
||||
1 test1
|
||||
2 test2
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test3")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
LAST_INSERT_ID()
|
||||
3
|
||||
SELECT * FROM t1;
|
||||
id f1
|
||||
1 test1
|
||||
2 test2
|
||||
3 test3
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` varchar(10) NOT NULL UNIQUE
|
||||
);
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test1")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
LAST_INSERT_ID()
|
||||
1
|
||||
SELECT * FROM t1;
|
||||
id f1
|
||||
1 test1
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test1"),("test4")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
LAST_INSERT_ID()
|
||||
1
|
||||
SELECT * FROM t1;
|
||||
id f1
|
||||
1 test1
|
||||
2 test4
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` varchar(10) NOT NULL UNIQUE,
|
||||
tim1 timestamp default '2003-01-01 00:00:00' on update current_timestamp
|
||||
);
|
||||
INSERT INTO t1 (f1) VALUES ("test1");
|
||||
SELECT id, f1 FROM t1;
|
||||
id f1
|
||||
1 test1
|
||||
REPLACE INTO t1 VALUES (0,"test1",null);
|
||||
SELECT id, f1 FROM t1;
|
||||
id f1
|
||||
0 test1
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE='';
|
||||
|
|
|
|||
|
|
@ -717,6 +717,147 @@ d8c4177d225791924.30714720
|
|||
d8c4177d2380fc201.39666693
|
||||
d8c4177d24ccef970.14957924
|
||||
DROP TABLE t1;
|
||||
create table t1 (
|
||||
c1 char(10), c2 char(10), c3 char(10), c4 char(10),
|
||||
c5 char(10), c6 char(10), c7 char(10), c8 char(10),
|
||||
c9 char(10), c10 char(10), c11 char(10), c12 char(10),
|
||||
c13 char(10), c14 char(10), c15 char(10), c16 char(10),
|
||||
index(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12,c13,c14,c15,c16)
|
||||
);
|
||||
insert into t1 (c1) values ('1'),('1'),('1'),('1');
|
||||
select * from t1 where
|
||||
c1 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c2 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c3 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c4 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c5 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c6 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c7 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c8 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c9 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c10 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC");
|
||||
c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16
|
||||
drop table t1;
|
||||
End of 4.1 tests
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL auto_increment,
|
||||
|
|
|
|||
|
|
@ -306,3 +306,16 @@ a b a b c
|
|||
1 1 1 2 1
|
||||
1 2 1 2 1
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1(
|
||||
a int, b int, c int, d int, e int, f int, g int, h int,
|
||||
PRIMARY KEY (a,b,c,d,e,f,g)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,2,3,4,5,6,7,99);
|
||||
SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7);
|
||||
h
|
||||
99
|
||||
SET @x:= (SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7));
|
||||
SELECT @x;
|
||||
@x
|
||||
99
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,29 @@ create table t2 like t1;
|
|||
load data local infile 'MYSQLTEST_VARDIR/master-data/test/rpl_misc_functions.outfile' into table t2;
|
||||
select * from t1, t2 where (t1.id=t2.id) and not(t1.i=t2.i and t1.r1=t2.r1 and t1.r2=t2.r2 and t1.p=t2.p);
|
||||
id i r1 r2 p id i r1 r2 p
|
||||
stop slave;
|
||||
drop table t1;
|
||||
drop table t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (col_a double default NULL);
|
||||
CREATE PROCEDURE test_replication_sp1()
|
||||
BEGIN
|
||||
INSERT INTO t1 VALUES (rand()), (rand());
|
||||
INSERT INTO t1 VALUES (rand());
|
||||
END|
|
||||
CREATE PROCEDURE test_replication_sp2()
|
||||
BEGIN
|
||||
CALL test_replication_sp1();
|
||||
CALL test_replication_sp1();
|
||||
END|
|
||||
CREATE FUNCTION test_replication_sf() RETURNS DOUBLE DETERMINISTIC
|
||||
BEGIN
|
||||
RETURN (rand() + rand());
|
||||
END|
|
||||
CALL test_replication_sp1();
|
||||
CALL test_replication_sp2();
|
||||
INSERT INTO t1 VALUES (test_replication_sf());
|
||||
INSERT INTO t1 VALUES (test_replication_sf());
|
||||
INSERT INTO t1 VALUES (test_replication_sf());
|
||||
DROP PROCEDURE IF EXISTS test_replication_sp1;
|
||||
DROP PROCEDURE IF EXISTS test_replication_sp2;
|
||||
DROP FUNCTION IF EXISTS test_replication_sf;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
|
|
|||
|
|
@ -3636,6 +3636,12 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
EXPLAIN SELECT 1 FROM t1 IGNORE INDEX FOR JOIN (a) WHERE a = 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
|
||||
EXPLAIN SELECT 1 FROM t1 USE INDEX FOR JOIN (a) WHERE a = 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
|
||||
EXPLAIN SELECT 1 FROM t1 FORCE INDEX FOR JOIN (a) WHERE a = 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
|
||||
CREATE TABLE t2 ( f11 int PRIMARY KEY );
|
||||
|
|
|
|||
|
|
@ -3905,3 +3905,45 @@ COUNT(*) a
|
|||
2 2
|
||||
3 3
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
CREATE TABLE t2 (m int, n int);
|
||||
INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
|
||||
INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
|
||||
SELECT COUNT(*) c, a,
|
||||
(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
|
||||
FROM t1 GROUP BY a;
|
||||
c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
|
||||
2 2 2
|
||||
3 3 3
|
||||
1 4 1,1
|
||||
SELECT COUNT(*) c, a,
|
||||
(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
|
||||
FROM t1 GROUP BY a;
|
||||
c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
|
||||
2 2 3
|
||||
3 3 4
|
||||
1 4 2,2
|
||||
DROP table t1,t2;
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
|
||||
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
|
||||
a
|
||||
SELECT a FROM t1 t0
|
||||
WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
|
||||
a
|
||||
1
|
||||
2
|
||||
SET @@sql_mode='ansi';
|
||||
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
|
||||
ERROR HY000: Invalid use of group function
|
||||
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
|
||||
ERROR HY000: Invalid use of group function
|
||||
SELECT a FROM t1 t0
|
||||
WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
|
||||
ERROR HY000: Invalid use of group function
|
||||
SET @@sql_mode=default;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -661,12 +661,6 @@ SELECT * FROM t1 GROUP by t1.a
|
|||
HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c
|
||||
HAVING MAX(t2.b+t1.a) < 10));
|
||||
a b c
|
||||
SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b))
|
||||
AS test FROM t1 GROUP BY a;
|
||||
a AVG(b) test
|
||||
1 4.0000 NULL
|
||||
2 2.0000 k
|
||||
3 2.5000 NULL
|
||||
SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;
|
||||
a b c
|
||||
1 3 c
|
||||
|
|
|
|||
|
|
@ -475,3 +475,13 @@ ALTER TABLE t1 MODIFY a VARCHAR(30) character set utf8 collate utf8_turkish_ci;
|
|||
SELECT a, length(a) la, @l:=lower(a) l, length(@l) ll, @u:=upper(a) u, length(@u) lu
|
||||
FROM t1 ORDER BY id;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #27079 Crash while grouping empty ucs2 strings
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
c1 text character set ucs2 collate ucs2_polish_ci NOT NULL
|
||||
) ENGINE=MyISAM;
|
||||
insert into t1 values (''),('a');
|
||||
SELECT COUNT(*), c1 FROM t1 GROUP BY c1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
|
|
|||
|
|
@ -572,6 +572,20 @@ select utext from t1 where utext like '%%';
|
|||
drop table t1;
|
||||
deallocate prepare stmt;
|
||||
|
||||
#
|
||||
# Bug#22638 SOUNDEX broken for international characters
|
||||
#
|
||||
set names latin1;
|
||||
set character_set_connection=ucs2;
|
||||
select soundex(''),soundex('he'),soundex('hello all folks'),soundex('#3556 in bugdb');
|
||||
select hex(soundex('')),hex(soundex('he')),hex(soundex('hello all folks')),hex(soundex('#3556 in bugdb'));
|
||||
select 'mood' sounds like 'mud';
|
||||
# Cyrillic A, BE, VE
|
||||
select hex(soundex(_ucs2 0x041004110412));
|
||||
# Make sure that "U+00BF INVERTED QUESTION MARK" is not considered as letter
|
||||
select hex(soundex(_ucs2 0x00BF00C0));
|
||||
set names latin1;
|
||||
|
||||
#
|
||||
# Bug #14290: character_maximum_length for text fields
|
||||
#
|
||||
|
|
|
|||
|
|
@ -702,6 +702,14 @@ select * from t1 where soundex(a) = soundex('TEST');
|
|||
select * from t1 where soundex(a) = soundex('test');
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#22638 SOUNDEX broken for international characters
|
||||
#
|
||||
select soundex(_utf8 0xE99885E8A788E99A8FE697B6E69BB4E696B0E79A84E696B0E997BB);
|
||||
select hex(soundex(_utf8 0xE99885E8A788E99A8FE697B6E69BB4E696B0E79A84E696B0E997BB));
|
||||
select soundex(_utf8 0xD091D092D093);
|
||||
select hex(soundex(_utf8 0xD091D092D093));
|
||||
|
||||
|
||||
SET collation_connection='utf8_general_ci';
|
||||
-- source include/ctype_filesort.inc
|
||||
|
|
|
|||
|
|
@ -203,3 +203,21 @@ select * from t1 where a is null;
|
|||
delete from t1 where a is null;
|
||||
select count(*) from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #26186: delete order by, sometimes accept unknown column
|
||||
#
|
||||
CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1);
|
||||
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
DELETE FROM t1 ORDER BY x;
|
||||
|
||||
# even columns from a table not used in query (and not even existing)
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
DELETE FROM t1 ORDER BY t2.x;
|
||||
|
||||
# subquery (as long as the subquery from is valid or DUAL)
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
DELETE FROM t1 ORDER BY (SELECT x);
|
||||
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -497,4 +497,14 @@ select f2,group_concat(f1) from t1 group by f2;
|
|||
--disable_metadata
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
#
|
||||
# Bug #26815: Unexpected built-in function behavior: group_concat(distinct
|
||||
# substring_index())
|
||||
#
|
||||
CREATE TABLE t1(a TEXT, b CHAR(20));
|
||||
INSERT INTO t1 VALUES ("one.1","one.1"),("two.2","two.2"),("one.3","one.3");
|
||||
SELECT GROUP_CONCAT(DISTINCT UCASE(a)) FROM t1;
|
||||
SELECT GROUP_CONCAT(DISTINCT UCASE(b)) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
|
|
|||
|
|
@ -423,6 +423,14 @@ from t1;
|
|||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #27164: Crash when mixing InnoDB and MyISAM Geospatial tables
|
||||
#
|
||||
CREATE TABLE t1(a POINT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
||||
#
|
||||
|
|
@ -471,3 +479,14 @@ create table t1 (g geometry not null);
|
|||
insert into t1 values(default);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #27300: create view with geometry functions lost columns types
|
||||
#
|
||||
CREATE TABLE t1 (a GEOMETRY);
|
||||
CREATE VIEW v1 AS SELECT GeomFromwkb(ASBINARY(a)) FROM t1;
|
||||
CREATE VIEW v2 AS SELECT a FROM t1;
|
||||
DESCRIBE v1;
|
||||
DESCRIBE v2;
|
||||
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -958,4 +958,148 @@ DROP DATABASE mysqltest4;
|
|||
DROP USER mysqltest_1@localhost;
|
||||
|
||||
|
||||
#
|
||||
# BUG#27337: Privileges are not restored properly.
|
||||
#
|
||||
# Actually, the patch for this bugs fixes two problems. So, here are two test
|
||||
# cases.
|
||||
|
||||
# Test case 1: privileges are not restored properly after calling a stored
|
||||
# routine defined with SQL SECURITY INVOKER clause.
|
||||
|
||||
# Prepare.
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS mysqltest1;
|
||||
DROP DATABASE IF EXISTS mysqltest2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE DATABASE mysqltest1;
|
||||
CREATE DATABASE mysqltest2;
|
||||
|
||||
GRANT ALL PRIVILEGES ON mysqltest1.* TO mysqltest_1@localhost;
|
||||
GRANT SELECT ON mysqltest2.* TO mysqltest_1@localhost;
|
||||
|
||||
CREATE PROCEDURE mysqltest1.p1() SQL SECURITY INVOKER
|
||||
SELECT 1;
|
||||
|
||||
# Test.
|
||||
|
||||
--connect (bug27337_con1,localhost,mysqltest_1,,mysqltest2)
|
||||
--echo
|
||||
--echo ---> connection: bug27337_con1
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
CREATE TABLE t1(c INT);
|
||||
|
||||
CALL mysqltest1.p1();
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
CREATE TABLE t1(c INT);
|
||||
|
||||
--disconnect bug27337_con1
|
||||
|
||||
--connect (bug27337_con2,localhost,mysqltest_1,,mysqltest2)
|
||||
--echo
|
||||
--echo ---> connection: bug27337_con2
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
CREATE TABLE t1(c INT);
|
||||
|
||||
SHOW TABLES;
|
||||
|
||||
# Cleanup.
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
--disconnect bug27337_con2
|
||||
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP DATABASE mysqltest2;
|
||||
|
||||
DROP USER mysqltest_1@localhost;
|
||||
|
||||
# Test case 2: priveleges are not checked properly for prepared statements.
|
||||
|
||||
# Prepare.
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS mysqltest1;
|
||||
DROP DATABASE IF EXISTS mysqltest2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE DATABASE mysqltest1;
|
||||
CREATE DATABASE mysqltest2;
|
||||
|
||||
CREATE TABLE mysqltest1.t1(c INT);
|
||||
CREATE TABLE mysqltest2.t2(c INT);
|
||||
|
||||
GRANT SELECT ON mysqltest1.t1 TO mysqltest_1@localhost;
|
||||
GRANT SELECT ON mysqltest2.t2 TO mysqltest_2@localhost;
|
||||
|
||||
# Test.
|
||||
|
||||
--connect (bug27337_con1,localhost,mysqltest_1,,mysqltest1)
|
||||
--echo
|
||||
--echo ---> connection: bug27337_con1
|
||||
|
||||
SHOW TABLES FROM mysqltest1;
|
||||
|
||||
PREPARE stmt1 FROM 'SHOW TABLES FROM mysqltest1';
|
||||
|
||||
EXECUTE stmt1;
|
||||
|
||||
--connect (bug27337_con2,localhost,mysqltest_2,,mysqltest2)
|
||||
--echo
|
||||
--echo ---> connection: bug27337_con2
|
||||
|
||||
SHOW COLUMNS FROM mysqltest2.t2;
|
||||
|
||||
PREPARE stmt2 FROM 'SHOW COLUMNS FROM mysqltest2.t2';
|
||||
|
||||
EXECUTE stmt2;
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
REVOKE SELECT ON mysqltest1.t1 FROM mysqltest_1@localhost;
|
||||
REVOKE SELECT ON mysqltest2.t2 FROM mysqltest_2@localhost;
|
||||
|
||||
--connection bug27337_con1
|
||||
--echo
|
||||
--echo ---> connection: bug27337_con1
|
||||
|
||||
--error ER_DBACCESS_DENIED_ERROR
|
||||
SHOW TABLES FROM mysqltest1;
|
||||
|
||||
--error ER_DBACCESS_DENIED_ERROR
|
||||
EXECUTE stmt1;
|
||||
|
||||
--connection bug27337_con2
|
||||
--echo
|
||||
--echo ---> connection: bug27337_con2
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SHOW COLUMNS FROM mysqltest2.t2;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
EXECUTE stmt2;
|
||||
|
||||
# Cleanup.
|
||||
|
||||
--connection default
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
--disconnect bug27337_con2
|
||||
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP DATABASE mysqltest2;
|
||||
|
||||
DROP USER mysqltest_1@localhost;
|
||||
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
|
|
|||
|
|
@ -195,3 +195,55 @@ SELECT LAST_INSERT_ID();
|
|||
INSERT t1 (f2) VALUES ('test') ON DUPLICATE KEY UPDATE f1 = LAST_INSERT_ID(f1);
|
||||
SELECT LAST_INSERT_ID();
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#23233: 0 as LAST_INSERT_ID() after INSERT .. ON DUPLICATE in the
|
||||
# NO_AUTO_VALUE_ON_ZERO mode.
|
||||
#
|
||||
SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` varchar(10) NOT NULL UNIQUE
|
||||
);
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test1")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test1")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
SELECT * FROM t1;
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test2")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT * FROM t1;
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test2")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
SELECT * FROM t1;
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test3")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` varchar(10) NOT NULL UNIQUE
|
||||
);
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test1")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
SELECT * FROM t1;
|
||||
INSERT IGNORE INTO t1 (f1) VALUES ("test1"),("test4")
|
||||
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
|
||||
SELECT LAST_INSERT_ID();
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE `t1` (
|
||||
`id` int(11) PRIMARY KEY auto_increment,
|
||||
`f1` varchar(10) NOT NULL UNIQUE,
|
||||
tim1 timestamp default '2003-01-01 00:00:00' on update current_timestamp
|
||||
);
|
||||
INSERT INTO t1 (f1) VALUES ("test1");
|
||||
SELECT id, f1 FROM t1;
|
||||
REPLACE INTO t1 VALUES (0,"test1",null);
|
||||
SELECT id, f1 FROM t1;
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE='';
|
||||
|
|
|
|||
|
|
@ -568,6 +568,149 @@ SELECT s.oxid FROM t1 v, t1 s
|
|||
|
||||
DROP TABLE t1;
|
||||
|
||||
# BUG#26624 high mem usage (crash) in range optimizer (depends on order of fields in where)
|
||||
create table t1 (
|
||||
c1 char(10), c2 char(10), c3 char(10), c4 char(10),
|
||||
c5 char(10), c6 char(10), c7 char(10), c8 char(10),
|
||||
c9 char(10), c10 char(10), c11 char(10), c12 char(10),
|
||||
c13 char(10), c14 char(10), c15 char(10), c16 char(10),
|
||||
index(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12,c13,c14,c15,c16)
|
||||
);
|
||||
insert into t1 (c1) values ('1'),('1'),('1'),('1');
|
||||
|
||||
# This must run without crash and fast:
|
||||
select * from t1 where
|
||||
c1 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c2 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c3 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c4 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c5 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c6 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c7 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c8 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c9 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
|
||||
and c10 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
|
||||
"abcdefg1", "123456781", "qwertyui1", "asddfg1",
|
||||
"abcdefg2", "123456782", "qwertyui2", "asddfg2",
|
||||
"abcdefg3", "123456783", "qwertyui3", "asddfg3",
|
||||
"abcdefg4", "123456784", "qwertyui4", "asddfg4",
|
||||
"abcdefg5", "123456785", "qwertyui5", "asddfg5",
|
||||
"abcdefg6", "123456786", "qwertyui6", "asddfg6",
|
||||
"abcdefg7", "123456787", "qwertyui7", "asddfg7",
|
||||
"abcdefg8", "123456788", "qwertyui8", "asddfg8",
|
||||
"abcdefg9", "123456789", "qwertyui9", "asddfg9",
|
||||
"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
|
||||
"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
|
||||
"abcdefgC", "12345678C", "qwertyuiC", "asddfgC");
|
||||
drop table t1;
|
||||
--echo End of 4.1 tests
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -139,3 +139,20 @@ EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1);
|
|||
SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1);
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug #27154: crash (memory corruption) when using row equalities
|
||||
#
|
||||
|
||||
CREATE TABLE t1(
|
||||
a int, b int, c int, d int, e int, f int, g int, h int,
|
||||
PRIMARY KEY (a,b,c,d,e,f,g)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,2,3,4,5,6,7,99);
|
||||
|
||||
SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7);
|
||||
|
||||
SET @x:= (SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7));
|
||||
SELECT @x;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -28,10 +28,76 @@ create table t2 like t1;
|
|||
eval load data local infile '$MYSQLTEST_VARDIR/master-data/test/rpl_misc_functions.outfile' into table t2;
|
||||
# compare them with the replica; the SELECT below should return no row
|
||||
select * from t1, t2 where (t1.id=t2.id) and not(t1.i=t2.i and t1.r1=t2.r1 and t1.r2=t2.r2 and t1.p=t2.p);
|
||||
stop slave;
|
||||
drop table t1;
|
||||
|
||||
connection master;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# BUG#25543 test calling rand() multiple times on the master in
|
||||
# a stored procedure.
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (col_a double default NULL);
|
||||
|
||||
DELIMITER |;
|
||||
|
||||
# Use a SP that calls rand() multiple times
|
||||
CREATE PROCEDURE test_replication_sp1()
|
||||
BEGIN
|
||||
INSERT INTO t1 VALUES (rand()), (rand());
|
||||
INSERT INTO t1 VALUES (rand());
|
||||
END|
|
||||
|
||||
# Use a SP that calls another SP to call rand() multiple times
|
||||
CREATE PROCEDURE test_replication_sp2()
|
||||
BEGIN
|
||||
CALL test_replication_sp1();
|
||||
CALL test_replication_sp1();
|
||||
END|
|
||||
|
||||
# Use a SF that calls rand() multiple times
|
||||
CREATE FUNCTION test_replication_sf() RETURNS DOUBLE DETERMINISTIC
|
||||
BEGIN
|
||||
RETURN (rand() + rand());
|
||||
END|
|
||||
|
||||
DELIMITER ;|
|
||||
|
||||
# Exercise the functions and procedures then compare the results on
|
||||
# the master to those on the slave.
|
||||
CALL test_replication_sp1();
|
||||
CALL test_replication_sp2();
|
||||
INSERT INTO t1 VALUES (test_replication_sf());
|
||||
INSERT INTO t1 VALUES (test_replication_sf());
|
||||
INSERT INTO t1 VALUES (test_replication_sf());
|
||||
|
||||
# Record the results of the query on the master
|
||||
--exec $MYSQL --port=$MASTER_MYPORT test -e "SELECT * FROM test.t1" > $MYSQLTEST_VARDIR/tmp/rpl_rand_master.sql
|
||||
|
||||
--sync_slave_with_master
|
||||
|
||||
# Record the results of the query on the slave
|
||||
--exec $MYSQL --port=$SLAVE_MYPORT test -e "SELECT * FROM test.t1" > $MYSQLTEST_VARDIR/tmp/rpl_rand_slave.sql
|
||||
|
||||
# Compare the results from the master to the slave.
|
||||
--exec diff $MYSQLTEST_VARDIR/tmp/rpl_rand_master.sql $MYSQLTEST_VARDIR/tmp/rpl_rand_slave.sql
|
||||
|
||||
# Cleanup
|
||||
connection master;
|
||||
--disable_warnings
|
||||
DROP PROCEDURE IF EXISTS test_replication_sp1;
|
||||
DROP PROCEDURE IF EXISTS test_replication_sp2;
|
||||
DROP FUNCTION IF EXISTS test_replication_sf;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
--sync_slave_with_master
|
||||
|
||||
# If all is good, when can cleanup our dump files.
|
||||
--system rm $MYSQLTEST_VARDIR/tmp/rpl_rand_master.sql
|
||||
--system rm $MYSQLTEST_VARDIR/tmp/rpl_rand_slave.sql
|
||||
|
|
|
|||
|
|
@ -3111,6 +3111,8 @@ DROP TABLE t1,t2,t3;
|
|||
CREATE TABLE t1 (a INT, b INT, KEY (a)); INSERT INTO t1 VALUES (1,1),(2,2);
|
||||
EXPLAIN SELECT 1 FROM t1 WHERE a = 1;
|
||||
EXPLAIN SELECT 1 FROM t1 IGNORE INDEX FOR JOIN (a) WHERE a = 1;
|
||||
EXPLAIN SELECT 1 FROM t1 USE INDEX FOR JOIN (a) WHERE a = 1;
|
||||
EXPLAIN SELECT 1 FROM t1 FORCE INDEX FOR JOIN (a) WHERE a = 1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -2763,3 +2763,49 @@ SELECT COUNT(*), a
|
|||
HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug #27229: GROUP_CONCAT in subselect with COUNT() as an argument
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
CREATE TABLE t2 (m int, n int);
|
||||
INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
|
||||
INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
|
||||
|
||||
SELECT COUNT(*) c, a,
|
||||
(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
|
||||
FROM t1 GROUP BY a;
|
||||
|
||||
SELECT COUNT(*) c, a,
|
||||
(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
|
||||
FROM t1 GROUP BY a;
|
||||
|
||||
DROP table t1,t2;
|
||||
|
||||
#
|
||||
# Bug #27348: SET FUNCTION used in a subquery from WHERE condition
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a int, b int);
|
||||
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
|
||||
|
||||
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
|
||||
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
|
||||
|
||||
SELECT a FROM t1 t0
|
||||
WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
|
||||
|
||||
SET @@sql_mode='ansi';
|
||||
--error 1111
|
||||
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
|
||||
--error 1111
|
||||
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
|
||||
|
||||
--error 1111
|
||||
SELECT a FROM t1 t0
|
||||
WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
|
||||
|
||||
SET @@sql_mode=default;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
|
|
|||
|
|
@ -507,8 +507,9 @@ SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
|
|||
SELECT * FROM t1 GROUP by t1.a
|
||||
HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c
|
||||
HAVING MAX(t2.b+t1.a) < 10));
|
||||
SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b))
|
||||
AS test FROM t1 GROUP BY a;
|
||||
#FIXME: Enable this test after fixing bug #27321
|
||||
#SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b))
|
||||
# AS test FROM t1 GROUP BY a;
|
||||
|
||||
SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;
|
||||
|
||||
|
|
|
|||
|
|
@ -1284,7 +1284,7 @@ public:
|
|||
int store_decimal(const my_decimal *);
|
||||
void get_key_image(char *buff,uint length,imagetype type);
|
||||
uint size_of() const { return sizeof(*this); }
|
||||
int reset(void) { return !maybe_null(); }
|
||||
int reset(void) { return !maybe_null() || Field_blob::reset(); }
|
||||
};
|
||||
#endif /*HAVE_SPATIAL*/
|
||||
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
|
|||
if (field == field->table->next_number_field)
|
||||
{
|
||||
field->table->auto_increment_field_not_null= FALSE;
|
||||
return 0; // field is set in handler.cc
|
||||
return 0; // field is set in fill_record()
|
||||
}
|
||||
if (current_thd->count_cuted_fields == CHECK_FIELD_WARN)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1598,7 +1598,6 @@ int handler::update_auto_increment()
|
|||
ulonglong nr;
|
||||
THD *thd= table->in_use;
|
||||
struct system_variables *variables= &thd->variables;
|
||||
bool auto_increment_field_not_null;
|
||||
DBUG_ENTER("handler::update_auto_increment");
|
||||
|
||||
/*
|
||||
|
|
@ -1606,14 +1605,11 @@ int handler::update_auto_increment()
|
|||
row was not inserted
|
||||
*/
|
||||
thd->prev_insert_id= thd->next_insert_id;
|
||||
auto_increment_field_not_null= table->auto_increment_field_not_null;
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
|
||||
if ((nr= table->next_number_field->val_int()) != 0 ||
|
||||
auto_increment_field_not_null &&
|
||||
table->auto_increment_field_not_null &&
|
||||
thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)
|
||||
{
|
||||
/* Clear flag for next row */
|
||||
/* Mark that we didn't generate a new value **/
|
||||
auto_increment_column_changed=0;
|
||||
adjust_next_insert_id_after_explicit_value(nr);
|
||||
|
|
|
|||
14
sql/item.cc
14
sql/item.cc
|
|
@ -1261,15 +1261,18 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
|
|||
Exception is Item_direct_view_ref which we need to convert to
|
||||
Item_ref to allow fields from view being stored in tmp table.
|
||||
*/
|
||||
Item_aggregate_ref *item_ref;
|
||||
uint el= fields.elements;
|
||||
Item *new_item, *real_itm= real_item();
|
||||
Item *real_itm= real_item();
|
||||
|
||||
ref_pointer_array[el]= real_itm;
|
||||
if (!(new_item= new Item_aggregate_ref(&thd->lex->current_select->context,
|
||||
if (!(item_ref= new Item_aggregate_ref(&thd->lex->current_select->context,
|
||||
ref_pointer_array + el, 0, name)))
|
||||
return; // fatal_error is set
|
||||
if (type() == SUM_FUNC_ITEM)
|
||||
item_ref->depended_from= ((Item_sum *) this)->depended_from();
|
||||
fields.push_front(real_itm);
|
||||
thd->change_item_tree(ref, new_item);
|
||||
thd->change_item_tree(ref, item_ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4272,7 +4275,6 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
|
|||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
if (this->type() == Item::TYPE_HOLDER)
|
||||
return new Field_blob(max_length, maybe_null, name, table,
|
||||
collation.collation, 1);
|
||||
|
|
@ -4280,6 +4282,10 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
|
|||
return new Field_blob(max_length, maybe_null, name, table,
|
||||
collation.collation);
|
||||
break; // Blob handled outside of case
|
||||
case MYSQL_TYPE_GEOMETRY:
|
||||
return new Field_geom(max_length, maybe_null, name, table,
|
||||
(Field::geometry_type)
|
||||
((Item_geometry_func *)this)->get_geometry_type());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1805,7 +1805,8 @@ void Item_func_soundex::fix_length_and_dec()
|
|||
{
|
||||
collation.set(args[0]->collation);
|
||||
max_length=args[0]->max_length;
|
||||
set_if_bigger(max_length,4);
|
||||
set_if_bigger(max_length, 4 * collation.collation->mbminlen);
|
||||
tmp_value.set_charset(collation.collation);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1815,14 +1816,15 @@ void Item_func_soundex::fix_length_and_dec()
|
|||
else return 0
|
||||
*/
|
||||
|
||||
static char soundex_toupper(char ch)
|
||||
static int soundex_toupper(int ch)
|
||||
{
|
||||
return (ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch;
|
||||
}
|
||||
|
||||
static char get_scode(char *ptr)
|
||||
|
||||
static char get_scode(int wc)
|
||||
{
|
||||
uchar ch= soundex_toupper(*ptr);
|
||||
int ch= soundex_toupper(wc);
|
||||
if (ch < 'A' || ch > 'Z')
|
||||
{
|
||||
// Thread extended alfa (country spec)
|
||||
|
|
@ -1832,46 +1834,121 @@ static char get_scode(char *ptr)
|
|||
}
|
||||
|
||||
|
||||
static bool my_uni_isalpha(int wc)
|
||||
{
|
||||
/*
|
||||
Return true for all Basic Latin letters: a..z A..Z.
|
||||
Return true for all Unicode characters with code higher than U+00C0:
|
||||
- characters between 'z' and U+00C0 are controls and punctuations.
|
||||
- "U+00C0 LATIN CAPITAL LETTER A WITH GRAVE" is the first letter after 'z'.
|
||||
*/
|
||||
return (wc >= 'a' && wc <= 'z') ||
|
||||
(wc >= 'A' && wc <= 'Z') ||
|
||||
(wc >= 0xC0);
|
||||
}
|
||||
|
||||
|
||||
String *Item_func_soundex::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String *res =args[0]->val_str(str);
|
||||
char last_ch,ch;
|
||||
CHARSET_INFO *cs= collation.collation;
|
||||
my_wc_t wc;
|
||||
uint nchars;
|
||||
int rc;
|
||||
|
||||
if ((null_value=args[0]->null_value))
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0; /* purecov: inspected */
|
||||
|
||||
if (tmp_value.alloc(max(res->length(),4)))
|
||||
if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
|
||||
return str; /* purecov: inspected */
|
||||
char *to= (char *) tmp_value.ptr();
|
||||
char *from= (char *) res->ptr(), *end=from+res->length();
|
||||
tmp_value.set_charset(cs);
|
||||
char *to_end= to + tmp_value.alloced_length();
|
||||
char *from= (char *) res->ptr(), *end= from + res->length();
|
||||
|
||||
while (from != end && !my_isalpha(cs,*from)) // Skip pre-space
|
||||
from++; /* purecov: inspected */
|
||||
if (from == end)
|
||||
return &my_empty_string; // No alpha characters.
|
||||
*to++ = soundex_toupper(*from); // Copy first letter
|
||||
last_ch = get_scode(from); // code of the first letter
|
||||
// for the first 'double-letter check.
|
||||
// Loop on input letters until
|
||||
// end of input (null) or output
|
||||
// letter code count = 3
|
||||
for (from++ ; from < end ; from++)
|
||||
for ( ; ; ) /* Skip pre-space */
|
||||
{
|
||||
if (!my_isalpha(cs,*from))
|
||||
continue;
|
||||
ch=get_scode(from);
|
||||
if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
|
||||
return &my_empty_string; /* EOL or invalid byte sequence */
|
||||
|
||||
if (rc == 1 && cs->ctype)
|
||||
{
|
||||
/* Single byte letter found */
|
||||
if (my_isalpha(cs, *from))
|
||||
{
|
||||
last_ch= get_scode(*from); // Code of the first letter
|
||||
*to++= soundex_toupper(*from++); // Copy first letter
|
||||
break;
|
||||
}
|
||||
from++;
|
||||
}
|
||||
else
|
||||
{
|
||||
from+= rc;
|
||||
if (my_uni_isalpha(wc))
|
||||
{
|
||||
/* Multibyte letter found */
|
||||
wc= soundex_toupper(wc);
|
||||
last_ch= get_scode(wc); // Code of the first letter
|
||||
if ((rc= cs->cset->wc_mb(cs, wc, (uchar*) to, (uchar*) to_end)) <= 0)
|
||||
{
|
||||
/* Extra safety - should not really happen */
|
||||
DBUG_ASSERT(false);
|
||||
return &my_empty_string;
|
||||
}
|
||||
to+= rc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
last_ch is now set to the first 'double-letter' check.
|
||||
loop on input letters until end of input
|
||||
*/
|
||||
for (nchars= 1 ; ; )
|
||||
{
|
||||
if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
|
||||
break; /* EOL or invalid byte sequence */
|
||||
|
||||
if (rc == 1 && cs->ctype)
|
||||
{
|
||||
if (!my_isalpha(cs, *from++))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
from+= rc;
|
||||
if (!my_uni_isalpha(wc))
|
||||
continue;
|
||||
}
|
||||
|
||||
ch= get_scode(wc);
|
||||
if ((ch != '0') && (ch != last_ch)) // if not skipped or double
|
||||
{
|
||||
*to++ = ch; // letter, copy to output
|
||||
last_ch = ch; // save code of last input letter
|
||||
} // for next double-letter check
|
||||
// letter, copy to output
|
||||
if ((rc= cs->cset->wc_mb(cs, (my_wc_t) ch,
|
||||
(uchar*) to, (uchar*) to_end)) <= 0)
|
||||
{
|
||||
// Extra safety - should not really happen
|
||||
DBUG_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
to+= rc;
|
||||
nchars++;
|
||||
last_ch= ch; // save code of last input letter
|
||||
} // for next double-letter check
|
||||
}
|
||||
for (end=(char*) tmp_value.ptr()+4 ; to < end ; to++)
|
||||
*to = '0';
|
||||
*to=0; // end string
|
||||
|
||||
/* Pad up to 4 characters with DIGIT ZERO, if the string is shorter */
|
||||
if (nchars < 4)
|
||||
{
|
||||
uint nbytes= (4 - nchars) * cs->mbminlen;
|
||||
cs->cset->fill(cs, to, nbytes, '0');
|
||||
to+= nbytes;
|
||||
}
|
||||
|
||||
tmp_value.length((uint) (to-tmp_value.ptr()));
|
||||
return &tmp_value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||
/* Save a pointer to object to be used in items for nested set functions */
|
||||
thd->lex->in_sum_func= this;
|
||||
nest_level= thd->lex->current_select->nest_level;
|
||||
nest_level_tables_count= thd->lex->current_select->join->tables;
|
||||
ref_by= 0;
|
||||
aggr_level= -1;
|
||||
aggr_sel= NULL;
|
||||
max_arg_level= -1;
|
||||
max_sum_func_level= -1;
|
||||
return FALSE;
|
||||
|
|
@ -149,9 +149,14 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||
if (register_sum_func(thd, ref))
|
||||
return TRUE;
|
||||
invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
|
||||
if (!invalid && thd->variables.sql_mode & MODE_ANSI)
|
||||
invalid= aggr_level < 0 && max_arg_level < nest_level;
|
||||
}
|
||||
if (!invalid && aggr_level < 0)
|
||||
{
|
||||
aggr_level= nest_level;
|
||||
aggr_sel= thd->lex->current_select;
|
||||
}
|
||||
/*
|
||||
By this moment we either found a subquery where the set function is
|
||||
to be aggregated and assigned a value that is >= 0 to aggr_level,
|
||||
|
|
@ -161,8 +166,9 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||
Additionally we have to check whether possible nested set functions
|
||||
are acceptable here: they are not, if the level of aggregation of
|
||||
some of them is less than aggr_level.
|
||||
*/
|
||||
invalid= aggr_level <= max_sum_func_level;
|
||||
*/
|
||||
if (!invalid)
|
||||
invalid= aggr_level <= max_sum_func_level;
|
||||
if (invalid)
|
||||
{
|
||||
my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE),
|
||||
|
|
@ -212,7 +218,6 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||
bool Item_sum::register_sum_func(THD *thd, Item **ref)
|
||||
{
|
||||
SELECT_LEX *sl;
|
||||
SELECT_LEX *aggr_sl= NULL;
|
||||
nesting_map allow_sum_func= thd->lex->allow_sum_func;
|
||||
for (sl= thd->lex->current_select->master_unit()->outer_select() ;
|
||||
sl && sl->nest_level > max_arg_level;
|
||||
|
|
@ -222,7 +227,7 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
|
|||
{
|
||||
/* Found the most nested subquery where the function can be aggregated */
|
||||
aggr_level= sl->nest_level;
|
||||
aggr_sl= sl;
|
||||
aggr_sel= sl;
|
||||
}
|
||||
}
|
||||
if (sl && (allow_sum_func & (1 << sl->nest_level)))
|
||||
|
|
@ -233,21 +238,22 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
|
|||
The set function will be aggregated in this subquery.
|
||||
*/
|
||||
aggr_level= sl->nest_level;
|
||||
aggr_sl= sl;
|
||||
aggr_sel= sl;
|
||||
|
||||
}
|
||||
if (aggr_level >= 0)
|
||||
{
|
||||
ref_by= ref;
|
||||
/* Add the object to the list of registered objects assigned to aggr_sl */
|
||||
if (!aggr_sl->inner_sum_func_list)
|
||||
/* Add the object to the list of registered objects assigned to aggr_sel */
|
||||
if (!aggr_sel->inner_sum_func_list)
|
||||
next= this;
|
||||
else
|
||||
{
|
||||
next= aggr_sl->inner_sum_func_list->next;
|
||||
aggr_sl->inner_sum_func_list->next= this;
|
||||
next= aggr_sel->inner_sum_func_list->next;
|
||||
aggr_sel->inner_sum_func_list->next= this;
|
||||
}
|
||||
aggr_sl->inner_sum_func_list= this;
|
||||
aggr_sl->with_sum_func= 1;
|
||||
aggr_sel->inner_sum_func_list= this;
|
||||
aggr_sel->with_sum_func= 1;
|
||||
|
||||
/*
|
||||
Mark Item_subselect(s) as containing aggregate function all the way up
|
||||
|
|
@ -265,11 +271,11 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
|
|||
has aggregate functions directly referenced (i.e. not through a sub-select).
|
||||
*/
|
||||
for (sl= thd->lex->current_select;
|
||||
sl && sl != aggr_sl && sl->master_unit()->item;
|
||||
sl && sl != aggr_sel && sl->master_unit()->item;
|
||||
sl= sl->master_unit()->outer_select() )
|
||||
sl->master_unit()->item->with_sum_func= 1;
|
||||
}
|
||||
thd->lex->current_select->mark_as_dependent(aggr_sl);
|
||||
thd->lex->current_select->mark_as_dependent(aggr_sel);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -299,10 +305,10 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
|
|||
|
||||
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||
Item_result_field(thd, item), arg_count(item->arg_count),
|
||||
aggr_sel(item->aggr_sel),
|
||||
nest_level(item->nest_level), aggr_level(item->aggr_level),
|
||||
quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
|
||||
forced_const(item->forced_const),
|
||||
nest_level_tables_count(item->nest_level_tables_count)
|
||||
forced_const(item->forced_const)
|
||||
{
|
||||
if (arg_count <= 2)
|
||||
args=tmp_args;
|
||||
|
|
@ -414,8 +420,7 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
|
|||
2-byte lenght.
|
||||
*/
|
||||
if (max_length/collation.collation->mbmaxlen > 255 &&
|
||||
max_length/collation.collation->mbmaxlen < UINT_MAX16 &&
|
||||
convert_blob_length)
|
||||
convert_blob_length < UINT_MAX16 && convert_blob_length)
|
||||
return new Field_varstring(convert_blob_length, maybe_null,
|
||||
name, table,
|
||||
collation.collation);
|
||||
|
|
@ -446,8 +451,7 @@ void Item_sum::update_used_tables ()
|
|||
used_tables_cache&= PSEUDO_TABLE_BITS;
|
||||
|
||||
/* the aggregate function is aggregated into its local context */
|
||||
if (aggr_level == nest_level)
|
||||
used_tables_cache |= (1 << nest_level_tables_count) - 1;
|
||||
used_tables_cache |= (1 << aggr_sel->join->tables) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ public:
|
|||
Item_sum *next; /* next in the circular chain of registered objects */
|
||||
uint arg_count;
|
||||
Item_sum *in_sum_func; /* embedding set function if any */
|
||||
st_select_lex * aggr_sel; /* select where the function is aggregated */
|
||||
int8 nest_level; /* number of the nesting level of the set function */
|
||||
int8 aggr_level; /* nesting level of the aggregating subquery */
|
||||
int8 max_arg_level; /* max level of unbound column references */
|
||||
|
|
@ -242,7 +243,6 @@ public:
|
|||
protected:
|
||||
table_map used_tables_cache;
|
||||
bool forced_const;
|
||||
byte nest_level_tables_count;
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -365,6 +365,8 @@ public:
|
|||
bool init_sum_func_check(THD *thd);
|
||||
bool check_sum_func(THD *thd, Item **ref);
|
||||
bool register_sum_func(THD *thd, Item **ref);
|
||||
st_select_lex *depended_from()
|
||||
{ return (nest_level == aggr_level ? 0 : aggr_sel); }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
|||
goto end;
|
||||
|
||||
/* A temporary table does not have locks. */
|
||||
if (table->s->tmp_table == TMP_TABLE)
|
||||
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
|
||||
goto end;
|
||||
|
||||
/* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
|
||||
|
|
@ -569,7 +569,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
|||
if (haystack->placeholder())
|
||||
continue;
|
||||
table2= haystack->table;
|
||||
if (table2->s->tmp_table == TMP_TABLE)
|
||||
if (table2->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
|
||||
continue;
|
||||
|
||||
/* All tables in list must be in lock. */
|
||||
|
|
@ -655,7 +655,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
|||
*write_lock_used=0;
|
||||
for (i=tables=lock_count=0 ; i < count ; i++)
|
||||
{
|
||||
if (table_ptr[i]->s->tmp_table != TMP_TABLE)
|
||||
if (table_ptr[i]->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
|
||||
{
|
||||
tables+=table_ptr[i]->file->lock_count();
|
||||
lock_count++;
|
||||
|
|
@ -697,7 +697,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
|||
TABLE *table;
|
||||
enum thr_lock_type lock_type;
|
||||
|
||||
if ((table=table_ptr[i])->s->tmp_table == TMP_TABLE)
|
||||
if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
|
||||
continue;
|
||||
lock_type= table->reginfo.lock_type;
|
||||
if (lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||
|
|
|
|||
|
|
@ -955,6 +955,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
|
|||
int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
|
||||
bool get_schema_tables_result(JOIN *join,
|
||||
enum enum_schema_table_state executed_place);
|
||||
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table);
|
||||
|
||||
#define is_schema_db(X) \
|
||||
!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, (X))
|
||||
|
||||
|
|
|
|||
|
|
@ -6125,12 +6125,12 @@ The minimum value for this variable is 4096.",
|
|||
(gptr*) &max_system_variables.tmp_table_size, 0, GET_ULL,
|
||||
REQUIRED_ARG, 32*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
|
||||
{"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
|
||||
"Allocation block size for transactions to be stored in binary log",
|
||||
"Allocation block size for various transaction-related structures",
|
||||
(gptr*) &global_system_variables.trans_alloc_block_size,
|
||||
(gptr*) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
|
||||
REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
|
||||
{"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
|
||||
"Persistent buffer for transactions to be stored in binary log",
|
||||
"Persistent buffer for various transaction-related structures",
|
||||
(gptr*) &global_system_variables.trans_prealloc_size,
|
||||
(gptr*) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
|
||||
REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0},
|
||||
|
|
|
|||
|
|
@ -1,161 +0,0 @@
|
|||
***************
|
||||
*** 177,188 ****
|
||||
} /* cplusplus */
|
||||
|
||||
|
||||
- #if defined(HAVE_LINUXTHREADS)
|
||||
- #define THR_KILL_SIGNAL SIGINT
|
||||
- #else
|
||||
- #define THR_KILL_SIGNAL SIGUSR2 // Can't use this with LinuxThreads
|
||||
- #endif
|
||||
-
|
||||
#ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
--- 177,182 ----
|
||||
} /* cplusplus */
|
||||
|
||||
|
||||
#ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
***************
|
||||
*** 505,510 ****
|
||||
static void clean_up_mutexes(void);
|
||||
static int test_if_case_insensitive(const char *dir_name);
|
||||
static void create_pid_file();
|
||||
|
||||
/****************************************************************************
|
||||
** Code to end mysqld
|
||||
--- 499,505 ----
|
||||
static void clean_up_mutexes(void);
|
||||
static int test_if_case_insensitive(const char *dir_name);
|
||||
static void create_pid_file();
|
||||
+ static uint get_thread_lib(void);
|
||||
|
||||
/****************************************************************************
|
||||
** Code to end mysqld
|
||||
***************
|
||||
*** 544,550 ****
|
||||
DBUG_PRINT("info",("Waiting for select_thread"));
|
||||
|
||||
#ifndef DONT_USE_THR_ALARM
|
||||
! if (pthread_kill(select_thread,THR_CLIENT_ALARM))
|
||||
break; // allready dead
|
||||
#endif
|
||||
set_timespec(abstime, 2);
|
||||
--- 539,546 ----
|
||||
DBUG_PRINT("info",("Waiting for select_thread"));
|
||||
|
||||
#ifndef DONT_USE_THR_ALARM
|
||||
! if (pthread_kill(select_thread,
|
||||
! thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1))
|
||||
break; // allready dead
|
||||
#endif
|
||||
set_timespec(abstime, 2);
|
||||
***************
|
||||
*** 844,850 ****
|
||||
sig,my_thread_id());
|
||||
}
|
||||
#ifdef DONT_REMEMBER_SIGNAL
|
||||
! sigset(sig,print_signal_warning); /* int. thread system calls */
|
||||
#endif
|
||||
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
|
||||
if (sig == SIGALRM)
|
||||
--- 840,846 ----
|
||||
sig,my_thread_id());
|
||||
}
|
||||
#ifdef DONT_REMEMBER_SIGNAL
|
||||
! my_sigset(sig, print_signal_warning); /* int. thread system calls */
|
||||
#endif
|
||||
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
|
||||
if (sig == SIGALRM)
|
||||
***************
|
||||
*** 1841,1848 ****
|
||||
DBUG_ENTER("init_signals");
|
||||
|
||||
if (test_flags & TEST_SIGINT)
|
||||
! sigset(THR_KILL_SIGNAL,end_thread_signal);
|
||||
! sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
|
||||
|
||||
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
|
||||
{
|
||||
--- 1837,1847 ----
|
||||
DBUG_ENTER("init_signals");
|
||||
|
||||
if (test_flags & TEST_SIGINT)
|
||||
! {
|
||||
! my_sigset(thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2,
|
||||
! end_thread_signal);
|
||||
! }
|
||||
! my_sigset(THR_SERVER_ALARM, print_signal_warning); // Should never be called!
|
||||
|
||||
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
|
||||
{
|
||||
***************
|
||||
*** 1877,1883 ****
|
||||
#endif
|
||||
(void) sigemptyset(&set);
|
||||
#ifdef THREAD_SPECIFIC_SIGPIPE
|
||||
! sigset(SIGPIPE,abort_thread);
|
||||
sigaddset(&set,SIGPIPE);
|
||||
#else
|
||||
(void) signal(SIGPIPE,SIG_IGN); // Can't know which thread
|
||||
--- 1876,1882 ----
|
||||
#endif
|
||||
(void) sigemptyset(&set);
|
||||
#ifdef THREAD_SPECIFIC_SIGPIPE
|
||||
! my_sigset(SIGPIPE, abort_thread);
|
||||
sigaddset(&set,SIGPIPE);
|
||||
#else
|
||||
(void) signal(SIGPIPE,SIG_IGN); // Can't know which thread
|
||||
***************
|
||||
*** 2237,2244 ****
|
||||
MY_INIT(argv[0]); // init my_sys library & pthreads
|
||||
tzset(); // Set tzname
|
||||
|
||||
start_time=time((time_t*) 0);
|
||||
-
|
||||
#ifdef OS2
|
||||
{
|
||||
// fix timezone for daylight saving
|
||||
--- 2236,2243 ----
|
||||
MY_INIT(argv[0]); // init my_sys library & pthreads
|
||||
tzset(); // Set tzname
|
||||
|
||||
+ thd_lib_detected= get_thread_lib();
|
||||
start_time=time((time_t*) 0);
|
||||
#ifdef OS2
|
||||
{
|
||||
// fix timezone for daylight saving
|
||||
***************
|
||||
*** 5547,5552 ****
|
||||
(void) my_write(file, (byte*) buff, (uint) (end-buff),MYF(MY_WME));
|
||||
(void) my_close(file, MYF(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
--- 5546,5567 ----
|
||||
(void) my_write(file, (byte*) buff, (uint) (end-buff),MYF(MY_WME));
|
||||
(void) my_close(file, MYF(0));
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ static uint get_thread_lib(void)
|
||||
+ {
|
||||
+ char buff[64];
|
||||
+
|
||||
+ #ifdef _CS_GNU_LIBPTHREAD_VERSION
|
||||
+ confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
|
||||
+
|
||||
+ if (!strncasecmp(buff, "NPTL", 4))
|
||||
+ return THD_LIB_NPTL;
|
||||
+ else if (!strncasecmp(buff, "linuxthreads", 12))
|
||||
+ return THD_LIB_LT;
|
||||
+ #endif
|
||||
+ return THD_LIB_OTHER;
|
||||
}
|
||||
|
||||
|
||||
170
sql/opt_range.cc
170
sql/opt_range.cc
|
|
@ -144,6 +144,89 @@ static char is_null_string[2]= {1,0};
|
|||
- get_quick_select() - Walk the SEL_ARG, materialize the key intervals,
|
||||
and create QUICK_RANGE_SELECT object that will
|
||||
read records within these intervals.
|
||||
|
||||
4. SPACE COMPLEXITY NOTES
|
||||
|
||||
SEL_ARG graph is a representation of an ordered disjoint sequence of
|
||||
intervals over the ordered set of index tuple values.
|
||||
|
||||
For multi-part keys, one can construct a WHERE expression such that its
|
||||
list of intervals will be of combinatorial size. Here is an example:
|
||||
|
||||
(keypart1 IN (1,2, ..., n1)) AND
|
||||
(keypart2 IN (1,2, ..., n2)) AND
|
||||
(keypart3 IN (1,2, ..., n3))
|
||||
|
||||
For this WHERE clause the list of intervals will have n1*n2*n3 intervals
|
||||
of form
|
||||
|
||||
(keypart1, keypart2, keypart3) = (k1, k2, k3), where 1 <= k{i} <= n{i}
|
||||
|
||||
SEL_ARG graph structure aims to reduce the amount of required space by
|
||||
"sharing" the elementary intervals when possible (the pic at the
|
||||
beginning of this comment has examples of such sharing). The sharing may
|
||||
prevent combinatorial blowup:
|
||||
|
||||
There are WHERE clauses that have combinatorial-size interval lists but
|
||||
will be represented by a compact SEL_ARG graph.
|
||||
Example:
|
||||
(keypartN IN (1,2, ..., n1)) AND
|
||||
...
|
||||
(keypart2 IN (1,2, ..., n2)) AND
|
||||
(keypart1 IN (1,2, ..., n3))
|
||||
|
||||
but not in all cases:
|
||||
|
||||
- There are WHERE clauses that do have a compact SEL_ARG-graph
|
||||
representation but get_mm_tree() and its callees will construct a
|
||||
graph of combinatorial size.
|
||||
Example:
|
||||
(keypart1 IN (1,2, ..., n1)) AND
|
||||
(keypart2 IN (1,2, ..., n2)) AND
|
||||
...
|
||||
(keypartN IN (1,2, ..., n3))
|
||||
|
||||
- There are WHERE clauses for which the minimal possible SEL_ARG graph
|
||||
representation will have combinatorial size.
|
||||
Example:
|
||||
By induction: Let's take any interval on some keypart in the middle:
|
||||
|
||||
kp15=c0
|
||||
|
||||
Then let's AND it with this interval 'structure' from preceding and
|
||||
following keyparts:
|
||||
|
||||
(kp14=c1 AND kp16=c3) OR keypart14=c2) (*)
|
||||
|
||||
We will obtain this SEL_ARG graph:
|
||||
|
||||
kp14 $ kp15 $ kp16
|
||||
$ $
|
||||
+---------+ $ +---------+ $ +---------+
|
||||
| kp14=c1 |--$-->| kp15=c0 |--$-->| kp16=c3 |
|
||||
+---------+ $ +---------+ $ +---------+
|
||||
| $ $
|
||||
+---------+ $ +---------+ $
|
||||
| kp14=c2 |--$-->| kp15=c0 | $
|
||||
+---------+ $ +---------+ $
|
||||
$ $
|
||||
|
||||
Note that we had to duplicate "kp15=c0" and there was no way to avoid
|
||||
that.
|
||||
The induction step: AND the obtained expression with another "wrapping"
|
||||
expression like (*).
|
||||
When the process ends because of the limit on max. number of keyparts
|
||||
we'll have:
|
||||
|
||||
WHERE clause length is O(3*#max_keyparts)
|
||||
SEL_ARG graph size is O(2^(#max_keyparts/2))
|
||||
|
||||
(it is also possible to construct a case where instead of 2 in 2^n we
|
||||
have a bigger constant, e.g. 4, and get a graph with 4^(31/2)= 2^31
|
||||
nodes)
|
||||
|
||||
We avoid consuming too much memory by setting a limit on the number of
|
||||
SEL_ARG object we can construct during one range analysis invocation.
|
||||
*/
|
||||
|
||||
class SEL_ARG :public Sql_alloc
|
||||
|
|
@ -174,6 +257,8 @@ public:
|
|||
enum leaf_color { BLACK,RED } color;
|
||||
enum Type { IMPOSSIBLE, MAYBE, MAYBE_KEY, KEY_RANGE } type;
|
||||
|
||||
enum { MAX_SEL_ARGS = 16000 };
|
||||
|
||||
SEL_ARG() {}
|
||||
SEL_ARG(SEL_ARG &);
|
||||
SEL_ARG(Field *,const char *,const char *);
|
||||
|
|
@ -245,7 +330,8 @@ public:
|
|||
return new SEL_ARG(field, part, min_value, arg->max_value,
|
||||
min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
|
||||
}
|
||||
SEL_ARG *clone(SEL_ARG *new_parent,SEL_ARG **next);
|
||||
SEL_ARG *clone(struct st_qsel_param *param, SEL_ARG *new_parent,
|
||||
SEL_ARG **next);
|
||||
|
||||
bool copy_min(SEL_ARG* arg)
|
||||
{ // Get overlapping range
|
||||
|
|
@ -387,7 +473,7 @@ public:
|
|||
{
|
||||
return parent->left == this ? &parent->left : &parent->right;
|
||||
}
|
||||
SEL_ARG *clone_tree();
|
||||
SEL_ARG *clone_tree(struct st_qsel_param *param);
|
||||
};
|
||||
|
||||
class SEL_IMERGE;
|
||||
|
|
@ -455,6 +541,8 @@ typedef struct st_qsel_param {
|
|||
/* Number of ranges in the last checked tree->key */
|
||||
uint n_ranges;
|
||||
uint8 first_null_comp; /* first null component if any, 0 - otherwise */
|
||||
/* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */
|
||||
uint alloced_sel_args;
|
||||
} PARAM;
|
||||
|
||||
class TABLE_READ_PLAN;
|
||||
|
|
@ -514,8 +602,8 @@ static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
|
|||
static SEL_TREE *tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
|
||||
static SEL_TREE *tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
|
||||
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
|
||||
static SEL_ARG *key_or(SEL_ARG *key1,SEL_ARG *key2);
|
||||
static SEL_ARG *key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag);
|
||||
static SEL_ARG *key_or(PARAM *param, SEL_ARG *key1,SEL_ARG *key2);
|
||||
static SEL_ARG *key_and(PARAM *param, SEL_ARG *key1,SEL_ARG *key2,uint clone_flag);
|
||||
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
|
||||
bool get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
|
||||
SEL_ARG *key_tree,char *min_key,uint min_key_flag,
|
||||
|
|
@ -740,6 +828,7 @@ int imerge_list_or_tree(PARAM *param,
|
|||
return im1->is_empty();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** Basic functions for SQL_SELECT and QUICK_RANGE_SELECT
|
||||
***************************************************************************/
|
||||
|
|
@ -1354,12 +1443,17 @@ SEL_ARG::SEL_ARG(Field *field_,uint8 part_,char *min_value_,char *max_value_,
|
|||
left=right= &null_element;
|
||||
}
|
||||
|
||||
SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
|
||||
SEL_ARG *SEL_ARG::clone(PARAM *param, SEL_ARG *new_parent, SEL_ARG **next_arg)
|
||||
{
|
||||
SEL_ARG *tmp;
|
||||
|
||||
/* Bail out if we have already generated too many SEL_ARGs */
|
||||
if (++param->alloced_sel_args > MAX_SEL_ARGS)
|
||||
return 0;
|
||||
|
||||
if (type != KEY_RANGE)
|
||||
{
|
||||
if (!(tmp= new SEL_ARG(type)))
|
||||
if (!(tmp= new (param->mem_root) SEL_ARG(type)))
|
||||
return 0; // out of memory
|
||||
tmp->prev= *next_arg; // Link into next/prev chain
|
||||
(*next_arg)->next=tmp;
|
||||
|
|
@ -1367,20 +1461,21 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!(tmp= new SEL_ARG(field,part, min_value,max_value,
|
||||
min_flag, max_flag, maybe_flag)))
|
||||
if (!(tmp= new (param->mem_root) SEL_ARG(field,part, min_value,max_value,
|
||||
min_flag, max_flag, maybe_flag)))
|
||||
return 0; // OOM
|
||||
tmp->parent=new_parent;
|
||||
tmp->next_key_part=next_key_part;
|
||||
if (left != &null_element)
|
||||
tmp->left=left->clone(tmp,next_arg);
|
||||
if (!(tmp->left=left->clone(param, tmp, next_arg)))
|
||||
return 0; // OOM
|
||||
|
||||
tmp->prev= *next_arg; // Link into next/prev chain
|
||||
(*next_arg)->next=tmp;
|
||||
(*next_arg)= tmp;
|
||||
|
||||
if (right != &null_element)
|
||||
if (!(tmp->right= right->clone(tmp,next_arg)))
|
||||
if (!(tmp->right= right->clone(param, tmp, next_arg)))
|
||||
return 0; // OOM
|
||||
}
|
||||
increment_use_count(1);
|
||||
|
|
@ -1458,11 +1553,12 @@ static int sel_cmp(Field *field, char *a,char *b,uint8 a_flag,uint8 b_flag)
|
|||
}
|
||||
|
||||
|
||||
SEL_ARG *SEL_ARG::clone_tree()
|
||||
SEL_ARG *SEL_ARG::clone_tree(PARAM *param)
|
||||
{
|
||||
SEL_ARG tmp_link,*next_arg,*root;
|
||||
next_arg= &tmp_link;
|
||||
root= clone((SEL_ARG *) 0, &next_arg);
|
||||
if (!(root= clone(param, (SEL_ARG *) 0, &next_arg)))
|
||||
return 0;
|
||||
next_arg->next=0; // Fix last link
|
||||
tmp_link.next->prev=0; // Fix first link
|
||||
if (root) // If not OOM
|
||||
|
|
@ -1937,6 +2033,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||
param.real_keynr[param.keys++]=idx;
|
||||
}
|
||||
param.key_parts_end=key_parts;
|
||||
param.alloced_sel_args= 0;
|
||||
|
||||
/* Calculate cost of full index read for the shortest covering index */
|
||||
if (!head->used_keys.is_clear_all())
|
||||
|
|
@ -3926,7 +4023,8 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
|
|||
while ((item=li++))
|
||||
{
|
||||
SEL_TREE *new_tree=get_mm_tree(param,item);
|
||||
if (param->thd->is_fatal_error)
|
||||
if (param->thd->is_fatal_error ||
|
||||
param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
|
||||
DBUG_RETURN(0); // out of memory
|
||||
tree=tree_and(param,tree,new_tree);
|
||||
if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
|
||||
|
|
@ -4500,9 +4598,9 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
|
|||
tree1->type=SEL_TREE::KEY_SMALLER;
|
||||
DBUG_RETURN(tree1);
|
||||
}
|
||||
|
||||
key_map result_keys;
|
||||
result_keys.clear_all();
|
||||
|
||||
/* Join the trees key per key */
|
||||
SEL_ARG **key1,**key2,**end;
|
||||
for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ;
|
||||
|
|
@ -4515,7 +4613,7 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
|
|||
flag|=CLONE_KEY1_MAYBE;
|
||||
if (*key2 && !(*key2)->simple_key())
|
||||
flag|=CLONE_KEY2_MAYBE;
|
||||
*key1=key_and(*key1,*key2,flag);
|
||||
*key1=key_and(param, *key1, *key2, flag);
|
||||
if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE)
|
||||
{
|
||||
tree1->type= SEL_TREE::IMPOSSIBLE;
|
||||
|
|
@ -4523,8 +4621,8 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
|
|||
}
|
||||
result_keys.set_bit(key1 - tree1->keys);
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (*key1)
|
||||
(*key1)->test_use_count(*key1);
|
||||
if (*key1 && param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
|
||||
(*key1)->test_use_count(*key1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -4599,13 +4697,14 @@ tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
|
|||
for (key1= tree1->keys,key2= tree2->keys,end= key1+param->keys ;
|
||||
key1 != end ; key1++,key2++)
|
||||
{
|
||||
*key1=key_or(*key1,*key2);
|
||||
*key1=key_or(param, *key1, *key2);
|
||||
if (*key1)
|
||||
{
|
||||
result=tree1; // Added to tree1
|
||||
result_keys.set_bit(key1 - tree1->keys);
|
||||
#ifdef EXTRA_DEBUG
|
||||
(*key1)->test_use_count(*key1);
|
||||
if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS)
|
||||
(*key1)->test_use_count(*key1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -4654,14 +4753,14 @@ tree_or(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
|
|||
/* And key trees where key1->part < key2 -> part */
|
||||
|
||||
static SEL_ARG *
|
||||
and_all_keys(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
|
||||
and_all_keys(PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
|
||||
{
|
||||
SEL_ARG *next;
|
||||
ulong use_count=key1->use_count;
|
||||
|
||||
if (key1->elements != 1)
|
||||
{
|
||||
key2->use_count+=key1->elements-1;
|
||||
key2->use_count+=key1->elements-1; //psergey: why we don't count that key1 has n-k-p?
|
||||
key2->increment_use_count((int) key1->elements-1);
|
||||
}
|
||||
if (key1->type == SEL_ARG::MAYBE_KEY)
|
||||
|
|
@ -4673,7 +4772,7 @@ and_all_keys(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
|
|||
{
|
||||
if (next->next_key_part)
|
||||
{
|
||||
SEL_ARG *tmp=key_and(next->next_key_part,key2,clone_flag);
|
||||
SEL_ARG *tmp= key_and(param, next->next_key_part, key2, clone_flag);
|
||||
if (tmp && tmp->type == SEL_ARG::IMPOSSIBLE)
|
||||
{
|
||||
key1=key1->tree_delete(next);
|
||||
|
|
@ -4682,6 +4781,8 @@ and_all_keys(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
|
|||
next->next_key_part=tmp;
|
||||
if (use_count)
|
||||
next->increment_use_count(use_count);
|
||||
if (param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
|
||||
break;
|
||||
}
|
||||
else
|
||||
next->next_key_part=key2;
|
||||
|
|
@ -4707,7 +4808,7 @@ and_all_keys(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
|
|||
*/
|
||||
|
||||
static SEL_ARG *
|
||||
key_and(SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
|
||||
key_and(PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
|
||||
{
|
||||
if (!key1)
|
||||
return key2;
|
||||
|
|
@ -4723,9 +4824,9 @@ key_and(SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
|
|||
// key1->part < key2->part
|
||||
key1->use_count--;
|
||||
if (key1->use_count > 0)
|
||||
if (!(key1= key1->clone_tree()))
|
||||
if (!(key1= key1->clone_tree(param)))
|
||||
return 0; // OOM
|
||||
return and_all_keys(key1,key2,clone_flag);
|
||||
return and_all_keys(param, key1, key2, clone_flag);
|
||||
}
|
||||
|
||||
if (((clone_flag & CLONE_KEY2_MAYBE) &&
|
||||
|
|
@ -4743,14 +4844,14 @@ key_and(SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
|
|||
if (key1->use_count > 1)
|
||||
{
|
||||
key1->use_count--;
|
||||
if (!(key1=key1->clone_tree()))
|
||||
if (!(key1=key1->clone_tree(param)))
|
||||
return 0; // OOM
|
||||
key1->use_count++;
|
||||
}
|
||||
if (key1->type == SEL_ARG::MAYBE_KEY)
|
||||
{ // Both are maybe key
|
||||
key1->next_key_part=key_and(key1->next_key_part,key2->next_key_part,
|
||||
clone_flag);
|
||||
key1->next_key_part=key_and(param, key1->next_key_part,
|
||||
key2->next_key_part, clone_flag);
|
||||
if (key1->next_key_part &&
|
||||
key1->next_key_part->type == SEL_ARG::IMPOSSIBLE)
|
||||
return key1;
|
||||
|
|
@ -4761,7 +4862,7 @@ key_and(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(key1,key2,clone_flag);
|
||||
return and_all_keys(param, key1, key2, clone_flag);
|
||||
}
|
||||
key2->use_count--; // Key2 doesn't have a tree
|
||||
}
|
||||
|
|
@ -4797,7 +4898,8 @@ key_and(SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
|
|||
}
|
||||
else if (get_range(&e2,&e1,key2))
|
||||
continue;
|
||||
SEL_ARG *next=key_and(e1->next_key_part,e2->next_key_part,clone_flag);
|
||||
SEL_ARG *next=key_and(param, e1->next_key_part, e2->next_key_part,
|
||||
clone_flag);
|
||||
e1->increment_use_count(1);
|
||||
e2->increment_use_count(1);
|
||||
if (!next || next->type != SEL_ARG::IMPOSSIBLE)
|
||||
|
|
@ -4845,7 +4947,7 @@ get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1)
|
|||
|
||||
|
||||
static SEL_ARG *
|
||||
key_or(SEL_ARG *key1,SEL_ARG *key2)
|
||||
key_or(PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
|
||||
{
|
||||
if (!key1)
|
||||
{
|
||||
|
|
@ -4893,7 +4995,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
|
|||
{
|
||||
swap_variables(SEL_ARG *,key1,key2);
|
||||
}
|
||||
if (key1->use_count > 0 || !(key1=key1->clone_tree()))
|
||||
if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
|
||||
return 0; // OOM
|
||||
}
|
||||
|
||||
|
|
@ -5037,7 +5139,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
|
|||
{ // tmp.min. <= x <= tmp.max
|
||||
tmp->maybe_flag|= key.maybe_flag;
|
||||
key.increment_use_count(key1->use_count+1);
|
||||
tmp->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
|
||||
tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
|
||||
if (!cmp) // Key2 is ready
|
||||
break;
|
||||
key.copy_max_to_min(tmp);
|
||||
|
|
@ -5068,7 +5170,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
|
|||
tmp->increment_use_count(key1->use_count+1);
|
||||
/* Increment key count as it may be used for next loop */
|
||||
key.increment_use_count(1);
|
||||
new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
|
||||
new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
|
||||
key1=key1->insert(new_arg);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1640,6 +1640,9 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
table->used_keys= table->s->keys_for_keyread;
|
||||
table->fulltext_searched= 0;
|
||||
table->file->ft_handler= 0;
|
||||
/* Catch wrong handling of the auto_increment_field_not_null. */
|
||||
DBUG_ASSERT(!table->auto_increment_field_not_null);
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
if (table->timestamp_field)
|
||||
table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
|
||||
table->pos_in_table_list= table_list;
|
||||
|
|
@ -2950,7 +2953,7 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
|
|||
share= tmp_table->s;
|
||||
tmp_table->reginfo.lock_type=TL_WRITE; // Simulate locked
|
||||
share->tmp_table= (tmp_table->file->has_transactions() ?
|
||||
TRANSACTIONAL_TMP_TABLE : TMP_TABLE);
|
||||
TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
|
||||
share->table_cache_key= (char*) (tmp_table+1);
|
||||
share->db= share->table_cache_key;
|
||||
share->key_length= (uint) (strmov(((char*) (share->table_name=
|
||||
|
|
@ -4886,7 +4889,6 @@ bool setup_tables_and_check_access(THD *thd,
|
|||
TABLE_LIST *leaves_tmp = NULL;
|
||||
bool first_table= true;
|
||||
|
||||
thd->leaf_count= 0;
|
||||
if (setup_tables (thd, context, from_clause, tables, conds,
|
||||
&leaves_tmp, select_insert))
|
||||
return TRUE;
|
||||
|
|
@ -4904,7 +4906,6 @@ bool setup_tables_and_check_access(THD *thd,
|
|||
return TRUE;
|
||||
}
|
||||
first_table= false;
|
||||
thd->leaf_count++;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -5295,6 +5296,11 @@ err_no_arena:
|
|||
values values to fill with
|
||||
ignore_errors TRUE if we should ignore errors
|
||||
|
||||
NOTE
|
||||
fill_record() may set table->auto_increment_field_not_null and a
|
||||
caller should make sure that it is reset after their last call to this
|
||||
function.
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE error occured
|
||||
|
|
@ -5307,27 +5313,52 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
|
|||
List_iterator_fast<Item> f(fields),v(values);
|
||||
Item *value, *fld;
|
||||
Item_field *field;
|
||||
TABLE *table= 0;
|
||||
DBUG_ENTER("fill_record");
|
||||
|
||||
/*
|
||||
Reset the table->auto_increment_field_not_null as it is valid for
|
||||
only one row.
|
||||
*/
|
||||
if (fields.elements)
|
||||
{
|
||||
/*
|
||||
On INSERT or UPDATE fields are checked to be from the same table,
|
||||
thus we safely can take table from the first field.
|
||||
*/
|
||||
fld= (Item_field*)f++;
|
||||
if (!(field= fld->filed_for_view_update()))
|
||||
{
|
||||
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name);
|
||||
goto err;
|
||||
}
|
||||
table= field->field->table;
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
f.rewind();
|
||||
}
|
||||
while ((fld= f++))
|
||||
{
|
||||
if (!(field= fld->filed_for_view_update()))
|
||||
{
|
||||
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name);
|
||||
DBUG_RETURN(TRUE);
|
||||
goto err;
|
||||
}
|
||||
value=v++;
|
||||
Field *rfield= field->field;
|
||||
TABLE *table= rfield->table;
|
||||
table= rfield->table;
|
||||
if (rfield == table->next_number_field)
|
||||
table->auto_increment_field_not_null= TRUE;
|
||||
if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
|
||||
{
|
||||
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(thd->net.report_error);
|
||||
err:
|
||||
if (table)
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -5376,6 +5407,11 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
|
|||
values list of fields
|
||||
ignore_errors TRUE if we should ignore errors
|
||||
|
||||
NOTE
|
||||
fill_record() may set table->auto_increment_field_not_null and a
|
||||
caller should make sure that it is reset after their last call to this
|
||||
function.
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE error occured
|
||||
|
|
@ -5386,19 +5422,38 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
|
|||
{
|
||||
List_iterator_fast<Item> v(values);
|
||||
Item *value;
|
||||
TABLE *table= 0;
|
||||
DBUG_ENTER("fill_record");
|
||||
|
||||
Field *field;
|
||||
/*
|
||||
Reset the table->auto_increment_field_not_null as it is valid for
|
||||
only one row.
|
||||
*/
|
||||
if (*ptr)
|
||||
{
|
||||
/*
|
||||
On INSERT or UPDATE fields are checked to be from the same table,
|
||||
thus we safely can take table from the first field.
|
||||
*/
|
||||
table= (*ptr)->table;
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
}
|
||||
while ((field = *ptr++))
|
||||
{
|
||||
value=v++;
|
||||
TABLE *table= field->table;
|
||||
table= field->table;
|
||||
if (field == table->next_number_field)
|
||||
table->auto_increment_field_not_null= TRUE;
|
||||
if (value->save_in_field(field, 0) == -1)
|
||||
DBUG_RETURN(TRUE);
|
||||
goto err;
|
||||
}
|
||||
DBUG_RETURN(thd->net.report_error);
|
||||
|
||||
err:
|
||||
if (table)
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -614,6 +614,18 @@ void THD::cleanup_after_query()
|
|||
clear_next_insert_id= 0;
|
||||
next_insert_id= 0;
|
||||
}
|
||||
/*
|
||||
Reset rand_used so that detection of calls to rand() will save random
|
||||
seeds if needed by the slave.
|
||||
|
||||
Do not reset rand_used if inside a stored function or trigger because
|
||||
only the call to these operations is logged. Thus only the calling
|
||||
statement needs to detect rand() calls made by its substatements. These
|
||||
substatements must not set rand_used to 0 because it would remove the
|
||||
detection of rand() by the calling statement.
|
||||
*/
|
||||
if (!in_sub_stmt)
|
||||
rand_used= 0;
|
||||
/* Free Items that were created during this execution */
|
||||
free_items();
|
||||
/* Reset where. */
|
||||
|
|
|
|||
|
|
@ -1496,9 +1496,6 @@ public:
|
|||
query_id_t first_query_id;
|
||||
} binlog_evt_union;
|
||||
|
||||
/* pass up the count of "leaf" tables in a JOIN out of setup_tables() */
|
||||
byte leaf_count;
|
||||
|
||||
THD();
|
||||
~THD();
|
||||
|
||||
|
|
|
|||
|
|
@ -1308,30 +1308,27 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
|
|||
DBUG_PRINT("info",("Use database: %s", new_db_file_name.str));
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (!force_switch) /* FIXME: this is BUG#27337. */
|
||||
{
|
||||
db_access=
|
||||
test_all_bits(sctx->master_access, DB_ACLS) ?
|
||||
DB_ACLS :
|
||||
acl_get(sctx->host,
|
||||
sctx->ip,
|
||||
sctx->priv_user,
|
||||
new_db_file_name.str,
|
||||
FALSE) | sctx->master_access;
|
||||
db_access=
|
||||
test_all_bits(sctx->master_access, DB_ACLS) ?
|
||||
DB_ACLS :
|
||||
acl_get(sctx->host,
|
||||
sctx->ip,
|
||||
sctx->priv_user,
|
||||
new_db_file_name.str,
|
||||
FALSE) | sctx->master_access;
|
||||
|
||||
if (!force_switch &&
|
||||
!(db_access & DB_ACLS) &&
|
||||
(!grant_option || check_grant_db(thd, new_db_file_name.str)))
|
||||
{
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
sctx->priv_user,
|
||||
sctx->priv_host,
|
||||
new_db_file_name.str);
|
||||
mysql_log.write(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
|
||||
sctx->priv_user, sctx->priv_host, new_db_file_name.str);
|
||||
my_free(new_db_file_name.str, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (!force_switch &&
|
||||
!(db_access & DB_ACLS) &&
|
||||
(!grant_option || check_grant_db(thd, new_db_file_name.str)))
|
||||
{
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
sctx->priv_user,
|
||||
sctx->priv_host,
|
||||
new_db_file_name.str);
|
||||
mysql_log.write(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
|
||||
sctx->priv_user, sctx->priv_host, new_db_file_name.str);
|
||||
my_free(new_db_file_name.str, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,27 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
if (mysql_prepare_delete(thd, table_list, &conds))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/* check ORDER BY even if it can be ignored */
|
||||
if (order && order->elements)
|
||||
{
|
||||
TABLE_LIST tables;
|
||||
List<Item> fields;
|
||||
List<Item> all_fields;
|
||||
|
||||
bzero((char*) &tables,sizeof(tables));
|
||||
tables.table = table;
|
||||
tables.alias = table_list->alias;
|
||||
|
||||
if (select_lex->setup_ref_array(thd, order->elements) ||
|
||||
setup_order(thd, select_lex->ref_pointer_array, &tables,
|
||||
fields, all_fields, (ORDER*) order->first))
|
||||
{
|
||||
delete select;
|
||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
const_cond= (!conds || conds->const_item());
|
||||
safe_update=test(thd->options & OPTION_SAFE_UPDATES);
|
||||
if (safe_update && const_cond)
|
||||
|
|
@ -148,23 +169,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
{
|
||||
uint length= 0;
|
||||
SORT_FIELD *sortorder;
|
||||
TABLE_LIST tables;
|
||||
List<Item> fields;
|
||||
List<Item> all_fields;
|
||||
ha_rows examined_rows;
|
||||
|
||||
bzero((char*) &tables,sizeof(tables));
|
||||
tables.table = table;
|
||||
tables.alias = table_list->alias;
|
||||
|
||||
if (select_lex->setup_ref_array(thd, order->elements) ||
|
||||
setup_order(thd, select_lex->ref_pointer_array, &tables,
|
||||
fields, all_fields, (ORDER*) order->first))
|
||||
{
|
||||
delete select;
|
||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
|
||||
usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ exit:
|
|||
orig_table_list->table_name= (char*) table->s->table_name;
|
||||
orig_table_list->table_name_length= strlen((char*)table->s->table_name);
|
||||
table->derived_select_number= first_select->select_number;
|
||||
table->s->tmp_table= TMP_TABLE;
|
||||
table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (orig_table_list->referencing_view)
|
||||
table->grant= orig_table_list->grant;
|
||||
|
|
|
|||
|
|
@ -757,6 +757,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||
table->next_number_field=0;
|
||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||
thd->next_insert_id=0; // Reset this if wrongly used
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
if (duplic != DUP_ERROR || ignore)
|
||||
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
|
||||
if (duplic == DUP_REPLACE &&
|
||||
|
|
@ -2349,14 +2350,12 @@ bool mysql_insert_select_prepare(THD *thd)
|
|||
DBUG_ASSERT(select_lex->leaf_tables != 0);
|
||||
lex->leaf_tables_insert= select_lex->leaf_tables;
|
||||
/* skip all leaf tables belonged to view where we are insert */
|
||||
for (first_select_leaf_table= select_lex->leaf_tables->next_leaf,
|
||||
thd->leaf_count --;
|
||||
for (first_select_leaf_table= select_lex->leaf_tables->next_leaf;
|
||||
first_select_leaf_table &&
|
||||
first_select_leaf_table->belong_to_view &&
|
||||
first_select_leaf_table->belong_to_view ==
|
||||
lex->leaf_tables_insert->belong_to_view;
|
||||
first_select_leaf_table= first_select_leaf_table->next_leaf,
|
||||
thd->leaf_count --)
|
||||
first_select_leaf_table= first_select_leaf_table->next_leaf)
|
||||
{}
|
||||
select_lex->leaf_tables= first_select_leaf_table;
|
||||
DBUG_RETURN(FALSE);
|
||||
|
|
@ -2573,6 +2572,7 @@ select_insert::~select_insert()
|
|||
if (table)
|
||||
{
|
||||
table->next_number_field=0;
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
table->file->reset();
|
||||
}
|
||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
class Sql_alloc
|
||||
{
|
||||
public:
|
||||
static void *operator new(size_t size)
|
||||
static void *operator new(size_t size) throw ()
|
||||
{
|
||||
return (void*) sql_alloc((uint) size);
|
||||
}
|
||||
|
|
@ -31,9 +31,9 @@ public:
|
|||
{
|
||||
return (void*) sql_alloc((uint) size);
|
||||
}
|
||||
static void *operator new[](size_t size, MEM_ROOT *mem_root)
|
||||
static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
|
||||
{ return (void*) alloc_root(mem_root, (uint) size); }
|
||||
static void *operator new(size_t size, MEM_ROOT *mem_root)
|
||||
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
|
||||
{ return (void*) alloc_root(mem_root, (uint) size); }
|
||||
static void operator delete(void *ptr, size_t size) { TRASH(ptr, size); }
|
||||
static void operator delete(void *ptr, MEM_ROOT *mem_root)
|
||||
|
|
|
|||
|
|
@ -493,6 +493,7 @@ err:
|
|||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0;
|
||||
}
|
||||
table->auto_increment_field_not_null= FALSE;
|
||||
thd->abort_on_warning= 0;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
|
@ -589,8 +590,6 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||
{
|
||||
uint length;
|
||||
byte save_chr;
|
||||
if (field == table->next_number_field)
|
||||
table->auto_increment_field_not_null= TRUE;
|
||||
if ((length=(uint) (read_info.row_end-pos)) >
|
||||
field->field_length)
|
||||
length=field->field_length;
|
||||
|
|
|
|||
167
sql/sql_parse.cc
167
sql/sql_parse.cc
|
|
@ -2237,7 +2237,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
|||
enum enum_schema_tables schema_table_idx)
|
||||
{
|
||||
DBUG_ENTER("prepare_schema_table");
|
||||
SELECT_LEX *sel= 0;
|
||||
SELECT_LEX *schema_select_lex= NULL;
|
||||
|
||||
switch (schema_table_idx) {
|
||||
case SCH_SCHEMATA:
|
||||
#if defined(DONT_ALLOW_SHOW_COMMANDS)
|
||||
|
|
@ -2245,11 +2246,9 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
|||
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
|
||||
DBUG_RETURN(1);
|
||||
#else
|
||||
if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
|
||||
check_global_access(thd, SHOW_DB_ACL))
|
||||
DBUG_RETURN(1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SCH_TABLE_NAMES:
|
||||
case SCH_TABLES:
|
||||
case SCH_VIEWS:
|
||||
|
|
@ -2259,32 +2258,25 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
|||
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
|
||||
DBUG_RETURN(1);
|
||||
#else
|
||||
if (lex->select_lex.db == NULL &&
|
||||
thd->copy_db_to(&lex->select_lex.db, NULL))
|
||||
{
|
||||
char *db;
|
||||
if (lex->select_lex.db == NULL &&
|
||||
thd->copy_db_to(&lex->select_lex.db, 0))
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
db= lex->select_lex.db;
|
||||
remove_escape(db); // Fix escaped '_'
|
||||
if (check_db_name(db))
|
||||
{
|
||||
my_error(ER_WRONG_DB_NAME, MYF(0), db);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (check_access(thd, SELECT_ACL, db, &thd->col_access, 0, 0,
|
||||
is_schema_db(db)))
|
||||
DBUG_RETURN(1); /* purecov: inspected */
|
||||
if (!thd->col_access && check_grant_db(thd,db))
|
||||
{
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
thd->security_ctx->priv_user, thd->security_ctx->priv_host,
|
||||
db);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
break;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
schema_select_lex= new SELECT_LEX();
|
||||
schema_select_lex->db= lex->select_lex.db;
|
||||
schema_select_lex->table_list.first= NULL;
|
||||
remove_escape(schema_select_lex->db); // Fix escaped '_'
|
||||
|
||||
if (check_db_name(schema_select_lex->db))
|
||||
{
|
||||
my_error(ER_WRONG_DB_NAME, MYF(0), schema_select_lex->db);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
#endif
|
||||
case SCH_COLUMNS:
|
||||
case SCH_STATISTICS:
|
||||
|
|
@ -2293,28 +2285,23 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
|||
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
|
||||
DBUG_RETURN(1);
|
||||
#else
|
||||
if (table_ident)
|
||||
{
|
||||
DBUG_ASSERT(table_ident);
|
||||
|
||||
TABLE_LIST **query_tables_last= lex->query_tables_last;
|
||||
sel= new SELECT_LEX();
|
||||
schema_select_lex= new SELECT_LEX();
|
||||
/* 'parent_lex' is used in init_query() so it must be before it. */
|
||||
sel->parent_lex= lex;
|
||||
sel->init_query();
|
||||
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
|
||||
(List<String> *) 0, (List<String> *) 0))
|
||||
schema_select_lex->parent_lex= lex;
|
||||
schema_select_lex->init_query();
|
||||
if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
|
||||
(List<String> *) 0, (List<String> *) 0))
|
||||
DBUG_RETURN(1);
|
||||
lex->query_tables_last= query_tables_last;
|
||||
TABLE_LIST *table_list= (TABLE_LIST*) sel->table_list.first;
|
||||
char *db= table_list->db;
|
||||
remove_escape(db); // Fix escaped '_'
|
||||
remove_escape(table_list->table_name);
|
||||
if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,
|
||||
&table_list->grant.privilege, 0, 0,
|
||||
test(table_list->schema_table)))
|
||||
DBUG_RETURN(1); /* purecov: inspected */
|
||||
if (grant_option && check_grant(thd, SELECT_ACL, table_list, 2,
|
||||
UINT_MAX, 0))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
TABLE_LIST *dst_table= (TABLE_LIST*) schema_select_lex->table_list.first;
|
||||
remove_escape(dst_table->db); // Fix escaped '_'
|
||||
remove_escape(dst_table->table_name);
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2341,7 +2328,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
|
||||
table_list->schema_select_lex= sel;
|
||||
table_list->schema_select_lex= schema_select_lex;
|
||||
table_list->schema_table_reformed= 1;
|
||||
statistic_increment(thd->status_var.com_stat[lex->orig_sql_command],
|
||||
&LOCK_status);
|
||||
|
|
@ -5390,6 +5377,83 @@ bool check_global_access(THD *thd, ulong want_access)
|
|||
}
|
||||
|
||||
|
||||
static bool check_show_access(THD *thd, TABLE_LIST *table)
|
||||
{
|
||||
switch (get_schema_table_idx(table->schema_table))
|
||||
{
|
||||
case SCH_SCHEMATA:
|
||||
return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
|
||||
check_global_access(thd, SHOW_DB_ACL);
|
||||
|
||||
case SCH_TABLE_NAMES:
|
||||
case SCH_TABLES:
|
||||
case SCH_VIEWS:
|
||||
case SCH_TRIGGERS:
|
||||
{
|
||||
const char *dst_db_name= table->schema_select_lex->db;
|
||||
|
||||
DBUG_ASSERT(dst_db_name);
|
||||
|
||||
if (check_access(thd, SELECT_ACL, dst_db_name,
|
||||
&thd->col_access, FALSE, FALSE,
|
||||
is_schema_db(dst_db_name)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!thd->col_access && check_grant_db(thd, dst_db_name))
|
||||
{
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
thd->security_ctx->priv_user,
|
||||
thd->security_ctx->priv_host,
|
||||
dst_db_name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case SCH_COLUMNS:
|
||||
case SCH_STATISTICS:
|
||||
{
|
||||
TABLE_LIST *dst_table=
|
||||
(TABLE_LIST *) table->schema_select_lex->table_list.first;
|
||||
|
||||
DBUG_ASSERT(dst_table);
|
||||
|
||||
if (check_access(thd, SELECT_ACL | EXTRA_ACL,
|
||||
dst_table->db,
|
||||
&dst_table->grant.privilege,
|
||||
FALSE, FALSE,
|
||||
test(dst_table->schema_table)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return grant_option &&
|
||||
check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE);
|
||||
}
|
||||
|
||||
case SCH_OPEN_TABLES:
|
||||
case SCH_VARIABLES:
|
||||
case SCH_STATUS:
|
||||
case SCH_PROCEDURES:
|
||||
case SCH_CHARSETS:
|
||||
case SCH_COLLATIONS:
|
||||
case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
|
||||
case SCH_USER_PRIVILEGES:
|
||||
case SCH_SCHEMA_PRIVILEGES:
|
||||
case SCH_TABLE_PRIVILEGES:
|
||||
case SCH_COLUMN_PRIVILEGES:
|
||||
case SCH_TABLE_CONSTRAINTS:
|
||||
case SCH_KEY_COLUMN_USAGE:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check the privilege for all used tables.
|
||||
|
||||
|
|
@ -5450,7 +5514,16 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||
Remove SHOW_VIEW_ACL, because it will be checked during making view
|
||||
*/
|
||||
tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
|
||||
if (tables->derived || tables->schema_table ||
|
||||
|
||||
if (tables->schema_table_reformed)
|
||||
{
|
||||
if (check_show_access(thd, tables))
|
||||
goto deny;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tables->derived ||
|
||||
(tables->table && (int)tables->table->s->tmp_table) ||
|
||||
my_tz_check_n_skip_implicit_tables(&tables,
|
||||
thd->lex->time_zone_tables_used))
|
||||
|
|
|
|||
|
|
@ -412,7 +412,12 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||
&select_lex->leaf_tables, FALSE,
|
||||
SELECT_ACL, SELECT_ACL))
|
||||
DBUG_RETURN(-1);
|
||||
tables= thd->leaf_count;
|
||||
|
||||
TABLE_LIST *table_ptr;
|
||||
for (table_ptr= select_lex->leaf_tables;
|
||||
table_ptr;
|
||||
table_ptr= table_ptr->next_leaf)
|
||||
tables++;
|
||||
|
||||
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
|
||||
select_lex->setup_ref_array(thd, og_num) ||
|
||||
|
|
@ -6942,6 +6947,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
|||
|
||||
SYNOPSIS
|
||||
check_row_equality()
|
||||
thd thread handle
|
||||
left_row left term of the row equality to be processed
|
||||
right_row right term of the row equality to be processed
|
||||
cond_equal multiple equalities that must hold together with the predicate
|
||||
|
|
@ -6962,7 +6968,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
|
|||
FALSE otherwise
|
||||
*/
|
||||
|
||||
static bool check_row_equality(Item *left_row, Item_row *right_row,
|
||||
static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
|
||||
COND_EQUAL *cond_equal, List<Item>* eq_list)
|
||||
{
|
||||
uint n= left_row->cols();
|
||||
|
|
@ -6973,13 +6979,21 @@ static bool check_row_equality(Item *left_row, Item_row *right_row,
|
|||
Item *right_item= right_row->element_index(i);
|
||||
if (left_item->type() == Item::ROW_ITEM &&
|
||||
right_item->type() == Item::ROW_ITEM)
|
||||
is_converted= check_row_equality((Item_row *) left_item,
|
||||
(Item_row *) right_item,
|
||||
cond_equal, eq_list);
|
||||
else
|
||||
{
|
||||
is_converted= check_row_equality(thd,
|
||||
(Item_row *) left_item,
|
||||
(Item_row *) right_item,
|
||||
cond_equal, eq_list);
|
||||
if (!is_converted)
|
||||
thd->lex->current_select->cond_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
|
||||
|
||||
if (!is_converted)
|
||||
thd->lex->current_select->cond_count++;
|
||||
}
|
||||
|
||||
if (!is_converted)
|
||||
{
|
||||
Item_func_eq *eq_item;
|
||||
if (!(eq_item= new Item_func_eq(left_item, right_item)))
|
||||
|
|
@ -6998,6 +7012,7 @@ static bool check_row_equality(Item *left_row, Item_row *right_row,
|
|||
|
||||
SYNOPSIS
|
||||
check_equality()
|
||||
thd thread handle
|
||||
item predicate to process
|
||||
cond_equal multiple equalities that must hold together with the predicate
|
||||
eq_list results of conversions of row equalities that are not simple
|
||||
|
|
@ -7022,7 +7037,7 @@ static bool check_row_equality(Item *left_row, Item_row *right_row,
|
|||
or, if the procedure fails by a fatal error.
|
||||
*/
|
||||
|
||||
static bool check_equality(Item *item, COND_EQUAL *cond_equal,
|
||||
static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
|
||||
List<Item> *eq_list)
|
||||
{
|
||||
if (item->type() == Item::FUNC_ITEM &&
|
||||
|
|
@ -7033,9 +7048,13 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal,
|
|||
|
||||
if (left_item->type() == Item::ROW_ITEM &&
|
||||
right_item->type() == Item::ROW_ITEM)
|
||||
return check_row_equality((Item_row *) left_item,
|
||||
{
|
||||
thd->lex->current_select->cond_count--;
|
||||
return check_row_equality(thd,
|
||||
(Item_row *) left_item,
|
||||
(Item_row *) right_item,
|
||||
cond_equal, eq_list);
|
||||
}
|
||||
else
|
||||
return check_simple_equality(left_item, right_item, item, cond_equal);
|
||||
}
|
||||
|
|
@ -7048,6 +7067,7 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal,
|
|||
|
||||
SYNOPSIS
|
||||
build_equal_items_for_cond()
|
||||
thd thread handle
|
||||
cond condition(expression) where to make replacement
|
||||
inherited path to all inherited multiple equality items
|
||||
|
||||
|
|
@ -7110,7 +7130,7 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal,
|
|||
pointer to the transformed condition
|
||||
*/
|
||||
|
||||
static COND *build_equal_items_for_cond(COND *cond,
|
||||
static COND *build_equal_items_for_cond(THD *thd, COND *cond,
|
||||
COND_EQUAL *inherited)
|
||||
{
|
||||
Item_equal *item_equal;
|
||||
|
|
@ -7143,7 +7163,7 @@ static COND *build_equal_items_for_cond(COND *cond,
|
|||
structure here because it's restored before each
|
||||
re-execution of any prepared statement/stored procedure.
|
||||
*/
|
||||
if (check_equality(item, &cond_equal, &eq_list))
|
||||
if (check_equality(thd, item, &cond_equal, &eq_list))
|
||||
li.remove();
|
||||
}
|
||||
|
||||
|
|
@ -7178,7 +7198,7 @@ static COND *build_equal_items_for_cond(COND *cond,
|
|||
while ((item= li++))
|
||||
{
|
||||
Item *new_item;
|
||||
if ((new_item = build_equal_items_for_cond(item, inherited))!= item)
|
||||
if ((new_item= build_equal_items_for_cond(thd, item, inherited)) != item)
|
||||
{
|
||||
/* This replacement happens only for standalone equalities */
|
||||
/*
|
||||
|
|
@ -7208,7 +7228,7 @@ static COND *build_equal_items_for_cond(COND *cond,
|
|||
for WHERE a=b AND c=d AND (b=c OR d=5)
|
||||
b=c is replaced by =(a,b,c,d).
|
||||
*/
|
||||
if (check_equality(cond, &cond_equal, &eq_list))
|
||||
if (check_equality(thd, cond, &cond_equal, &eq_list))
|
||||
{
|
||||
int n= cond_equal.current_level.elements + eq_list.elements;
|
||||
if (n == 0)
|
||||
|
|
@ -7271,7 +7291,7 @@ static COND *build_equal_items_for_cond(COND *cond,
|
|||
|
||||
SYNOPSIS
|
||||
build_equal_items()
|
||||
thd Thread handler
|
||||
thd thread handle
|
||||
cond condition to build the multiple equalities for
|
||||
inherited path to all inherited multiple equality items
|
||||
join_list list of join tables to which the condition refers to
|
||||
|
|
@ -7332,7 +7352,7 @@ static COND *build_equal_items(THD *thd, COND *cond,
|
|||
|
||||
if (cond)
|
||||
{
|
||||
cond= build_equal_items_for_cond(cond, inherited);
|
||||
cond= build_equal_items_for_cond(thd, cond, inherited);
|
||||
cond->update_used_tables();
|
||||
if (cond->type() == Item::COND_ITEM &&
|
||||
((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
|
||||
|
|
@ -8788,20 +8808,19 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
|
|||
|
||||
enum enum_field_types type;
|
||||
/*
|
||||
DATE/TIME fields have STRING_RESULT result type. To preserve
|
||||
type they needed to be handled separately.
|
||||
DATE/TIME and GEOMETRY fields have STRING_RESULT result type.
|
||||
To preserve type they needed to be handled separately.
|
||||
*/
|
||||
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
|
||||
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE ||
|
||||
type == MYSQL_TYPE_TIMESTAMP)
|
||||
type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_GEOMETRY)
|
||||
new_field= item->tmp_table_field_from_field_type(table);
|
||||
/*
|
||||
Make sure that the blob fits into a Field_varstring which has
|
||||
2-byte lenght.
|
||||
*/
|
||||
else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
|
||||
item->max_length/item->collation.collation->mbmaxlen < UINT_MAX16
|
||||
&& convert_blob_length)
|
||||
convert_blob_length < UINT_MAX16 && convert_blob_length)
|
||||
new_field= new Field_varstring(convert_blob_length, maybe_null,
|
||||
item->name, table,
|
||||
item->collation.collation);
|
||||
|
|
@ -9169,7 +9188,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
table->s->table_name= table->s->path= tmpname;
|
||||
table->s->db= "";
|
||||
table->s->blob_ptr_size= mi_portable_sizeof_char_ptr;
|
||||
table->s->tmp_table= TMP_TABLE;
|
||||
table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
|
||||
table->s->db_low_byte_first=1; // True for HEAP and MyISAM
|
||||
table->s->table_charset= param->table_charset;
|
||||
table->s->keys_for_keyread.init();
|
||||
|
|
@ -9193,13 +9212,19 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
{
|
||||
if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
|
||||
{
|
||||
/*
|
||||
Mark that the we have ignored an item that refers to a summary
|
||||
function. We need to know this if someone is going to use
|
||||
DISTINCT on the result.
|
||||
*/
|
||||
param->using_indirect_summary_function=1;
|
||||
continue;
|
||||
if (item->used_tables() & OUTER_REF_TABLE_BIT)
|
||||
item->update_used_tables();
|
||||
if (type == Item::SUBSELECT_ITEM ||
|
||||
(item->used_tables() & ~OUTER_REF_TABLE_BIT))
|
||||
{
|
||||
/*
|
||||
Mark that the we have ignored an item that refers to a summary
|
||||
function. We need to know this if someone is going to use
|
||||
DISTINCT on the result.
|
||||
*/
|
||||
param->using_indirect_summary_function=1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (item->const_item() && (int) hidden_field_count <= 0)
|
||||
continue; // We don't have to store this
|
||||
|
|
@ -9384,6 +9409,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
table->s->default_values= table->record[1]+alloc_length;
|
||||
}
|
||||
copy_func[0]=0; // End marker
|
||||
param->func_count= copy_func - param->items_to_copy;
|
||||
|
||||
recinfo=param->start_recinfo;
|
||||
null_flags=(uchar*) table->record[0];
|
||||
|
|
@ -13564,6 +13590,7 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
|
|||
if (!sum_item->quick_group)
|
||||
param->quick_group=0; // UDF SUM function
|
||||
param->sum_func_count++;
|
||||
param->func_count++;
|
||||
|
||||
for (uint i=0 ; i < sum_item->arg_count ; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2148,7 +2148,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
*/
|
||||
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
|
||||
|
||||
if (lsel)
|
||||
if (lsel && lsel->table_list.first)
|
||||
{
|
||||
TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
|
||||
bool res;
|
||||
|
|
|
|||
|
|
@ -4058,7 +4058,9 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
|||
{
|
||||
copy_ptr->do_copy(copy_ptr);
|
||||
}
|
||||
if ((error=to->file->write_row((byte*) to->record[0])))
|
||||
error=to->file->write_row((byte*) to->record[0]);
|
||||
to->auto_increment_field_not_null= FALSE;
|
||||
if (error)
|
||||
{
|
||||
if (!ignore ||
|
||||
(error != HA_ERR_FOUND_DUPP_KEY &&
|
||||
|
|
|
|||
|
|
@ -1092,7 +1092,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
key_alg opt_btree_or_rtree
|
||||
|
||||
%type <string_list>
|
||||
key_usage_list key_usage_list_inner using_list
|
||||
key_usage_list using_list
|
||||
|
||||
%type <key_part>
|
||||
key_part
|
||||
|
|
@ -5907,19 +5907,15 @@ opt_key_definition:
|
|||
sel->use_index_ptr= &sel->use_index;
|
||||
sel->table_join_options|= TL_OPTION_FORCE_INDEX;
|
||||
}
|
||||
| IGNORE_SYM key_or_index opt_for_join key_usage_list_inner
|
||||
| IGNORE_SYM key_usage_list
|
||||
{
|
||||
SELECT_LEX *sel= Select;
|
||||
sel->ignore_index= *$4;
|
||||
sel->ignore_index= *$2;
|
||||
sel->ignore_index_ptr= &sel->ignore_index;
|
||||
};
|
||||
|
||||
key_usage_list:
|
||||
key_or_index key_usage_list_inner
|
||||
{ $$= $2; }
|
||||
;
|
||||
|
||||
key_usage_list_inner:
|
||||
key_or_index opt_for_join
|
||||
{ Select->interval_list.empty(); }
|
||||
'(' key_list_or_empty ')'
|
||||
{ $$= &Select->interval_list; }
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ typedef struct st_grant_info
|
|||
ulong orig_want_privilege;
|
||||
} GRANT_INFO;
|
||||
|
||||
enum tmp_table_type {NO_TMP_TABLE=0, TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2,
|
||||
enum tmp_table_type {NO_TMP_TABLE=0,
|
||||
NON_TRANSACTIONAL_TMP_TABLE=1, TRANSACTIONAL_TMP_TABLE=2,
|
||||
SYSTEM_TMP_TABLE=3};
|
||||
|
||||
enum frm_type_enum
|
||||
|
|
@ -273,6 +274,11 @@ struct st_table {
|
|||
my_bool no_cache;
|
||||
/* To signal that we should reset query_id for tables and cols */
|
||||
my_bool clear_query_id;
|
||||
/*
|
||||
To indicate that a non-null value of the auto_increment field
|
||||
was provided by the user or retrieved from the current record.
|
||||
Used only in the MODE_NO_AUTO_VALUE_ON_ZERO mode.
|
||||
*/
|
||||
my_bool auto_increment_field_not_null;
|
||||
my_bool insert_or_update; /* Can be used by the handler */
|
||||
my_bool alias_name_used; /* true if table_name is alias */
|
||||
|
|
|
|||
|
|
@ -6744,7 +6744,7 @@ typedef struct my_uca_scanner_handler_st
|
|||
int (*next)(my_uca_scanner *scanner);
|
||||
} my_uca_scanner_handler;
|
||||
|
||||
static uint16 nochar[]= {0};
|
||||
static uint16 nochar[]= {0,0};
|
||||
|
||||
|
||||
#ifdef HAVE_CHARSET_ucs2
|
||||
|
|
@ -6769,13 +6769,32 @@ static void my_uca_scanner_init_ucs2(my_uca_scanner *scanner,
|
|||
CHARSET_INFO *cs __attribute__((unused)),
|
||||
const uchar *str, uint length)
|
||||
{
|
||||
/* Note, no needs to initialize scanner->wbeg */
|
||||
scanner->sbeg= str;
|
||||
scanner->send= str + length - 2;
|
||||
scanner->wbeg= nochar;
|
||||
scanner->uca_length= cs->sort_order;
|
||||
scanner->uca_weight= cs->sort_order_big;
|
||||
scanner->contractions= cs->contractions;
|
||||
if (length)
|
||||
{
|
||||
scanner->sbeg= str;
|
||||
scanner->send= str + length - 2;
|
||||
scanner->uca_length= cs->sort_order;
|
||||
scanner->uca_weight= cs->sort_order_big;
|
||||
scanner->contractions= cs->contractions;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Sometimes this function is called with
|
||||
str=NULL and length=0, which should be
|
||||
considered as an empty string.
|
||||
|
||||
The above initialization is unsafe for such cases,
|
||||
because scanner->send is initialized to (NULL-2), which is 0xFFFFFFFE.
|
||||
Then we fall into an endless loop in my_uca_scanner_next_ucs2().
|
||||
|
||||
Do special initialization for the case when length=0.
|
||||
Initialize scanner->sbeg to an address greater than scanner->send.
|
||||
Next call of my_uca_scanner_next_ucs2() will correctly return with -1.
|
||||
*/
|
||||
scanner->sbeg= (uchar*) &nochar[1];
|
||||
scanner->send= (uchar*) &nochar[0];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2764,6 +2764,7 @@ static int my_strnncoll_utf8_cs(CHARSET_INFO *cs,
|
|||
const uchar *te=t+tlen;
|
||||
int save_diff = 0;
|
||||
int diff;
|
||||
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
|
||||
|
||||
while ( s < se && t < te )
|
||||
{
|
||||
|
|
@ -2800,13 +2801,16 @@ static int my_strnncoll_utf8_cs(CHARSET_INFO *cs,
|
|||
|
||||
static int my_strnncollsp_utf8_cs(CHARSET_INFO *cs,
|
||||
const uchar *s, uint slen,
|
||||
const uchar *t, uint tlen)
|
||||
const uchar *t, uint tlen,
|
||||
my_bool diff_if_only_endspace_difference
|
||||
__attribute__((unused)))
|
||||
{
|
||||
int s_res,t_res;
|
||||
my_wc_t s_wc,t_wc;
|
||||
const uchar *se= s+slen;
|
||||
const uchar *te= t+tlen;
|
||||
int save_diff = 0;
|
||||
MY_UNICASE_INFO **uni_plane= cs->caseinfo;
|
||||
|
||||
while ( s < se && t < te )
|
||||
{
|
||||
|
|
@ -2875,6 +2879,7 @@ static MY_COLLATION_HANDLER my_collation_cs_handler =
|
|||
my_strnncoll_utf8_cs,
|
||||
my_strnncollsp_utf8_cs,
|
||||
my_strnxfrm_utf8,
|
||||
my_strnxfrmlen_utf8,
|
||||
my_like_range_simple,
|
||||
my_wildcmp_mb,
|
||||
my_strcasecmp_utf8,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue