Merge 10.2 into 10.3
This commit is contained in:
commit
1864a8ea93
@ -110,11 +110,13 @@ FOREACH(_base
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
ENDFOREACH()
|
ENDFOREACH()
|
||||||
|
|
||||||
|
IF(NOT RPM AND NOT DEB)
|
||||||
FOREACH(tool gtar tar)
|
FOREACH(tool gtar tar)
|
||||||
STRING(TOUPPER ${tool} TOOL)
|
STRING(TOUPPER ${tool} TOOL)
|
||||||
FIND_PROGRAM(${TOOL}_EXECUTABLE ${tool} DOC "path to the executable")
|
FIND_PROGRAM(${TOOL}_EXECUTABLE ${tool} DOC "path to the executable")
|
||||||
MARK_AS_ADVANCED(${TOOL}_EXECUTABLE)
|
MARK_AS_ADVANCED(${TOOL}_EXECUTABLE)
|
||||||
ENDFOREACH()
|
ENDFOREACH()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
FIND_PACKAGE(Git)
|
FIND_PACKAGE(Git)
|
||||||
|
|
||||||
|
13
cmake/FindGit.cmake
Normal file
13
cmake/FindGit.cmake
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
if(GIT_EXECUTABLE)
|
||||||
|
set(GIT_FOUND TRUE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
if(DEFINED GIT_EXECUTABLE)
|
||||||
|
set(GIT_FOUND FALSE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(orig_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
|
||||||
|
unset(CMAKE_MODULE_PATH)
|
||||||
|
include(FindGit)
|
||||||
|
set(CMAKE_MODULE_PATH ${orig_CMAKE_MODULE_PATH})
|
@ -1,4 +1,9 @@
|
|||||||
|
if(JAVA_AWT_LIBRARY)
|
||||||
|
set(JNI_FOUND TRUE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
if(DEFINED JAVA_AWT_LIBRARY)
|
if(DEFINED JAVA_AWT_LIBRARY)
|
||||||
|
set(JNI_FOUND FALSE)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
|
if(Java_JAVA_EXECUTABLE)
|
||||||
|
set(JAVA_FOUND TRUE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
if(DEFINED Java_JAVA_EXECUTABLE)
|
if(DEFINED Java_JAVA_EXECUTABLE)
|
||||||
|
set(JAVA_FOUND FALSE)
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -88,6 +88,12 @@ ENDIF()
|
|||||||
|
|
||||||
SET(WITH_INNODB_SNAPPY OFF CACHE STRING "")
|
SET(WITH_INNODB_SNAPPY OFF CACHE STRING "")
|
||||||
SET(WITH_NUMA 0 CACHE BOOL "")
|
SET(WITH_NUMA 0 CACHE BOOL "")
|
||||||
|
SET(CPU_LEVEL1_DCACHE_LINESIZE 0)
|
||||||
|
|
||||||
|
IF(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git)
|
||||||
|
SET(GIT_EXECUTABLE GIT_EXECUTABLE-NOTFOUND CACHE FILEPATH "")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
SET(INSTALL_MYSQLTESTDIR "" CACHE STRING "")
|
SET(INSTALL_MYSQLTESTDIR "" CACHE STRING "")
|
||||||
SET(INSTALL_SQLBENCHDIR "" CACHE STRING "")
|
SET(INSTALL_SQLBENCHDIR "" CACHE STRING "")
|
||||||
|
@ -124,8 +124,6 @@ SET(ignored
|
|||||||
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man"
|
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man"
|
||||||
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man1"
|
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man1"
|
||||||
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man8"
|
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man8"
|
||||||
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man1*"
|
|
||||||
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man8*"
|
|
||||||
"%ignore ${CMAKE_INSTALL_PREFIX}/share/pkgconfig"
|
"%ignore ${CMAKE_INSTALL_PREFIX}/share/pkgconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
# Symbols with information about the CPU.
|
# Symbols with information about the CPU.
|
||||||
|
|
||||||
|
IF(NOT DEFINED CPU_LEVEL1_DCACHE_LINESIZE)
|
||||||
|
|
||||||
IF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
IF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
FIND_PROGRAM(SYSCTL sysctl)
|
FIND_PROGRAM(SYSCTL sysctl)
|
||||||
MARK_AS_ADVANCED(SYSCTL)
|
MARK_AS_ADVANCED(SYSCTL)
|
||||||
@ -37,3 +39,5 @@ ELSE()
|
|||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
ENDIF()
|
||||||
|
@ -29,7 +29,7 @@ IF(NOT CMAKE_CROSSCOMPILING)
|
|||||||
TARGET_LINK_LIBRARIES(factorial dbug)
|
TARGET_LINK_LIBRARIES(factorial dbug)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(NOT WIN32 AND NOT CMAKE_GENERATOR MATCHES Xcode)
|
IF(NOT WIN32 AND NOT CMAKE_GENERATOR MATCHES Xcode AND NOT RPM AND NOT DEB)
|
||||||
FIND_PROGRAM(GROFF groff)
|
FIND_PROGRAM(GROFF groff)
|
||||||
FIND_PROGRAM(NROFF nroff)
|
FIND_PROGRAM(NROFF nroff)
|
||||||
MARK_AS_ADVANCED(GROFF)
|
MARK_AS_ADVANCED(GROFF)
|
||||||
|
4
debian/mariadb-plugin-connect.install
vendored
4
debian/mariadb-plugin-connect.install
vendored
@ -1,2 +1,6 @@
|
|||||||
etc/mysql/conf.d/connect.cnf etc/mysql/mariadb.conf.d
|
etc/mysql/conf.d/connect.cnf etc/mysql/mariadb.conf.d
|
||||||
usr/lib/mysql/plugin/ha_connect.so
|
usr/lib/mysql/plugin/ha_connect.so
|
||||||
|
usr/share/mysql/Mongo2.jar
|
||||||
|
usr/share/mysql/Mongo3.jar
|
||||||
|
usr/share/mysql/JavaWrappers.jar
|
||||||
|
usr/share/mysql/JdbcInterface.jar
|
||||||
|
@ -1120,10 +1120,10 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
2 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||||
5 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
5 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||||
NULL UNION RESULT <union2,5> ALL NULL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union2,5> ALL NULL NULL NULL NULL NULL NULL
|
||||||
6 UNION <derived9> ALL NULL NULL NULL NULL 14 100.00
|
6 UNION <derived14> ALL NULL NULL NULL NULL 14 100.00
|
||||||
9 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
14 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||||
12 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
11 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||||
NULL UNION RESULT <union9,12> ALL NULL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union14,11> ALL NULL NULL NULL NULL NULL NULL
|
||||||
NULL UNION RESULT <union1,6> ALL NULL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union1,6> ALL NULL NULL NULL NULL NULL NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 with cte_e as (with cte_o as (with cte_i as (/* select#4 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union /* select#5 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)/* select#1 */ select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union /* select#6 */ select `cte_e2`.`a` AS `a` from `cte_e` `cte_e2`
|
Note 1003 with cte_e as (with cte_o as (with cte_i as (/* select#4 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union /* select#5 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)/* select#1 */ select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union /* select#6 */ select `cte_e2`.`a` AS `a` from `cte_e` `cte_e2`
|
||||||
@ -1763,6 +1763,207 @@ a c
|
|||||||
2 1
|
2 1
|
||||||
7 3
|
7 3
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-23886: Stored Function returning the result of a query
|
||||||
|
# that uses CTE over a table twice
|
||||||
|
#
|
||||||
|
create table t1 (c1 int);
|
||||||
|
insert into t1 values (1),(2),(6);
|
||||||
|
create function f1() returns int return
|
||||||
|
( with cte1 as (select c1 from t1)
|
||||||
|
select sum(c1) from
|
||||||
|
(select * from cte1 union all select * from cte1) dt
|
||||||
|
);
|
||||||
|
select f1();
|
||||||
|
f1()
|
||||||
|
18
|
||||||
|
create function f2() returns int return
|
||||||
|
( with cte1 as (select c1 from t1)
|
||||||
|
select sum(s.c1) from cte1 as s, cte1 as t where s.c1=t.c1
|
||||||
|
);
|
||||||
|
select f2();
|
||||||
|
f2()
|
||||||
|
9
|
||||||
|
create function f3() returns int return
|
||||||
|
( with cte1 as (select c1 from t1)
|
||||||
|
select
|
||||||
|
case
|
||||||
|
when exists(select 1 from cte1 where c1 between 1 and 2) then 1
|
||||||
|
when exists(select 1 from cte1 where c1 between 5 and 6) then 2
|
||||||
|
else 0
|
||||||
|
end
|
||||||
|
);
|
||||||
|
select f3();
|
||||||
|
f3()
|
||||||
|
1
|
||||||
|
create view v1 as (select c1 from t1);
|
||||||
|
create function f4() returns int return
|
||||||
|
( select sum(c1) from
|
||||||
|
(select * from v1 union all select * from v1) dt
|
||||||
|
);
|
||||||
|
select f4();
|
||||||
|
f4()
|
||||||
|
18
|
||||||
|
create function f5() returns int return
|
||||||
|
( select sum(s.c1) from v1 as s, v1 as t where s.c1=t.c1
|
||||||
|
);
|
||||||
|
select f5();
|
||||||
|
f5()
|
||||||
|
9
|
||||||
|
create view v2(s) as
|
||||||
|
with cte1 as (select c1 from t1)
|
||||||
|
select sum(c1) from (select * from cte1 union all select * from cte1) dt;
|
||||||
|
create function f6() returns int return
|
||||||
|
(select s from v2);
|
||||||
|
select f6();
|
||||||
|
f6()
|
||||||
|
18
|
||||||
|
create function f7() returns int return
|
||||||
|
( select r.s from v2 as r, v2 as t where r.s=t.s
|
||||||
|
);
|
||||||
|
select f7();
|
||||||
|
f7()
|
||||||
|
18
|
||||||
|
select f5() + f6();
|
||||||
|
f5() + f6()
|
||||||
|
27
|
||||||
|
prepare stmt from "select f5() + f6();";
|
||||||
|
execute stmt;
|
||||||
|
f5() + f6()
|
||||||
|
27
|
||||||
|
execute stmt;
|
||||||
|
f5() + f6()
|
||||||
|
27
|
||||||
|
deallocate prepare stmt;
|
||||||
|
drop function f1;
|
||||||
|
drop function f2;
|
||||||
|
drop function f3;
|
||||||
|
drop function f4;
|
||||||
|
drop function f5;
|
||||||
|
drop function f6;
|
||||||
|
drop function f7;
|
||||||
|
drop view v1;
|
||||||
|
drop view v2;
|
||||||
|
create table t2 (a int, b int);
|
||||||
|
insert into t2
|
||||||
|
with cte1 as (select c1 from t1)
|
||||||
|
select * from cte1 as s, cte1 as t where s.c1=t.c1 and s.c1 > 5;
|
||||||
|
select * from t2;
|
||||||
|
a b
|
||||||
|
6 6
|
||||||
|
create procedure p1()
|
||||||
|
begin
|
||||||
|
insert into t2
|
||||||
|
with cte1 as (select c1 from t1)
|
||||||
|
select * from cte1 as s, cte1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
|
||||||
|
end |
|
||||||
|
call p1();
|
||||||
|
select * from t2;
|
||||||
|
a b
|
||||||
|
6 6
|
||||||
|
2 2
|
||||||
|
drop procedure p1;
|
||||||
|
# checking CTE resolution for queries with hanging CTEs
|
||||||
|
with
|
||||||
|
cte1(a) as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(b) as (select * from cte1 where a >= 2),
|
||||||
|
cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
|
||||||
|
select * from cte3;
|
||||||
|
a b
|
||||||
|
1 2
|
||||||
|
select * from t2;
|
||||||
|
a b
|
||||||
|
6 6
|
||||||
|
2 2
|
||||||
|
with
|
||||||
|
cte1(a) as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(b) as (select * from cte1 where a >= 2),
|
||||||
|
cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
|
||||||
|
select * from t2;
|
||||||
|
a b
|
||||||
|
6 6
|
||||||
|
2 2
|
||||||
|
with
|
||||||
|
cte1(a) as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(b) as (select * from cte1 where c1 >= 2),
|
||||||
|
cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
|
||||||
|
select * from t2;
|
||||||
|
ERROR 42S22: Unknown column 'c1' in 'where clause'
|
||||||
|
with
|
||||||
|
cte1(a) as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(b) as (select * from cte1 where a >= 2),
|
||||||
|
cte3 as (select * from cte1,cte2 where cte1.a < cte2.c1)
|
||||||
|
select * from t2;
|
||||||
|
ERROR 42S22: Unknown column 'cte2.c1' in 'where clause'
|
||||||
|
with
|
||||||
|
cte1 as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select * from cte2;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
with
|
||||||
|
cte1 as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select * from t2;
|
||||||
|
a b
|
||||||
|
6 6
|
||||||
|
2 2
|
||||||
|
with
|
||||||
|
cte1 as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=c1)
|
||||||
|
select * from t2;
|
||||||
|
ERROR 23000: Column 'c1' in where clause is ambiguous
|
||||||
|
with cte3 as
|
||||||
|
( with cte2(a,b) as
|
||||||
|
( with cte1 as (select * from t1 where c1 <= 2)
|
||||||
|
select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select r1.a,r2.b from cte2 as r1, cte2 as r2)
|
||||||
|
select * from cte3;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
1 2
|
||||||
|
2 2
|
||||||
|
with cte3 as
|
||||||
|
( with cte2(a,b) as
|
||||||
|
( with cte1 as (select * from t1 where c1 <= 2)
|
||||||
|
select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select r1.a,r2.b from cte2 as r1, cte2 as r2)
|
||||||
|
select * from t2;
|
||||||
|
a b
|
||||||
|
6 6
|
||||||
|
2 2
|
||||||
|
with cte3 as
|
||||||
|
( with cte2(a,b) as
|
||||||
|
( with cte1 as (select * from t1 where c1 <= 2)
|
||||||
|
select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select r1.c1,r2.c1 from cte2 as r1, cte2 as r2)
|
||||||
|
select * from t2;
|
||||||
|
ERROR 42S22: Unknown column 'r1.c1' in 'field list'
|
||||||
|
create procedure p1()
|
||||||
|
begin
|
||||||
|
insert into t2
|
||||||
|
with cte1 as (select c1 from t1)
|
||||||
|
select * from t1 as s, t1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
|
||||||
|
end |
|
||||||
|
call p1();
|
||||||
|
select * from t2;
|
||||||
|
a b
|
||||||
|
6 6
|
||||||
|
2 2
|
||||||
|
2 2
|
||||||
|
drop procedure p1;
|
||||||
|
create procedure p1()
|
||||||
|
begin
|
||||||
|
insert into t2
|
||||||
|
with cte1 as (select a from t1)
|
||||||
|
select * from t1 as s, t1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
|
||||||
|
end |
|
||||||
|
call p1();
|
||||||
|
ERROR 42S22: Unknown column 'a' in 'field list'
|
||||||
|
drop procedure p1;
|
||||||
|
drop table t1,t2;
|
||||||
# End of 10.2 tests
|
# End of 10.2 tests
|
||||||
#
|
#
|
||||||
# MDEV-21673: several references to CTE that uses
|
# MDEV-21673: several references to CTE that uses
|
||||||
|
@ -1261,6 +1261,208 @@ select a, c from cte as r2 where a > 4;
|
|||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-23886: Stored Function returning the result of a query
|
||||||
|
--echo # that uses CTE over a table twice
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
create table t1 (c1 int);
|
||||||
|
insert into t1 values (1),(2),(6);
|
||||||
|
|
||||||
|
create function f1() returns int return
|
||||||
|
( with cte1 as (select c1 from t1)
|
||||||
|
select sum(c1) from
|
||||||
|
(select * from cte1 union all select * from cte1) dt
|
||||||
|
);
|
||||||
|
select f1();
|
||||||
|
|
||||||
|
create function f2() returns int return
|
||||||
|
( with cte1 as (select c1 from t1)
|
||||||
|
select sum(s.c1) from cte1 as s, cte1 as t where s.c1=t.c1
|
||||||
|
);
|
||||||
|
select f2();
|
||||||
|
|
||||||
|
create function f3() returns int return
|
||||||
|
( with cte1 as (select c1 from t1)
|
||||||
|
select
|
||||||
|
case
|
||||||
|
when exists(select 1 from cte1 where c1 between 1 and 2) then 1
|
||||||
|
when exists(select 1 from cte1 where c1 between 5 and 6) then 2
|
||||||
|
else 0
|
||||||
|
end
|
||||||
|
);
|
||||||
|
select f3();
|
||||||
|
|
||||||
|
create view v1 as (select c1 from t1);
|
||||||
|
|
||||||
|
create function f4() returns int return
|
||||||
|
( select sum(c1) from
|
||||||
|
(select * from v1 union all select * from v1) dt
|
||||||
|
);
|
||||||
|
select f4();
|
||||||
|
|
||||||
|
create function f5() returns int return
|
||||||
|
( select sum(s.c1) from v1 as s, v1 as t where s.c1=t.c1
|
||||||
|
);
|
||||||
|
select f5();
|
||||||
|
|
||||||
|
create view v2(s) as
|
||||||
|
with cte1 as (select c1 from t1)
|
||||||
|
select sum(c1) from (select * from cte1 union all select * from cte1) dt;
|
||||||
|
|
||||||
|
create function f6() returns int return
|
||||||
|
(select s from v2);
|
||||||
|
select f6();
|
||||||
|
|
||||||
|
create function f7() returns int return
|
||||||
|
( select r.s from v2 as r, v2 as t where r.s=t.s
|
||||||
|
);
|
||||||
|
select f7();
|
||||||
|
|
||||||
|
select f5() + f6();
|
||||||
|
|
||||||
|
prepare stmt from "select f5() + f6();";
|
||||||
|
execute stmt;
|
||||||
|
execute stmt;
|
||||||
|
deallocate prepare stmt;
|
||||||
|
|
||||||
|
drop function f1;
|
||||||
|
drop function f2;
|
||||||
|
drop function f3;
|
||||||
|
drop function f4;
|
||||||
|
drop function f5;
|
||||||
|
drop function f6;
|
||||||
|
drop function f7;
|
||||||
|
|
||||||
|
drop view v1;
|
||||||
|
drop view v2;
|
||||||
|
|
||||||
|
create table t2 (a int, b int);
|
||||||
|
|
||||||
|
insert into t2
|
||||||
|
with cte1 as (select c1 from t1)
|
||||||
|
select * from cte1 as s, cte1 as t where s.c1=t.c1 and s.c1 > 5;
|
||||||
|
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
|
||||||
|
create procedure p1()
|
||||||
|
begin
|
||||||
|
insert into t2
|
||||||
|
with cte1 as (select c1 from t1)
|
||||||
|
select * from cte1 as s, cte1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
|
||||||
|
end |
|
||||||
|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
call p1();
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
drop procedure p1;
|
||||||
|
|
||||||
|
--echo # checking CTE resolution for queries with hanging CTEs
|
||||||
|
|
||||||
|
with
|
||||||
|
cte1(a) as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(b) as (select * from cte1 where a >= 2),
|
||||||
|
cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
|
||||||
|
select * from cte3;
|
||||||
|
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
with
|
||||||
|
cte1(a) as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(b) as (select * from cte1 where a >= 2),
|
||||||
|
cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
with
|
||||||
|
cte1(a) as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(b) as (select * from cte1 where c1 >= 2),
|
||||||
|
cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
with
|
||||||
|
cte1(a) as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(b) as (select * from cte1 where a >= 2),
|
||||||
|
cte3 as (select * from cte1,cte2 where cte1.a < cte2.c1)
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
with
|
||||||
|
cte1 as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select * from cte2;
|
||||||
|
|
||||||
|
with
|
||||||
|
cte1 as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
--error ER_NON_UNIQ_ERROR
|
||||||
|
with
|
||||||
|
cte1 as (select * from t1 where c1 <= 2),
|
||||||
|
cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=c1)
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
with cte3 as
|
||||||
|
( with cte2(a,b) as
|
||||||
|
( with cte1 as (select * from t1 where c1 <= 2)
|
||||||
|
select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select r1.a,r2.b from cte2 as r1, cte2 as r2)
|
||||||
|
select * from cte3;
|
||||||
|
|
||||||
|
with cte3 as
|
||||||
|
( with cte2(a,b) as
|
||||||
|
( with cte1 as (select * from t1 where c1 <= 2)
|
||||||
|
select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select r1.a,r2.b from cte2 as r1, cte2 as r2)
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
with cte3 as
|
||||||
|
( with cte2(a,b) as
|
||||||
|
( with cte1 as (select * from t1 where c1 <= 2)
|
||||||
|
select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
|
||||||
|
select r1.c1,r2.c1 from cte2 as r1, cte2 as r2)
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
|
||||||
|
create procedure p1()
|
||||||
|
begin
|
||||||
|
insert into t2
|
||||||
|
with cte1 as (select c1 from t1)
|
||||||
|
select * from t1 as s, t1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
|
||||||
|
end |
|
||||||
|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
call p1();
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
drop procedure p1;
|
||||||
|
|
||||||
|
delimiter |;
|
||||||
|
|
||||||
|
create procedure p1()
|
||||||
|
begin
|
||||||
|
insert into t2
|
||||||
|
with cte1 as (select a from t1)
|
||||||
|
select * from t1 as s, t1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
|
||||||
|
end |
|
||||||
|
|
||||||
|
delimiter ;|
|
||||||
|
|
||||||
|
--error ER_BAD_FIELD_ERROR
|
||||||
|
call p1();
|
||||||
|
|
||||||
|
drop procedure p1;
|
||||||
|
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
--echo # End of 10.2 tests
|
--echo # End of 10.2 tests
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -22,9 +22,40 @@ SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a
|
|||||||
@a BINARY @a REVERSE(@a) HEX(@a) HEX(REVERSE(@a))
|
@a BINARY @a REVERSE(@a) HEX(@a) HEX(REVERSE(@a))
|
||||||
aя a@r1 яa 61407231 40723161
|
aя a@r1 яa 61407231 40723161
|
||||||
#
|
#
|
||||||
|
# Beginning of 10.2 test.
|
||||||
|
#
|
||||||
|
# MDEV-25462: Assertion `m_status == DA_ERROR || m_status == DA_OK ||
|
||||||
|
# m_status == DA_OK_BULK' failed in Diagnostics_area::message from
|
||||||
|
# get_schema_tables_record
|
||||||
|
#
|
||||||
|
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
|
||||||
|
@@character_set_client @@character_set_connection @@character_set_results
|
||||||
|
utf8 utf8 utf8
|
||||||
|
SET @old_character_set_client= @@character_set_client;
|
||||||
|
SET @old_character_set_connection= @@character_set_connection;
|
||||||
|
SET @old_character_set_results= @@character_set_results;
|
||||||
|
SET NAMES 'filename';
|
||||||
|
ERROR 42000: Variable 'character_set_client' can't be set to the value of 'filename'
|
||||||
|
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
|
||||||
|
@@character_set_client @@character_set_connection @@character_set_results
|
||||||
|
utf8 utf8 utf8
|
||||||
|
CREATE VIEW v2 AS SELECT 1;
|
||||||
|
SHOW TABLE STATUS;
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
|
||||||
|
v2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL VIEW NULL NULL
|
||||||
|
DROP VIEW v2;
|
||||||
|
SET @@character_set_client= @old_character_set_client;
|
||||||
|
SET @@character_set_connection= @old_character_set_connection;
|
||||||
|
SET @@character_set_results= @old_character_set_results;
|
||||||
|
#
|
||||||
|
# End of 10.2 test
|
||||||
|
#
|
||||||
|
#
|
||||||
# MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
|
# MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
|
||||||
#
|
#
|
||||||
SET CHARACTER_SET_CLIENT=17;
|
SET CHARACTER_SET_CLIENT=17;
|
||||||
|
ERROR 42000: Variable 'character_set_client' can't be set to the value of '17'
|
||||||
SELECT doc.`Children`.0 FROM t1;
|
SELECT doc.`Children`.0 FROM t1;
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?Children??0?FROM?t1' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.0 FROM t1' at line 1
|
||||||
SET NAMES latin1;
|
SET NAMES latin1;
|
||||||
|
# End of 10.3 tests
|
||||||
|
@ -28,12 +28,40 @@ select convert(convert(',' using filename) using binary);
|
|||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a));
|
SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a));
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Beginning of 10.2 test.
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25462: Assertion `m_status == DA_ERROR || m_status == DA_OK ||
|
||||||
|
--echo # m_status == DA_OK_BULK' failed in Diagnostics_area::message from
|
||||||
|
--echo # get_schema_tables_record
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
|
||||||
|
SET @old_character_set_client= @@character_set_client;
|
||||||
|
SET @old_character_set_connection= @@character_set_connection;
|
||||||
|
SET @old_character_set_results= @@character_set_results;
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
SET NAMES 'filename';
|
||||||
|
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
|
||||||
|
CREATE VIEW v2 AS SELECT 1;
|
||||||
|
SHOW TABLE STATUS;
|
||||||
|
DROP VIEW v2;
|
||||||
|
SET @@character_set_client= @old_character_set_client;
|
||||||
|
SET @@character_set_connection= @old_character_set_connection;
|
||||||
|
SET @@character_set_results= @old_character_set_results;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.2 test
|
||||||
|
--echo #
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
|
--echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
--error ER_WRONG_VALUE_FOR_VAR
|
||||||
SET CHARACTER_SET_CLIENT=17;
|
SET CHARACTER_SET_CLIENT=17;
|
||||||
--error ER_PARSE_ERROR
|
--error ER_PARSE_ERROR
|
||||||
SELECT doc.`Children`.0 FROM t1;
|
SELECT doc.`Children`.0 FROM t1;
|
||||||
SET NAMES latin1;
|
SET NAMES latin1;
|
||||||
|
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
@ -1468,7 +1468,7 @@ lc-messages-dir MYSQL_SHAREDIR/
|
|||||||
lc-time-names en_US
|
lc-time-names en_US
|
||||||
local-infile TRUE
|
local-infile TRUE
|
||||||
lock-wait-timeout 86400
|
lock-wait-timeout 86400
|
||||||
log-bin (No default value)
|
log-bin foo
|
||||||
log-bin-compress FALSE
|
log-bin-compress FALSE
|
||||||
log-bin-compress-min-len 256
|
log-bin-compress-min-len 256
|
||||||
log-bin-index (No default value)
|
log-bin-index (No default value)
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# force symbolic-links=0 (valgrind build has a different default)
|
# force symbolic-links=0 (valgrind build has a different default)
|
||||||
#
|
#
|
||||||
|
|
||||||
exec $MYSQLD_BOOTSTRAP_CMD --symbolic-links=0 --lower-case-table-names=1 --help --verbose > $MYSQL_TMP_DIR/mysqld--help.txt 2>&1;
|
exec $MYSQLD_BOOTSTRAP_CMD --symbolic-links=0 --log-bin=foo --lower-case-table-names=1 --help --verbose > $MYSQL_TMP_DIR/mysqld--help.txt 2>&1;
|
||||||
|
|
||||||
# The inline perl code below will copy $MYSQL_TMP_DIR/mysqld--help.txt
|
# The inline perl code below will copy $MYSQL_TMP_DIR/mysqld--help.txt
|
||||||
# to output, but filter away some variable stuff (e.g. paths).
|
# to output, but filter away some variable stuff (e.g. paths).
|
||||||
|
@ -2721,7 +2721,15 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
SELECT a FROM t1 WHERE (a, a) IN (SELECT 1, 2) AND a = (SELECT MIN(b) FROM t2);
|
SELECT a FROM t1 WHERE (a, a) IN (SELECT 1, 2) AND a = (SELECT MIN(b) FROM t2);
|
||||||
a
|
a
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
# End of 10.2 tests
|
#
|
||||||
|
# MDEV-22462: Item_in_subselect::create_single_in_to_exists_cond(JOIN *, Item **, Item **): Assertion `false' failed.
|
||||||
|
#
|
||||||
|
select 1 from dual where 1 in (select 5 from dual where 1);
|
||||||
|
1
|
||||||
|
create table t1 (a int);
|
||||||
|
insert into t1 values (1),(2),(3);
|
||||||
|
update t1 set a = 2 where a in (select a from dual where a = a);
|
||||||
|
drop table t1;
|
||||||
#
|
#
|
||||||
# MDEV-18335: Assertion `!error || error == 137' failed in subselect_rowid_merge_engine::init
|
# MDEV-18335: Assertion `!error || error == 137' failed in subselect_rowid_merge_engine::init
|
||||||
#
|
#
|
||||||
@ -2847,4 +2855,15 @@ INSERT INTO t2 VALUES (3),(4);
|
|||||||
SELECT 1 IN (SELECT (SELECT a FROM t1) AS x FROM t2 GROUP BY x);
|
SELECT 1 IN (SELECT (SELECT a FROM t1) AS x FROM t2 GROUP BY x);
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
#
|
||||||
|
# MDEV-25629: Crash in get_sort_by_table() in subquery with order by having outer ref
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (i1 int);
|
||||||
|
insert into t1 values (1),(2);
|
||||||
|
SELECT 1
|
||||||
|
FROM (t1 JOIN t1 AS ref_t1 ON
|
||||||
|
(t1.i1 > (SELECT ref_t1.i1 AS c0 FROM t1 b ORDER BY -c0)));
|
||||||
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
DROP TABLE t1;
|
||||||
|
# End of 10.2 tests
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
|
@ -2236,7 +2236,17 @@ SELECT a FROM t1 WHERE (a, a) IN (SELECT 1, 2) AND a = (SELECT MIN(b) FROM t2);
|
|||||||
|
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
--echo # End of 10.2 tests
|
--echo #
|
||||||
|
--echo # MDEV-22462: Item_in_subselect::create_single_in_to_exists_cond(JOIN *, Item **, Item **): Assertion `false' failed.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
select 1 from dual where 1 in (select 5 from dual where 1);
|
||||||
|
|
||||||
|
create table t1 (a int);
|
||||||
|
insert into t1 values (1),(2),(3);
|
||||||
|
|
||||||
|
update t1 set a = 2 where a in (select a from dual where a = a);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-18335: Assertion `!error || error == 137' failed in subselect_rowid_merge_engine::init
|
--echo # MDEV-18335: Assertion `!error || error == 137' failed in subselect_rowid_merge_engine::init
|
||||||
@ -2353,4 +2363,19 @@ INSERT INTO t2 VALUES (3),(4); # Optional, fails either way
|
|||||||
SELECT 1 IN (SELECT (SELECT a FROM t1) AS x FROM t2 GROUP BY x);
|
SELECT 1 IN (SELECT (SELECT a FROM t1) AS x FROM t2 GROUP BY x);
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25629: Crash in get_sort_by_table() in subquery with order by having outer ref
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (i1 int);
|
||||||
|
insert into t1 values (1),(2);
|
||||||
|
|
||||||
|
--error ER_SUBQUERY_NO_1_ROW
|
||||||
|
SELECT 1
|
||||||
|
FROM (t1 JOIN t1 AS ref_t1 ON
|
||||||
|
(t1.i1 > (SELECT ref_t1.i1 AS c0 FROM t1 b ORDER BY -c0)));
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo # End of 10.2 tests
|
||||||
|
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
@ -20,7 +20,7 @@ master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f INT) ENGINE=INNODB
|
|||||||
master-bin.000001 # Gtid # # GTID #-#-#
|
master-bin.000001 # Gtid # # GTID #-#-#
|
||||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f INT) ENGINE=INNODB
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f INT) ENGINE=INNODB
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
FLUSH LOGS;
|
RESET MASTER;
|
||||||
#
|
#
|
||||||
# Kill OPTIMIZE command after table modification
|
# Kill OPTIMIZE command after table modification
|
||||||
#
|
#
|
||||||
|
@ -56,7 +56,7 @@ SET debug_sync = 'reset';
|
|||||||
--source include/show_binlog_events.inc
|
--source include/show_binlog_events.inc
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
FLUSH LOGS;
|
RESET MASTER;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Kill OPTIMIZE command after table modification
|
--echo # Kill OPTIMIZE command after table modification
|
||||||
@ -81,6 +81,9 @@ eval KILL $thd_id;
|
|||||||
SET debug_sync = 'reset';
|
SET debug_sync = 'reset';
|
||||||
--disconnect con1
|
--disconnect con1
|
||||||
|
|
||||||
|
--let $wait_binlog_event= OPTIMIZE
|
||||||
|
--source include/wait_for_binlog_event.inc
|
||||||
|
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
|
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
|
||||||
FLUSH LOGS;
|
FLUSH LOGS;
|
||||||
|
@ -264,6 +264,18 @@ t1 CREATE TABLE `t1` (
|
|||||||
`f1` int(11) NOT NULL
|
`f1` int(11) NOT NULL
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-25271 Double free of table when inplace alter
|
||||||
|
# FTS add index fails
|
||||||
|
#
|
||||||
|
call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation.");
|
||||||
|
call mtr.add_suppression("InnoDB: Error number .* means");
|
||||||
|
call mtr.add_suppression("InnoDB: Cannot create file");
|
||||||
|
call mtr.add_suppression("InnoDB: Failed to create");
|
||||||
|
CREATE TABLE t1(a TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL UNIQUE) ENGINE=InnoDB;
|
||||||
|
ALTER TABLE t1 ADD FULLTEXT(a), ALGORITHM=INPLACE;
|
||||||
|
ERROR HY000: Got error 11 "Resource temporarily unavailable" from storage engine InnoDB
|
||||||
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
|
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
|
||||||
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
|
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@ -52,3 +52,16 @@ CHECK TABLE t1;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-25663 Double free of transaction during TRUNCATE
|
||||||
|
#
|
||||||
|
call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
|
||||||
|
SET DEBUG_DBUG='-d,ib_create_table_fail_too_many_trx';
|
||||||
|
CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
|
||||||
|
SET @save_dbug= @@debug_dbug;
|
||||||
|
SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
|
||||||
|
TRUNCATE t1;
|
||||||
|
ERROR HY000: Got error -1 "Internal error < 0 (Not system error)" from storage engine InnoDB
|
||||||
|
SET debug_dbug=@save_dbug;
|
||||||
|
DROP TABLE t1;
|
||||||
|
# End of 10.3 tests
|
||||||
|
1
mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt
Normal file
1
mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--enable-plugin-innodb-sys-tables
|
@ -319,6 +319,25 @@ ALTER TABLE t1 ADD FTS_DOC_ID INT UNSIGNED NOT NULL, ALGORITHM=INPLACE;
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25271 Double free of table when inplace alter
|
||||||
|
--echo # FTS add index fails
|
||||||
|
--echo #
|
||||||
|
call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation.");
|
||||||
|
call mtr.add_suppression("InnoDB: Error number .* means");
|
||||||
|
call mtr.add_suppression("InnoDB: Cannot create file");
|
||||||
|
call mtr.add_suppression("InnoDB: Failed to create");
|
||||||
|
|
||||||
|
let MYSQLD_DATADIR=`select @@datadir`;
|
||||||
|
CREATE TABLE t1(a TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL UNIQUE) ENGINE=InnoDB;
|
||||||
|
let $fts_aux_file= `select concat('FTS_',right(concat(repeat('0',16), lower(hex(TABLE_ID))),16),'_BEING_DELETED.ibd') FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1'`;
|
||||||
|
write_file $MYSQLD_DATADIR/test/$fts_aux_file;
|
||||||
|
EOF
|
||||||
|
--error ER_GET_ERRNO
|
||||||
|
ALTER TABLE t1 ADD FULLTEXT(a), ALGORITHM=INPLACE;
|
||||||
|
DROP TABLE t1;
|
||||||
|
remove_file $MYSQLD_DATADIR/test/$fts_aux_file;
|
||||||
|
|
||||||
# Add more than one FTS index
|
# Add more than one FTS index
|
||||||
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
|
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
|
||||||
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
|
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
|
||||||
|
@ -83,3 +83,18 @@ ALTER TABLE t1 ADD bl INT AS (LENGTH(b)) VIRTUAL;
|
|||||||
CHECK TABLE t1;
|
CHECK TABLE t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--source include/wait_until_count_sessions.inc
|
--source include/wait_until_count_sessions.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25663 Double free of transaction during TRUNCATE
|
||||||
|
--echo #
|
||||||
|
call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
|
||||||
|
SET DEBUG_DBUG='-d,ib_create_table_fail_too_many_trx';
|
||||||
|
|
||||||
|
CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
|
||||||
|
SET @save_dbug= @@debug_dbug;
|
||||||
|
SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
|
||||||
|
--error ER_GET_ERRNO
|
||||||
|
TRUNCATE t1;
|
||||||
|
SET debug_dbug=@save_dbug;
|
||||||
|
DROP TABLE t1;
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
119
mysql-test/suite/perfschema/r/hostcache_ipv4_auth_ed25519.result
Normal file
119
mysql-test/suite/perfschema/r/hostcache_ipv4_auth_ed25519.result
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
install soname 'auth_ed25519';
|
||||||
|
flush status;
|
||||||
|
flush hosts;
|
||||||
|
flush user_resources;
|
||||||
|
flush privileges;
|
||||||
|
select `User`, `Host` from mysql.`user` where `host` like '%\\%%';
|
||||||
|
User Host
|
||||||
|
select `User`, `Host` from mysql.`user` where `user` like '192.%';
|
||||||
|
User Host
|
||||||
|
select `User`, `Host` from mysql.`user` where `user` like '2001:%';
|
||||||
|
User Host
|
||||||
|
select `User`, `Host` from mysql.`user` where `user` like 'santa.claus.%';
|
||||||
|
User Host
|
||||||
|
create user plug1@'santa.claus.ipv4.example.com'
|
||||||
|
identified with ed25519 as 'foo';
|
||||||
|
create user plug2@'santa.claus.ipv4.example.com'
|
||||||
|
identified with ED25519 as 'vubFBzIrapbfHct1/J72dnUryz5VS7lA6XHH8sIx4TI';
|
||||||
|
set @saved_dbug = @@global.debug_dbug;
|
||||||
|
set global debug_dbug= "+d,vio_peer_addr_fake_ipv4,getnameinfo_fake_ipv4,getaddrinfo_fake_good_ipv4";
|
||||||
|
connect(127.0.0.1,plug1,foo,test,PORT,SOCKET);
|
||||||
|
connect con1, 127.0.0.1, plug1,foo,,$MASTER_MYPORT;
|
||||||
|
ERROR 28000: Access denied for user 'plug1'@'santa.claus.ipv4.example.com' (using password: NO)
|
||||||
|
"Dumping performance_schema.host_cache"
|
||||||
|
IP 192.0.2.4
|
||||||
|
HOST santa.claus.ipv4.example.com
|
||||||
|
HOST_VALIDATED YES
|
||||||
|
SUM_CONNECT_ERRORS 0
|
||||||
|
COUNT_HOST_BLOCKED_ERRORS 0
|
||||||
|
COUNT_NAMEINFO_TRANSIENT_ERRORS 0
|
||||||
|
COUNT_NAMEINFO_PERMANENT_ERRORS 0
|
||||||
|
COUNT_FORMAT_ERRORS 0
|
||||||
|
COUNT_ADDRINFO_TRANSIENT_ERRORS 0
|
||||||
|
COUNT_ADDRINFO_PERMANENT_ERRORS 0
|
||||||
|
COUNT_FCRDNS_ERRORS 0
|
||||||
|
COUNT_HOST_ACL_ERRORS 0
|
||||||
|
COUNT_NO_AUTH_PLUGIN_ERRORS 0
|
||||||
|
COUNT_AUTH_PLUGIN_ERRORS 1
|
||||||
|
COUNT_HANDSHAKE_ERRORS 0
|
||||||
|
COUNT_PROXY_USER_ERRORS 0
|
||||||
|
COUNT_PROXY_USER_ACL_ERRORS 0
|
||||||
|
COUNT_AUTHENTICATION_ERRORS 0
|
||||||
|
COUNT_SSL_ERRORS 0
|
||||||
|
COUNT_MAX_USER_CONNECTIONS_ERRORS 0
|
||||||
|
COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS 0
|
||||||
|
COUNT_DEFAULT_DATABASE_ERRORS 0
|
||||||
|
COUNT_INIT_CONNECT_ERRORS 0
|
||||||
|
COUNT_LOCAL_ERRORS 0
|
||||||
|
COUNT_UNKNOWN_ERRORS 0
|
||||||
|
FIRST_ERROR_SEEN set
|
||||||
|
LAST_ERROR_SEEN set
|
||||||
|
connect(127.0.0.1,plug2,bar,test,PORT,SOCKET);
|
||||||
|
connect con1, 127.0.0.1, plug2,bar,,$MASTER_MYPORT;
|
||||||
|
ERROR 28000: Access denied for user 'plug2'@'santa.claus.ipv4.example.com' (using password: YES)
|
||||||
|
"Dumping performance_schema.host_cache"
|
||||||
|
IP 192.0.2.4
|
||||||
|
HOST santa.claus.ipv4.example.com
|
||||||
|
HOST_VALIDATED YES
|
||||||
|
SUM_CONNECT_ERRORS 0
|
||||||
|
COUNT_HOST_BLOCKED_ERRORS 0
|
||||||
|
COUNT_NAMEINFO_TRANSIENT_ERRORS 0
|
||||||
|
COUNT_NAMEINFO_PERMANENT_ERRORS 0
|
||||||
|
COUNT_FORMAT_ERRORS 0
|
||||||
|
COUNT_ADDRINFO_TRANSIENT_ERRORS 0
|
||||||
|
COUNT_ADDRINFO_PERMANENT_ERRORS 0
|
||||||
|
COUNT_FCRDNS_ERRORS 0
|
||||||
|
COUNT_HOST_ACL_ERRORS 0
|
||||||
|
COUNT_NO_AUTH_PLUGIN_ERRORS 0
|
||||||
|
COUNT_AUTH_PLUGIN_ERRORS 1
|
||||||
|
COUNT_HANDSHAKE_ERRORS 0
|
||||||
|
COUNT_PROXY_USER_ERRORS 0
|
||||||
|
COUNT_PROXY_USER_ACL_ERRORS 0
|
||||||
|
COUNT_AUTHENTICATION_ERRORS 1
|
||||||
|
COUNT_SSL_ERRORS 0
|
||||||
|
COUNT_MAX_USER_CONNECTIONS_ERRORS 0
|
||||||
|
COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS 0
|
||||||
|
COUNT_DEFAULT_DATABASE_ERRORS 0
|
||||||
|
COUNT_INIT_CONNECT_ERRORS 0
|
||||||
|
COUNT_LOCAL_ERRORS 0
|
||||||
|
COUNT_UNKNOWN_ERRORS 0
|
||||||
|
FIRST_ERROR_SEEN set
|
||||||
|
LAST_ERROR_SEEN set
|
||||||
|
connect con1, 127.0.0.1, plug2,foo,,$MASTER_MYPORT;
|
||||||
|
select current_user();
|
||||||
|
current_user()
|
||||||
|
plug2@santa.claus.ipv4.example.com
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
"Dumping performance_schema.host_cache"
|
||||||
|
IP 192.0.2.4
|
||||||
|
HOST santa.claus.ipv4.example.com
|
||||||
|
HOST_VALIDATED YES
|
||||||
|
SUM_CONNECT_ERRORS 0
|
||||||
|
COUNT_HOST_BLOCKED_ERRORS 0
|
||||||
|
COUNT_NAMEINFO_TRANSIENT_ERRORS 0
|
||||||
|
COUNT_NAMEINFO_PERMANENT_ERRORS 0
|
||||||
|
COUNT_FORMAT_ERRORS 0
|
||||||
|
COUNT_ADDRINFO_TRANSIENT_ERRORS 0
|
||||||
|
COUNT_ADDRINFO_PERMANENT_ERRORS 0
|
||||||
|
COUNT_FCRDNS_ERRORS 0
|
||||||
|
COUNT_HOST_ACL_ERRORS 0
|
||||||
|
COUNT_NO_AUTH_PLUGIN_ERRORS 0
|
||||||
|
COUNT_AUTH_PLUGIN_ERRORS 1
|
||||||
|
COUNT_HANDSHAKE_ERRORS 0
|
||||||
|
COUNT_PROXY_USER_ERRORS 0
|
||||||
|
COUNT_PROXY_USER_ACL_ERRORS 0
|
||||||
|
COUNT_AUTHENTICATION_ERRORS 1
|
||||||
|
COUNT_SSL_ERRORS 0
|
||||||
|
COUNT_MAX_USER_CONNECTIONS_ERRORS 0
|
||||||
|
COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS 0
|
||||||
|
COUNT_DEFAULT_DATABASE_ERRORS 0
|
||||||
|
COUNT_INIT_CONNECT_ERRORS 0
|
||||||
|
COUNT_LOCAL_ERRORS 0
|
||||||
|
COUNT_UNKNOWN_ERRORS 0
|
||||||
|
FIRST_ERROR_SEEN set
|
||||||
|
LAST_ERROR_SEEN set
|
||||||
|
drop user plug1@'santa.claus.ipv4.example.com';
|
||||||
|
drop user plug2@'santa.claus.ipv4.example.com';
|
||||||
|
set @@global.debug_dbug = @saved_dbug;
|
||||||
|
uninstall plugin ed25519;
|
@ -0,0 +1,53 @@
|
|||||||
|
#
|
||||||
|
# Tests for the performance_schema host_cache.
|
||||||
|
#
|
||||||
|
# Test authorization with auth plugins.
|
||||||
|
# error reporting in:
|
||||||
|
# - column COUNT_AUTH_PLUGIN_ERRORS
|
||||||
|
# - column COUNT_PROXY_USER_ERRORS
|
||||||
|
# - column COUNT_PROXY_USER_ACL_ERRORS
|
||||||
|
|
||||||
|
source include/not_embedded.inc;
|
||||||
|
source include/have_debug.inc;
|
||||||
|
source include/have_perfschema.inc;
|
||||||
|
source include/have_plugin_auth.inc;
|
||||||
|
source include/have_hostname_cache.inc;
|
||||||
|
|
||||||
|
if (!$AUTH_ED25519_SO) {
|
||||||
|
skip No auth_ed25519 plugin;
|
||||||
|
}
|
||||||
|
install soname 'auth_ed25519';
|
||||||
|
|
||||||
|
# Enforce a clean state
|
||||||
|
source ../include/wait_for_pfs_thread_count.inc;
|
||||||
|
source ../include/hostcache_set_state.inc;
|
||||||
|
|
||||||
|
create user plug1@'santa.claus.ipv4.example.com'
|
||||||
|
identified with ed25519 as 'foo';
|
||||||
|
create user plug2@'santa.claus.ipv4.example.com'
|
||||||
|
identified with ED25519 as 'vubFBzIrapbfHct1/J72dnUryz5VS7lA6XHH8sIx4TI';
|
||||||
|
|
||||||
|
set @saved_dbug = @@global.debug_dbug;
|
||||||
|
set global debug_dbug= "+d,vio_peer_addr_fake_ipv4,getnameinfo_fake_ipv4,getaddrinfo_fake_good_ipv4";
|
||||||
|
|
||||||
|
replace_result $MASTER_MYPORT PORT $MASTER_MYSOCK SOCKET;
|
||||||
|
error ER_ACCESS_DENIED_ERROR;
|
||||||
|
connect con1, 127.0.0.1, plug1,foo,,$MASTER_MYPORT;
|
||||||
|
source ../include/hostcache_dump.inc;
|
||||||
|
|
||||||
|
replace_result $MASTER_MYPORT PORT $MASTER_MYSOCK SOCKET;
|
||||||
|
error ER_ACCESS_DENIED_ERROR;
|
||||||
|
connect con1, 127.0.0.1, plug2,bar,,$MASTER_MYPORT;
|
||||||
|
source ../include/hostcache_dump.inc;
|
||||||
|
|
||||||
|
connect con1, 127.0.0.1, plug2,foo,,$MASTER_MYPORT;
|
||||||
|
select current_user();
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
source ../include/hostcache_dump.inc;
|
||||||
|
|
||||||
|
drop user plug1@'santa.claus.ipv4.example.com';
|
||||||
|
drop user plug2@'santa.claus.ipv4.example.com';
|
||||||
|
|
||||||
|
set @@global.debug_dbug = @saved_dbug;
|
||||||
|
uninstall plugin ed25519;
|
@ -41,17 +41,17 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
|
|||||||
|
|
||||||
/* prepare the pk */
|
/* prepare the pk */
|
||||||
if (info->auth_string_length != PASSWORD_LEN)
|
if (info->auth_string_length != PASSWORD_LEN)
|
||||||
return CR_AUTH_USER_CREDENTIALS;
|
return CR_ERROR; // bad password in the user table
|
||||||
memcpy(pw, info->auth_string, PASSWORD_LEN);
|
memcpy(pw, info->auth_string, PASSWORD_LEN);
|
||||||
pw[PASSWORD_LEN]= '=';
|
pw[PASSWORD_LEN]= '=';
|
||||||
if (my_base64_decode(pw, PASSWORD_LEN_BUF, pk, NULL, 0) != CRYPTO_PUBLICKEYBYTES)
|
if (my_base64_decode(pw, PASSWORD_LEN_BUF, pk, NULL, 0) != CRYPTO_PUBLICKEYBYTES)
|
||||||
return CR_AUTH_USER_CREDENTIALS;
|
return CR_ERROR; // bad password in the user table
|
||||||
|
|
||||||
info->password_used= PASSWORD_USED_YES;
|
info->password_used= PASSWORD_USED_YES;
|
||||||
|
|
||||||
/* prepare random nonce */
|
/* prepare random nonce */
|
||||||
if (my_random_bytes((unsigned char *)nonce, (int)sizeof(nonce)))
|
if (my_random_bytes((unsigned char *)nonce, (int)sizeof(nonce)))
|
||||||
return CR_AUTH_USER_CREDENTIALS;
|
return CR_ERROR; // eh? OpenSSL error
|
||||||
|
|
||||||
/* send it */
|
/* send it */
|
||||||
if (vio->write_packet(vio, reply + CRYPTO_BYTES, NONCE_BYTES))
|
if (vio->write_packet(vio, reply + CRYPTO_BYTES, NONCE_BYTES))
|
||||||
@ -63,7 +63,7 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
|
|||||||
memcpy(reply, pkt, CRYPTO_BYTES);
|
memcpy(reply, pkt, CRYPTO_BYTES);
|
||||||
|
|
||||||
if (crypto_sign_open(reply, CRYPTO_BYTES + NONCE_BYTES, pk))
|
if (crypto_sign_open(reply, CRYPTO_BYTES + NONCE_BYTES, pk))
|
||||||
return CR_ERROR;
|
return CR_AUTH_USER_CREDENTIALS; // wrong password provided by the user
|
||||||
|
|
||||||
return CR_OK;
|
return CR_OK;
|
||||||
}
|
}
|
||||||
|
@ -875,7 +875,9 @@ get_openssl()
|
|||||||
readonly OPENSSL_BINARY
|
readonly OPENSSL_BINARY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
# Generate a string equivalent to 16 random bytes
|
# Generate a string equivalent to 16 random bytes
|
||||||
|
#
|
||||||
wsrep_gen_secret()
|
wsrep_gen_secret()
|
||||||
{
|
{
|
||||||
get_openssl
|
get_openssl
|
||||||
@ -889,16 +891,36 @@ wsrep_gen_secret()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Checking if the address passed to us is local.
|
||||||
|
# If the second parameter is nonzero, then this function
|
||||||
|
# does not check for matches with local domain names:
|
||||||
|
#
|
||||||
is_local_ip()
|
is_local_ip()
|
||||||
{
|
{
|
||||||
[ "$1" = '127.0.0.1' ] && return 0
|
# Rapid recognition of the most common cases:
|
||||||
[ "$1" = '127.0.0.2' ] && return 0
|
[ "$1" = '127.0.0.1' -o \
|
||||||
[ "$1" = 'localhost' ] && return 0
|
"$1" = '127.0.0.2' -o \
|
||||||
[ "$1" = '[::1]' ] && return 0
|
"$1" = 'localhost' -o \
|
||||||
[ "$1" = "$(hostname -s)" ] && return 0
|
"$1" = '[::1]' ] && return 0
|
||||||
[ "$1" = "$(hostname -f)" ] && return 0
|
# If the address starts with "127." this is probably a local
|
||||||
[ "$1" = "$(hostname -d)" ] && return 0
|
# address, but we need to clarify what follows this prefix:
|
||||||
|
if [ "${1#127.}" != "$1" ]; then
|
||||||
|
# All 127.0.0.0/8 addresses are local:
|
||||||
|
if echo "$1" | grep -q -E '^127\.[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# If the second parameter is nonzero, then we will skip
|
||||||
|
# the domain name check:
|
||||||
|
if [ "${2:-0}" -eq 0 ]; then
|
||||||
|
# We consider all the names of a given host to be local addresses:
|
||||||
|
[ "$1" = "$(hostname -s)" -o \
|
||||||
|
"$1" = "$(hostname -f)" -o \
|
||||||
|
"$1" = "$(hostname -d)" ] && return 0
|
||||||
|
fi
|
||||||
|
# Now let's check if the given address is assigned to
|
||||||
|
# one of the network cards:
|
||||||
local ip_util="$(command -v ip)"
|
local ip_util="$(command -v ip)"
|
||||||
if [ -n "$ip_util" ]; then
|
if [ -n "$ip_util" ]; then
|
||||||
# ip address show ouput format is " inet[6] <address>/<mask>":
|
# ip address show ouput format is " inet[6] <address>/<mask>":
|
||||||
@ -914,7 +936,6 @@ is_local_ip()
|
|||||||
| grep -F " $1 " >/dev/null && return 0
|
| grep -F " $1 " >/dev/null && return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6129,6 +6129,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
|||||||
*/
|
*/
|
||||||
set_max_sum_func_level(thd, select);
|
set_max_sum_func_level(thd, select);
|
||||||
set_field(new_field);
|
set_field(new_field);
|
||||||
|
depended_from= (*((Item_field**)res))->depended_from;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2002, 2016, Oracle and/or its affiliates.
|
/* Copyright (c) 2002, 2016, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2010, 2016, MariaDB
|
Copyright (c) 2010, 2021, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -1779,7 +1779,6 @@ double Item_in_subselect::val_real()
|
|||||||
As far as Item_in_subselect called only from Item_in_optimizer this
|
As far as Item_in_subselect called only from Item_in_optimizer this
|
||||||
method should not be used
|
method should not be used
|
||||||
*/
|
*/
|
||||||
DBUG_ASSERT(0);
|
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
if (forced_const)
|
if (forced_const)
|
||||||
return value;
|
return value;
|
||||||
@ -2255,11 +2254,12 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
|
|||||||
*/
|
*/
|
||||||
Item *item= (Item*) select_lex->item_list.head();
|
Item *item= (Item*) select_lex->item_list.head();
|
||||||
|
|
||||||
if (select_lex->table_list.elements)
|
if (select_lex->table_list.elements ||
|
||||||
|
!(select_lex->master_unit()->is_unit_op()))
|
||||||
{
|
{
|
||||||
Item *having= item;
|
Item *having= item;
|
||||||
Item *orig_item= item;
|
Item *orig_item= item;
|
||||||
|
|
||||||
item= func->create(thd, expr, item);
|
item= func->create(thd, expr, item);
|
||||||
if (!abort_on_null && orig_item->maybe_null)
|
if (!abort_on_null && orig_item->maybe_null)
|
||||||
{
|
{
|
||||||
@ -2303,32 +2303,28 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (select_lex->master_unit()->is_unit_op())
|
DBUG_ASSERT(select_lex->master_unit()->is_unit_op());
|
||||||
{
|
LEX_CSTRING field_name= {STRING_WITH_LEN("<result>") };
|
||||||
LEX_CSTRING field_name= {STRING_WITH_LEN("<result>") };
|
Item *new_having=
|
||||||
Item *new_having=
|
func->create(thd, expr,
|
||||||
func->create(thd, expr,
|
new (thd->mem_root) Item_ref_null_helper(thd,
|
||||||
new (thd->mem_root) Item_ref_null_helper(thd,
|
|
||||||
&select_lex->context,
|
&select_lex->context,
|
||||||
this,
|
this,
|
||||||
&select_lex->ref_pointer_array[0],
|
&select_lex->ref_pointer_array[0],
|
||||||
(char *)"<no matter>",
|
(char *)"<no matter>",
|
||||||
&field_name));
|
&field_name));
|
||||||
if (!abort_on_null && left_expr->maybe_null)
|
if (!abort_on_null && left_expr->maybe_null)
|
||||||
{
|
{
|
||||||
disable_cond_guard_for_const_null_left_expr(0);
|
disable_cond_guard_for_const_null_left_expr(0);
|
||||||
if (!(new_having= new (thd->mem_root) Item_func_trig_cond(thd, new_having,
|
if (!(new_having= new (thd->mem_root) Item_func_trig_cond(thd, new_having,
|
||||||
get_cond_guard(0))))
|
get_cond_guard(0))))
|
||||||
DBUG_RETURN(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
new_having->name= in_having_cond;
|
|
||||||
if (fix_having(new_having, select_lex))
|
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
*having_item= new_having;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
DBUG_ASSERT(false);
|
new_having->name= in_having_cond;
|
||||||
|
if (fix_having(new_having, select_lex))
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
*having_item= new_having;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5407,7 +5407,7 @@ static int init_server_components()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_bin_log)
|
if (!opt_help && opt_bin_log)
|
||||||
{
|
{
|
||||||
if (mysql_bin_log.open_index_file(opt_binlog_index_name, opt_bin_logname,
|
if (mysql_bin_log.open_index_file(opt_binlog_index_name, opt_bin_logname,
|
||||||
TRUE))
|
TRUE))
|
||||||
|
@ -582,7 +582,7 @@ extern ulonglong my_pcre_frame_size;
|
|||||||
*/
|
*/
|
||||||
extern my_bool opt_large_pages;
|
extern my_bool opt_large_pages;
|
||||||
extern uint opt_large_page_size;
|
extern uint opt_large_page_size;
|
||||||
extern char lc_messages_dir[FN_REFLEN];
|
extern MYSQL_PLUGIN_IMPORT char lc_messages_dir[FN_REFLEN];
|
||||||
extern char *lc_messages_dir_ptr, *log_error_file_ptr;
|
extern char *lc_messages_dir_ptr, *log_error_file_ptr;
|
||||||
extern MYSQL_PLUGIN_IMPORT char reg_ext[FN_EXTLEN];
|
extern MYSQL_PLUGIN_IMPORT char reg_ext[FN_EXTLEN];
|
||||||
extern MYSQL_PLUGIN_IMPORT uint reg_ext_length;
|
extern MYSQL_PLUGIN_IMPORT uint reg_ext_length;
|
||||||
|
@ -3426,8 +3426,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (open_tables)
|
if (open_tables)
|
||||||
res= check_dependencies_in_with_clauses(m_lex->with_clauses_list) ||
|
res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
|
||||||
instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
|
|
||||||
|
|
||||||
if (likely(!res))
|
if (likely(!res))
|
||||||
{
|
{
|
||||||
|
@ -3520,7 +3520,11 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags,
|
|||||||
if (tables->derived)
|
if (tables->derived)
|
||||||
{
|
{
|
||||||
if (!tables->view)
|
if (!tables->view)
|
||||||
|
{
|
||||||
|
if (!tables->is_derived())
|
||||||
|
tables->set_derived();
|
||||||
goto end;
|
goto end;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
We restore view's name and database wiped out by derived tables
|
We restore view's name and database wiped out by derived tables
|
||||||
processing and fall back to standard open process in order to
|
processing and fall back to standard open process in order to
|
||||||
@ -3530,35 +3534,6 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags,
|
|||||||
tables->db= tables->view_db;
|
tables->db= tables->view_db;
|
||||||
tables->table_name= tables->view_name;
|
tables->table_name= tables->view_name;
|
||||||
}
|
}
|
||||||
else if (tables->select_lex)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Check whether 'tables' refers to a table defined in a with clause.
|
|
||||||
If so set the reference to the definition in tables->with.
|
|
||||||
*/
|
|
||||||
if (!tables->with)
|
|
||||||
tables->with= tables->select_lex->find_table_def_in_with_clauses(tables);
|
|
||||||
/*
|
|
||||||
If 'tables' is defined in a with clause set the pointer to the
|
|
||||||
specification from its definition in tables->derived.
|
|
||||||
*/
|
|
||||||
if (tables->with)
|
|
||||||
{
|
|
||||||
if (tables->is_recursive_with_table() &&
|
|
||||||
!tables->is_with_table_recursive_reference())
|
|
||||||
{
|
|
||||||
tables->with->rec_outer_references++;
|
|
||||||
With_element *with_elem= tables->with;
|
|
||||||
while ((with_elem= with_elem->get_next_mutually_recursive()) !=
|
|
||||||
tables->with)
|
|
||||||
with_elem->rec_outer_references++;
|
|
||||||
}
|
|
||||||
if (tables->set_as_with_table(thd, tables->with))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
else
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tables->derived && is_infoschema_db(&tables->db))
|
if (!tables->derived && is_infoschema_db(&tables->db))
|
||||||
{
|
{
|
||||||
|
@ -2736,6 +2736,60 @@ void THD::close_active_vio()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief MySQL parser used for recursive invocations
|
||||||
|
|
||||||
|
@param old_lex The LEX structure in the state when this parser
|
||||||
|
is called recursively
|
||||||
|
@param lex The LEX structure used to parse a new SQL fragment
|
||||||
|
@param str The SQL fragment to parse
|
||||||
|
@param str_len The length of the SQL fragment to parse
|
||||||
|
@param stmt_prepare_mode true <=> when parsing a prepare statement
|
||||||
|
|
||||||
|
@details
|
||||||
|
This function is to be used when parsing of an SQL fragment is
|
||||||
|
needed within one of the grammar rules.
|
||||||
|
|
||||||
|
@notes
|
||||||
|
Currently the function is used only when the specification of a CTE
|
||||||
|
is parsed for the not first and not recursive references of the CTE.
|
||||||
|
|
||||||
|
@retval false On a successful parsing of the fragment
|
||||||
|
@retval true Otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool THD::sql_parser(LEX *old_lex, LEX *lex,
|
||||||
|
char *str, uint str_len, bool stmt_prepare_mode)
|
||||||
|
{
|
||||||
|
extern int MYSQLparse(THD * thd);
|
||||||
|
|
||||||
|
bool parse_status= false;
|
||||||
|
Parser_state parser_state;
|
||||||
|
Parser_state *old_parser_state= m_parser_state;
|
||||||
|
|
||||||
|
if (parser_state.init(this, str, str_len))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
m_parser_state= &parser_state;
|
||||||
|
parser_state.m_lip.stmt_prepare_mode= stmt_prepare_mode;
|
||||||
|
parser_state.m_lip.multi_statements= false;
|
||||||
|
parser_state.m_lip.m_digest= NULL;
|
||||||
|
|
||||||
|
lex->param_list= old_lex->param_list;
|
||||||
|
lex->sphead= old_lex->sphead;
|
||||||
|
lex->spname= old_lex->spname;
|
||||||
|
lex->spcont= old_lex->spcont;
|
||||||
|
lex->sp_chistics= old_lex->sp_chistics;
|
||||||
|
lex->trg_chistics= old_lex->trg_chistics;
|
||||||
|
|
||||||
|
parse_status= MYSQLparse(this) != 0;
|
||||||
|
|
||||||
|
m_parser_state= old_parser_state;
|
||||||
|
|
||||||
|
return parse_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Item_change_record: public ilink
|
struct Item_change_record: public ilink
|
||||||
{
|
{
|
||||||
Item **place;
|
Item **place;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2009, 2020, MariaDB Corporation.
|
Copyright (c) 2009, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -958,7 +958,7 @@ mysqld_collation_get_by_name(const char *name,
|
|||||||
|
|
||||||
static inline bool is_supported_parser_charset(CHARSET_INFO *cs)
|
static inline bool is_supported_parser_charset(CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
return MY_TEST(cs->mbminlen == 1);
|
return MY_TEST(cs->mbminlen == 1 && cs->number != 17 /* filename */);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MYSQL_SERVER
|
#ifdef MYSQL_SERVER
|
||||||
@ -4226,15 +4226,11 @@ public:
|
|||||||
to resolve all CTE names as we don't need this message to be thrown
|
to resolve all CTE names as we don't need this message to be thrown
|
||||||
for any CTE references.
|
for any CTE references.
|
||||||
*/
|
*/
|
||||||
if (!lex->with_clauses_list)
|
if (!lex->with_cte_resolution)
|
||||||
{
|
{
|
||||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/* This will allow to throw an error later for non-CTE references */
|
|
||||||
to->str= NULL;
|
|
||||||
to->length= 0;
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
to->str= strmake(db.str, db.length);
|
to->str= strmake(db.str, db.length);
|
||||||
@ -4839,6 +4835,9 @@ public:
|
|||||||
mysql_mutex_unlock(&LOCK_thread_count);
|
mysql_mutex_unlock(&LOCK_thread_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sql_parser(LEX *old_lex, LEX *lex,
|
||||||
|
char *str, uint str_len, bool stmt_prepare_mode);
|
||||||
|
|
||||||
|
|
||||||
uint get_net_wait_timeout()
|
uint get_net_wait_timeout()
|
||||||
{
|
{
|
||||||
|
430
sql/sql_cte.cc
430
sql/sql_cte.cc
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2016, 2017 MariaDB
|
Copyright (c) 2016, 2021, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -75,7 +75,7 @@ bool With_clause::add_with_element(With_element *elem)
|
|||||||
true on failure
|
true on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool check_dependencies_in_with_clauses(With_clause *with_clauses_list)
|
bool LEX::check_dependencies_in_with_clauses()
|
||||||
{
|
{
|
||||||
for (With_clause *with_clause= with_clauses_list;
|
for (With_clause *with_clause= with_clauses_list;
|
||||||
with_clause;
|
with_clause;
|
||||||
@ -91,6 +91,200 @@ bool check_dependencies_in_with_clauses(With_clause *with_clauses_list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Resolve references to CTE in specification of hanging CTE
|
||||||
|
|
||||||
|
@details
|
||||||
|
A CTE to which there are no references in the query is called hanging CTE.
|
||||||
|
Although such CTE is not used for execution its specification must be
|
||||||
|
subject to context analysis. All errors concerning references to
|
||||||
|
non-existing tables or fields occurred in the specification must be
|
||||||
|
reported as well as all other errors caught at the prepare stage.
|
||||||
|
The specification of a hanging CTE might contain references to other
|
||||||
|
CTE outside of the specification and within it if the specification
|
||||||
|
contains a with clause. This function resolves all such references for
|
||||||
|
all hanging CTEs encountered in the processed query.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
false on success
|
||||||
|
true on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
LEX::resolve_references_to_cte_in_hanging_cte()
|
||||||
|
{
|
||||||
|
for (With_clause *with_clause= with_clauses_list;
|
||||||
|
with_clause; with_clause= with_clause->next_with_clause)
|
||||||
|
{
|
||||||
|
for (With_element *with_elem= with_clause->with_list.first;
|
||||||
|
with_elem; with_elem= with_elem->next)
|
||||||
|
{
|
||||||
|
if (!with_elem->is_referenced())
|
||||||
|
{
|
||||||
|
TABLE_LIST *first_tbl=
|
||||||
|
with_elem->spec->first_select()->table_list.first;
|
||||||
|
TABLE_LIST **with_elem_end_pos= with_elem->head->tables_pos.end_pos;
|
||||||
|
if (first_tbl && resolve_references_to_cte(first_tbl, with_elem_end_pos))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Resolve table references to CTE from a sub-chain of table references
|
||||||
|
|
||||||
|
@param tables Points to the beginning of the sub-chain
|
||||||
|
@param tables_last Points to the address with the sub-chain barrier
|
||||||
|
|
||||||
|
@details
|
||||||
|
The method resolves tables references to CTE from the chain of
|
||||||
|
table references specified by the parameters 'tables' and 'tables_last'.
|
||||||
|
It resolves the references against the CTE definition occurred in a query
|
||||||
|
or the specification of a CTE whose parsing tree is represented by
|
||||||
|
this LEX structure. The method is always called right after the process
|
||||||
|
of parsing the query or of the specification of a CTE has been finished,
|
||||||
|
thus the chain of table references used in the parsed fragment has been
|
||||||
|
already built. It is assumed that parameters of the method specify a
|
||||||
|
a sub-chain of this chain.
|
||||||
|
If a table reference can be potentially a table reference to a CTE and it
|
||||||
|
has not been resolved yet then the method tries to find the definition
|
||||||
|
of the CTE against which the reference can be resolved. If it succeeds
|
||||||
|
it sets the field TABLE_LIST::with to point to the found definition.
|
||||||
|
It also sets the field TABLE_LIST::derived to point to the specification
|
||||||
|
of the found CTE and sets TABLE::db.str to empty_c_string. This will
|
||||||
|
allow to handle this table reference like a reference to a derived handle.
|
||||||
|
If another table reference has been already resolved against this CTE
|
||||||
|
and this CTE is not recursive then a clone of the CTE specification is
|
||||||
|
constructed using the function With_element::clone_parsed_spec() and
|
||||||
|
TABLE_LIST::derived is set to point to this clone rather than to the
|
||||||
|
original specification.
|
||||||
|
If the method does not find a matched CTE definition in the parsed fragment
|
||||||
|
then in the case when the flag this->only_cte_resolution is set to true
|
||||||
|
it just moves to the resolution of the next table reference from the
|
||||||
|
specified sub-chain while in the case when this->only_cte_resolution is set
|
||||||
|
to false the method additionally sets an mdl request for this table
|
||||||
|
reference.
|
||||||
|
|
||||||
|
@notes
|
||||||
|
The flag this->only_cte_resolution is set to true in the cases when
|
||||||
|
the failure to resolve a table reference as a CTE reference within
|
||||||
|
the fragment associated with this LEX structure does not imply that
|
||||||
|
this table reference cannot be resolved as such at all.
|
||||||
|
|
||||||
|
@retval false On success: no errors reported, no memory allocations failed
|
||||||
|
@retval true Otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool LEX::resolve_references_to_cte(TABLE_LIST *tables,
|
||||||
|
TABLE_LIST **tables_last)
|
||||||
|
{
|
||||||
|
With_element *with_elem= 0;
|
||||||
|
|
||||||
|
for (TABLE_LIST *tbl= tables; tbl != *tables_last; tbl= tbl->next_global)
|
||||||
|
{
|
||||||
|
if (tbl->derived)
|
||||||
|
continue;
|
||||||
|
if (!tbl->db.length && !tbl->with)
|
||||||
|
tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl);
|
||||||
|
if (!tbl->with) // no CTE matches table reference tbl
|
||||||
|
{
|
||||||
|
if (only_cte_resolution)
|
||||||
|
continue;
|
||||||
|
if (!tbl->db.length) // no database specified in table reference tbl
|
||||||
|
{
|
||||||
|
if (!thd->db.length) // no default database is set
|
||||||
|
{
|
||||||
|
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (copy_db_to(&tbl->db))
|
||||||
|
return true;
|
||||||
|
if (!(tbl->table_options & TL_OPTION_ALIAS))
|
||||||
|
tbl->mdl_request.init(MDL_key::TABLE, tbl->db.str,
|
||||||
|
tbl->table_name.str,
|
||||||
|
tbl->mdl_type, MDL_TRANSACTION);
|
||||||
|
tbl->mdl_request.set_type((tbl->lock_type >= TL_WRITE_ALLOW_WRITE) ?
|
||||||
|
MDL_SHARED_WRITE : MDL_SHARED_READ);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
with_elem= tbl->with;
|
||||||
|
if (tbl->is_recursive_with_table() &&
|
||||||
|
!tbl->is_with_table_recursive_reference())
|
||||||
|
{
|
||||||
|
tbl->with->rec_outer_references++;
|
||||||
|
while ((with_elem= with_elem->get_next_mutually_recursive()) !=
|
||||||
|
tbl->with)
|
||||||
|
with_elem->rec_outer_references++;
|
||||||
|
}
|
||||||
|
if (!with_elem->is_used_in_query || with_elem->is_recursive)
|
||||||
|
{
|
||||||
|
tbl->derived= with_elem->spec;
|
||||||
|
if (tbl->derived != tbl->select_lex->master_unit() &&
|
||||||
|
!with_elem->is_recursive &&
|
||||||
|
!tbl->is_with_table_recursive_reference())
|
||||||
|
{
|
||||||
|
tbl->derived->move_as_slave(tbl->select_lex);
|
||||||
|
}
|
||||||
|
with_elem->is_used_in_query= true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(tbl->derived= tbl->with->clone_parsed_spec(thd->lex, tbl)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
tbl->db.str= empty_c_string;
|
||||||
|
tbl->db.length= 0;
|
||||||
|
tbl->schema_table= 0;
|
||||||
|
if (tbl->derived)
|
||||||
|
{
|
||||||
|
tbl->derived->first_select()->linkage= DERIVED_TABLE_TYPE;
|
||||||
|
}
|
||||||
|
if (tbl->with->is_recursive && tbl->is_with_table_recursive_reference())
|
||||||
|
continue;
|
||||||
|
with_elem->inc_references();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Find out dependencies between CTEs, resolve references to them
|
||||||
|
|
||||||
|
@details
|
||||||
|
The function can be called in two modes. With this->with_cte_resolution
|
||||||
|
set to false the function only finds out all dependencies between CTEs
|
||||||
|
used in a query expression with a WITH clause whose parsing has been
|
||||||
|
just finished. Based on these dependencies recursive CTEs are detected.
|
||||||
|
If this->with_cte_resolution is set to true the function additionally
|
||||||
|
resolves all references to CTE occurred in this query expression.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
true on failure
|
||||||
|
false on success
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
LEX::check_cte_dependencies_and_resolve_references()
|
||||||
|
{
|
||||||
|
if (check_dependencies_in_with_clauses())
|
||||||
|
return true;
|
||||||
|
if (!with_cte_resolution)
|
||||||
|
return false;
|
||||||
|
if (resolve_references_to_cte(query_tables, query_tables_last))
|
||||||
|
return true;
|
||||||
|
if (resolve_references_to_cte_in_hanging_cte())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief
|
@brief
|
||||||
Check dependencies between tables defined in this with clause
|
Check dependencies between tables defined in this with clause
|
||||||
@ -129,10 +323,11 @@ bool With_clause::check_dependencies()
|
|||||||
elem != with_elem;
|
elem != with_elem;
|
||||||
elem= elem->next)
|
elem= elem->next)
|
||||||
{
|
{
|
||||||
if (lex_string_cmp(system_charset_info, with_elem->query_name,
|
if (my_strcasecmp(system_charset_info, with_elem->get_name_str(),
|
||||||
elem->query_name) == 0)
|
elem->get_name_str()) == 0)
|
||||||
{
|
{
|
||||||
my_error(ER_DUP_QUERY_NAME, MYF(0), with_elem->query_name->str);
|
my_error(ER_DUP_QUERY_NAME, MYF(0),
|
||||||
|
with_elem->get_name_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,13 +434,12 @@ With_element *With_clause::find_table_def(TABLE_LIST *table,
|
|||||||
with_elem != barrier;
|
with_elem != barrier;
|
||||||
with_elem= with_elem->next)
|
with_elem= with_elem->next)
|
||||||
{
|
{
|
||||||
if (my_strcasecmp(system_charset_info, with_elem->query_name->str,
|
if (my_strcasecmp(system_charset_info, with_elem->get_name_str(),
|
||||||
table->table_name.str) == 0 &&
|
table->table_name.str) == 0 &&
|
||||||
!table->is_fqtn)
|
!table->is_fqtn)
|
||||||
{
|
{
|
||||||
table->set_derived();
|
table->set_derived();
|
||||||
table->db.str= empty_c_string;
|
with_elem->referenced= true;
|
||||||
table->db.length= 0;
|
|
||||||
return with_elem;
|
return with_elem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -602,7 +796,7 @@ bool With_clause::check_anchors()
|
|||||||
if (elem == with_elem)
|
if (elem == with_elem)
|
||||||
{
|
{
|
||||||
my_error(ER_RECURSIVE_WITHOUT_ANCHORS, MYF(0),
|
my_error(ER_RECURSIVE_WITHOUT_ANCHORS, MYF(0),
|
||||||
with_elem->query_name->str);
|
with_elem->get_name_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -635,7 +829,7 @@ bool With_clause::check_anchors()
|
|||||||
if (elem->work_dep_map & elem->get_elem_map())
|
if (elem->work_dep_map & elem->get_elem_map())
|
||||||
{
|
{
|
||||||
my_error(ER_UNACCEPTABLE_MUTUAL_RECURSION, MYF(0),
|
my_error(ER_UNACCEPTABLE_MUTUAL_RECURSION, MYF(0),
|
||||||
with_elem->query_name->str);
|
with_elem->get_name_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -787,7 +981,8 @@ bool With_element::set_unparsed_spec(THD *thd, char *spec_start, char *spec_end,
|
|||||||
@brief
|
@brief
|
||||||
Create a clone of the specification for the given with table
|
Create a clone of the specification for the given with table
|
||||||
|
|
||||||
@param thd The context of the statement containing this with element
|
@param old_lex The LEX structure created for the query or CTE specification
|
||||||
|
where this With_element is defined
|
||||||
@param with_table The reference to the table defined in this element for which
|
@param with_table The reference to the table defined in this element for which
|
||||||
the clone is created.
|
the clone is created.
|
||||||
|
|
||||||
@ -797,12 +992,13 @@ bool With_element::set_unparsed_spec(THD *thd, char *spec_start, char *spec_end,
|
|||||||
this element.
|
this element.
|
||||||
The clone is created when the string with the specification saved in
|
The clone is created when the string with the specification saved in
|
||||||
unparsed_spec is fed into the parser as an input string. The parsing
|
unparsed_spec is fed into the parser as an input string. The parsing
|
||||||
this string a unit object representing the specification is build.
|
this string a unit object representing the specification is built.
|
||||||
A chain of all table references occurred in the specification is also
|
A chain of all table references occurred in the specification is also
|
||||||
formed.
|
formed.
|
||||||
The method includes the new unit and its sub-unit into hierarchy of
|
The method includes the new unit and its sub-unit into hierarchy of
|
||||||
the units of the main query. I also insert the constructed chain of the
|
the units of the main query. I also insert the constructed chain of the
|
||||||
table references into the chain of all table references of the main query.
|
table references into the chain of all table references of the main query.
|
||||||
|
The method resolves all references to CTE in the clone.
|
||||||
|
|
||||||
@note
|
@note
|
||||||
Clones is created only for not first references to tables defined in
|
Clones is created only for not first references to tables defined in
|
||||||
@ -818,115 +1014,129 @@ bool With_element::set_unparsed_spec(THD *thd, char *spec_start, char *spec_end,
|
|||||||
NULL - otherwise
|
NULL - otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
|
st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
|
||||||
TABLE_LIST *with_table)
|
TABLE_LIST *with_table)
|
||||||
{
|
{
|
||||||
|
THD *thd= old_lex->thd;
|
||||||
LEX *lex;
|
LEX *lex;
|
||||||
st_select_lex_unit *res= NULL;
|
st_select_lex_unit *res= NULL;
|
||||||
Query_arena backup;
|
|
||||||
Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
|
|
||||||
|
|
||||||
if (!(lex= (LEX*) new(thd->mem_root) st_lex_local))
|
if (!(lex= (LEX*) new(thd->mem_root) st_lex_local))
|
||||||
{
|
|
||||||
if (arena)
|
|
||||||
thd->restore_active_arena(arena, &backup);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
|
||||||
LEX *old_lex= thd->lex;
|
|
||||||
thd->lex= lex;
|
thd->lex= lex;
|
||||||
|
|
||||||
bool parse_status= false;
|
bool parse_status= false;
|
||||||
Parser_state parser_state;
|
|
||||||
TABLE_LIST *spec_tables;
|
|
||||||
TABLE_LIST *spec_tables_tail;
|
|
||||||
st_select_lex *with_select;
|
st_select_lex *with_select;
|
||||||
|
|
||||||
char save_end= unparsed_spec.str[unparsed_spec.length];
|
char save_end= unparsed_spec.str[unparsed_spec.length];
|
||||||
((char*) &unparsed_spec.str[unparsed_spec.length])[0]= '\0';
|
const_cast<char*>(unparsed_spec.str)[unparsed_spec.length]= '\0';
|
||||||
if (parser_state.init(thd, (char*) unparsed_spec.str, (unsigned int)unparsed_spec.length))
|
|
||||||
goto err;
|
|
||||||
parser_state.m_lip.stmt_prepare_mode= stmt_prepare_mode;
|
|
||||||
parser_state.m_lip.multi_statements= false;
|
|
||||||
parser_state.m_lip.m_digest= NULL;
|
|
||||||
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
lex->clone_spec_offset= unparsed_spec_offset;
|
lex->clone_spec_offset= unparsed_spec_offset;
|
||||||
lex->param_list= old_lex->param_list;
|
lex->with_cte_resolution= true;
|
||||||
lex->sphead= old_lex->sphead;
|
|
||||||
lex->spname= old_lex->spname;
|
|
||||||
lex->spcont= old_lex->spcont;
|
|
||||||
lex->sp_chistics= old_lex->sp_chistics;
|
|
||||||
|
|
||||||
lex->stmt_lex= old_lex;
|
/*
|
||||||
with_select= &lex->select_lex;
|
The specification of a CTE is to be parsed as a regular query.
|
||||||
with_select->select_number= ++thd->lex->stmt_lex->current_select_number;
|
At the very end of the parsing query the function
|
||||||
parse_status= parse_sql(thd, &parser_state, 0);
|
check_cte_dependencies_and_resolve_references() will be called.
|
||||||
((char*) &unparsed_spec.str[unparsed_spec.length])[0]= save_end;
|
It will check the dependencies between CTEs that are defined
|
||||||
|
within the query and will resolve CTE references in this query.
|
||||||
|
If a table reference is not resolved as a CTE reference within
|
||||||
|
this query it still can be resolved as a reference to a CTE defined
|
||||||
|
in the same clause as the CTE whose specification is to be parsed
|
||||||
|
or defined in an embedding CTE definition.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
with
|
||||||
|
cte1 as ( ... ),
|
||||||
|
cte2 as ([WITH ...] select ... from cte1 ...)
|
||||||
|
select ... from cte2 as r, ..., cte2 as s ...
|
||||||
|
|
||||||
|
Here the specification of cte2 has be cloned for table reference
|
||||||
|
with alias s1. The specification contains a reference to cte1
|
||||||
|
that is defined outside this specification. If the reference to
|
||||||
|
cte1 cannot be resolved within the specification of cte2 it's
|
||||||
|
not necessarily has to be a reference to a non-CTE table. That's
|
||||||
|
why the flag lex->only_cte_resolution has to be set to true
|
||||||
|
before parsing of the specification of cte2 invoked by this
|
||||||
|
function starts. Otherwise an mdl_lock would be requested for s
|
||||||
|
and this would not be correct.
|
||||||
|
*/
|
||||||
|
|
||||||
|
lex->only_cte_resolution= true;
|
||||||
|
|
||||||
|
lex->stmt_lex= old_lex->stmt_lex ? old_lex->stmt_lex : old_lex;
|
||||||
|
|
||||||
|
parse_status= thd->sql_parser(old_lex, lex,
|
||||||
|
(char*) unparsed_spec.str,
|
||||||
|
(unsigned int)unparsed_spec.length,
|
||||||
|
stmt_prepare_mode);
|
||||||
|
|
||||||
|
const_cast<char*>(unparsed_spec.str)[unparsed_spec.length]= save_end;
|
||||||
|
with_select= lex->unit.first_select();
|
||||||
|
with_select->select_number= ++lex->stmt_lex->current_select_number;
|
||||||
|
|
||||||
if (parse_status)
|
if (parse_status)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (check_dependencies_in_with_clauses(lex->with_clauses_list))
|
/*
|
||||||
goto err;
|
The global chain of TABLE_LIST objects created for the specification that
|
||||||
|
just has been parsed is added to such chain that contains the reference
|
||||||
spec_tables= lex->query_tables;
|
to the CTE whose specification is parsed right after the TABLE_LIST object
|
||||||
spec_tables_tail= 0;
|
created for the reference.
|
||||||
for (TABLE_LIST *tbl= spec_tables;
|
*/
|
||||||
tbl;
|
if (lex->query_tables)
|
||||||
tbl= tbl->next_global)
|
|
||||||
{
|
{
|
||||||
if (!tbl->derived && !tbl->schema_table &&
|
head->tables_pos.set_start_pos(&with_table->next_global);
|
||||||
thd->open_temporary_table(tbl))
|
head->tables_pos.set_end_pos(lex->query_tables_last);
|
||||||
goto err;
|
TABLE_LIST *next_tbl= with_table->next_global;
|
||||||
spec_tables_tail= tbl;
|
if (next_tbl)
|
||||||
}
|
|
||||||
if (spec_tables)
|
|
||||||
{
|
|
||||||
if (with_table->next_global)
|
|
||||||
{
|
{
|
||||||
spec_tables_tail->next_global= with_table->next_global;
|
*(lex->query_tables->prev_global= next_tbl->prev_global)=
|
||||||
with_table->next_global->prev_global= &spec_tables_tail->next_global;
|
lex->query_tables;
|
||||||
|
*(next_tbl->prev_global= lex->query_tables_last)= next_tbl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
old_lex->query_tables_last= &spec_tables_tail->next_global;
|
*(lex->query_tables->prev_global= old_lex->query_tables_last)=
|
||||||
|
lex->query_tables;
|
||||||
|
old_lex->query_tables_last= lex->query_tables_last;
|
||||||
}
|
}
|
||||||
spec_tables->prev_global= &with_table->next_global;
|
|
||||||
with_table->next_global= spec_tables;
|
|
||||||
}
|
}
|
||||||
res= &lex->unit;
|
res= &lex->unit;
|
||||||
res->with_element= this;
|
res->with_element= this;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The unit of the specification that just has been parsed is included
|
||||||
|
as a slave of the select that contained in its from list the table
|
||||||
|
reference for which the unit has been created.
|
||||||
|
*/
|
||||||
lex->unit.include_down(with_table->select_lex);
|
lex->unit.include_down(with_table->select_lex);
|
||||||
lex->unit.set_slave(with_select);
|
lex->unit.set_slave(with_select);
|
||||||
|
lex->unit.cloned_from= spec;
|
||||||
old_lex->all_selects_list=
|
old_lex->all_selects_list=
|
||||||
(st_select_lex*) (lex->all_selects_list->
|
(st_select_lex*) (lex->all_selects_list->
|
||||||
insert_chain_before(
|
insert_chain_before(
|
||||||
(st_select_lex_node **) &(old_lex->all_selects_list),
|
(st_select_lex_node **) &(old_lex->all_selects_list),
|
||||||
with_select));
|
with_select));
|
||||||
if (check_dependencies_in_with_clauses(lex->with_clauses_list))
|
|
||||||
res= NULL;
|
|
||||||
/*
|
|
||||||
Resolve references to CTE from the spec_tables list that has not
|
|
||||||
been resolved yet.
|
|
||||||
*/
|
|
||||||
for (TABLE_LIST *tbl= spec_tables;
|
|
||||||
tbl;
|
|
||||||
tbl= tbl->next_global)
|
|
||||||
{
|
|
||||||
if (!tbl->with)
|
|
||||||
tbl->with= with_select->find_table_def_in_with_clauses(tbl);
|
|
||||||
if (tbl == spec_tables_tail)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
lex->sphead= NULL; // in order not to delete lex->sphead
|
/*
|
||||||
|
Now all references to the CTE defined outside of the cloned specification
|
||||||
|
has to be resolved. Additionally if old_lex->only_cte_resolution == false
|
||||||
|
for the table references that has not been resolved requests for mdl_locks
|
||||||
|
has to be set.
|
||||||
|
*/
|
||||||
|
lex->only_cte_resolution= old_lex->only_cte_resolution;
|
||||||
|
if (lex->resolve_references_to_cte(lex->query_tables,
|
||||||
|
lex->query_tables_last))
|
||||||
|
{
|
||||||
|
res= NULL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
lex->sphead= NULL; // in order not to delete lex->sphead
|
||||||
lex_end(lex);
|
lex_end(lex);
|
||||||
err:
|
err:
|
||||||
if (arena)
|
|
||||||
thd->restore_active_arena(arena, &backup);
|
|
||||||
thd->lex= old_lex;
|
thd->lex= old_lex;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1096,58 +1306,6 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
@brief
|
|
||||||
Set the specifying unit in this reference to a with table
|
|
||||||
|
|
||||||
@details
|
|
||||||
The method assumes that the given element with_elem defines the table T
|
|
||||||
this table reference refers to.
|
|
||||||
If this is the first reference to T the method just sets its specification
|
|
||||||
in the field 'derived' as the unit that yields T. Otherwise the method
|
|
||||||
first creates a clone specification and sets rather this clone in this field.
|
|
||||||
|
|
||||||
@retval
|
|
||||||
false on success
|
|
||||||
true on failure
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
|
|
||||||
{
|
|
||||||
if (table)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
This table was prematurely identified as a temporary table.
|
|
||||||
We correct it here, but it's not a nice solution in the case
|
|
||||||
when the temporary table with this name is not used anywhere
|
|
||||||
else in the query.
|
|
||||||
*/
|
|
||||||
thd->mark_tmp_table_as_free_for_reuse(table);
|
|
||||||
table= 0;
|
|
||||||
}
|
|
||||||
with= with_elem;
|
|
||||||
schema_table= NULL;
|
|
||||||
if (!with_elem->is_referenced() || with_elem->is_recursive)
|
|
||||||
{
|
|
||||||
derived= with_elem->spec;
|
|
||||||
if (derived != select_lex->master_unit() &&
|
|
||||||
!with_elem->is_recursive &&
|
|
||||||
!is_with_table_recursive_reference())
|
|
||||||
{
|
|
||||||
derived->move_as_slave(select_lex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!(derived= with_elem->clone_parsed_spec(thd, this)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
derived->first_select()->linkage= DERIVED_TABLE_TYPE;
|
|
||||||
with_elem->inc_references();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool TABLE_LIST::is_recursive_with_table()
|
bool TABLE_LIST::is_recursive_with_table()
|
||||||
{
|
{
|
||||||
return with && with->is_recursive;
|
return with && with->is_recursive;
|
||||||
@ -1247,7 +1405,7 @@ bool st_select_lex::check_unrestricted_recursive(bool only_standard_compliant)
|
|||||||
if (only_standard_compliant && with_elem->is_unrestricted())
|
if (only_standard_compliant && with_elem->is_unrestricted())
|
||||||
{
|
{
|
||||||
my_error(ER_NOT_STANDARD_COMPLIANT_RECURSIVE,
|
my_error(ER_NOT_STANDARD_COMPLIANT_RECURSIVE,
|
||||||
MYF(0), with_elem->query_name->str);
|
MYF(0), with_elem->get_name_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1447,7 +1605,7 @@ void With_clause::print(String *str, enum_query_type query_type)
|
|||||||
|
|
||||||
void With_element::print(String *str, enum_query_type query_type)
|
void With_element::print(String *str, enum_query_type query_type)
|
||||||
{
|
{
|
||||||
str->append(query_name);
|
str->append(get_name());
|
||||||
if (column_list.elements)
|
if (column_list.elements)
|
||||||
{
|
{
|
||||||
List_iterator_fast<LEX_CSTRING> li(column_list);
|
List_iterator_fast<LEX_CSTRING> li(column_list);
|
||||||
|
@ -24,6 +24,39 @@ class select_unit;
|
|||||||
struct st_unit_ctxt_elem;
|
struct st_unit_ctxt_elem;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class With_element_head
|
||||||
|
@brief Head of the definition of a CTE table
|
||||||
|
|
||||||
|
It contains the name of the CTE and it contains the position of the subchain
|
||||||
|
of table references used in the definition in the global chain of table
|
||||||
|
references used in the query where this definition is encountered.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class With_element_head : public Sql_alloc
|
||||||
|
{
|
||||||
|
/* The name of the defined CTE */
|
||||||
|
LEX_CSTRING *query_name;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
The structure describing the subchain of the table references used in
|
||||||
|
the specification of the defined CTE in the global chain of table
|
||||||
|
references used in the query. The structure is fully defined only
|
||||||
|
after the CTE definition has been parsed.
|
||||||
|
*/
|
||||||
|
TABLE_CHAIN tables_pos;
|
||||||
|
|
||||||
|
With_element_head(LEX_CSTRING *name)
|
||||||
|
: query_name(name)
|
||||||
|
{
|
||||||
|
tables_pos.set_start_pos(0);
|
||||||
|
tables_pos.set_end_pos(0);
|
||||||
|
}
|
||||||
|
friend class With_element;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@class With_element
|
@class With_element
|
||||||
@brief Definition of a CTE table
|
@brief Definition of a CTE table
|
||||||
@ -85,9 +118,22 @@ private:
|
|||||||
subqueries and specifications of other with elements).
|
subqueries and specifications of other with elements).
|
||||||
*/
|
*/
|
||||||
uint references;
|
uint references;
|
||||||
|
|
||||||
|
/*
|
||||||
|
true <=> this With_element is referred in the query in which the
|
||||||
|
element is defined
|
||||||
|
*/
|
||||||
|
bool referenced;
|
||||||
|
|
||||||
|
/*
|
||||||
|
true <=> this With_element is needed for the execution of the query
|
||||||
|
in which the element is defined
|
||||||
|
*/
|
||||||
|
bool is_used_in_query;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Unparsed specification of the query that specifies this element.
|
Unparsed specification of the query that specifies this element.
|
||||||
It used to build clones of the specification if they are needed.
|
It's used to build clones of the specification if they are needed.
|
||||||
*/
|
*/
|
||||||
LEX_CSTRING unparsed_spec;
|
LEX_CSTRING unparsed_spec;
|
||||||
/* Offset of the specification in the input string */
|
/* Offset of the specification in the input string */
|
||||||
@ -101,10 +147,11 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
The name of the table introduced by this with elememt. The name
|
Contains the name of the defined With element and the position of
|
||||||
can be used in FROM lists of the queries in the scope of the element.
|
the subchain of the tables references used by its definition in the
|
||||||
|
global chain of TABLE_LIST objects created for the whole query.
|
||||||
*/
|
*/
|
||||||
LEX_CSTRING *query_name;
|
With_element_head *head;
|
||||||
/*
|
/*
|
||||||
Optional list of column names to name the columns of the table introduced
|
Optional list of column names to name the columns of the table introduced
|
||||||
by this with element. It is used in the case when the names are not
|
by this with element. It is used in the case when the names are not
|
||||||
@ -162,18 +209,27 @@ public:
|
|||||||
/* List of derived tables containing recursive references to this CTE */
|
/* List of derived tables containing recursive references to this CTE */
|
||||||
SQL_I_List<TABLE_LIST> derived_with_rec_ref;
|
SQL_I_List<TABLE_LIST> derived_with_rec_ref;
|
||||||
|
|
||||||
With_element(LEX_CSTRING *name,
|
With_element(With_element_head *h,
|
||||||
List <LEX_CSTRING> list,
|
List <LEX_CSTRING> list,
|
||||||
st_select_lex_unit *unit)
|
st_select_lex_unit *unit)
|
||||||
: next(NULL), base_dep_map(0), derived_dep_map(0),
|
: next(NULL), base_dep_map(0), derived_dep_map(0),
|
||||||
sq_dep_map(0), work_dep_map(0), mutually_recursive(0),
|
sq_dep_map(0), work_dep_map(0), mutually_recursive(0),
|
||||||
top_level_dep_map(0), sq_rec_ref(NULL),
|
top_level_dep_map(0), sq_rec_ref(NULL),
|
||||||
next_mutually_recursive(NULL), references(0),
|
next_mutually_recursive(NULL), references(0),
|
||||||
query_name(name), column_list(list), spec(unit),
|
referenced(false), is_used_in_query(false),
|
||||||
|
head(h), column_list(list), spec(unit),
|
||||||
is_recursive(false), rec_outer_references(0), with_anchor(false),
|
is_recursive(false), rec_outer_references(0), with_anchor(false),
|
||||||
level(0), rec_result(NULL)
|
level(0), rec_result(NULL)
|
||||||
{ unit->with_element= this; }
|
{ unit->with_element= this; }
|
||||||
|
|
||||||
|
LEX_CSTRING *get_name() { return head->query_name; }
|
||||||
|
const char *get_name_str() { return get_name()->str; }
|
||||||
|
|
||||||
|
void set_tables_start_pos(TABLE_LIST **pos)
|
||||||
|
{ head->tables_pos.set_start_pos(pos); }
|
||||||
|
void set_tables_end_pos(TABLE_LIST **pos)
|
||||||
|
{ head->tables_pos.set_end_pos(pos); }
|
||||||
|
|
||||||
bool check_dependencies_in_spec();
|
bool check_dependencies_in_spec();
|
||||||
|
|
||||||
void check_dependencies_in_select(st_select_lex *sl, st_unit_ctxt_elem *ctxt,
|
void check_dependencies_in_select(st_select_lex *sl, st_unit_ctxt_elem *ctxt,
|
||||||
@ -200,9 +256,9 @@ public:
|
|||||||
bool set_unparsed_spec(THD *thd, char *spec_start, char *spec_end,
|
bool set_unparsed_spec(THD *thd, char *spec_start, char *spec_end,
|
||||||
my_ptrdiff_t spec_offset);
|
my_ptrdiff_t spec_offset);
|
||||||
|
|
||||||
st_select_lex_unit *clone_parsed_spec(THD *thd, TABLE_LIST *with_table);
|
st_select_lex_unit *clone_parsed_spec(LEX *old_lex, TABLE_LIST *with_table);
|
||||||
|
|
||||||
bool is_referenced() { return references != 0; }
|
bool is_referenced() { return referenced; }
|
||||||
|
|
||||||
void inc_references() { references++; }
|
void inc_references() { references++; }
|
||||||
|
|
||||||
@ -260,6 +316,12 @@ public:
|
|||||||
void prepare_for_next_iteration();
|
void prepare_for_next_iteration();
|
||||||
|
|
||||||
friend class With_clause;
|
friend class With_clause;
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool LEX::resolve_references_to_cte(TABLE_LIST *tables,
|
||||||
|
TABLE_LIST **tables_last);
|
||||||
|
friend
|
||||||
|
bool LEX::resolve_references_to_cte_in_hanging_cte();
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint max_number_of_elements_in_with_clause= sizeof(table_map)*8;
|
const uint max_number_of_elements_in_with_clause= sizeof(table_map)*8;
|
||||||
@ -356,8 +418,10 @@ public:
|
|||||||
friend class With_element;
|
friend class With_element;
|
||||||
|
|
||||||
friend
|
friend
|
||||||
bool
|
bool LEX::check_dependencies_in_with_clauses();
|
||||||
check_dependencies_in_with_clauses(With_clause *with_clauses_list);
|
|
||||||
|
friend
|
||||||
|
bool LEX::resolve_references_to_cte_in_hanging_cte();
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
|
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2009, 2020, MariaDB Corporation
|
Copyright (c) 2009, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -702,6 +702,8 @@ void LEX::start(THD *thd_arg)
|
|||||||
explain_json= false;
|
explain_json= false;
|
||||||
context_analysis_only= 0;
|
context_analysis_only= 0;
|
||||||
derived_tables= 0;
|
derived_tables= 0;
|
||||||
|
with_cte_resolution= false;
|
||||||
|
only_cte_resolution= false;
|
||||||
safe_to_cache_query= 1;
|
safe_to_cache_query= 1;
|
||||||
parsing_options.reset();
|
parsing_options.reset();
|
||||||
empty_field_list_on_rset= 0;
|
empty_field_list_on_rset= 0;
|
||||||
@ -2300,6 +2302,7 @@ void st_select_lex_unit::init_query()
|
|||||||
is_view= false;
|
is_view= false;
|
||||||
with_clause= 0;
|
with_clause= 0;
|
||||||
with_element= 0;
|
with_element= 0;
|
||||||
|
cloned_from= 0;
|
||||||
columns_are_renamed= false;
|
columns_are_renamed= false;
|
||||||
intersect_mark= NULL;
|
intersect_mark= NULL;
|
||||||
with_wrapped_tvc= false;
|
with_wrapped_tvc= false;
|
||||||
|
@ -846,6 +846,8 @@ public:
|
|||||||
With_clause *with_clause;
|
With_clause *with_clause;
|
||||||
/* With element where this unit is used as the specification (if any) */
|
/* With element where this unit is used as the specification (if any) */
|
||||||
With_element *with_element;
|
With_element *with_element;
|
||||||
|
/* The unit used as a CTE specification from which this unit is cloned */
|
||||||
|
st_select_lex_unit *cloned_from;
|
||||||
/* thread handler */
|
/* thread handler */
|
||||||
THD *thd;
|
THD *thd;
|
||||||
/*
|
/*
|
||||||
@ -1378,7 +1380,9 @@ public:
|
|||||||
}
|
}
|
||||||
With_element *get_with_element()
|
With_element *get_with_element()
|
||||||
{
|
{
|
||||||
return master_unit()->with_element;
|
return master_unit()->cloned_from ?
|
||||||
|
master_unit()->cloned_from->with_element :
|
||||||
|
master_unit()->with_element;
|
||||||
}
|
}
|
||||||
With_element *find_table_def_in_with_clauses(TABLE_LIST *table);
|
With_element *find_table_def_in_with_clauses(TABLE_LIST *table);
|
||||||
bool check_unrestricted_recursive(bool only_standard_compliant);
|
bool check_unrestricted_recursive(bool only_standard_compliant);
|
||||||
@ -3062,6 +3066,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint8 derived_tables;
|
uint8 derived_tables;
|
||||||
uint8 context_analysis_only;
|
uint8 context_analysis_only;
|
||||||
|
/*
|
||||||
|
true <=> The parsed fragment requires resolution of references to CTE
|
||||||
|
at the end of parsing. This name resolution process involves searching
|
||||||
|
for possible dependencies between CTE defined in the parsed fragment and
|
||||||
|
detecting possible recursive references.
|
||||||
|
The flag is set to true if the fragment contains CTE definitions.
|
||||||
|
*/
|
||||||
|
bool with_cte_resolution;
|
||||||
|
/*
|
||||||
|
true <=> only resolution of references to CTE are required in the parsed
|
||||||
|
fragment, no checking of dependencies between CTE is required.
|
||||||
|
This flag is used only when parsing clones of CTE specifications.
|
||||||
|
*/
|
||||||
|
bool only_cte_resolution;
|
||||||
bool local_file;
|
bool local_file;
|
||||||
bool check_exists;
|
bool check_exists;
|
||||||
bool autocommit;
|
bool autocommit;
|
||||||
@ -4030,6 +4048,12 @@ public:
|
|||||||
return !create_like() && !create_select();
|
return !create_like() && !create_select();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_dependencies_in_with_clauses();
|
||||||
|
bool resolve_references_to_cte_in_hanging_cte();
|
||||||
|
bool check_cte_dependencies_and_resolve_references();
|
||||||
|
bool resolve_references_to_cte(TABLE_LIST *tables,
|
||||||
|
TABLE_LIST **tables_last);
|
||||||
|
|
||||||
SELECT_LEX *exclude_last_select();
|
SELECT_LEX *exclude_last_select();
|
||||||
bool add_unit_in_brackets(SELECT_LEX *nselect);
|
bool add_unit_in_brackets(SELECT_LEX *nselect);
|
||||||
void check_automatic_up(enum sub_select_type type);
|
void check_automatic_up(enum sub_select_type type);
|
||||||
|
@ -3506,9 +3506,6 @@ mysql_execute_command(THD *thd)
|
|||||||
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
|
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
if (unlikely(thd->slave_thread))
|
if (unlikely(thd->slave_thread))
|
||||||
{
|
{
|
||||||
@ -8060,7 +8057,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
ptr->is_fqtn= TRUE;
|
ptr->is_fqtn= TRUE;
|
||||||
ptr->db= table->db;
|
ptr->db= table->db;
|
||||||
}
|
}
|
||||||
else if (lex->copy_db_to(&ptr->db))
|
else if (!lex->with_cte_resolution && lex->copy_db_to(&ptr->db))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
else
|
else
|
||||||
ptr->is_fqtn= FALSE;
|
ptr->is_fqtn= FALSE;
|
||||||
@ -8075,9 +8072,11 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
if (ptr->db.length && ptr->db.str != any_db)
|
if (ptr->db.length && ptr->db.str != any_db)
|
||||||
ptr->db.length= my_casedn_str(files_charset_info, (char*) ptr->db.str);
|
ptr->db.length= my_casedn_str(files_charset_info, (char*) ptr->db.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr->table_name= table->table;
|
ptr->table_name= table->table;
|
||||||
ptr->lock_type= lock_type;
|
ptr->lock_type= lock_type;
|
||||||
|
ptr->mdl_type= mdl_type;
|
||||||
|
ptr->table_options= table_options;
|
||||||
ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
|
ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
|
||||||
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
|
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
|
||||||
ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX);
|
ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX);
|
||||||
@ -8765,8 +8764,10 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type, bool for_update
|
|||||||
{
|
{
|
||||||
tables->lock_type= lock_type;
|
tables->lock_type= lock_type;
|
||||||
tables->updating= for_update;
|
tables->updating= for_update;
|
||||||
tables->mdl_request.set_type((lock_type >= TL_WRITE_ALLOW_WRITE) ?
|
|
||||||
MDL_SHARED_WRITE : MDL_SHARED_READ);
|
if (tables->db.length)
|
||||||
|
tables->mdl_request.set_type((lock_type >= TL_WRITE_ALLOW_WRITE) ?
|
||||||
|
MDL_SHARED_WRITE : MDL_SHARED_READ);
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -2359,9 +2359,6 @@ static bool check_prepared_statement(Prepared_statement *stmt)
|
|||||||
if (tables)
|
if (tables)
|
||||||
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
|
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
|
||||||
|
|
||||||
if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (sql_command_flags[sql_command] & CF_HA_CLOSE)
|
if (sql_command_flags[sql_command] & CF_HA_CLOSE)
|
||||||
mysql_ha_rm_tables(thd, tables);
|
mysql_ha_rm_tables(thd, tables);
|
||||||
|
|
||||||
|
@ -431,12 +431,6 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
|||||||
lex->link_first_table_back(view, link_to_local);
|
lex->link_first_table_back(view, link_to_local);
|
||||||
view->open_type= OT_BASE_ONLY;
|
view->open_type= OT_BASE_ONLY;
|
||||||
|
|
||||||
if (check_dependencies_in_with_clauses(lex->with_clauses_list))
|
|
||||||
{
|
|
||||||
res= TRUE;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -889,6 +883,13 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
|||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ensure character set number != 17 (character set = filename) and mbminlen=1
|
||||||
|
because these character sets are not parser friendly, which can give weird
|
||||||
|
sequence in .frm file of view and later give parsing error.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(thd->charset()->mbminlen == 1 && thd->charset()->number != 17);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
View definition query -- a SELECT statement that fully defines view. It
|
View definition query -- a SELECT statement that fully defines view. It
|
||||||
is generated from the Item-tree built from the original (specified by
|
is generated from the Item-tree built from the original (specified by
|
||||||
@ -1411,9 +1412,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
|
|||||||
TABLE_LIST *tbl;
|
TABLE_LIST *tbl;
|
||||||
Security_context *security_ctx= 0;
|
Security_context *security_ctx= 0;
|
||||||
|
|
||||||
if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check rights to run commands (ANALYZE SELECT, EXPLAIN SELECT &
|
Check rights to run commands (ANALYZE SELECT, EXPLAIN SELECT &
|
||||||
SHOW CREATE) which show underlying tables.
|
SHOW CREATE) which show underlying tables.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2010, 2020, MariaDB
|
Copyright (c) 2010, 2021, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -839,6 +839,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
|
|||||||
class sp_head *sphead;
|
class sp_head *sphead;
|
||||||
class sp_name *spname;
|
class sp_name *spname;
|
||||||
class sp_variable *spvar;
|
class sp_variable *spvar;
|
||||||
|
class With_element_head *with_element_head;
|
||||||
class With_clause *with_clause;
|
class With_clause *with_clause;
|
||||||
class Virtual_column_info *virtual_column;
|
class Virtual_column_info *virtual_column;
|
||||||
|
|
||||||
@ -2207,7 +2208,7 @@ END_OF_INPUT
|
|||||||
|
|
||||||
%type <with_clause> opt_with_clause with_clause
|
%type <with_clause> opt_with_clause with_clause
|
||||||
|
|
||||||
%type <lex_str_ptr> query_name
|
%type <with_element_head> with_element_head
|
||||||
|
|
||||||
%type <lex_str_list> opt_with_column_list
|
%type <lex_str_list> opt_with_column_list
|
||||||
|
|
||||||
@ -3345,7 +3346,11 @@ call:
|
|||||||
if (unlikely(Lex->call_statement_start(thd, $2)))
|
if (unlikely(Lex->call_statement_start(thd, $2)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
opt_sp_cparam_list {}
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* CALL parameters */
|
/* CALL parameters */
|
||||||
@ -4227,6 +4232,8 @@ sp_proc_stmt_return:
|
|||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
sp_head *sp= lex->sphead;
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont,
|
if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont,
|
||||||
$3, lex)) ||
|
$3, lex)) ||
|
||||||
unlikely(sp->restore_lex(thd)))
|
unlikely(sp->restore_lex(thd)))
|
||||||
@ -4236,6 +4243,8 @@ sp_proc_stmt_return:
|
|||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
sp_head *sp= lex->sphead;
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
if (unlikely(sp->m_handler->add_instr_preturn(thd, sp,
|
if (unlikely(sp->m_handler->add_instr_preturn(thd, sp,
|
||||||
lex->spcont)))
|
lex->spcont)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@ -5343,12 +5352,16 @@ create_select_query_expression:
|
|||||||
{
|
{
|
||||||
Select->set_braces(0);
|
Select->set_braces(0);
|
||||||
Select->set_with_clause($1);
|
Select->set_with_clause($1);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
union_clause
|
union_clause
|
||||||
| opt_with_clause SELECT_SYM create_select_part2
|
| opt_with_clause SELECT_SYM create_select_part2
|
||||||
create_select_part3_union_not_ready create_select_part4
|
create_select_part3_union_not_ready create_select_part4
|
||||||
{
|
{
|
||||||
Select->set_with_clause($1);
|
Select->set_with_clause($1);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| '(' create_select_query_specification ')'
|
| '(' create_select_query_specification ')'
|
||||||
| '(' create_select_query_specification ')'
|
| '(' create_select_query_specification ')'
|
||||||
@ -6097,6 +6110,8 @@ create_select_query_specification:
|
|||||||
create_select_part4
|
create_select_part4
|
||||||
{
|
{
|
||||||
Select->set_with_clause($1);
|
Select->set_with_clause($1);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -9205,6 +9220,8 @@ select:
|
|||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->sql_command= SQLCOM_SELECT;
|
lex->sql_command= SQLCOM_SELECT;
|
||||||
lex->current_select->set_with_clause($1);
|
lex->current_select->set_with_clause($1);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -13234,6 +13251,8 @@ do:
|
|||||||
expr_list
|
expr_list
|
||||||
{
|
{
|
||||||
Lex->insert_list= $3;
|
Lex->insert_list= $3;
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -13462,6 +13481,8 @@ insert:
|
|||||||
}
|
}
|
||||||
insert_field_spec opt_insert_update
|
insert_field_spec opt_insert_update
|
||||||
{
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
Lex->mark_first_table_as_inserting();
|
Lex->mark_first_table_as_inserting();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -13481,6 +13502,8 @@ replace:
|
|||||||
}
|
}
|
||||||
insert_field_spec
|
insert_field_spec
|
||||||
{
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
Lex->mark_first_table_as_inserting();
|
Lex->mark_first_table_as_inserting();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -13729,7 +13752,11 @@ update:
|
|||||||
*/
|
*/
|
||||||
slex->set_lock_for_tables($3, slex->table_list.elements == 1);
|
slex->set_lock_for_tables($3, slex->table_list.elements == 1);
|
||||||
}
|
}
|
||||||
opt_where_clause opt_order_clause delete_limit_clause {}
|
opt_where_clause opt_order_clause delete_limit_clause
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
update_list:
|
update_list:
|
||||||
@ -13844,6 +13871,8 @@ single_multi:
|
|||||||
{
|
{
|
||||||
if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex)))
|
if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -14870,6 +14899,8 @@ load:
|
|||||||
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
|
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
|
||||||
opt_load_data_set_spec
|
opt_load_data_set_spec
|
||||||
{
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
Lex->mark_first_table_as_inserting();
|
Lex->mark_first_table_as_inserting();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -15287,6 +15318,8 @@ with_clause:
|
|||||||
if (unlikely(with_clause == NULL))
|
if (unlikely(with_clause == NULL))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->derived_tables|= DERIVED_WITH;
|
Lex->derived_tables|= DERIVED_WITH;
|
||||||
|
Lex->with_cte_resolution= true;
|
||||||
|
Lex->with_cte_resolution= true;
|
||||||
Lex->curr_with_clause= with_clause;
|
Lex->curr_with_clause= with_clause;
|
||||||
with_clause->add_to_list(Lex->with_clauses_list_last_next);
|
with_clause->add_to_list(Lex->with_clauses_list_last_next);
|
||||||
}
|
}
|
||||||
@ -15311,7 +15344,7 @@ with_list:
|
|||||||
|
|
||||||
|
|
||||||
with_list_element:
|
with_list_element:
|
||||||
query_name
|
with_element_head
|
||||||
opt_with_column_list
|
opt_with_column_list
|
||||||
{
|
{
|
||||||
$2= new List<LEX_CSTRING> (Lex->with_column_list);
|
$2= new List<LEX_CSTRING> (Lex->with_column_list);
|
||||||
@ -15332,6 +15365,7 @@ with_list_element:
|
|||||||
if (elem->set_unparsed_spec(thd, spec_start, $8,
|
if (elem->set_unparsed_spec(thd, spec_start, $8,
|
||||||
spec_start - query_start))
|
spec_start - query_start))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
elem->set_tables_end_pos(lex->query_tables_last);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -15358,12 +15392,17 @@ with_column_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
query_name:
|
with_element_head:
|
||||||
ident
|
ident
|
||||||
{
|
{
|
||||||
$$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
|
LEX_CSTRING *name=
|
||||||
|
(LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
|
||||||
if (unlikely($$ == NULL))
|
if (unlikely($$ == NULL))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
$$= new (thd->mem_root) With_element_head(name);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
$$->tables_pos.set_start_pos(Lex->query_tables_last);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -16308,7 +16347,10 @@ set:
|
|||||||
sp_create_assignment_lex(thd, yychar == YYEMPTY);
|
sp_create_assignment_lex(thd, yychar == YYEMPTY);
|
||||||
}
|
}
|
||||||
start_option_value_list
|
start_option_value_list
|
||||||
{}
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
| SET STATEMENT_SYM
|
| SET STATEMENT_SYM
|
||||||
{
|
{
|
||||||
Lex->set_stmt_init();
|
Lex->set_stmt_init();
|
||||||
@ -17825,6 +17867,9 @@ view_select:
|
|||||||
lex->create_view->check= $4;
|
lex->create_view->check= $4;
|
||||||
lex->parsing_options.allows_variable= TRUE;
|
lex->parsing_options.allows_variable= TRUE;
|
||||||
lex->current_select->set_with_clause($2);
|
lex->current_select->set_with_clause($2);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2010, 2020, MariaDB
|
Copyright (c) 2010, 2021, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -232,6 +232,7 @@ void ORAerror(THD *thd, const char *s)
|
|||||||
class sp_head *sphead;
|
class sp_head *sphead;
|
||||||
class sp_name *spname;
|
class sp_name *spname;
|
||||||
class sp_variable *spvar;
|
class sp_variable *spvar;
|
||||||
|
class With_element_head *with_element_head;
|
||||||
class With_clause *with_clause;
|
class With_clause *with_clause;
|
||||||
class Virtual_column_info *virtual_column;
|
class Virtual_column_info *virtual_column;
|
||||||
|
|
||||||
@ -1628,7 +1629,7 @@ END_OF_INPUT
|
|||||||
|
|
||||||
%type <with_clause> opt_with_clause with_clause
|
%type <with_clause> opt_with_clause with_clause
|
||||||
|
|
||||||
%type <lex_str_ptr> query_name
|
%type <with_element_head> with_element_head
|
||||||
|
|
||||||
%type <lex_str_list> opt_with_column_list
|
%type <lex_str_list> opt_with_column_list
|
||||||
|
|
||||||
@ -2999,7 +3000,11 @@ call:
|
|||||||
if (unlikely(Lex->call_statement_start(thd, $2)))
|
if (unlikely(Lex->call_statement_start(thd, $2)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
opt_sp_cparam_list {}
|
opt_sp_cparam_list
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* CALL parameters */
|
/* CALL parameters */
|
||||||
@ -3986,6 +3991,8 @@ sp_proc_stmt_return:
|
|||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
sp_head *sp= lex->sphead;
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont,
|
if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont,
|
||||||
$3, lex)) ||
|
$3, lex)) ||
|
||||||
unlikely(sp->restore_lex(thd)))
|
unlikely(sp->restore_lex(thd)))
|
||||||
@ -3995,6 +4002,8 @@ sp_proc_stmt_return:
|
|||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
sp_head *sp= lex->sphead;
|
sp_head *sp= lex->sphead;
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
if (unlikely(sp->m_handler->add_instr_preturn(thd, sp,
|
if (unlikely(sp->m_handler->add_instr_preturn(thd, sp,
|
||||||
lex->spcont)))
|
lex->spcont)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
@ -5185,12 +5194,16 @@ create_select_query_expression:
|
|||||||
{
|
{
|
||||||
Select->set_braces(0);
|
Select->set_braces(0);
|
||||||
Select->set_with_clause($1);
|
Select->set_with_clause($1);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
union_clause
|
union_clause
|
||||||
| opt_with_clause SELECT_SYM create_select_part2
|
| opt_with_clause SELECT_SYM create_select_part2
|
||||||
create_select_part3_union_not_ready create_select_part4
|
create_select_part3_union_not_ready create_select_part4
|
||||||
{
|
{
|
||||||
Select->set_with_clause($1);
|
Select->set_with_clause($1);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| '(' create_select_query_specification ')'
|
| '(' create_select_query_specification ')'
|
||||||
| '(' create_select_query_specification ')'
|
| '(' create_select_query_specification ')'
|
||||||
@ -5939,6 +5952,8 @@ create_select_query_specification:
|
|||||||
create_select_part4
|
create_select_part4
|
||||||
{
|
{
|
||||||
Select->set_with_clause($1);
|
Select->set_with_clause($1);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -9135,6 +9150,8 @@ select:
|
|||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->sql_command= SQLCOM_SELECT;
|
lex->sql_command= SQLCOM_SELECT;
|
||||||
lex->current_select->set_with_clause($1);
|
lex->current_select->set_with_clause($1);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -13172,6 +13189,8 @@ do:
|
|||||||
expr_list
|
expr_list
|
||||||
{
|
{
|
||||||
Lex->insert_list= $3;
|
Lex->insert_list= $3;
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -13416,6 +13435,8 @@ insert:
|
|||||||
}
|
}
|
||||||
insert_field_spec opt_insert_update
|
insert_field_spec opt_insert_update
|
||||||
{
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
Lex->mark_first_table_as_inserting();
|
Lex->mark_first_table_as_inserting();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -13435,6 +13456,8 @@ replace:
|
|||||||
}
|
}
|
||||||
insert_field_spec
|
insert_field_spec
|
||||||
{
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
Lex->mark_first_table_as_inserting();
|
Lex->mark_first_table_as_inserting();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -13683,7 +13706,11 @@ update:
|
|||||||
*/
|
*/
|
||||||
slex->set_lock_for_tables($3, slex->table_list.elements == 1);
|
slex->set_lock_for_tables($3, slex->table_list.elements == 1);
|
||||||
}
|
}
|
||||||
opt_where_clause opt_order_clause delete_limit_clause {}
|
opt_where_clause opt_order_clause delete_limit_clause
|
||||||
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
update_list:
|
update_list:
|
||||||
@ -13798,6 +13825,8 @@ single_multi:
|
|||||||
{
|
{
|
||||||
if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex)))
|
if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -14830,6 +14859,8 @@ load:
|
|||||||
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
|
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
|
||||||
opt_load_data_set_spec
|
opt_load_data_set_spec
|
||||||
{
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
Lex->mark_first_table_as_inserting();
|
Lex->mark_first_table_as_inserting();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -15247,6 +15278,8 @@ with_clause:
|
|||||||
if (unlikely(with_clause == NULL))
|
if (unlikely(with_clause == NULL))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->derived_tables|= DERIVED_WITH;
|
Lex->derived_tables|= DERIVED_WITH;
|
||||||
|
Lex->with_cte_resolution= true;
|
||||||
|
Lex->with_cte_resolution= true;
|
||||||
Lex->curr_with_clause= with_clause;
|
Lex->curr_with_clause= with_clause;
|
||||||
with_clause->add_to_list(Lex->with_clauses_list_last_next);
|
with_clause->add_to_list(Lex->with_clauses_list_last_next);
|
||||||
}
|
}
|
||||||
@ -15271,7 +15304,7 @@ with_list:
|
|||||||
|
|
||||||
|
|
||||||
with_list_element:
|
with_list_element:
|
||||||
query_name
|
with_element_head
|
||||||
opt_with_column_list
|
opt_with_column_list
|
||||||
{
|
{
|
||||||
$2= new List<LEX_CSTRING> (Lex->with_column_list);
|
$2= new List<LEX_CSTRING> (Lex->with_column_list);
|
||||||
@ -15292,6 +15325,7 @@ with_list_element:
|
|||||||
if (elem->set_unparsed_spec(thd, spec_start, $8,
|
if (elem->set_unparsed_spec(thd, spec_start, $8,
|
||||||
spec_start - query_start))
|
spec_start - query_start))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
elem->set_tables_end_pos(lex->query_tables_last);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -15318,12 +15352,17 @@ with_column_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
query_name:
|
with_element_head:
|
||||||
ident
|
ident
|
||||||
{
|
{
|
||||||
$$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
|
LEX_CSTRING *name=
|
||||||
|
(LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
|
||||||
if (unlikely($$ == NULL))
|
if (unlikely($$ == NULL))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
|
$$= new (thd->mem_root) With_element_head(name);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
$$->tables_pos.set_start_pos(Lex->query_tables_last);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -16305,7 +16344,10 @@ set:
|
|||||||
sp_create_assignment_lex(thd, yychar == YYEMPTY);
|
sp_create_assignment_lex(thd, yychar == YYEMPTY);
|
||||||
}
|
}
|
||||||
start_option_value_list
|
start_option_value_list
|
||||||
{}
|
{
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
| SET STATEMENT_SYM
|
| SET STATEMENT_SYM
|
||||||
{
|
{
|
||||||
Lex->set_stmt_init();
|
Lex->set_stmt_init();
|
||||||
@ -17873,6 +17915,9 @@ view_select:
|
|||||||
lex->create_view->check= $4;
|
lex->create_view->check= $4;
|
||||||
lex->parsing_options.allows_variable= TRUE;
|
lex->parsing_options.allows_variable= TRUE;
|
||||||
lex->current_select->set_with_clause($2);
|
lex->current_select->set_with_clause($2);
|
||||||
|
if (Lex->check_cte_dependencies_and_resolve_references())
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
37
sql/table.h
37
sql/table.h
@ -2056,6 +2056,29 @@ struct vers_select_conds_t
|
|||||||
|
|
||||||
struct LEX;
|
struct LEX;
|
||||||
class Index_hint;
|
class Index_hint;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@struct TABLE_CHAIN
|
||||||
|
@brief Subchain of global chain of table references
|
||||||
|
|
||||||
|
The structure contains a pointer to the address of the next_global
|
||||||
|
pointer to the first TABLE_LIST objectof the subchain and the address
|
||||||
|
of the next_global pointer to the element right after the last
|
||||||
|
TABLE_LIST object of the subchain. For an empty subchain both pointers
|
||||||
|
have the same value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct TABLE_CHAIN
|
||||||
|
{
|
||||||
|
TABLE_CHAIN() {}
|
||||||
|
|
||||||
|
TABLE_LIST **start_pos;
|
||||||
|
TABLE_LIST ** end_pos;
|
||||||
|
|
||||||
|
void set_start_pos(TABLE_LIST **pos) { start_pos= pos; }
|
||||||
|
void set_end_pos(TABLE_LIST **pos) { end_pos= pos; }
|
||||||
|
};
|
||||||
|
|
||||||
struct TABLE_LIST
|
struct TABLE_LIST
|
||||||
{
|
{
|
||||||
TABLE_LIST() {} /* Remove gcc warning */
|
TABLE_LIST() {} /* Remove gcc warning */
|
||||||
@ -2380,6 +2403,20 @@ struct TABLE_LIST
|
|||||||
/* call back function for asking handler about caching in query cache */
|
/* call back function for asking handler about caching in query cache */
|
||||||
qc_engine_callback callback_func;
|
qc_engine_callback callback_func;
|
||||||
thr_lock_type lock_type;
|
thr_lock_type lock_type;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Two fields below are set during parsing this table reference in the cases
|
||||||
|
when the table reference can be potentially a reference to a CTE table.
|
||||||
|
In this cases the fact that the reference is a reference to a CTE or not
|
||||||
|
will be ascertained at the very end of parsing of the query when referencies
|
||||||
|
to CTE are resolved. For references to CTE and to derived tables no mdl
|
||||||
|
requests are needed while for other table references they are. If a request
|
||||||
|
is possibly postponed the info that allows to issue this request must be
|
||||||
|
saved in 'mdl_type' and 'table_options'.
|
||||||
|
*/
|
||||||
|
enum_mdl_type mdl_type;
|
||||||
|
ulong table_options;
|
||||||
|
|
||||||
uint outer_join; /* Which join type */
|
uint outer_join; /* Which join type */
|
||||||
uint shared; /* Used in multi-upd */
|
uint shared; /* Used in multi-upd */
|
||||||
bool updatable; /* VIEW/TABLE can be updated now */
|
bool updatable; /* VIEW/TABLE can be updated now */
|
||||||
|
@ -413,11 +413,11 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
|
|||||||
INSTALL(FILES
|
INSTALL(FILES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/JavaWrappers.jar
|
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/JavaWrappers.jar
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
|
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
|
||||||
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
|
DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT connect-engine)
|
||||||
IF(CONNECT_WITH_MONGO)
|
IF(CONNECT_WITH_MONGO)
|
||||||
INSTALL(FILES
|
INSTALL(FILES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo2.jar
|
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo2.jar
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo3.jar
|
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo3.jar
|
||||||
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
|
DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT connect-engine)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@ -57,8 +57,8 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
|
|||||||
extern char *JvmPath; // The connect_jvm_path global variable value
|
extern char *JvmPath; // The connect_jvm_path global variable value
|
||||||
extern char *ClassPath; // The connect_class_path global variable value
|
extern char *ClassPath; // The connect_class_path global variable value
|
||||||
|
|
||||||
char *GetPluginDir(void);
|
|
||||||
char *GetJavaWrapper(void); // The connect_java_wrapper variable value
|
char *GetJavaWrapper(void); // The connect_java_wrapper variable value
|
||||||
|
extern MYSQL_PLUGIN_IMPORT char lc_messages_dir[FN_REFLEN];
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Static JAVAConn objects. */
|
/* Static JAVAConn objects. */
|
||||||
@ -401,23 +401,23 @@ bool JAVAConn::Open(PGLOBAL g)
|
|||||||
} // endif ClassPath
|
} // endif ClassPath
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Java source will be compiled as a jar file installed in the plugin dir
|
// Java source will be compiled as a jar file installed in the mysql share dir
|
||||||
jpop->Append(sep);
|
jpop->Append(sep);
|
||||||
jpop->Append(GetPluginDir());
|
jpop->Append(lc_messages_dir);
|
||||||
jpop->Append("JdbcInterface.jar");
|
jpop->Append("JdbcInterface.jar");
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
// All wrappers are pre-compiled in JavaWrappers.jar in the plugin dir
|
// All wrappers are pre-compiled in JavaWrappers.jar in the mysql share dir
|
||||||
jpop->Append(sep);
|
jpop->Append(sep);
|
||||||
jpop->Append(GetPluginDir());
|
jpop->Append(lc_messages_dir);
|
||||||
jpop->Append("JavaWrappers.jar");
|
jpop->Append("JavaWrappers.jar");
|
||||||
|
|
||||||
#if defined(MONGO_SUPPORT)
|
#if defined(MONGO_SUPPORT)
|
||||||
jpop->Append(sep);
|
jpop->Append(sep);
|
||||||
jpop->Append(GetPluginDir());
|
jpop->Append(lc_messages_dir);
|
||||||
jpop->Append("Mongo3.jar");
|
jpop->Append("Mongo3.jar");
|
||||||
jpop->Append(sep);
|
jpop->Append(sep);
|
||||||
jpop->Append(GetPluginDir());
|
jpop->Append(lc_messages_dir);
|
||||||
jpop->Append("Mongo2.jar");
|
jpop->Append("Mongo2.jar");
|
||||||
#endif // MONGO_SUPPORT
|
#endif // MONGO_SUPPORT
|
||||||
|
|
||||||
|
@ -1787,7 +1787,6 @@ fts_create_one_common_table(
|
|||||||
dict_table_add_system_columns(new_table, heap);
|
dict_table_add_system_columns(new_table, heap);
|
||||||
error = row_create_table_for_mysql(new_table, trx,
|
error = row_create_table_for_mysql(new_table, trx,
|
||||||
FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||||
|
|
||||||
if (error == DB_SUCCESS) {
|
if (error == DB_SUCCESS) {
|
||||||
|
|
||||||
dict_index_t* index = dict_mem_index_create(
|
dict_index_t* index = dict_mem_index_create(
|
||||||
@ -1808,17 +1807,22 @@ fts_create_one_common_table(
|
|||||||
error = row_create_index_for_mysql(index, trx, NULL);
|
error = row_create_index_for_mysql(index, trx, NULL);
|
||||||
|
|
||||||
trx->dict_operation = op;
|
trx->dict_operation = op;
|
||||||
|
} else {
|
||||||
|
err_exit:
|
||||||
|
new_table = NULL;
|
||||||
|
ib::warn() << "Failed to create FTS common table "
|
||||||
|
<< fts_table_name;
|
||||||
|
trx->error_state = error;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
dict_mem_table_free(new_table);
|
dict_mem_table_free(new_table);
|
||||||
new_table = NULL;
|
|
||||||
ib::warn() << "Failed to create FTS common table "
|
|
||||||
<< fts_table_name;
|
|
||||||
trx->error_state = DB_SUCCESS;
|
trx->error_state = DB_SUCCESS;
|
||||||
row_drop_table_for_mysql(fts_table_name, trx, SQLCOM_DROP_DB);
|
row_drop_table_for_mysql(fts_table_name, trx, SQLCOM_DROP_DB);
|
||||||
trx->error_state = error;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(new_table);
|
return(new_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1864,6 +1868,8 @@ fts_create_common_tables(
|
|||||||
|
|
||||||
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
|
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
|
||||||
|
|
||||||
|
op = trx_get_dict_operation(trx);
|
||||||
|
|
||||||
error = fts_drop_common_tables(trx, &fts_table);
|
error = fts_drop_common_tables(trx, &fts_table);
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
@ -1879,7 +1885,8 @@ fts_create_common_tables(
|
|||||||
dict_table_t* common_table = fts_create_one_common_table(
|
dict_table_t* common_table = fts_create_one_common_table(
|
||||||
trx, table, full_name[i], fts_table.suffix, heap);
|
trx, table, full_name[i], fts_table.suffix, heap);
|
||||||
|
|
||||||
if (common_table == NULL) {
|
if (!common_table) {
|
||||||
|
trx->error_state = DB_SUCCESS;
|
||||||
error = DB_ERROR;
|
error = DB_ERROR;
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
} else {
|
} else {
|
||||||
@ -1925,8 +1932,6 @@ fts_create_common_tables(
|
|||||||
|
|
||||||
error = row_create_index_for_mysql(index, trx, NULL);
|
error = row_create_index_for_mysql(index, trx, NULL);
|
||||||
|
|
||||||
trx->dict_operation = op;
|
|
||||||
|
|
||||||
func_exit:
|
func_exit:
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
for (it = common_tables.begin(); it != common_tables.end();
|
for (it = common_tables.begin(); it != common_tables.end();
|
||||||
@ -1936,6 +1941,8 @@ func_exit:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trx->dict_operation = op;
|
||||||
|
|
||||||
common_tables.clear();
|
common_tables.clear();
|
||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
|
|
||||||
@ -2019,16 +2026,20 @@ fts_create_one_index_table(
|
|||||||
error = row_create_index_for_mysql(index, trx, NULL);
|
error = row_create_index_for_mysql(index, trx, NULL);
|
||||||
|
|
||||||
trx->dict_operation = op;
|
trx->dict_operation = op;
|
||||||
|
} else {
|
||||||
|
err_exit:
|
||||||
|
new_table = NULL;
|
||||||
|
ib::warn() << "Failed to create FTS index table "
|
||||||
|
<< table_name;
|
||||||
|
trx->error_state = error;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
dict_mem_table_free(new_table);
|
dict_mem_table_free(new_table);
|
||||||
new_table = NULL;
|
|
||||||
ib::warn() << "Failed to create FTS index table "
|
|
||||||
<< table_name;
|
|
||||||
trx->error_state = DB_SUCCESS;
|
trx->error_state = DB_SUCCESS;
|
||||||
row_drop_table_for_mysql(table_name, trx, SQLCOM_DROP_DB);
|
row_drop_table_for_mysql(table_name, trx, SQLCOM_DROP_DB);
|
||||||
trx->error_state = error;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(new_table);
|
return(new_table);
|
||||||
|
@ -6367,7 +6367,9 @@ no_such_table:
|
|||||||
/* Index block size in InnoDB: used by MySQL in query optimization */
|
/* Index block size in InnoDB: used by MySQL in query optimization */
|
||||||
stats.block_size = srv_page_size;
|
stats.block_size = srv_page_size;
|
||||||
|
|
||||||
if (m_prebuilt->table == NULL
|
const my_bool for_vc_purge = THDVAR(thd, background_thread);
|
||||||
|
|
||||||
|
if (for_vc_purge || !m_prebuilt->table
|
||||||
|| m_prebuilt->table->is_temporary()
|
|| m_prebuilt->table->is_temporary()
|
||||||
|| m_prebuilt->table->persistent_autoinc
|
|| m_prebuilt->table->persistent_autoinc
|
||||||
|| !m_prebuilt->table->is_readable()) {
|
|| !m_prebuilt->table->is_readable()) {
|
||||||
@ -6394,7 +6396,7 @@ no_such_table:
|
|||||||
ut_ad(!m_prebuilt->table
|
ut_ad(!m_prebuilt->table
|
||||||
|| table->versioned() == m_prebuilt->table->versioned());
|
|| table->versioned() == m_prebuilt->table->versioned());
|
||||||
|
|
||||||
if (!THDVAR(thd, background_thread)) {
|
if (!for_vc_purge) {
|
||||||
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST
|
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST
|
||||||
| HA_STATUS_OPEN);
|
| HA_STATUS_OPEN);
|
||||||
}
|
}
|
||||||
@ -12834,7 +12836,6 @@ create_table_info_t::create_table_update_dict()
|
|||||||
if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) {
|
if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) {
|
||||||
dict_table_close(innobase_table, FALSE, FALSE);
|
dict_table_close(innobase_table, FALSE, FALSE);
|
||||||
srv_active_wake_master_thread();
|
srv_active_wake_master_thread();
|
||||||
m_trx->free();
|
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12961,19 +12962,12 @@ ha_innobase::create(
|
|||||||
}
|
}
|
||||||
trx_rollback_for_mysql(trx);
|
trx_rollback_for_mysql(trx);
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
if (own_trx) {
|
goto func_exit;
|
||||||
trx->free();
|
|
||||||
}
|
|
||||||
DBUG_RETURN(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
innobase_commit_low(trx);
|
innobase_commit_low(trx);
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
|
|
||||||
if (own_trx) {
|
|
||||||
trx->free();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush the log to reduce probability that the .frm files and
|
/* Flush the log to reduce probability that the .frm files and
|
||||||
the InnoDB data dictionary get out-of-sync if the user runs
|
the InnoDB data dictionary get out-of-sync if the user runs
|
||||||
with innodb_flush_log_at_trx_commit = 0 */
|
with innodb_flush_log_at_trx_commit = 0 */
|
||||||
@ -12983,6 +12977,11 @@ ha_innobase::create(
|
|||||||
|
|
||||||
error = info.create_table_update_dict();
|
error = info.create_table_update_dict();
|
||||||
|
|
||||||
|
func_exit:
|
||||||
|
if (own_trx) {
|
||||||
|
trx->free();
|
||||||
|
}
|
||||||
|
|
||||||
/* Tell the InnoDB server that there might be work for
|
/* Tell the InnoDB server that there might be work for
|
||||||
utility threads: */
|
utility threads: */
|
||||||
|
|
||||||
|
11
storage/mroonga/vendor/groonga/CMakeLists.txt
vendored
11
storage/mroonga/vendor/groonga/CMakeLists.txt
vendored
@ -588,14 +588,13 @@ else()
|
|||||||
set(GRN_WITH_MESSAGE_PACK FALSE)
|
set(GRN_WITH_MESSAGE_PACK FALSE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_program(RUBY NAMES
|
|
||||||
"ruby2.3" "ruby23"
|
|
||||||
"ruby2.2" "ruby22"
|
|
||||||
"ruby2.1" "ruby21"
|
|
||||||
"ruby")
|
|
||||||
|
|
||||||
option(GRN_WITH_MRUBY "use mruby" OFF)
|
option(GRN_WITH_MRUBY "use mruby" OFF)
|
||||||
if(GRN_WITH_MRUBY)
|
if(GRN_WITH_MRUBY)
|
||||||
|
find_program(RUBY NAMES
|
||||||
|
"ruby2.3" "ruby23"
|
||||||
|
"ruby2.2" "ruby22"
|
||||||
|
"ruby2.1" "ruby21"
|
||||||
|
"ruby")
|
||||||
set(MRUBY_INCLUDE_DIRS
|
set(MRUBY_INCLUDE_DIRS
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/vendor/mruby-source/include")
|
"${CMAKE_CURRENT_SOURCE_DIR}/vendor/mruby-source/include")
|
||||||
set(MRUBY_LIBS mruby)
|
set(MRUBY_LIBS mruby)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user