mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge remote-tracking branch '10.0' into 10.1
This commit is contained in:
24
CREDITS
24
CREDITS
@@ -4,17 +4,19 @@ organization registered in the USA.
|
||||
The current main sponsors of the MariaDB Foundation are:
|
||||
|
||||
Alibaba Cloud https://intl.aliyun.com (2017)
|
||||
Booking.com https://www.booking.com (2013 - 2017)
|
||||
Development Bank of Singapore https://dbs.com (2016 - 2017)
|
||||
MariaDB Corporation https://www.mariadb.com (2013 - 2017)
|
||||
Visma https://visma.com (2015 - 2017)
|
||||
Acronis http://acronis.com (2016 - 2017)
|
||||
Nexedi https://www.nexedi.com (2016 - 2017)
|
||||
Automattic https://automattic.com (2014 - 2017)
|
||||
Tencent Game DBA http://tencentdba.com/about (2016 - 2017)
|
||||
Tencent TDSQL http://tdsql.org/ (2016 - 2017)
|
||||
Verkkokauppa.com https://www.verkkokauppa.com (2015 - 2017)
|
||||
Virtuozzo https://virtuozzo.com (2016 - 2017)
|
||||
Booking.com https://www.booking.com (2013)
|
||||
Tencent Cloud https://cloud.tencent.com (2017)
|
||||
Development Bank of Singapore https://dbs.com (2016)
|
||||
IBM https://www.ibm.com (2017)
|
||||
MariaDB Corporation https://www.mariadb.com (2013)
|
||||
Visma https://visma.com (2015)
|
||||
Acronis http://acronis.com (2016)
|
||||
Nexedi https://www.nexedi.com (2016)
|
||||
Automattic https://automattic.com (2014)
|
||||
Tencent Game DBA http://tencentdba.com/about (2016)
|
||||
Tencent TDSQL http://tdsql.org (2016)
|
||||
Verkkokauppa.com https://www.verkkokauppa.com (2015)
|
||||
Virtuozzo https://virtuozzo.com (2016)
|
||||
|
||||
For a full list of sponsors, see
|
||||
https://mariadb.org/about/supporters/
|
||||
|
@@ -1721,12 +1721,23 @@ void log_msg(const char *fmt, ...)
|
||||
int cat_file(DYNAMIC_STRING* ds, const char* filename)
|
||||
{
|
||||
int fd;
|
||||
int len;
|
||||
char buff[16384];
|
||||
size_t len;
|
||||
char *buff;
|
||||
|
||||
if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
|
||||
return 1;
|
||||
while((len= (int)my_read(fd, (uchar*)&buff, sizeof(buff)-1, MYF(0))) > 0)
|
||||
|
||||
len= (size_t) my_seek(fd, 0, SEEK_END, MYF(0));
|
||||
my_seek(fd, 0, SEEK_SET, MYF(0));
|
||||
if (len == (size_t)MY_FILEPOS_ERROR ||
|
||||
!(buff= (char*)my_malloc(len + 1, MYF(0))))
|
||||
{
|
||||
my_close(fd, MYF(0));
|
||||
return 1;
|
||||
}
|
||||
len= my_read(fd, (uchar*)buff, len, MYF(0));
|
||||
my_close(fd, MYF(0));
|
||||
|
||||
{
|
||||
char *p= buff, *start= buff,*end=buff+len;
|
||||
while (p < end)
|
||||
@@ -1749,7 +1760,7 @@ int cat_file(DYNAMIC_STRING* ds, const char* filename)
|
||||
*p= 0;
|
||||
replace_dynstr_append_mem(ds, start, p-start);
|
||||
}
|
||||
my_close(fd, MYF(0));
|
||||
my_free(buff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -33,7 +33,12 @@ SET(CPACK_COMPONENTS_ALL Server ManPagesServer IniFiles Server_Scripts
|
||||
)
|
||||
|
||||
SET(CPACK_RPM_PACKAGE_NAME ${CPACK_PACKAGE_NAME})
|
||||
IF(CMAKE_VERSION VERSION_LESS "3.6.0")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${VERSION}-${RPM}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
ELSE()
|
||||
SET(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
|
||||
SET(CPACK_RPM_DEBUGINFO_PACKAGE ON)
|
||||
ENDIF()
|
||||
|
||||
SET(CPACK_RPM_PACKAGE_RELEASE "1%{?dist}")
|
||||
SET(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
|
||||
|
@@ -2,9 +2,11 @@ SHOW CONTRIBUTORS;
|
||||
Name Location Comment
|
||||
Booking.com https://www.booking.com Founding member, Platinum Sponsor of the MariaDB Foundation
|
||||
Alibaba Cloud https://intl.aliyun.com Platinum Sponsor of the MariaDB Foundation
|
||||
Tencent Cloud https://cloud.tencent.com Platinum Sponsor of the MariaDB Foundation
|
||||
MariaDB Corporation https://mariadb.com Founding member, Gold Sponsor of the MariaDB Foundation
|
||||
Visma https://visma.com Gold Sponsor of the MariaDB Foundation
|
||||
DBS https://dbs.com Gold Sponsor of the MariaDB Foundation
|
||||
IBM https://www.ibm.com Gold Sponsor of the MariaDB Foundation
|
||||
Nexedi https://www.nexedi.com Silver Sponsor of the MariaDB Foundation
|
||||
Acronis http://www.acronis.com Silver Sponsor of the MariaDB Foundation
|
||||
Auttomattic https://automattic.com Bronze Sponsor of the MariaDB Foundation
|
||||
|
@@ -5628,6 +5628,23 @@ SELECT 'a','aa';
|
||||
a aa
|
||||
a aa
|
||||
#
|
||||
# MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
||||
#
|
||||
SET NAMES utf8, character_set_connection=ucs2;
|
||||
SET @save_optimizer_switch=@@optimizer_switch;
|
||||
SET optimizer_switch=_utf8'derived_merge=on';
|
||||
CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('abcdefghi');
|
||||
SET NAMES utf8, character_set_connection=ucs2;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT HEX(t) t2 FROM t1) sub;
|
||||
c2
|
||||
616263646566676869-616263646566676869
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TO_BASE64(t) t2 FROM t1) sub;
|
||||
c2
|
||||
YWJjZGVmZ2hp-YWJjZGVmZ2hp
|
||||
DROP TABLE t1;
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
#
|
||||
# End of 10.0 tests
|
||||
#
|
||||
select collation(cast("a" as char(10) unicode binary));
|
||||
|
@@ -149,3 +149,116 @@ CALL p1();
|
||||
########################################40100.000
|
||||
DROP PROCEDURE p1;
|
||||
# End of 5.1 tests
|
||||
#
|
||||
# Start of 10.0 tests
|
||||
#
|
||||
#
|
||||
# MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
||||
#
|
||||
SET @save_optimizer_switch=@@optimizer_switch;
|
||||
SET optimizer_switch='derived_merge=on';
|
||||
CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('1234567');
|
||||
SELECT CONCAT(SUBSTR(t2, 1, 3), SUBSTR(t2, 5)) c1,
|
||||
CONCAT(SUBSTR(t2,1,3),'---',SUBSTR(t2,5)) c2
|
||||
FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub;
|
||||
c1 c2
|
||||
123567 123---567
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub;
|
||||
c2
|
||||
1234567-1234567
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('1234567');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub;
|
||||
c2
|
||||
1234567-1234567
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT REVERSE(t) t2 FROM t1) sub;
|
||||
c2
|
||||
7654321-7654321
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT SOUNDEX(t) t2 FROM t1) sub;
|
||||
c2
|
||||
-
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TO_BASE64(t) t2 FROM t1) sub;
|
||||
c2
|
||||
MTIzNDU2Nw==-MTIzNDU2Nw==
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT WEIGHT_STRING(t) t2 FROM t1) sub;
|
||||
c2
|
||||
1234567-1234567
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT HEX(t) t2 FROM t1) sub;
|
||||
c2
|
||||
31323334353637-31323334353637
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT QUOTE(t) t2 FROM t1) sub;
|
||||
c2
|
||||
'1234567'-'1234567'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES(TO_BASE64('abcdefghi'));
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT FROM_BASE64(t) t2 FROM t1) sub;
|
||||
c2
|
||||
abcdefghi-abcdefghi
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES(HEX('abcdefghi'));
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UNHEX(t) t2 FROM t1) sub;
|
||||
c2
|
||||
abcdefghi-abcdefghi
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (t VARCHAR(30) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('test');
|
||||
SELECT LENGTH(CONCAT(t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub;
|
||||
c2
|
||||
16
|
||||
SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub;
|
||||
c2
|
||||
33
|
||||
SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub;
|
||||
c2
|
||||
34
|
||||
SELECT LENGTH(CONCAT(t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub;
|
||||
c2
|
||||
4
|
||||
SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub;
|
||||
c2
|
||||
9
|
||||
SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub;
|
||||
c2
|
||||
10
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (t VARCHAR(64) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('123456789');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT MD5(t) t2 FROM t1) sub;
|
||||
c2
|
||||
25f9e794323b453885f5181f1b624d0b-25f9e794323b453885f5181f1b624d0b
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT FORMAT(t,2) t2 FROM t1) sub;
|
||||
c2
|
||||
123,456,789.00-123,456,789.00
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('abcdefghi');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT INSERT(t,3,4,'xxx') t2 FROM t1) sub;
|
||||
c2
|
||||
abxxxghi-abxxxghi
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('abcdefghi');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LEFT(t,10) t2 FROM t1) sub;
|
||||
c2
|
||||
abcdefghi-abcdefghi
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT RIGHT(t,10) t2 FROM t1) sub;
|
||||
c2
|
||||
abcdefghi-abcdefghi
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT SUBSTR(t,1,10) t2 FROM t1) sub;
|
||||
c2
|
||||
abcdefghi-abcdefghi
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LTRIM(t) t2 FROM t1) sub;
|
||||
c2
|
||||
abcdefghi-abcdefghi
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT RTRIM(t) t2 FROM t1) sub;
|
||||
c2
|
||||
abcdefghi-abcdefghi
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TRIM(t) t2 FROM t1) sub;
|
||||
c2
|
||||
abcdefghi-abcdefghi
|
||||
DROP TABLE t1;
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
|
@@ -107,6 +107,24 @@ OLD_PASSWORD(c1) PASSWORD(c1)
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
#
|
||||
# Start of 10.0 tests
|
||||
#
|
||||
#
|
||||
# MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
||||
#
|
||||
SET @save_optimizer_switch=@@optimizer_switch;
|
||||
SET optimizer_switch='derived_merge=on';
|
||||
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('abcdefghi');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT ENCRYPT(t,'aa') t2 FROM t1) sub;
|
||||
c2
|
||||
aaHHlPHAM4sjs-aaHHlPHAM4sjs
|
||||
DROP TABLE t1;
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
#
|
||||
# End of 10.0 tests
|
||||
#
|
||||
#
|
||||
# Start of 10.1 tests
|
||||
#
|
||||
# Start of func_str_ascii_checksum.inc
|
||||
|
@@ -1715,6 +1715,24 @@ AsText(g)
|
||||
NULL
|
||||
POINT(1 1)
|
||||
#
|
||||
# MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
||||
#
|
||||
SET @save_optimizer_switch=@@optimizer_switch;
|
||||
SET optimizer_switch='derived_merge=on';
|
||||
CREATE TABLE t1 (x INT, y INT);
|
||||
INSERT INTO t1 VALUES(0,0);
|
||||
SELECT LENGTH(t2) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub;
|
||||
c2
|
||||
25
|
||||
SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub;
|
||||
c2
|
||||
51
|
||||
SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub;
|
||||
c2
|
||||
52
|
||||
DROP TABLE t1;
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
#
|
||||
# End 10.0 tests
|
||||
#
|
||||
SHOW CREATE TABLE information_schema.geometry_columns;
|
||||
|
@@ -2303,6 +2303,94 @@ pk f1 sq
|
||||
5 3 5
|
||||
set optimizer_switch= @save_optimizer_switch;
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# mdev-12838: scan of materialized of semi-join subquery in join
|
||||
#
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
CREATE TABLE t1 (
|
||||
dispatch_group varchar(32),
|
||||
assignment_group varchar(32),
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id),
|
||||
KEY idx1 (dispatch_group),
|
||||
KEY idx2 (assignment_group)
|
||||
) ENGINE=MyISAM;
|
||||
CREATE TABLE t2 (
|
||||
ugroup varchar(32),
|
||||
user varchar(32),
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id),
|
||||
KEY idx3 (ugroup),
|
||||
KEY idx4 (user)
|
||||
) ENGINE=MyISAM;
|
||||
CREATE TABLE t3 (
|
||||
type mediumtext,
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id)
|
||||
) ENGINE=MyISAM;
|
||||
set optimizer_switch='materialization=off';
|
||||
explain SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary
|
||||
1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
|
||||
1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary
|
||||
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
|
||||
SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
assignment_group
|
||||
df50316637232000158bbfc8bcbe5d23
|
||||
e08fad2637232000158bbfc8bcbe5d39
|
||||
ec70316637232000158bbfc8bcbe5d60
|
||||
7b10fd2637232000158bbfc8bcbe5d30
|
||||
ebb4620037332000158bbfc8bcbe5d89
|
||||
set optimizer_switch='materialization=on';
|
||||
explain SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
|
||||
1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where
|
||||
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
|
||||
2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where
|
||||
2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
|
||||
SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
assignment_group
|
||||
df50316637232000158bbfc8bcbe5d23
|
||||
e08fad2637232000158bbfc8bcbe5d39
|
||||
ec70316637232000158bbfc8bcbe5d60
|
||||
7b10fd2637232000158bbfc8bcbe5d30
|
||||
ebb4620037332000158bbfc8bcbe5d89
|
||||
DROP TABLE t1,t2,t3;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
# End of 5.5 tests
|
||||
#
|
||||
# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
|
||||
|
@@ -485,3 +485,20 @@ FROM t2 AS t2a INNER JOIN t2 t2b INNER JOIN t3
|
||||
ON (f3 = t2b.f2) );
|
||||
f1
|
||||
DROP TABLE t1,t2,t3;
|
||||
#
|
||||
# MDEV-12963: min/max optimization optimizing away all tables employed
|
||||
# for uncorrelated IN subquery used in a disjunct of WHERE
|
||||
#
|
||||
create table t1 (a int, index idx(a)) engine=myisam;
|
||||
insert into t1 values (4),(7),(1),(3),(9);
|
||||
select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
|
||||
a
|
||||
3
|
||||
7
|
||||
9
|
||||
explain
|
||||
select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index idx idx 5 NULL 5 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
drop table t1;
|
||||
|
@@ -1633,3 +1633,25 @@ Warnings:
|
||||
Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join (`test`.`t2`) where ((rand() < 0))
|
||||
drop table t1,t2;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
#
|
||||
# mdev-12855: materialization of a semi-join subquery + ORDER BY
|
||||
#
|
||||
CREATE TABLE t1 (f1 varchar(8), KEY(f1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES ('qux'),('foo');
|
||||
CREATE TABLE t2 (f2 varchar(8)) ENGINE=InnoDB;
|
||||
INSERT INTO t2 VALUES ('bar'),('foo'),('qux');
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' )
|
||||
HAVING f1 != 'foo'
|
||||
ORDER BY f1;
|
||||
f1
|
||||
qux
|
||||
explain SELECT f1 FROM t1
|
||||
WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' )
|
||||
HAVING f1 != 'foo'
|
||||
ORDER BY f1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index f1 f1 11 NULL 2 Using index
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 11 func 1
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
|
||||
DROP TABLE t1,t2;
|
||||
|
@@ -2343,6 +2343,94 @@ pk f1 sq
|
||||
5 3 5
|
||||
set optimizer_switch= @save_optimizer_switch;
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# mdev-12838: scan of materialized of semi-join subquery in join
|
||||
#
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
CREATE TABLE t1 (
|
||||
dispatch_group varchar(32),
|
||||
assignment_group varchar(32),
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id),
|
||||
KEY idx1 (dispatch_group),
|
||||
KEY idx2 (assignment_group)
|
||||
) ENGINE=MyISAM;
|
||||
CREATE TABLE t2 (
|
||||
ugroup varchar(32),
|
||||
user varchar(32),
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id),
|
||||
KEY idx3 (ugroup),
|
||||
KEY idx4 (user)
|
||||
) ENGINE=MyISAM;
|
||||
CREATE TABLE t3 (
|
||||
type mediumtext,
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id)
|
||||
) ENGINE=MyISAM;
|
||||
set optimizer_switch='materialization=off';
|
||||
explain SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary
|
||||
1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
|
||||
1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary
|
||||
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
|
||||
SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
assignment_group
|
||||
df50316637232000158bbfc8bcbe5d23
|
||||
e08fad2637232000158bbfc8bcbe5d39
|
||||
ec70316637232000158bbfc8bcbe5d60
|
||||
7b10fd2637232000158bbfc8bcbe5d30
|
||||
ebb4620037332000158bbfc8bcbe5d89
|
||||
set optimizer_switch='materialization=on';
|
||||
explain SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
|
||||
1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where
|
||||
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
|
||||
2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where
|
||||
2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
|
||||
SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
assignment_group
|
||||
df50316637232000158bbfc8bcbe5d23
|
||||
e08fad2637232000158bbfc8bcbe5d39
|
||||
ec70316637232000158bbfc8bcbe5d60
|
||||
7b10fd2637232000158bbfc8bcbe5d30
|
||||
ebb4620037332000158bbfc8bcbe5d89
|
||||
DROP TABLE t1,t2,t3;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
# End of 5.5 tests
|
||||
#
|
||||
# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
|
||||
|
@@ -5976,6 +5976,68 @@ use_case_id InitialDeadline
|
||||
10 2015-12-18
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-12666: CURRENT_ROLE() and DATABASE() does not work in a view
|
||||
#
|
||||
# DATABASE() fails only when the initial view creation features a NULL
|
||||
# default database.
|
||||
#
|
||||
# CREATE, USE and DROP database so that we have no "default" database.
|
||||
#
|
||||
CREATE DATABASE temporary;
|
||||
USE temporary;
|
||||
DROP DATABASE temporary;
|
||||
SELECT DATABASE();
|
||||
DATABASE()
|
||||
NULL
|
||||
CREATE VIEW test.v_no_db AS SELECT DATABASE() = 'temporary_two';
|
||||
SHOW CREATE VIEW test.v_no_db;
|
||||
View Create View character_set_client collation_connection
|
||||
v_no_db CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v_no_db` AS select (database() = 'temporary_two') AS `DATABASE() = 'temporary_two'` latin1 latin1_swedish_ci
|
||||
PREPARE prepared_no_database FROM "SELECT DATABASE() = 'temporary_two'";
|
||||
#
|
||||
# All statements should return NULL
|
||||
#
|
||||
EXECUTE prepared_no_database;
|
||||
DATABASE() = 'temporary_two'
|
||||
NULL
|
||||
SELECT DATABASE() = 'temporary_two';
|
||||
DATABASE() = 'temporary_two'
|
||||
NULL
|
||||
SELECT * FROM test.v_no_db;
|
||||
DATABASE() = 'temporary_two'
|
||||
NULL
|
||||
CREATE DATABASE temporary_two;
|
||||
USE temporary_two;
|
||||
CREATE VIEW test.v_with_db AS SELECT DATABASE() = 'temporary_two';
|
||||
PREPARE prepared_with_database FROM "SELECT DATABASE() = 'temporary_two'";
|
||||
#
|
||||
# All statements should return 1;
|
||||
#
|
||||
SELECT DATABASE() = 'temporary_two';
|
||||
DATABASE() = 'temporary_two'
|
||||
1
|
||||
SELECT * FROM test.v_no_db;
|
||||
DATABASE() = 'temporary_two'
|
||||
1
|
||||
SELECT * FROM test.v_with_db;
|
||||
DATABASE() = 'temporary_two'
|
||||
1
|
||||
EXECUTE prepared_with_database;
|
||||
DATABASE() = 'temporary_two'
|
||||
1
|
||||
#
|
||||
# Prepared statements maintain default database to be the same
|
||||
# during on creation so this should return NULL still.
|
||||
# See MySQL bug #25843
|
||||
#
|
||||
EXECUTE prepared_no_database;
|
||||
DATABASE() = 'temporary_two'
|
||||
NULL
|
||||
DROP DATABASE temporary_two;
|
||||
DROP VIEW test.v_no_db;
|
||||
DROP VIEW test.v_with_db;
|
||||
USE test;
|
||||
# -----------------------------------------------------------------
|
||||
# -- End of 10.0 tests.
|
||||
# -----------------------------------------------------------------
|
||||
|
6
mysql-test/suite/parts/r/quoting.result
Normal file
6
mysql-test/suite/parts/r/quoting.result
Normal file
@@ -0,0 +1,6 @@
|
||||
set sql_mode=ansi_quotes;
|
||||
create table t1 (i int) partition by range (i) (partition flush values less than maxvalue);
|
||||
set sql_mode=default;
|
||||
lock tables t1 read local;
|
||||
unlock tables;
|
||||
drop table t1;
|
10
mysql-test/suite/parts/t/quoting.test
Normal file
10
mysql-test/suite/parts/t/quoting.test
Normal file
@@ -0,0 +1,10 @@
|
||||
#
|
||||
# MDEV-13017 LOCK TABLE fails with irrelevant error while working with tables affected by ANSI_QUOTES
|
||||
#
|
||||
--source include/have_partition.inc
|
||||
set sql_mode=ansi_quotes;
|
||||
create table t1 (i int) partition by range (i) (partition flush values less than maxvalue);
|
||||
set sql_mode=default;
|
||||
lock tables t1 read local;
|
||||
unlock tables;
|
||||
drop table t1;
|
103
mysql-test/suite/roles/current_role_view-12666.result
Normal file
103
mysql-test/suite/roles/current_role_view-12666.result
Normal file
@@ -0,0 +1,103 @@
|
||||
CREATE USER has_role@'localhost';
|
||||
GRANT ALL PRIVILEGES ON *.* TO has_role@'localhost';
|
||||
CREATE ROLE test_role;
|
||||
GRANT test_role TO has_role@'localhost';
|
||||
CREATE USER no_role@'localhost';
|
||||
GRANT ALL PRIVILEGES ON *.* TO no_role@'localhost';
|
||||
CREATE TABLE view_role_test (
|
||||
id int primary key,
|
||||
role_name varchar(50)
|
||||
);
|
||||
INSERT INTO view_role_test VALUES (1, 'test_role');
|
||||
#
|
||||
# Use the same logic for stored procedures.
|
||||
#
|
||||
PREPARE prepared_no_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()";
|
||||
#
|
||||
# Creating a view with no CURRENT_ROLE() set and one with CURRENT_ROLE()
|
||||
# set. Both should produce the same SHOW CREATE VIEW output.
|
||||
#
|
||||
CREATE
|
||||
DEFINER = no_role@localhost
|
||||
SQL SECURITY INVOKER
|
||||
VIEW v_view_role_test_no_current_role
|
||||
AS
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
SHOW CREATE VIEW v_view_role_test_no_current_role;
|
||||
View Create View character_set_client collation_connection
|
||||
v_view_role_test_no_current_role CREATE ALGORITHM=UNDEFINED DEFINER=`no_role`@`localhost` SQL SECURITY INVOKER VIEW `v_view_role_test_no_current_role` AS select `view_role_test`.`id` AS `id`,`view_role_test`.`role_name` AS `role_name` from `view_role_test` where (`view_role_test`.`role_name` = current_role()) latin1 latin1_swedish_ci
|
||||
#
|
||||
# No values should be returned
|
||||
#
|
||||
EXECUTE prepared_no_current_role;
|
||||
id role_name
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
id role_name
|
||||
SELECT * FROM v_view_role_test_no_current_role;
|
||||
id role_name
|
||||
#
|
||||
# Now let's set the role. Create identical views as before. See if
|
||||
# their behaviour is different. It should not be.
|
||||
#
|
||||
SET ROLE test_role;
|
||||
SELECT CURRENT_USER();
|
||||
CURRENT_USER()
|
||||
root@localhost
|
||||
SELECT CURRENT_ROLE();
|
||||
CURRENT_ROLE()
|
||||
test_role
|
||||
#
|
||||
# Create the VIEW and prepared Statement with a CURRENT_ROLE() set.
|
||||
#
|
||||
CREATE
|
||||
DEFINER = no_role@localhost
|
||||
SQL SECURITY INVOKER
|
||||
VIEW v_view_role_test_with_current_role
|
||||
AS
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
PREPARE prepared_with_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()";
|
||||
SHOW CREATE VIEW v_view_role_test_with_current_role;
|
||||
View Create View character_set_client collation_connection
|
||||
v_view_role_test_with_current_role CREATE ALGORITHM=UNDEFINED DEFINER=`no_role`@`localhost` SQL SECURITY INVOKER VIEW `v_view_role_test_with_current_role` AS select `view_role_test`.`id` AS `id`,`view_role_test`.`role_name` AS `role_name` from `view_role_test` where (`view_role_test`.`role_name` = current_role()) latin1 latin1_swedish_ci
|
||||
#
|
||||
# Values should be returned for all select statements as we do have
|
||||
# a CURRENT_ROLE() active;
|
||||
#
|
||||
EXECUTE prepared_no_current_role;
|
||||
id role_name
|
||||
1 test_role
|
||||
EXECUTE prepared_with_current_role;
|
||||
id role_name
|
||||
1 test_role
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
id role_name
|
||||
1 test_role
|
||||
SELECT * FROM v_view_role_test_no_current_role;
|
||||
id role_name
|
||||
1 test_role
|
||||
SELECT * FROM v_view_role_test_with_current_role;
|
||||
id role_name
|
||||
1 test_role
|
||||
SET ROLE NONE;
|
||||
#
|
||||
# No values should be returned for all select statements as we do not have
|
||||
# a CURRENT_ROLE() active;
|
||||
#
|
||||
EXECUTE prepared_no_current_role;
|
||||
id role_name
|
||||
EXECUTE prepared_with_current_role;
|
||||
id role_name
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
id role_name
|
||||
SELECT * FROM v_view_role_test_no_current_role;
|
||||
id role_name
|
||||
SELECT * FROM v_view_role_test_with_current_role;
|
||||
id role_name
|
||||
DROP USER has_role@'localhost';
|
||||
DROP USER no_role@'localhost';
|
||||
DROP ROLE test_role;
|
||||
DROP table view_role_test;
|
||||
DROP VIEW v_view_role_test_no_current_role;
|
||||
DROP VIEW v_view_role_test_with_current_role;
|
||||
DROP PREPARE prepared_no_current_role;
|
||||
DROP PREPARE prepared_with_current_role;
|
102
mysql-test/suite/roles/current_role_view-12666.test
Normal file
102
mysql-test/suite/roles/current_role_view-12666.test
Normal file
@@ -0,0 +1,102 @@
|
||||
#
|
||||
# MDEV-12666 CURRENT_ROLE() does not work in a view
|
||||
#
|
||||
--source include/not_embedded.inc
|
||||
|
||||
CREATE USER has_role@'localhost';
|
||||
GRANT ALL PRIVILEGES ON *.* TO has_role@'localhost';
|
||||
|
||||
CREATE ROLE test_role;
|
||||
GRANT test_role TO has_role@'localhost';
|
||||
|
||||
CREATE USER no_role@'localhost';
|
||||
GRANT ALL PRIVILEGES ON *.* TO no_role@'localhost';
|
||||
|
||||
CREATE TABLE view_role_test (
|
||||
id int primary key,
|
||||
role_name varchar(50)
|
||||
);
|
||||
|
||||
INSERT INTO view_role_test VALUES (1, 'test_role');
|
||||
|
||||
--echo #
|
||||
--echo # Use the same logic for stored procedures.
|
||||
--echo #
|
||||
PREPARE prepared_no_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()";
|
||||
|
||||
--echo #
|
||||
--echo # Creating a view with no CURRENT_ROLE() set and one with CURRENT_ROLE()
|
||||
--echo # set. Both should produce the same SHOW CREATE VIEW output.
|
||||
--echo #
|
||||
CREATE
|
||||
DEFINER = no_role@localhost
|
||||
SQL SECURITY INVOKER
|
||||
VIEW v_view_role_test_no_current_role
|
||||
AS
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
|
||||
SHOW CREATE VIEW v_view_role_test_no_current_role;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # No values should be returned
|
||||
--echo #
|
||||
EXECUTE prepared_no_current_role;
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
SELECT * FROM v_view_role_test_no_current_role;
|
||||
|
||||
--echo #
|
||||
--echo # Now let's set the role. Create identical views as before. See if
|
||||
--echo # their behaviour is different. It should not be.
|
||||
--echo #
|
||||
SET ROLE test_role;
|
||||
|
||||
SELECT CURRENT_USER();
|
||||
SELECT CURRENT_ROLE();
|
||||
|
||||
--echo #
|
||||
--echo # Create the VIEW and prepared Statement with a CURRENT_ROLE() set.
|
||||
--echo #
|
||||
CREATE
|
||||
DEFINER = no_role@localhost
|
||||
SQL SECURITY INVOKER
|
||||
VIEW v_view_role_test_with_current_role
|
||||
AS
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
|
||||
PREPARE prepared_with_current_role FROM "SELECT * from view_role_test WHERE role_name = CURRENT_ROLE()";
|
||||
|
||||
SHOW CREATE VIEW v_view_role_test_with_current_role;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Values should be returned for all select statements as we do have
|
||||
--echo # a CURRENT_ROLE() active;
|
||||
--echo #
|
||||
EXECUTE prepared_no_current_role;
|
||||
EXECUTE prepared_with_current_role;
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
SELECT * FROM v_view_role_test_no_current_role;
|
||||
SELECT * FROM v_view_role_test_with_current_role;
|
||||
|
||||
SET ROLE NONE;
|
||||
--echo #
|
||||
--echo # No values should be returned for all select statements as we do not have
|
||||
--echo # a CURRENT_ROLE() active;
|
||||
--echo #
|
||||
EXECUTE prepared_no_current_role;
|
||||
EXECUTE prepared_with_current_role;
|
||||
SELECT * FROM view_role_test WHERE role_name = CURRENT_ROLE();
|
||||
SELECT * FROM v_view_role_test_no_current_role;
|
||||
SELECT * FROM v_view_role_test_with_current_role;
|
||||
|
||||
|
||||
DROP USER has_role@'localhost';
|
||||
DROP USER no_role@'localhost';
|
||||
DROP ROLE test_role;
|
||||
|
||||
DROP table view_role_test;
|
||||
DROP VIEW v_view_role_test_no_current_role;
|
||||
DROP VIEW v_view_role_test_with_current_role;
|
||||
DROP PREPARE prepared_no_current_role;
|
||||
DROP PREPARE prepared_with_current_role;
|
65
mysql-test/suite/roles/show_create_database-10463.result
Normal file
65
mysql-test/suite/roles/show_create_database-10463.result
Normal file
@@ -0,0 +1,65 @@
|
||||
drop database if exists db;
|
||||
Warnings:
|
||||
Note 1008 Can't drop database 'db'; database doesn't exist
|
||||
create role r1;
|
||||
create user beep@'%';
|
||||
create database db;
|
||||
create table db.t1 (i int);
|
||||
create table db.t2 (b int);
|
||||
grant select on db.* to r1;
|
||||
grant r1 to beep@'%';
|
||||
show databases;
|
||||
Database
|
||||
information_schema
|
||||
test
|
||||
show create database db;
|
||||
ERROR 42000: Access denied for user 'beep'@'localhost' to database 'db'
|
||||
select table_schema, table_name from information_schema.tables
|
||||
where table_schema = 'db';
|
||||
table_schema table_name
|
||||
set role r1;
|
||||
show databases;
|
||||
Database
|
||||
db
|
||||
information_schema
|
||||
test
|
||||
show create database db;
|
||||
Database Create Database
|
||||
db CREATE DATABASE `db` /*!40100 DEFAULT CHARACTER SET latin1 */
|
||||
select table_schema, table_name from information_schema.tables
|
||||
where table_schema = 'db';
|
||||
table_schema table_name
|
||||
db t1
|
||||
db t2
|
||||
create role r2;
|
||||
create user beep2@'%';
|
||||
grant update on db.* to r2;
|
||||
grant r2 to beep2;
|
||||
show databases;
|
||||
Database
|
||||
information_schema
|
||||
test
|
||||
show create database db;
|
||||
ERROR 42000: Access denied for user 'beep2'@'localhost' to database 'db'
|
||||
select table_schema, table_name from information_schema.tables
|
||||
where table_schema = 'db';
|
||||
table_schema table_name
|
||||
set role r2;
|
||||
show databases;
|
||||
Database
|
||||
db
|
||||
information_schema
|
||||
test
|
||||
show create database db;
|
||||
Database Create Database
|
||||
db CREATE DATABASE `db` /*!40100 DEFAULT CHARACTER SET latin1 */
|
||||
select table_schema, table_name from information_schema.tables
|
||||
where table_schema = 'db';
|
||||
table_schema table_name
|
||||
db t1
|
||||
db t2
|
||||
drop database db;
|
||||
drop role r1;
|
||||
drop user beep;
|
||||
drop role r2;
|
||||
drop user beep2;
|
55
mysql-test/suite/roles/show_create_database-10463.test
Normal file
55
mysql-test/suite/roles/show_create_database-10463.test
Normal file
@@ -0,0 +1,55 @@
|
||||
source include/not_embedded.inc;
|
||||
|
||||
drop database if exists db;
|
||||
|
||||
create role r1;
|
||||
create user beep@'%';
|
||||
|
||||
create database db;
|
||||
create table db.t1 (i int);
|
||||
create table db.t2 (b int);
|
||||
grant select on db.* to r1;
|
||||
grant r1 to beep@'%';
|
||||
|
||||
--connect (con1,localhost,beep,,)
|
||||
show databases;
|
||||
--error ER_DBACCESS_DENIED_ERROR
|
||||
show create database db;
|
||||
select table_schema, table_name from information_schema.tables
|
||||
where table_schema = 'db';
|
||||
|
||||
set role r1;
|
||||
show databases;
|
||||
show create database db;
|
||||
select table_schema, table_name from information_schema.tables
|
||||
where table_schema = 'db';
|
||||
|
||||
|
||||
connection default;
|
||||
create role r2;
|
||||
create user beep2@'%';
|
||||
|
||||
grant update on db.* to r2;
|
||||
grant r2 to beep2;
|
||||
--connect (con2,localhost,beep2,,)
|
||||
show databases;
|
||||
--error ER_DBACCESS_DENIED_ERROR
|
||||
show create database db;
|
||||
select table_schema, table_name from information_schema.tables
|
||||
where table_schema = 'db';
|
||||
|
||||
set role r2;
|
||||
show databases;
|
||||
|
||||
show create database db;
|
||||
select table_schema, table_name from information_schema.tables
|
||||
where table_schema = 'db';
|
||||
|
||||
|
||||
connection default;
|
||||
|
||||
drop database db;
|
||||
drop role r1;
|
||||
drop user beep;
|
||||
drop role r2;
|
||||
drop user beep2;
|
@@ -59,6 +59,12 @@ drop table t1;
|
||||
SELECT 'bug' as '' FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb'
|
||||
and SUPPORT='YES';
|
||||
|
||||
#
|
||||
# MDEV-13063 Server crashes in intern_plugin_lock or assertion `plugin_ptr->ref_count == 1' fails in plugin_init
|
||||
#
|
||||
--error 1
|
||||
--exec $MYSQLD_BOOTSTRAP_CMD --myisam_recover_options=NONE
|
||||
|
||||
--echo End of 5.5 tests
|
||||
|
||||
--source include/not_windows_embedded.inc
|
||||
|
@@ -927,6 +927,22 @@ SELECT CONCAT(CONVERT('pi=' USING ucs2),PI()) AS PI;
|
||||
SET NAMES utf8, character_set_connection=ucs2;
|
||||
SELECT 'a','aa';
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
||||
--echo #
|
||||
|
||||
SET NAMES utf8, character_set_connection=ucs2;
|
||||
SET @save_optimizer_switch=@@optimizer_switch;
|
||||
SET optimizer_switch=_utf8'derived_merge=on';
|
||||
CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('abcdefghi');
|
||||
SET NAMES utf8, character_set_connection=ucs2;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT HEX(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TO_BASE64(t) t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.0 tests
|
||||
--echo #
|
||||
|
@@ -145,3 +145,94 @@ CALL p1();
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
--echo # End of 5.1 tests
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.0 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
||||
--echo #
|
||||
|
||||
SET @save_optimizer_switch=@@optimizer_switch;
|
||||
SET optimizer_switch='derived_merge=on';
|
||||
|
||||
CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('1234567');
|
||||
SELECT CONCAT(SUBSTR(t2, 1, 3), SUBSTR(t2, 5)) c1,
|
||||
CONCAT(SUBSTR(t2,1,3),'---',SUBSTR(t2,5)) c2
|
||||
FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
|
||||
# Other functions affected by MDEV-10306
|
||||
|
||||
CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('1234567');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT CONVERT(t USING latin1) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT REVERSE(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT SOUNDEX(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TO_BASE64(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT WEIGHT_STRING(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT HEX(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT QUOTE(t) t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES(TO_BASE64('abcdefghi'));
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT FROM_BASE64(t) t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES(HEX('abcdefghi'));
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UNHEX(t) t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (t VARCHAR(30) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('test');
|
||||
SELECT LENGTH(CONCAT(t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub;
|
||||
SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub;
|
||||
SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT AES_ENCRYPT(t,'x') t2 FROM t1) sub;
|
||||
SELECT LENGTH(CONCAT(t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub;
|
||||
SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub;
|
||||
SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT AES_DECRYPT(AES_ENCRYPT(t,'x'),'x') t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
# Functions not affected by MDEV-10306
|
||||
# They only had an unused tmp_value, which was removed.
|
||||
|
||||
CREATE TABLE t1 (t VARCHAR(64) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('123456789');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT MD5(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT FORMAT(t,2) t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
|
||||
# Functions not affected by MDEV-10306
|
||||
# They already use tmp_value only for internal purposes and
|
||||
# return the result in the String passed to val_str()
|
||||
|
||||
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('abcdefghi');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT INSERT(t,3,4,'xxx') t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
# Functions not affected by MDEV-10306
|
||||
# They use this code style:
|
||||
# String *res= args[0]->val_str(str);
|
||||
# tmp_value.set(*res, start, end);
|
||||
# return &tmp_value;
|
||||
|
||||
CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('abcdefghi');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LEFT(t,10) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT RIGHT(t,10) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT SUBSTR(t,1,10) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LTRIM(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT RTRIM(t) t2 FROM t1) sub;
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT TRIM(t) t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
|
@@ -70,6 +70,28 @@ SELECT OLD_PASSWORD(c1), PASSWORD(c1) FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
--echo #
|
||||
--echo # Start of 10.0 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
||||
--echo #
|
||||
|
||||
SET @save_optimizer_switch=@@optimizer_switch;
|
||||
SET optimizer_switch='derived_merge=on';
|
||||
# ENCRYPT() is not affected by MDEV-10306
|
||||
# It already uses tmp_value only for internal purposes and
|
||||
# returns the result in the String passed to val_str()
|
||||
CREATE TABLE t1 (t VARCHAR(32) CHARSET latin1);
|
||||
INSERT INTO t1 VALUES('abcdefghi');
|
||||
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT ENCRYPT(t,'aa') t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.0 tests
|
||||
--echo #
|
||||
|
||||
|
||||
--echo #
|
||||
|
@@ -1464,6 +1464,21 @@ DROP VIEW v1;
|
||||
--echo #
|
||||
SELECT AsText(g) FROM (SELECT NULL AS g UNION SELECT Point(1,1)) AS t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10306 Wrong results with combination of CONCAT, SUBSTR and CONVERT in subquery
|
||||
--echo #
|
||||
|
||||
SET @save_optimizer_switch=@@optimizer_switch;
|
||||
SET optimizer_switch='derived_merge=on';
|
||||
CREATE TABLE t1 (x INT, y INT);
|
||||
INSERT INTO t1 VALUES(0,0);
|
||||
SELECT LENGTH(t2) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub;
|
||||
SELECT LENGTH(CONCAT(t2,'-',t2)) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub;
|
||||
SELECT LENGTH(CONCAT(t2,'--',t2)) c2 FROM (SELECT ST_BUFFER(POINT(x,y), 0) t2 FROM t1) sub;
|
||||
DROP TABLE t1;
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End 10.0 tests
|
||||
--echo #
|
||||
|
@@ -507,3 +507,19 @@ SELECT * FROM t1
|
||||
ON (f3 = t2b.f2) );
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-12963: min/max optimization optimizing away all tables employed
|
||||
--echo # for uncorrelated IN subquery used in a disjunct of WHERE
|
||||
--echo #
|
||||
|
||||
create table t1 (a int, index idx(a)) engine=myisam;
|
||||
insert into t1 values (4),(7),(1),(3),(9);
|
||||
|
||||
select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
|
||||
explain
|
||||
select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
|
||||
|
||||
drop table t1;
|
||||
|
||||
|
||||
|
@@ -283,3 +283,23 @@ select * from t1 where (rand() < 0) and i in (select i from t2);
|
||||
|
||||
drop table t1,t2;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
--echo #
|
||||
--echo # mdev-12855: materialization of a semi-join subquery + ORDER BY
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (f1 varchar(8), KEY(f1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES ('qux'),('foo');
|
||||
CREATE TABLE t2 (f2 varchar(8)) ENGINE=InnoDB;
|
||||
INSERT INTO t2 VALUES ('bar'),('foo'),('qux');
|
||||
|
||||
let $q=
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' )
|
||||
HAVING f1 != 'foo'
|
||||
ORDER BY f1;
|
||||
|
||||
eval $q;
|
||||
eval explain $q;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
@@ -1950,6 +1950,213 @@ set optimizer_switch= @save_optimizer_switch;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # mdev-12838: scan of materialized of semi-join subquery in join
|
||||
--echo #
|
||||
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
|
||||
CREATE TABLE t1 (
|
||||
dispatch_group varchar(32),
|
||||
assignment_group varchar(32),
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id),
|
||||
KEY idx1 (dispatch_group),
|
||||
KEY idx2 (assignment_group)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
CREATE TABLE t2 (
|
||||
ugroup varchar(32),
|
||||
user varchar(32),
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id),
|
||||
KEY idx3 (ugroup),
|
||||
KEY idx4 (user)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
CREATE TABLE t3 (
|
||||
type mediumtext,
|
||||
sys_id char(32),
|
||||
PRIMARY KEY (sys_id)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
--disable_query_log
|
||||
|
||||
INSERT INTO t1 VALUES
|
||||
('e5d9f63237232000158bbfc8bcbe5dbf','f304ae0037332000158bbfc8bcbe5d4f',
|
||||
'5398c0e037003000158bbfc8bcbe5dbb'),
|
||||
('69d9f63237232000158bbfc8bcbe5dcb','7172ea0037332000158bbfc8bcbe5db6',
|
||||
'5c188ca037003000158bbfc8bcbe5dbc'),
|
||||
('577ed708d773020058c92cf65e61037a','699708d4d773020058c92cf65e61037c',
|
||||
'623a8cd4d773020058c92cf65e6103ea'),
|
||||
('96fb652637232000158bbfc8bcbe5db4','df50316637232000158bbfc8bcbe5d23',
|
||||
'6835bd6637232000158bbfc8bcbe5d21'),
|
||||
('e1d9f63237232000158bbfc8bcbe5db8','96346e0037332000158bbfc8bcbe5daa',
|
||||
'697880e037003000158bbfc8bcbe5dcd'),
|
||||
('25d9f63237232000158bbfc8bcbe5dbe','f304ae0037332000158bbfc8bcbe5d4f',
|
||||
'6a9804e037003000158bbfc8bcbe5d09'),
|
||||
('96fb652637232000158bbfc8bcbe5db4','e08fad2637232000158bbfc8bcbe5d39',
|
||||
'6d25f96637232000158bbfc8bcbe5d79'),
|
||||
('e9d9f63237232000158bbfc8bcbe5dc6','7172ea0037332000158bbfc8bcbe5db6',
|
||||
'702880e037003000158bbfc8bcbe5d94'),
|
||||
('a5d9f63237232000158bbfc8bcbe5dca','f304ae0037332000158bbfc8bcbe5d4f',
|
||||
'7188c0e037003000158bbfc8bcbe5d75'),
|
||||
('65d9f63237232000158bbfc8bcbe5dc4','f304ae0037332000158bbfc8bcbe5d4f',
|
||||
'778880e037003000158bbfc8bcbe5d9e'),
|
||||
('a1d9f63237232000158bbfc8bcbe5dc3','7172ea0037332000158bbfc8bcbe5db6',
|
||||
'7d0840e037003000158bbfc8bcbe5dde'),
|
||||
('21d9f63237232000158bbfc8bcbe5db7','96346e0037332000158bbfc8bcbe5daa',
|
||||
'7f6880e037003000158bbfc8bcbe5da7'),
|
||||
('96fb652637232000158bbfc8bcbe5db4','ec70316637232000158bbfc8bcbe5d60',
|
||||
'8025f96637232000158bbfc8bcbe5dd0'),
|
||||
('3dd9f63237232000158bbfc8bcbe5dcc','7172ea0037332000158bbfc8bcbe5db6',
|
||||
'823880e037003000158bbfc8bcbe5ded'),
|
||||
('96fb652637232000158bbfc8bcbe5db4','7b10fd2637232000158bbfc8bcbe5d30',
|
||||
'9a353d6637232000158bbfc8bcbe5dee'),
|
||||
('75d9f63237232000158bbfc8bcbe5dd0','ebb4620037332000158bbfc8bcbe5d89',
|
||||
'a558c0e037003000158bbfc8bcbe5d36'),
|
||||
('6dd9f63237232000158bbfc8bcbe5db5','96346e0037332000158bbfc8bcbe5daa',
|
||||
'bc78cca037003000158bbfc8bcbe5d74'),
|
||||
('add9f63237232000158bbfc8bcbe5dc7','7172ea0037332000158bbfc8bcbe5db6',
|
||||
'c53804a037003000158bbfc8bcbe5db8'),
|
||||
('fdd9f63237232000158bbfc8bcbe5dcd','7864ae0037332000158bbfc8bcbe5db8',
|
||||
'cfe740e037003000158bbfc8bcbe5de8'),
|
||||
('96fb652637232000158bbfc8bcbe5db4','3120fd2637232000158bbfc8bcbe5d42',
|
||||
'e2257d6637232000158bbfc8bcbe5ded'),
|
||||
('3c3725e237232000158bbfc8bcbe5da1','96346e0037332000158bbfc8bcbe5daa',
|
||||
'ee78c0e037003000158bbfc8bcbe5db5'),
|
||||
('a9d9f63237232000158bbfc8bcbe5dc0','7172ea0037332000158bbfc8bcbe5db6',
|
||||
'f00888a037003000158bbfc8bcbe5dd3'),
|
||||
('29d9f63237232000158bbfc8bcbe5db9','7172ea0037332000158bbfc8bcbe5db6',
|
||||
'fa0880e037003000158bbfc8bcbe5d70'),
|
||||
('b1d9f63237232000158bbfc8bcbe5dcf','ebb4620037332000158bbfc8bcbe5d89',
|
||||
'fa48c0e037003000158bbfc8bcbe5d28');
|
||||
|
||||
INSERT INTO t2 VALUES
|
||||
('17801ac21b13200050fdfbcd2c0713e8','8e826bf03710200044e0bfc8bcbe5d86',
|
||||
'14c19a061b13200050fdfbcd2c07134b'),
|
||||
('577ed708d773020058c92cf65e61037a','931644d4d773020058c92cf65e61034c',
|
||||
'339888d4d773020058c92cf65e6103aa'),
|
||||
('df50316637232000158bbfc8bcbe5d23','92826bf03710200044e0bfc8bcbe5da9',
|
||||
'3682f56637232000158bbfc8bcbe5d44'),
|
||||
('b4f342b237232000158bbfc8bcbe5def','86826bf03710200044e0bfc8bcbe5d70',
|
||||
'38e4c2b237232000158bbfc8bcbe5dea'),
|
||||
('7b10fd2637232000158bbfc8bcbe5d30','8a826bf03710200044e0bfc8bcbe5d72',
|
||||
'4442b56637232000158bbfc8bcbe5d43'),
|
||||
('3120fd2637232000158bbfc8bcbe5d42','82826bf03710200044e0bfc8bcbe5d89',
|
||||
'49d2396637232000158bbfc8bcbe5d12'),
|
||||
('96fb652637232000158bbfc8bcbe5db4','86826bf03710200044e0bfc8bcbe5d79',
|
||||
'4e3ca52637232000158bbfc8bcbe5d3e'),
|
||||
('17801ac21b13200050fdfbcd2c0713e8','824fd523bf4320007a6d257b3f073963',
|
||||
'58c19a061b13200050fdfbcd2c07134e'),
|
||||
('699708d4d773020058c92cf65e61037c','901784d4d773020058c92cf65e6103da',
|
||||
'5bc708d4d773020058c92cf65e6103d5'),
|
||||
('75d9f63237232000158bbfc8bcbe5dd0','86826bf03710200044e0bfc8bcbe5d79',
|
||||
'6b52cb7237232000158bbfc8bcbe5ded'),
|
||||
('f253da061b13200050fdfbcd2c0713ab','8e826bf03710200044e0bfc8bcbe5d86',
|
||||
'81045e061b13200050fdfbcd2c071373'),
|
||||
('7b10fd2637232000158bbfc8bcbe5d30','8e826bf03710200044e0bfc8bcbe5d74',
|
||||
'8c42b56637232000158bbfc8bcbe5d3f'),
|
||||
('e5d9f63237232000158bbfc8bcbe5dbf','7a826bf03710200044e0bfc8bcbe5df5',
|
||||
'a7acfe3237232000158bbfc8bcbe5d78'),
|
||||
('8a5055c9c61122780043563ef53438e3','9ee1b13dc6112271007f9d0efdb69cd0',
|
||||
'a9aff553c6112276015a8006174bee21'),
|
||||
('8a4dde73c6112278017a6a4baf547aa7','9ee1b13dc6112271007f9d0efdb69cd0',
|
||||
'a9b2f526c61122760003ae07349d294f'),
|
||||
('aaccc971c0a8001500fe1ff4302de101','9ee1b13dc6112271007f9d0efdb69cd0',
|
||||
'aacceed3c0a80015009069bba51c4e21'),
|
||||
('65d9f63237232000158bbfc8bcbe5dc4','8d56406a0a0a0a6b004070b354aada28',
|
||||
'ac1bfa3237232000158bbfc8bcbe5dc3'),
|
||||
('b85d44954a3623120004689b2d5dd60a','97000fcc0a0a0a6e0104ca999f619e5b',
|
||||
'b77bc032cbb00200d71cb9c0c24c9c45'),
|
||||
('220f8e71c61122840197e57c33464f70','8d56406a0a0a0a6b004070b354aada28',
|
||||
'b9b74f080a0a0b343ba75b95bdb27056'),
|
||||
('e08fad2637232000158bbfc8bcbe5d39','82826bf03710200044e0bfc8bcbe5d80',
|
||||
'be02756637232000158bbfc8bcbe5d8b'),
|
||||
('ebb4620037332000158bbfc8bcbe5d89','7682abf03710200044e0bfc8bcbe5d25',
|
||||
'c0122f4437732000158bbfc8bcbe5d7d'),
|
||||
('96fb652637232000158bbfc8bcbe5db4','7a82abf03710200044e0bfc8bcbe5d27',
|
||||
'c23ca52637232000158bbfc8bcbe5d3b'),
|
||||
('22122b37c611228400f9ff91c857581d','9ee1b13dc6112271007f9d0efdb69cd0',
|
||||
'd23bbf5dac14641866947512bde59dc5'),
|
||||
('db53a9290a0a0a650091abebccf833c6','9ee1b13dc6112271007f9d0efdb69cd0',
|
||||
'db54a0f60a0a0a65002c54dcb72b4f41'),
|
||||
('e08fad2637232000158bbfc8bcbe5d39','8e826bf03710200044e0bfc8bcbe5d86',
|
||||
'f602756637232000158bbfc8bcbe5d88'),
|
||||
('699708d4d773020058c92cf65e61037c','8d59d601d7b3020058c92cf65e6103c2',
|
||||
'f718a241d7b3020058c92cf65e610332'),
|
||||
('df50316637232000158bbfc8bcbe5d23','9e826bf03710200044e0bfc8bcbe5da6',
|
||||
'fe82f56637232000158bbfc8bcbe5d4e'),
|
||||
('f972d6061b13200050fdfbcd2c0713e5','780395f0df031100a9e78b6c3df2631f',
|
||||
'ff4395f0df031100a9e78b6c3df2637e');
|
||||
|
||||
INSERT INTO t3 VALUES
|
||||
('87245e061b13200050fdfbcd2c0713cc','7172ea0037332000158bbfc8bcbe5db6'),
|
||||
('74af88c6c611227d0066386e74dc853d','74ad1ff3c611227d01d25feac2af603f'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','75d9f63237232000158bbfc8bcbe5dd0'),
|
||||
('98906fb137032000158bbfc8bcbe5d65','781da52637232000158bbfc8bcbe5db8'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','7864ae0037332000158bbfc8bcbe5db8'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','7b10fd2637232000158bbfc8bcbe5d30'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','81a880e037003000158bbfc8bcbe5df8'),
|
||||
('74af88c6c611227d0066386e74dc853d','8a4cb6d4c61122780043b1642efcd52b'),
|
||||
('1cb8ab9bff500200158bffffffffff62','8a4dde73c6112278017a6a4baf547aa7'),
|
||||
('1cb8ab9bff500200158bffffffffff62','8a5055c9c61122780043563ef53438e3'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','96346e0037332000158bbfc8bcbe5daa'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','96fb652637232000158bbfc8bcbe5db4'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','a1d9f63237232000158bbfc8bcbe5dc3'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','a5d9f63237232000158bbfc8bcbe5dca'),
|
||||
('1cb8ab9bff500200158bffffffffff62','a715cd759f2002002920bde8132e7018'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','a9d9f63237232000158bbfc8bcbe5dc0'),
|
||||
('74af88c6c611227d0066386e74dc853d','aacb62e2c0a80015007f67f752c2b12c'),
|
||||
('74af88c6c611227d0066386e74dc853d','aaccc971c0a8001500fe1ff4302de101'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','add9f63237232000158bbfc8bcbe5dbb'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','add9f63237232000158bbfc8bcbe5dc7'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','b1d9f63237232000158bbfc8bcbe5dcf'),
|
||||
('1cb8ab9bff500200158bffffffffff62','b85d44954a3623120004689b2d5dd60a'),
|
||||
('1cb8ab9bff500200158bffffffffff62','b97e89b94a36231201676b73322a0311'),
|
||||
('1cb8ab9bff500200158bffffffffff62','cfcbad03d711110050f5edcb9e61038f'),
|
||||
('1cb8ab9bff500200158bffffffffff62','d625dccec0a8016700a222a0f7900d06'),
|
||||
('1cb8ab9bff500200158bffffffffff62','db53580b0a0a0a6501aa37c294a2ba6b'),
|
||||
('1cb8ab9bff500200158bffffffffff62','db53a9290a0a0a650091abebccf833c6'),
|
||||
('1cb8ab9bff500200158bffffffffff62','dc0db135c332010016194ffe5bba8f23'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','df50316637232000158bbfc8bcbe5d23'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','e08fad2637232000158bbfc8bcbe5d39'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','e1d9f63237232000158bbfc8bcbe5db8'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','e5d9f63237232000158bbfc8bcbe5db4'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','e5d9f63237232000158bbfc8bcbe5dbf'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','e9d9f63237232000158bbfc8bcbe5dba'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','e9d9f63237232000158bbfc8bcbe5dc6'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','ebb4620037332000158bbfc8bcbe5d89'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','ec70316637232000158bbfc8bcbe5d60'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','f253da061b13200050fdfbcd2c0713ab'),
|
||||
('87245e061b13200050fdfbcd2c0713cc','f304ae0037332000158bbfc8bcbe5d4f'),
|
||||
('98906fb137032000158bbfc8bcbe5d65','f972d6061b13200050fdfbcd2c0713e5'),
|
||||
('59e22fb137032000158bbfc8bcbe5d52','fdd9f63237232000158bbfc8bcbe5dcd');
|
||||
|
||||
--enable_query_log
|
||||
|
||||
let $q=
|
||||
SELECT t1.assignment_group
|
||||
FROM t1, t3
|
||||
WHERE t1.assignment_group = t3.sys_id AND
|
||||
t1.dispatch_group IN
|
||||
(SELECT t2.ugroup
|
||||
FROM t2, t3 t3_i
|
||||
WHERE t2.ugroup = t3_i.sys_id AND
|
||||
t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
|
||||
t2.user = '86826bf03710200044e0bfc8bcbe5d79');
|
||||
|
||||
set optimizer_switch='materialization=off';
|
||||
eval explain $q;
|
||||
eval $q;
|
||||
|
||||
set optimizer_switch='materialization=on';
|
||||
eval explain $q;
|
||||
eval $q;
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
--echo # End of 5.5 tests
|
||||
--echo #
|
||||
--echo # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
|
||||
|
@@ -5826,6 +5826,55 @@ SELECT * FROM v1 where use_case_id = 10;
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-12666: CURRENT_ROLE() and DATABASE() does not work in a view
|
||||
--echo #
|
||||
--echo # DATABASE() fails only when the initial view creation features a NULL
|
||||
--echo # default database.
|
||||
--echo #
|
||||
--echo # CREATE, USE and DROP database so that we have no "default" database.
|
||||
--echo #
|
||||
CREATE DATABASE temporary;
|
||||
USE temporary;
|
||||
DROP DATABASE temporary;
|
||||
SELECT DATABASE();
|
||||
|
||||
CREATE VIEW test.v_no_db AS SELECT DATABASE() = 'temporary_two';
|
||||
SHOW CREATE VIEW test.v_no_db;
|
||||
PREPARE prepared_no_database FROM "SELECT DATABASE() = 'temporary_two'";
|
||||
|
||||
--echo #
|
||||
--echo # All statements should return NULL
|
||||
--echo #
|
||||
EXECUTE prepared_no_database;
|
||||
SELECT DATABASE() = 'temporary_two';
|
||||
SELECT * FROM test.v_no_db;
|
||||
|
||||
CREATE DATABASE temporary_two;
|
||||
USE temporary_two;
|
||||
CREATE VIEW test.v_with_db AS SELECT DATABASE() = 'temporary_two';
|
||||
PREPARE prepared_with_database FROM "SELECT DATABASE() = 'temporary_two'";
|
||||
|
||||
--echo #
|
||||
--echo # All statements should return 1;
|
||||
--echo #
|
||||
SELECT DATABASE() = 'temporary_two';
|
||||
SELECT * FROM test.v_no_db;
|
||||
SELECT * FROM test.v_with_db;
|
||||
EXECUTE prepared_with_database;
|
||||
|
||||
--echo #
|
||||
--echo # Prepared statements maintain default database to be the same
|
||||
--echo # during on creation so this should return NULL still.
|
||||
--echo # See MySQL bug #25843
|
||||
--echo #
|
||||
EXECUTE prepared_no_database;
|
||||
|
||||
DROP DATABASE temporary_two;
|
||||
DROP VIEW test.v_no_db;
|
||||
DROP VIEW test.v_with_db;
|
||||
USE test;
|
||||
|
||||
--echo # -----------------------------------------------------------------
|
||||
--echo # -- End of 10.0 tests.
|
||||
--echo # -----------------------------------------------------------------
|
||||
|
@@ -205,7 +205,7 @@ int my_realpath(char *to, const char *filename, myf MyFlags)
|
||||
|
||||
const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
char buf[FN_REFLEN + 1];
|
||||
char *s= buf, *e= buf+1, *end= strnmov(buf, pathname, sizeof(buf));
|
||||
int fd, dfd= -1;
|
||||
|
||||
|
@@ -126,12 +126,21 @@ const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd);
|
||||
res= AT; \
|
||||
if (dfd >= 0) close(dfd); \
|
||||
return res;
|
||||
#elif defined(HAVE_REALPATH)
|
||||
#elif defined(HAVE_REALPATH) && defined(PATH_MAX)
|
||||
#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
|
||||
char buf[PATH_MAX+1]; \
|
||||
if (realpath(pathname, buf) == NULL) return -1; \
|
||||
if (strcmp(pathname, buf)) { errno= ENOTDIR; return -1; } \
|
||||
return NOAT;
|
||||
#elif defined(HAVE_REALPATH)
|
||||
#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
|
||||
char *buf= realpath(pathname, NULL); \
|
||||
int res; \
|
||||
if (buf == NULL) return -1; \
|
||||
if (strcmp(pathname, buf)) { errno= ENOTDIR; res= -1; } \
|
||||
else res= NOAT; \
|
||||
free(buf); \
|
||||
return res;
|
||||
#else
|
||||
#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
|
||||
return NOAT;
|
||||
|
@@ -39,9 +39,11 @@ struct show_table_contributors_st show_table_contributors[]= {
|
||||
/* MariaDB foundation sponsors, in contribution, size , time order */
|
||||
{"Booking.com", "https://www.booking.com", "Founding member, Platinum Sponsor of the MariaDB Foundation"},
|
||||
{"Alibaba Cloud", "https://intl.aliyun.com", "Platinum Sponsor of the MariaDB Foundation"},
|
||||
{"Tencent Cloud", "https://cloud.tencent.com", "Platinum Sponsor of the MariaDB Foundation"},
|
||||
{"MariaDB Corporation", "https://mariadb.com", "Founding member, Gold Sponsor of the MariaDB Foundation"},
|
||||
{"Visma", "https://visma.com", "Gold Sponsor of the MariaDB Foundation"},
|
||||
{"DBS", "https://dbs.com", "Gold Sponsor of the MariaDB Foundation"},
|
||||
{"IBM", "https://www.ibm.com", "Gold Sponsor of the MariaDB Foundation"},
|
||||
{"Nexedi", "https://www.nexedi.com", "Silver Sponsor of the MariaDB Foundation"},
|
||||
{"Acronis", "http://www.acronis.com", "Silver Sponsor of the MariaDB Foundation"},
|
||||
{"Auttomattic", "https://automattic.com", "Bronze Sponsor of the MariaDB Foundation"},
|
||||
|
35
sql/item.h
35
sql/item.h
@@ -857,25 +857,20 @@ public:
|
||||
store return value of this method.
|
||||
|
||||
NOTE
|
||||
Buffer passed via argument should only be used if the item itself
|
||||
doesn't have an own String buffer. In case when the item maintains
|
||||
it's own string buffer, it's preferable to return it instead to
|
||||
minimize number of mallocs/memcpys.
|
||||
The caller of this method can modify returned string, but only in case
|
||||
when it was allocated on heap, (is_alloced() is true). This allows
|
||||
the caller to efficiently use a buffer allocated by a child without
|
||||
having to allocate a buffer of it's own. The buffer, given to
|
||||
val_str() as argument, belongs to the caller and is later used by the
|
||||
caller at it's own choosing.
|
||||
A few implications from the above:
|
||||
- unless you return a string object which only points to your buffer
|
||||
but doesn't manages it you should be ready that it will be
|
||||
modified.
|
||||
- even for not allocated strings (is_alloced() == false) the caller
|
||||
can change charset (see Item_func_{typecast/binary}. XXX: is this
|
||||
a bug?
|
||||
- still you should try to minimize data copying and return internal
|
||||
object whenever possible.
|
||||
The caller can modify the returned String, if it's not marked
|
||||
"const" (with the String::mark_as_const() method). That means that
|
||||
if the item returns its own internal buffer (e.g. tmp_value), it
|
||||
*must* be marked "const" [1]. So normally it's preferrable to
|
||||
return the result value in the String, that was passed as an
|
||||
argument. But, for example, SUBSTR() returns a String that simply
|
||||
points into the buffer of SUBSTR()'s args[0]->val_str(). Such a
|
||||
String is always "const", so it's ok to use tmp_value for that and
|
||||
avoid reallocating/copying of the argument String.
|
||||
|
||||
[1] consider SELECT CONCAT(f, ":", f) FROM (SELECT func() AS f);
|
||||
here the return value of f() is used twice in the top-level
|
||||
select, and if they share the same tmp_value buffer, modifying the
|
||||
first one will implicitly modify the second too.
|
||||
|
||||
RETURN
|
||||
In case of NULL value return 0 (NULL pointer) and set null_value flag
|
||||
@@ -1651,7 +1646,7 @@ public:
|
||||
{ return this; }
|
||||
virtual bool expr_cache_is_needed(THD *) { return FALSE; }
|
||||
virtual Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
|
||||
bool needs_charset_converter(uint32 length, CHARSET_INFO *tocs)
|
||||
bool needs_charset_converter(uint32 length, CHARSET_INFO *tocs) const
|
||||
{
|
||||
/*
|
||||
This will return "true" if conversion happens:
|
||||
|
@@ -1859,7 +1859,7 @@ String *Item_func_buffer::val_str(String *str_value)
|
||||
{
|
||||
DBUG_ENTER("Item_func_buffer::val_str");
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String *obj= args[0]->val_str(&tmp_value);
|
||||
String *obj= args[0]->val_str(str_value);
|
||||
double dist= args[1]->val_real();
|
||||
Geometry_buffer buffer;
|
||||
Geometry *g;
|
||||
|
@@ -239,7 +239,6 @@ public:
|
||||
|
||||
class Item_func_spatial_collection: public Item_geometry_func
|
||||
{
|
||||
String tmp_value;
|
||||
enum Geometry::wkbType coll_type;
|
||||
enum Geometry::wkbType item_type;
|
||||
public:
|
||||
@@ -412,7 +411,6 @@ protected:
|
||||
|
||||
Gcalc_result_receiver res_receiver;
|
||||
Gcalc_operation_reducer operation;
|
||||
String tmp_value;
|
||||
|
||||
public:
|
||||
Item_func_buffer(THD *thd, Item *obj, Item *distance):
|
||||
|
@@ -67,8 +67,14 @@ size_t username_char_length= 80;
|
||||
Conversion happens only in case of "tricky" Item character set (e.g. UCS2).
|
||||
Normally conversion does not happen, and val_str_ascii() is immediately
|
||||
returned instead.
|
||||
|
||||
No matter if conversion is needed or not needed,
|
||||
the result is always returned in "str" (see MDEV-10306 why).
|
||||
|
||||
@param [OUT] str - Store the result here
|
||||
@param [IN] ascii_buffer - Use this temporary buffer to call val_str_ascii()
|
||||
*/
|
||||
String *Item_func::val_str_from_val_str_ascii(String *str, String *str2)
|
||||
String *Item_func::val_str_from_val_str_ascii(String *str, String *ascii_buffer)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
||||
@@ -80,19 +86,19 @@ String *Item_func::val_str_from_val_str_ascii(String *str, String *str2)
|
||||
return res;
|
||||
}
|
||||
|
||||
DBUG_ASSERT(str != str2);
|
||||
DBUG_ASSERT(str != ascii_buffer);
|
||||
|
||||
uint errors;
|
||||
String *res= val_str_ascii(str);
|
||||
String *res= val_str_ascii(ascii_buffer);
|
||||
if (!res)
|
||||
return 0;
|
||||
|
||||
if ((null_value= str2->copy(res->ptr(), res->length(),
|
||||
if ((null_value= str->copy(res->ptr(), res->length(),
|
||||
&my_charset_latin1, collation.collation,
|
||||
&errors)))
|
||||
return 0;
|
||||
|
||||
return str2;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -308,11 +314,11 @@ void Item_aes_crypt::create_key(String *user_key, uchar *real_key)
|
||||
}
|
||||
|
||||
|
||||
String *Item_aes_crypt::val_str(String *str)
|
||||
String *Item_aes_crypt::val_str(String *str2)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
StringBuffer<80> user_key_buf;
|
||||
String *sptr= args[0]->val_str(str);
|
||||
String *sptr= args[0]->val_str(&str_value);
|
||||
String *user_key= args[1]->val_str(&user_key_buf);
|
||||
uint32 aes_length;
|
||||
|
||||
@@ -321,17 +327,17 @@ String *Item_aes_crypt::val_str(String *str)
|
||||
null_value=0;
|
||||
aes_length=my_aes_get_size(MY_AES_ECB, sptr->length());
|
||||
|
||||
if (!str_value.alloc(aes_length)) // Ensure that memory is free
|
||||
if (!str2->alloc(aes_length)) // Ensure that memory is free
|
||||
{
|
||||
uchar rkey[AES_KEY_LENGTH / 8];
|
||||
create_key(user_key, rkey);
|
||||
|
||||
if (!my_aes_crypt(MY_AES_ECB, what, (uchar*)sptr->ptr(), sptr->length(),
|
||||
(uchar*)str_value.ptr(), &aes_length,
|
||||
(uchar*)str2->ptr(), &aes_length,
|
||||
rkey, AES_KEY_LENGTH / 8, 0, 0))
|
||||
{
|
||||
str_value.length((uint) aes_length);
|
||||
return &str_value;
|
||||
str2->length((uint) aes_length);
|
||||
return str2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -346,6 +352,7 @@ void Item_func_aes_encrypt::fix_length_and_dec()
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Item_func_aes_decrypt::fix_length_and_dec()
|
||||
{
|
||||
max_length=args[0]->max_length;
|
||||
@@ -374,7 +381,7 @@ void Item_func_to_base64::fix_length_and_dec()
|
||||
|
||||
String *Item_func_to_base64::val_str_ascii(String *str)
|
||||
{
|
||||
String *res= args[0]->val_str(str);
|
||||
String *res= args[0]->val_str(&tmp_value);
|
||||
bool too_long= false;
|
||||
int length;
|
||||
if (!res ||
|
||||
@@ -382,7 +389,7 @@ String *Item_func_to_base64::val_str_ascii(String *str)
|
||||
(too_long=
|
||||
((uint) (length= base64_needed_encoded_length((int) res->length())) >
|
||||
current_thd->variables.max_allowed_packet)) ||
|
||||
tmp_value.alloc((uint) length))
|
||||
str->alloc((uint) length))
|
||||
{
|
||||
null_value= 1; // NULL input, too long input, or OOM.
|
||||
if (too_long)
|
||||
@@ -396,11 +403,11 @@ String *Item_func_to_base64::val_str_ascii(String *str)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
base64_encode(res->ptr(), (int) res->length(), (char*) tmp_value.ptr());
|
||||
base64_encode(res->ptr(), (int) res->length(), (char*) str->ptr());
|
||||
DBUG_ASSERT(length > 0);
|
||||
tmp_value.length((uint) length - 1); // Without trailing '\0'
|
||||
str->length((uint) length - 1); // Without trailing '\0'
|
||||
null_value= 0;
|
||||
return &tmp_value;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +428,7 @@ void Item_func_from_base64::fix_length_and_dec()
|
||||
|
||||
String *Item_func_from_base64::val_str(String *str)
|
||||
{
|
||||
String *res= args[0]->val_str_ascii(str);
|
||||
String *res= args[0]->val_str_ascii(&tmp_value);
|
||||
int length;
|
||||
const char *end_ptr;
|
||||
|
||||
@@ -441,11 +448,11 @@ String *Item_func_from_base64::val_str(String *str)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tmp_value.alloc((uint) length))
|
||||
if (str->alloc((uint) length))
|
||||
goto err;
|
||||
|
||||
if ((length= base64_decode(res->ptr(), (int) res->length(),
|
||||
(char *) tmp_value.ptr(), &end_ptr, 0)) < 0 ||
|
||||
(char *) str->ptr(), &end_ptr, 0)) < 0 ||
|
||||
end_ptr < res->ptr() + res->length())
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
@@ -455,9 +462,9 @@ String *Item_func_from_base64::val_str(String *str)
|
||||
goto err;
|
||||
}
|
||||
|
||||
tmp_value.length((uint) length);
|
||||
str->length((uint) length);
|
||||
null_value= 0;
|
||||
return &tmp_value;
|
||||
return str;
|
||||
err:
|
||||
null_value= 1; // NULL input, too long input, OOM, or badly formed input
|
||||
return 0;
|
||||
@@ -713,7 +720,7 @@ String *Item_func_des_encrypt::val_str(String *str)
|
||||
struct st_des_keyschedule keyschedule;
|
||||
const char *append_str="********";
|
||||
uint key_number, res_length, tail;
|
||||
String *res= args[0]->val_str(str);
|
||||
String *res= args[0]->val_str(&tmp_value);
|
||||
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0; // ENCRYPT(NULL) == NULL
|
||||
@@ -737,7 +744,7 @@ String *Item_func_des_encrypt::val_str(String *str)
|
||||
}
|
||||
else
|
||||
{
|
||||
String *keystr=args[1]->val_str(&tmp_value);
|
||||
String *keystr= args[1]->val_str(str);
|
||||
if (!keystr)
|
||||
goto error;
|
||||
key_number=127; // User key string
|
||||
@@ -769,23 +776,23 @@ String *Item_func_des_encrypt::val_str(String *str)
|
||||
tmp_arg.length(0);
|
||||
tmp_arg.append(res->ptr(), res->length());
|
||||
code= ER_OUT_OF_RESOURCES;
|
||||
if (tmp_arg.append(append_str, tail) || tmp_value.alloc(res_length+1))
|
||||
if (tmp_arg.append(append_str, tail) || str->alloc(res_length+1))
|
||||
goto error;
|
||||
tmp_arg[res_length-1]=tail; // save extra length
|
||||
tmp_value.realloc(res_length+1);
|
||||
tmp_value.length(res_length+1);
|
||||
tmp_value.set_charset(&my_charset_bin);
|
||||
tmp_value[0]=(char) (128 | key_number);
|
||||
str->realloc(res_length+1);
|
||||
str->length(res_length+1);
|
||||
str->set_charset(&my_charset_bin);
|
||||
(*str)[0]=(char) (128 | key_number);
|
||||
// Real encryption
|
||||
bzero((char*) &ivec,sizeof(ivec));
|
||||
DES_ede3_cbc_encrypt((const uchar*) (tmp_arg.ptr()),
|
||||
(uchar*) (tmp_value.ptr()+1),
|
||||
(uchar*) (str->ptr()+1),
|
||||
res_length,
|
||||
&keyschedule.ks1,
|
||||
&keyschedule.ks2,
|
||||
&keyschedule.ks3,
|
||||
&ivec, TRUE);
|
||||
return &tmp_value;
|
||||
return str;
|
||||
|
||||
error:
|
||||
THD *thd= current_thd;
|
||||
@@ -811,7 +818,7 @@ String *Item_func_des_decrypt::val_str(String *str)
|
||||
DES_cblock ivec;
|
||||
struct st_des_keyblock keyblock;
|
||||
struct st_des_keyschedule keyschedule;
|
||||
String *res= args[0]->val_str(str);
|
||||
String *res= args[0]->val_str(&tmp_value);
|
||||
uint length,tail;
|
||||
|
||||
if ((null_value= args[0]->null_value))
|
||||
@@ -835,7 +842,7 @@ String *Item_func_des_decrypt::val_str(String *str)
|
||||
else
|
||||
{
|
||||
// We make good 24-byte (168 bit) key from given plaintext key with MD5
|
||||
String *keystr=args[1]->val_str(&tmp_value);
|
||||
String *keystr= args[1]->val_str(str);
|
||||
if (!keystr)
|
||||
goto error;
|
||||
|
||||
@@ -850,23 +857,23 @@ String *Item_func_des_decrypt::val_str(String *str)
|
||||
DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
|
||||
}
|
||||
code= ER_OUT_OF_RESOURCES;
|
||||
if (tmp_value.alloc(length-1))
|
||||
if (str->alloc(length-1))
|
||||
goto error;
|
||||
|
||||
bzero((char*) &ivec,sizeof(ivec));
|
||||
DES_ede3_cbc_encrypt((const uchar*) res->ptr()+1,
|
||||
(uchar*) (tmp_value.ptr()),
|
||||
(uchar*) (str->ptr()),
|
||||
length-1,
|
||||
&keyschedule.ks1,
|
||||
&keyschedule.ks2,
|
||||
&keyschedule.ks3,
|
||||
&ivec, FALSE);
|
||||
/* Restore old length of key */
|
||||
if ((tail=(uint) (uchar) tmp_value[length-2]) > 8)
|
||||
if ((tail=(uint) (uchar) (*str)[length-2]) > 8)
|
||||
goto wrong_key; // Wrong key
|
||||
tmp_value.length(length-1-tail);
|
||||
tmp_value.set_charset(&my_charset_bin);
|
||||
return &tmp_value;
|
||||
str->length(length-1-tail);
|
||||
str->set_charset(&my_charset_bin);
|
||||
return str;
|
||||
|
||||
error:
|
||||
{
|
||||
@@ -1064,25 +1071,26 @@ void Item_func_concat_ws::fix_length_and_dec()
|
||||
String *Item_func_reverse::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String *res = args[0]->val_str(str);
|
||||
char *ptr, *end, *tmp;
|
||||
String *res= args[0]->val_str(&tmp_value);
|
||||
const char *ptr, *end;
|
||||
char *tmp;
|
||||
|
||||
if ((null_value=args[0]->null_value))
|
||||
return 0;
|
||||
/* An empty string is a special case as the string pointer may be null */
|
||||
if (!res->length())
|
||||
return make_empty_result();
|
||||
if (tmp_value.alloced_length() < res->length() &&
|
||||
tmp_value.realloc(res->length()))
|
||||
if (str->alloced_length() < res->length() &&
|
||||
str->realloc(res->length()))
|
||||
{
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
tmp_value.length(res->length());
|
||||
tmp_value.set_charset(res->charset());
|
||||
ptr= (char *) res->ptr();
|
||||
end= ptr + res->length();
|
||||
tmp= (char *) tmp_value.ptr() + tmp_value.length();
|
||||
str->length(res->length());
|
||||
str->set_charset(res->charset());
|
||||
ptr= res->ptr();
|
||||
end= res->end();
|
||||
tmp= (char *) str->end();
|
||||
#ifdef USE_MB
|
||||
if (use_mb(res->charset()))
|
||||
{
|
||||
@@ -1106,7 +1114,7 @@ String *Item_func_reverse::val_str(String *str)
|
||||
while (ptr < end)
|
||||
*--tmp= *ptr++;
|
||||
}
|
||||
return &tmp_value;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -2286,6 +2294,7 @@ String *Item_func_database::val_str(String *str)
|
||||
}
|
||||
else
|
||||
str->copy(thd->db, thd->db_length, system_charset_info);
|
||||
null_value= 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -2320,6 +2329,28 @@ bool Item_func_user::init(const char *user, const char *host)
|
||||
}
|
||||
|
||||
|
||||
Item *Item_func_sysconst::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
|
||||
{
|
||||
/*
|
||||
During view or prepared statement creation, the item should not
|
||||
make use of const_charset_converter as it would imply substitution
|
||||
with constant items which is not correct. Functions can have different
|
||||
values during view creation and view execution based on context.
|
||||
|
||||
Return the identical item during view creation and prepare.
|
||||
*/
|
||||
if (!thd->lex->is_ps_or_view_context_analysis())
|
||||
return this;
|
||||
return const_charset_converter(thd, tocs, true, fully_qualified_func_name());
|
||||
}
|
||||
|
||||
bool Item_func_sysconst::const_item() const
|
||||
{
|
||||
if (current_thd->lex->is_ps_or_view_context_analysis())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Item_func_user::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
return (Item_func_sysconst::fix_fields(thd, ref) ||
|
||||
@@ -2345,21 +2376,19 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref)
|
||||
|
||||
Security_context *ctx= context->security_ctx
|
||||
? context->security_ctx : thd->security_ctx;
|
||||
|
||||
if (ctx->priv_role[0])
|
||||
{
|
||||
if (str_value.copy(ctx->priv_role, strlen(ctx->priv_role),
|
||||
system_charset_info))
|
||||
return 1;
|
||||
|
||||
str_value.mark_as_const();
|
||||
null_value= maybe_null= 0;
|
||||
return 0;
|
||||
}
|
||||
null_value= maybe_null= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Item_func_soundex::fix_length_and_dec()
|
||||
{
|
||||
uint32 char_length= args[0]->max_char_length();
|
||||
@@ -2367,7 +2396,6 @@ void Item_func_soundex::fix_length_and_dec()
|
||||
DBUG_ASSERT(collation.collation != NULL);
|
||||
set_if_bigger(char_length, 4);
|
||||
fix_char_length(char_length);
|
||||
tmp_value.set_charset(collation.collation);
|
||||
}
|
||||
|
||||
|
||||
@@ -2412,7 +2440,7 @@ static bool my_uni_isalpha(int wc)
|
||||
String *Item_func_soundex::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String *res =args[0]->val_str(str);
|
||||
String *res= args[0]->val_str(&tmp_value);
|
||||
char last_ch,ch;
|
||||
CHARSET_INFO *cs= collation.collation;
|
||||
my_wc_t wc;
|
||||
@@ -2422,10 +2450,11 @@ String *Item_func_soundex::val_str(String *str)
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0; /* purecov: inspected */
|
||||
|
||||
if (tmp_value.alloc(MY_MAX(res->length(), 4 * cs->mbminlen)))
|
||||
return str; /* purecov: inspected */
|
||||
char *to= (char *) tmp_value.ptr();
|
||||
char *to_end= to + tmp_value.alloced_length();
|
||||
if (str->alloc(MY_MAX(res->length(), 4 * cs->mbminlen)))
|
||||
return &tmp_value; /* purecov: inspected */
|
||||
str->set_charset(collation.collation);
|
||||
char *to= (char *) str->ptr();
|
||||
char *to_end= to + str->alloced_length();
|
||||
char *from= (char *) res->ptr(), *end= from + res->length();
|
||||
|
||||
for ( ; ; ) /* Skip pre-space */
|
||||
@@ -2510,8 +2539,8 @@ String *Item_func_soundex::val_str(String *str)
|
||||
to+= nbytes;
|
||||
}
|
||||
|
||||
tmp_value.length((uint) (to-tmp_value.ptr()));
|
||||
return &tmp_value;
|
||||
str->length((uint) (to - str->ptr()));
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -3333,13 +3362,13 @@ String *Item_func_conv_charset::val_str(String *str)
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (use_cached_value)
|
||||
return null_value ? 0 : &str_value;
|
||||
String *arg= args[0]->val_str(str);
|
||||
String *arg= args[0]->val_str(&tmp_value);
|
||||
String_copier_for_item copier(current_thd);
|
||||
return ((null_value= args[0]->null_value ||
|
||||
copier.copy_with_warn(collation.collation, &tmp_value,
|
||||
copier.copy_with_warn(collation.collation, str,
|
||||
arg->charset(), arg->ptr(),
|
||||
arg->length(), arg->length()))) ?
|
||||
0 : &tmp_value;
|
||||
0 : str;
|
||||
}
|
||||
|
||||
void Item_func_conv_charset::fix_length_and_dec()
|
||||
@@ -3482,7 +3511,7 @@ String *Item_func_weight_string::val_str(String *str)
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
||||
if (args[0]->result_type() != STRING_RESULT ||
|
||||
!(res= args[0]->val_str(str)))
|
||||
!(res= args[0]->val_str(&tmp_value)))
|
||||
goto nl;
|
||||
|
||||
/*
|
||||
@@ -3532,19 +3561,20 @@ String *Item_func_weight_string::val_str(String *str)
|
||||
goto nl;
|
||||
}
|
||||
}
|
||||
if (tmp_value.alloc(tmp_length))
|
||||
|
||||
if (str->alloc(tmp_length))
|
||||
goto nl;
|
||||
|
||||
frm_length= cs->coll->strnxfrm(cs,
|
||||
(uchar *) tmp_value.ptr(), tmp_length,
|
||||
(uchar *) str->ptr(), tmp_length,
|
||||
nweights ? nweights : tmp_length,
|
||||
(const uchar *) res->ptr(), res->length(),
|
||||
flags);
|
||||
DBUG_ASSERT(frm_length <= tmp_length);
|
||||
|
||||
tmp_value.length(frm_length);
|
||||
str->length(frm_length);
|
||||
null_value= 0;
|
||||
return &tmp_value;
|
||||
return str;
|
||||
|
||||
nl:
|
||||
null_value= 1;
|
||||
@@ -3585,18 +3615,18 @@ String *Item_func_hex::val_str_ascii(String *str)
|
||||
}
|
||||
|
||||
/* Convert given string to a hex string, character by character */
|
||||
res= args[0]->val_str(str);
|
||||
if (!res || tmp_value.alloc(res->length()*2+1))
|
||||
res= args[0]->val_str(&tmp_value);
|
||||
if (!res || str->alloc(res->length()*2+1))
|
||||
{
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
null_value=0;
|
||||
tmp_value.length(res->length()*2);
|
||||
tmp_value.set_charset(&my_charset_latin1);
|
||||
str->length(res->length()*2);
|
||||
str->set_charset(&my_charset_latin1);
|
||||
|
||||
octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length());
|
||||
return &tmp_value;
|
||||
octet2hex((char*) str->ptr(), res->ptr(), res->length());
|
||||
return str;
|
||||
}
|
||||
|
||||
/** Convert given hex string to a binary string. */
|
||||
@@ -3609,8 +3639,8 @@ String *Item_func_unhex::val_str(String *str)
|
||||
uint length;
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
||||
res= args[0]->val_str(str);
|
||||
if (!res || tmp_value.alloc(length= (1+res->length())/2))
|
||||
res= args[0]->val_str(&tmp_value);
|
||||
if (!res || str->alloc(length= (1+res->length())/2))
|
||||
{
|
||||
null_value=1;
|
||||
return 0;
|
||||
@@ -3618,8 +3648,8 @@ String *Item_func_unhex::val_str(String *str)
|
||||
|
||||
from= res->ptr();
|
||||
null_value= 0;
|
||||
tmp_value.length(length);
|
||||
to= (char*) tmp_value.ptr();
|
||||
str->length(length);
|
||||
to= (char*) str->ptr();
|
||||
if (res->length() % 2)
|
||||
{
|
||||
int hex_char;
|
||||
@@ -3637,7 +3667,7 @@ String *Item_func_unhex::val_str(String *str)
|
||||
if ((null_value= (hex_char == -1)))
|
||||
return 0;
|
||||
}
|
||||
return &tmp_value;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -3888,7 +3918,7 @@ String *Item_func_quote::val_str(String *str)
|
||||
|
||||
ulong max_allowed_packet= current_thd->variables.max_allowed_packet;
|
||||
char *from, *to, *end, *start;
|
||||
String *arg= args[0]->val_str(str);
|
||||
String *arg= args[0]->val_str(&tmp_value);
|
||||
uint arg_length, new_length;
|
||||
if (!arg) // Null argument
|
||||
{
|
||||
@@ -3915,7 +3945,7 @@ String *Item_func_quote::val_str(String *str)
|
||||
set_if_smaller(new_length, max_allowed_packet);
|
||||
}
|
||||
|
||||
if (tmp_value.alloc(new_length))
|
||||
if (str->alloc(new_length))
|
||||
goto null;
|
||||
|
||||
if (collation.collation->mbmaxlen > 1)
|
||||
@@ -3923,7 +3953,7 @@ String *Item_func_quote::val_str(String *str)
|
||||
CHARSET_INFO *cs= collation.collation;
|
||||
int mblen;
|
||||
uchar *to_end;
|
||||
to= (char*) tmp_value.ptr();
|
||||
to= (char*) str->ptr();
|
||||
to_end= (uchar*) to + new_length;
|
||||
|
||||
/* Put leading quote */
|
||||
@@ -3960,14 +3990,14 @@ String *Item_func_quote::val_str(String *str)
|
||||
if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
|
||||
goto toolong;
|
||||
to+= mblen;
|
||||
new_length= to - tmp_value.ptr();
|
||||
new_length= to - str->ptr();
|
||||
goto ret;
|
||||
}
|
||||
|
||||
/*
|
||||
We replace characters from the end to the beginning
|
||||
*/
|
||||
to= (char*) tmp_value.ptr() + new_length - 1;
|
||||
to= (char*) str->ptr() + new_length - 1;
|
||||
*to--= '\'';
|
||||
for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
|
||||
{
|
||||
@@ -3997,10 +4027,10 @@ String *Item_func_quote::val_str(String *str)
|
||||
*to= '\'';
|
||||
|
||||
ret:
|
||||
tmp_value.length(new_length);
|
||||
tmp_value.set_charset(collation.collation);
|
||||
str->length(new_length);
|
||||
str->set_charset(collation.collation);
|
||||
null_value= 0;
|
||||
return &tmp_value;
|
||||
return str;
|
||||
|
||||
toolong:
|
||||
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
@@ -4074,7 +4104,7 @@ String *Item_func_compress::val_str(String *str)
|
||||
char *tmp, *last_char;
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
||||
if (!(res= args[0]->val_str(str)))
|
||||
if (!(res= args[0]->val_str(&tmp_value)))
|
||||
{
|
||||
null_value= 1;
|
||||
return 0;
|
||||
@@ -4095,13 +4125,13 @@ String *Item_func_compress::val_str(String *str)
|
||||
|
||||
// Check new_size overflow: new_size <= res->length()
|
||||
if (((uint32) (new_size+5) <= res->length()) ||
|
||||
buffer.realloc((uint32) new_size + 4 + 1))
|
||||
str->realloc((uint32) new_size + 4 + 1))
|
||||
{
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
body= ((Byte*)buffer.ptr()) + 4;
|
||||
body= ((Byte*)str->ptr()) + 4;
|
||||
|
||||
// As far as we have checked res->is_empty() we can use ptr()
|
||||
if ((err= my_compress_buffer(body, &new_size, (const uchar *)res->ptr(),
|
||||
@@ -4115,7 +4145,7 @@ String *Item_func_compress::val_str(String *str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects
|
||||
tmp= (char*) str->ptr(); // int4store is a macro; avoid side effects
|
||||
int4store(tmp, res->length() & 0x3FFFFFFF);
|
||||
|
||||
/* This is to ensure that things works for CHAR fields, which trim ' ': */
|
||||
@@ -4126,15 +4156,15 @@ String *Item_func_compress::val_str(String *str)
|
||||
new_size++;
|
||||
}
|
||||
|
||||
buffer.length((uint32)new_size + 4);
|
||||
return &buffer;
|
||||
str->length((uint32)new_size + 4);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
String *Item_func_uncompress::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String *res= args[0]->val_str(str);
|
||||
String *res= args[0]->val_str(&tmp_value);
|
||||
ulong new_size;
|
||||
int err;
|
||||
uint code;
|
||||
@@ -4167,14 +4197,14 @@ String *Item_func_uncompress::val_str(String *str)
|
||||
max_allowed_packet));
|
||||
goto err;
|
||||
}
|
||||
if (buffer.realloc((uint32)new_size))
|
||||
if (str->realloc((uint32)new_size))
|
||||
goto err;
|
||||
|
||||
if ((err= uncompress((Byte*)buffer.ptr(), &new_size,
|
||||
if ((err= uncompress((Byte*)str->ptr(), &new_size,
|
||||
((const Bytef*)res->ptr())+4,res->length()-4)) == Z_OK)
|
||||
{
|
||||
buffer.length((uint32) new_size);
|
||||
return &buffer;
|
||||
str->length((uint32) new_size);
|
||||
return str;
|
||||
}
|
||||
|
||||
code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR :
|
||||
|
@@ -141,7 +141,6 @@ public:
|
||||
|
||||
class Item_func_md5 :public Item_str_ascii_checksum_func
|
||||
{
|
||||
String tmp_value;
|
||||
public:
|
||||
Item_func_md5(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {}
|
||||
String *val_str_ascii(String *);
|
||||
@@ -241,7 +240,6 @@ public:
|
||||
|
||||
class Item_func_decode_histogram :public Item_str_func
|
||||
{
|
||||
String tmp_value;
|
||||
public:
|
||||
Item_func_decode_histogram(THD *thd, Item *a, Item *b):
|
||||
Item_str_func(thd, a, b) {}
|
||||
@@ -622,10 +620,7 @@ class Item_func_sysconst :public Item_str_func
|
||||
public:
|
||||
Item_func_sysconst(THD *thd): Item_str_func(thd)
|
||||
{ collation.set(system_charset_info,DERIVATION_SYSCONST); }
|
||||
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
|
||||
{
|
||||
return const_charset_converter(thd, tocs, true, fully_qualified_func_name());
|
||||
}
|
||||
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
|
||||
/*
|
||||
Used to create correct Item name in new converted item in
|
||||
safe_charset_converter, return string representation of this function
|
||||
@@ -637,6 +632,7 @@ public:
|
||||
return trace_unsupported_by_check_vcol_func_processor(
|
||||
fully_qualified_func_name());
|
||||
}
|
||||
bool const_item() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -715,7 +711,7 @@ public:
|
||||
String *val_str(String *)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
return (null_value ? 0 : &str_value);
|
||||
return null_value ? NULL : &str_value;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -757,7 +753,6 @@ public:
|
||||
|
||||
class Item_func_format :public Item_str_ascii_func
|
||||
{
|
||||
String tmp_str;
|
||||
MY_LOCALE *locale;
|
||||
public:
|
||||
Item_func_format(THD *thd, Item *org, Item *dec):
|
||||
@@ -814,7 +809,6 @@ public:
|
||||
|
||||
class Item_func_binlog_gtid_pos :public Item_str_func
|
||||
{
|
||||
String tmp_value;
|
||||
public:
|
||||
Item_func_binlog_gtid_pos(THD *thd, Item *arg1, Item *arg2):
|
||||
Item_str_func(thd, arg1, arg2) {}
|
||||
@@ -1212,7 +1206,7 @@ public:
|
||||
|
||||
class Item_func_compress: public Item_str_binary_checksum_func
|
||||
{
|
||||
String buffer;
|
||||
String tmp_value;
|
||||
public:
|
||||
Item_func_compress(THD *thd, Item *a)
|
||||
:Item_str_binary_checksum_func(thd, a) {}
|
||||
@@ -1223,7 +1217,7 @@ public:
|
||||
|
||||
class Item_func_uncompress: public Item_str_binary_checksum_func
|
||||
{
|
||||
String buffer;
|
||||
String tmp_value;
|
||||
public:
|
||||
Item_func_uncompress(THD *thd, Item *a)
|
||||
:Item_str_binary_checksum_func(thd, a) {}
|
||||
|
@@ -3446,6 +3446,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
|
||||
table_map remaining_tables= 0;
|
||||
table_map handled_tabs= 0;
|
||||
join->sjm_lookup_tables= 0;
|
||||
join->sjm_scan_tables= 0;
|
||||
for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--)
|
||||
{
|
||||
POSITION *pos= join->best_positions + tablenr;
|
||||
@@ -3503,6 +3504,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
|
||||
for (i= tablenr; i != (first + sjm->tables - 1); i--)
|
||||
rem_tables |= join->best_positions[i].table->table->map;
|
||||
|
||||
for (i= first; i < first+ sjm->tables; i++)
|
||||
join->sjm_scan_tables |= join->best_positions[i].table->table->map;
|
||||
|
||||
POSITION dummy;
|
||||
join->cur_sj_inner_tables= 0;
|
||||
for (i= first + sjm->tables; i <= tablenr; i++)
|
||||
|
@@ -1871,6 +1871,22 @@ static int add_subpartition_by(File fptr)
|
||||
return err + add_partition_by(fptr);
|
||||
}
|
||||
|
||||
static int add_name_string(File fptr, const char *name)
|
||||
{
|
||||
int err;
|
||||
String name_string("", 0, system_charset_info);
|
||||
THD *thd= current_thd;
|
||||
ulonglong save_sql_mode= thd->variables.sql_mode;
|
||||
thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
|
||||
ulonglong save_options= thd->variables.option_bits;
|
||||
thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
|
||||
append_identifier(thd, &name_string, name, strlen(name));
|
||||
thd->variables.sql_mode= save_sql_mode;
|
||||
thd->variables.option_bits= save_options;
|
||||
err= add_string_object(fptr, &name_string);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int add_part_field_list(File fptr, List<char> field_list)
|
||||
{
|
||||
uint i, num_fields;
|
||||
@@ -1882,15 +1898,7 @@ static int add_part_field_list(File fptr, List<char> field_list)
|
||||
err+= add_begin_parenthesis(fptr);
|
||||
while (i < num_fields)
|
||||
{
|
||||
const char *field_str= part_it++;
|
||||
String field_string("", 0, system_charset_info);
|
||||
THD *thd= current_thd;
|
||||
ulonglong save_options= thd->variables.option_bits;
|
||||
thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
|
||||
append_identifier(thd, &field_string, field_str,
|
||||
strlen(field_str));
|
||||
thd->variables.option_bits= save_options;
|
||||
err+= add_string_object(fptr, &field_string);
|
||||
err+= add_name_string(fptr, part_it++);
|
||||
if (i != (num_fields-1))
|
||||
err+= add_comma(fptr);
|
||||
i++;
|
||||
@@ -1899,20 +1907,6 @@ static int add_part_field_list(File fptr, List<char> field_list)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int add_name_string(File fptr, const char *name)
|
||||
{
|
||||
int err;
|
||||
String name_string("", 0, system_charset_info);
|
||||
THD *thd= current_thd;
|
||||
ulonglong save_options= thd->variables.option_bits;
|
||||
thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
|
||||
append_identifier(thd, &name_string, name,
|
||||
strlen(name));
|
||||
thd->variables.option_bits= save_options;
|
||||
err= add_string_object(fptr, &name_string);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int add_int(File fptr, longlong number)
|
||||
{
|
||||
char buff[32];
|
||||
|
@@ -326,6 +326,12 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin);
|
||||
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
|
||||
static void reap_plugins(void);
|
||||
|
||||
bool plugin_is_forced(struct st_plugin_int *p)
|
||||
{
|
||||
return p->load_option == PLUGIN_FORCE ||
|
||||
p->load_option == PLUGIN_FORCE_PLUS_PERMANENT;
|
||||
}
|
||||
|
||||
static void report_error(int where_to, uint error, ...)
|
||||
{
|
||||
va_list args;
|
||||
@@ -1390,7 +1396,7 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
|
||||
|
||||
if (options_only || state == PLUGIN_IS_DISABLED)
|
||||
{
|
||||
ret= 0;
|
||||
ret= !options_only && plugin_is_forced(plugin);
|
||||
state= PLUGIN_IS_DISABLED;
|
||||
goto err;
|
||||
}
|
||||
@@ -1700,8 +1706,7 @@ int plugin_init(int *argc, char **argv, int flags)
|
||||
while ((plugin_ptr= *(--reap)))
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
if (plugin_ptr->load_option == PLUGIN_FORCE ||
|
||||
plugin_ptr->load_option == PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
if (plugin_is_forced(plugin_ptr))
|
||||
reaped_mandatory_plugin= TRUE;
|
||||
plugin_deinitialize(plugin_ptr, true);
|
||||
mysql_mutex_lock(&LOCK_plugin);
|
||||
@@ -3644,8 +3649,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
|
||||
plugin_dash.length + 1);
|
||||
strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS);
|
||||
|
||||
if (tmp->load_option != PLUGIN_FORCE &&
|
||||
tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
if (!plugin_is_forced(tmp))
|
||||
{
|
||||
/* support --skip-plugin-foo syntax */
|
||||
options[0].name= plugin_name_ptr;
|
||||
@@ -4017,8 +4021,11 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
my_afree(tmp_backup);
|
||||
}
|
||||
|
||||
if (tmp->load_option != PLUGIN_FORCE &&
|
||||
tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
/*
|
||||
We adjust the default value to account for the hardcoded exceptions
|
||||
we have set for the federated and ndbcluster storage engines.
|
||||
*/
|
||||
if (!plugin_is_forced(tmp))
|
||||
opts[0].def_value= opts[1].def_value= plugin_load_option;
|
||||
|
||||
error= handle_options(argc, &argv, opts, mark_changed);
|
||||
@@ -4034,8 +4041,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
||||
Set plugin loading policy from option value. First element in the option
|
||||
list is always the <plugin name> option value.
|
||||
*/
|
||||
if (tmp->load_option != PLUGIN_FORCE &&
|
||||
tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
|
||||
if (!plugin_is_forced(tmp))
|
||||
plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value;
|
||||
}
|
||||
|
||||
|
@@ -122,7 +122,7 @@
|
||||
#define OPTION_AUTOCOMMIT (1ULL << 8) // THD, user
|
||||
#define OPTION_BIG_SELECTS (1ULL << 9) // THD, user
|
||||
#define OPTION_LOG_OFF (1ULL << 10) // THD, user
|
||||
#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user, unused
|
||||
#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user
|
||||
#define TMP_TABLE_ALL_COLUMNS (1ULL << 12) // SELECT, intern
|
||||
#define OPTION_WARNINGS (1ULL << 13) // THD, user
|
||||
#define OPTION_AUTO_IS_NULL (1ULL << 14) // THD, user, binlog
|
||||
|
@@ -1309,6 +1309,7 @@ JOIN::optimize_inner()
|
||||
DBUG_PRINT("info",("Select tables optimized away"));
|
||||
zero_result_cause= "Select tables optimized away";
|
||||
tables_list= 0; // All tables resolved
|
||||
select_lex->min_max_opt_list.empty();
|
||||
const_tables= top_join_tab_count= table_count;
|
||||
/*
|
||||
Extract all table-independent conditions and replace the WHERE
|
||||
@@ -3075,8 +3076,11 @@ void JOIN::exec_inner()
|
||||
if (sort_table_cond)
|
||||
{
|
||||
if (!curr_table->select)
|
||||
{
|
||||
if (!(curr_table->select= new SQL_SELECT))
|
||||
DBUG_VOID_RETURN;
|
||||
curr_table->select->head= curr_table->table;
|
||||
}
|
||||
if (!curr_table->select->cond)
|
||||
curr_table->select->cond= sort_table_cond;
|
||||
else
|
||||
@@ -8221,6 +8225,63 @@ bool JOIN_TAB::hash_join_is_possible()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Check whether a KEYUSE can be really used for access this join table
|
||||
|
||||
@param join Join structure with the best join order
|
||||
for which the check is performed
|
||||
@param keyuse Evaluated KEYUSE structure
|
||||
|
||||
@details
|
||||
This function is supposed to be used after the best execution plan have been
|
||||
already chosen and the JOIN_TAB array for the best join order been already set.
|
||||
For a given KEYUSE to access this JOIN_TAB in the best execution plan the
|
||||
function checks whether it really can be used. The function first performs
|
||||
the check with access_from_tables_is_allowed(). If it succeeds it checks
|
||||
whether the keyuse->val does not use some fields of a materialized semijoin
|
||||
nest that cannot be used to build keys to access outer tables.
|
||||
Such KEYUSEs exists for the query like this:
|
||||
select * from ot
|
||||
where ot.c in (select it1.c from it1, it2 where it1.c=f(it2.c))
|
||||
Here we have two KEYUSEs to access table ot: with val=it1.c and val=f(it2.c).
|
||||
However if the subquery was materialized the second KEYUSE cannot be employed
|
||||
to access ot.
|
||||
|
||||
@retval true the given keyuse can be used for ref access of this JOIN_TAB
|
||||
@retval false otherwise
|
||||
*/
|
||||
|
||||
bool JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan(JOIN *join,
|
||||
KEYUSE *keyuse)
|
||||
{
|
||||
if (!access_from_tables_is_allowed(keyuse->used_tables,
|
||||
join->sjm_lookup_tables))
|
||||
return false;
|
||||
if (join->sjm_scan_tables & table->map)
|
||||
return true;
|
||||
table_map keyuse_sjm_scan_tables= keyuse->used_tables &
|
||||
join->sjm_scan_tables;
|
||||
if (!keyuse_sjm_scan_tables)
|
||||
return true;
|
||||
uint sjm_tab_nr= 0;
|
||||
while (!(keyuse_sjm_scan_tables & table_map(1) << sjm_tab_nr))
|
||||
sjm_tab_nr++;
|
||||
JOIN_TAB *sjm_tab= join->map2table[sjm_tab_nr];
|
||||
TABLE_LIST *emb_sj_nest= sjm_tab->emb_sj_nest;
|
||||
if (!(emb_sj_nest->sj_mat_info && emb_sj_nest->sj_mat_info->is_used &&
|
||||
emb_sj_nest->sj_mat_info->is_sj_scan))
|
||||
return true;
|
||||
st_select_lex *sjm_sel= emb_sj_nest->sj_subq_pred->unit->first_select();
|
||||
for (uint i= 0; i < sjm_sel->item_list.elements; i++)
|
||||
{
|
||||
if (sjm_sel->ref_pointer_array[i] == keyuse->val)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static uint
|
||||
cache_record_length(JOIN *join,uint idx)
|
||||
{
|
||||
@@ -8792,6 +8853,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
|
||||
do
|
||||
{
|
||||
if (!(~used_tables & keyuse->used_tables) &&
|
||||
join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) &&
|
||||
are_tables_local(join_tab, keyuse->used_tables))
|
||||
{
|
||||
if (first_keyuse)
|
||||
@@ -8806,6 +8868,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
|
||||
{
|
||||
if (curr->keypart == keyuse->keypart &&
|
||||
!(~used_tables & curr->used_tables) &&
|
||||
join_tab->keyuse_is_valid_for_access_in_chosen_plan(join,
|
||||
keyuse) &&
|
||||
are_tables_local(join_tab, curr->used_tables))
|
||||
break;
|
||||
}
|
||||
@@ -8840,6 +8904,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
|
||||
do
|
||||
{
|
||||
if (!(~used_tables & keyuse->used_tables) &&
|
||||
join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) &&
|
||||
are_tables_local(join_tab, keyuse->used_tables))
|
||||
{
|
||||
bool add_key_part= TRUE;
|
||||
@@ -8849,6 +8914,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
|
||||
{
|
||||
if (curr->keypart == keyuse->keypart &&
|
||||
!(~used_tables & curr->used_tables) &&
|
||||
join_tab->keyuse_is_valid_for_access_in_chosen_plan(join,
|
||||
curr) &&
|
||||
are_tables_local(join_tab, curr->used_tables))
|
||||
{
|
||||
keyuse->keypart= NO_KEYPART;
|
||||
@@ -8951,8 +9018,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
|
||||
do
|
||||
{
|
||||
if (!(~used_tables & keyuse->used_tables) &&
|
||||
j->access_from_tables_is_allowed(keyuse->used_tables,
|
||||
join->sjm_lookup_tables))
|
||||
j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse))
|
||||
{
|
||||
if (are_tables_local(j, keyuse->val->used_tables()))
|
||||
{
|
||||
@@ -9022,8 +9088,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
|
||||
for (i=0 ; i < keyparts ; keyuse++,i++)
|
||||
{
|
||||
while (((~used_tables) & keyuse->used_tables) ||
|
||||
!j->access_from_tables_is_allowed(keyuse->used_tables,
|
||||
join->sjm_lookup_tables) ||
|
||||
!j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) ||
|
||||
keyuse->keypart == NO_KEYPART ||
|
||||
(keyuse->keypart !=
|
||||
(is_hash_join_key_no(key) ?
|
||||
|
@@ -557,6 +557,8 @@ typedef struct st_join_table {
|
||||
!(used_sjm_lookup_tables & ~emb_sj_nest->sj_inner_tables));
|
||||
}
|
||||
|
||||
bool keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, KEYUSE *keyuse);
|
||||
|
||||
void remove_redundant_bnl_scan_conds();
|
||||
|
||||
void save_explain_data(Explain_table_access *eta, table_map prefix_tables,
|
||||
@@ -1042,6 +1044,11 @@ public:
|
||||
to materialize and access by lookups
|
||||
*/
|
||||
table_map sjm_lookup_tables;
|
||||
/**
|
||||
Bitmap of semijoin tables that the chosen plan decided
|
||||
to materialize to scan the results of materialization
|
||||
*/
|
||||
table_map sjm_scan_tables;
|
||||
/*
|
||||
Constant tables for which we have found a row (as opposed to those for
|
||||
which we didn't).
|
||||
@@ -1415,6 +1422,7 @@ public:
|
||||
pre_sort_join_tab= NULL;
|
||||
emb_sjm_nest= NULL;
|
||||
sjm_lookup_tables= 0;
|
||||
sjm_scan_tables= 0;
|
||||
|
||||
/*
|
||||
The following is needed because JOIN::cleanup(true) may be called for
|
||||
|
@@ -1323,8 +1323,13 @@ bool mysqld_show_create_db(THD *thd, LEX_STRING *dbname,
|
||||
if (test_all_bits(sctx->master_access, DB_ACLS))
|
||||
db_access=DB_ACLS;
|
||||
else
|
||||
db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname->str, 0) |
|
||||
sctx->master_access);
|
||||
{
|
||||
db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname->str, 0) |
|
||||
sctx->master_access;
|
||||
if (sctx->priv_role[0])
|
||||
db_access|= acl_get("", "", sctx->priv_role, dbname->str, 0);
|
||||
}
|
||||
|
||||
if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname->str))
|
||||
{
|
||||
status_var_increment(thd->status_var.access_denied_errors);
|
||||
@@ -4922,7 +4927,9 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
}
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
|
||||
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
|
||||
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, false) ||
|
||||
(sctx->priv_role[0] ?
|
||||
acl_get("", "", sctx->priv_role, db_name->str, false) : 0) ||
|
||||
!check_grant_db(thd, db_name->str))
|
||||
#endif
|
||||
{
|
||||
|
Reference in New Issue
Block a user