mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Manual merge
This commit is contained in:
@ -834,14 +834,14 @@ show create view v1;
|
|||||||
View Create View
|
View Create View
|
||||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1`
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1`
|
||||||
drop view v1;
|
drop view v1;
|
||||||
create table t<EFBFBD> (c<EFBFBD> char);
|
create table t (c char);
|
||||||
create view v<EFBFBD> as select c<EFBFBD> from t<EFBFBD>;
|
create view v as select c from t;
|
||||||
insert into v<EFBFBD> values ('<EFBFBD>');
|
insert into v values ('');
|
||||||
select * from v<EFBFBD>;
|
select * from v;
|
||||||
c<EFBFBD>
|
c
|
||||||
<EFBFBD>
|
|
||||||
drop view v<EFBFBD>;
|
drop view v;
|
||||||
drop table t<EFBFBD>;
|
drop table t;
|
||||||
create table t1 (a int, b int);
|
create table t1 (a int, b int);
|
||||||
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
|
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
|
||||||
create view v1(c) as select a+1 from t1 where b >= 4;
|
create view v1(c) as select a+1 from t1 where b >= 4;
|
||||||
@ -2060,17 +2060,6 @@ CALL p1();
|
|||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime);
|
|
||||||
create view v1 as select * from t1;
|
|
||||||
desc v1;
|
|
||||||
Field Type Null Key Default Extra
|
|
||||||
f1 tinyint(1) YES NULL
|
|
||||||
f2 char(1) YES NULL
|
|
||||||
f3 varchar(1) YES NULL
|
|
||||||
f4 geometry YES NULL
|
|
||||||
f5 datetime YES NULL
|
|
||||||
drop view v1;
|
|
||||||
drop table t1;
|
|
||||||
create table t1(f1 datetime);
|
create table t1(f1 datetime);
|
||||||
insert into t1 values('2005.01.01 12:0:0');
|
insert into t1 values('2005.01.01 12:0:0');
|
||||||
create view v1 as select f1, subtime(f1, '1:1:1') as sb from t1;
|
create view v1 as select f1, subtime(f1, '1:1:1') as sb from t1;
|
||||||
@ -2543,7 +2532,7 @@ create table t1(f1 int, f2 int);
|
|||||||
create view v1 as select ta.f1 as a, tb.f1 as b from t1 ta, t1 tb where ta.f1=tb
|
create view v1 as select ta.f1 as a, tb.f1 as b from t1 ta, t1 tb where ta.f1=tb
|
||||||
.f1 and ta.f2=tb.f2;
|
.f1 and ta.f2=tb.f2;
|
||||||
insert into t1 values(1,1),(2,2);
|
insert into t1 values(1,1),(2,2);
|
||||||
create view v2 as select * from v1 where a > 1 with check option;
|
create view v2 as select * from v1 where a > 1 with local check option;
|
||||||
select * from v2;
|
select * from v2;
|
||||||
a b
|
a b
|
||||||
2 2
|
2 2
|
||||||
@ -3016,6 +3005,17 @@ i j
|
|||||||
6 3
|
6 3
|
||||||
DROP VIEW v1, v2;
|
DROP VIEW v1, v2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE VIEW v AS SELECT !0 * 5 AS x FROM DUAL;
|
||||||
|
SHOW CREATE VIEW v;
|
||||||
|
View Create View
|
||||||
|
v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select ((not(0)) * 5) AS `x`
|
||||||
|
SELECT !0 * 5 AS x FROM DUAL;
|
||||||
|
x
|
||||||
|
5
|
||||||
|
SELECT * FROM v;
|
||||||
|
x
|
||||||
|
5
|
||||||
|
DROP VIEW v;
|
||||||
DROP VIEW IF EXISTS v1;
|
DROP VIEW IF EXISTS v1;
|
||||||
CREATE VIEW v1 AS SELECT 'The\ZEnd';
|
CREATE VIEW v1 AS SELECT 'The\ZEnd';
|
||||||
SELECT * FROM v1;
|
SELECT * FROM v1;
|
||||||
@ -3025,6 +3025,107 @@ SHOW CREATE VIEW v1;
|
|||||||
View Create View
|
View Create View
|
||||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd`
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd`
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
|
CREATE TABLE t1 (mydate DATETIME);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('2007-01-01'), ('2007-01-02'), ('2007-01-30'), ('2007-01-31');
|
||||||
|
CREATE VIEW v1 AS SELECT mydate from t1;
|
||||||
|
SELECT * FROM t1 WHERE mydate BETWEEN '2007-01-01' AND '2007-01-31';
|
||||||
|
mydate
|
||||||
|
2007-01-01 00:00:00
|
||||||
|
2007-01-02 00:00:00
|
||||||
|
2007-01-30 00:00:00
|
||||||
|
2007-01-31 00:00:00
|
||||||
|
SELECT * FROM v1 WHERE mydate BETWEEN '2007-01-01' AND '2007-01-31';
|
||||||
|
mydate
|
||||||
|
2007-01-01 00:00:00
|
||||||
|
2007-01-02 00:00:00
|
||||||
|
2007-01-30 00:00:00
|
||||||
|
2007-01-31 00:00:00
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
CREATE TABLE t2 (b int);
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
INSERT INTO t2 VALUES (1), (2);
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT t2.b FROM t1,t2 WHERE t1.a = t2.b WITH CHECK OPTION;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
b
|
||||||
|
1
|
||||||
|
2
|
||||||
|
UPDATE v1 SET b=3;
|
||||||
|
ERROR HY000: CHECK OPTION failed 'test.v1'
|
||||||
|
SELECT * FROM v1;
|
||||||
|
b
|
||||||
|
1
|
||||||
|
2
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
SELECT * FROM t2;
|
||||||
|
b
|
||||||
|
1
|
||||||
|
2
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
create table t1(f1 int, f2 int);
|
||||||
|
insert into t1 values(1,2),(1,3),(1,1),(2,3),(2,1),(2,2);
|
||||||
|
select * from t1;
|
||||||
|
f1 f2
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
1 1
|
||||||
|
2 3
|
||||||
|
2 1
|
||||||
|
2 2
|
||||||
|
create view v1 as select * from t1 order by f2;
|
||||||
|
select * from v1;
|
||||||
|
f1 f2
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
1 2
|
||||||
|
2 2
|
||||||
|
1 3
|
||||||
|
2 3
|
||||||
|
explain extended select * from v1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 100.00 Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` order by `test`.`t1`.`f2`
|
||||||
|
select * from v1 order by f1;
|
||||||
|
f1 f2
|
||||||
|
1 1
|
||||||
|
1 2
|
||||||
|
1 3
|
||||||
|
2 1
|
||||||
|
2 2
|
||||||
|
2 3
|
||||||
|
explain extended select * from v1 order by f1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 100.00 Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` order by `test`.`t1`.`f1`,`test`.`t1`.`f2`
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int(11) NOT NULL PRIMARY KEY,
|
||||||
|
country varchar(32),
|
||||||
|
code int(11) default NULL
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1,'ITALY',100),(2,'ITALY',200),(3,'FRANCE',100), (4,'ITALY',100);
|
||||||
|
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
SELECT code, COUNT(DISTINCT country) FROM t1 GROUP BY code ORDER BY MAX(id);
|
||||||
|
code COUNT(DISTINCT country)
|
||||||
|
200 1
|
||||||
|
100 2
|
||||||
|
SELECT code, COUNT(DISTINCT country) FROM v1 GROUP BY code ORDER BY MAX(id);
|
||||||
|
code COUNT(DISTINCT country)
|
||||||
|
200 1
|
||||||
|
100 2
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
DROP VIEW IF EXISTS v1;
|
DROP VIEW IF EXISTS v1;
|
||||||
SELECT * FROM (SELECT 1) AS t;
|
SELECT * FROM (SELECT 1) AS t;
|
||||||
1
|
1
|
||||||
|
@ -748,12 +748,12 @@ drop view v1;
|
|||||||
#
|
#
|
||||||
# VIEWs with national characters
|
# VIEWs with national characters
|
||||||
#
|
#
|
||||||
create table t<EFBFBD> (c<EFBFBD> char);
|
create table t (c char);
|
||||||
create view v<EFBFBD> as select c<EFBFBD> from t<EFBFBD>;
|
create view v as select c from t;
|
||||||
insert into v<EFBFBD> values ('<EFBFBD>');
|
insert into v values ('');
|
||||||
select * from v<EFBFBD>;
|
select * from v;
|
||||||
drop view v<EFBFBD>;
|
drop view v;
|
||||||
drop table t<EFBFBD>;
|
drop table t;
|
||||||
|
|
||||||
#
|
#
|
||||||
# problem with used_tables() of outer reference resolved in VIEW
|
# problem with used_tables() of outer reference resolved in VIEW
|
||||||
@ -1878,15 +1878,6 @@ DROP PROCEDURE p1;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
|
||||||
# Bug #11335 View redefines column types
|
|
||||||
#
|
|
||||||
create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime);
|
|
||||||
create view v1 as select * from t1;
|
|
||||||
desc v1;
|
|
||||||
drop view v1;
|
|
||||||
drop table t1;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #11760 Typo in Item_func_add_time::print() results in NULLs returned
|
# Bug #11760 Typo in Item_func_add_time::print() results in NULLs returned
|
||||||
# subtime() in view
|
# subtime() in view
|
||||||
@ -2386,7 +2377,7 @@ create table t1(f1 int, f2 int);
|
|||||||
create view v1 as select ta.f1 as a, tb.f1 as b from t1 ta, t1 tb where ta.f1=tb
|
create view v1 as select ta.f1 as a, tb.f1 as b from t1 ta, t1 tb where ta.f1=tb
|
||||||
.f1 and ta.f2=tb.f2;
|
.f1 and ta.f2=tb.f2;
|
||||||
insert into t1 values(1,1),(2,2);
|
insert into t1 values(1,1),(2,2);
|
||||||
create view v2 as select * from v1 where a > 1 with check option;
|
create view v2 as select * from v1 where a > 1 with local check option;
|
||||||
select * from v2;
|
select * from v2;
|
||||||
update v2 set b=3 where a=2;
|
update v2 set b=3 where a=2;
|
||||||
select * from v2;
|
select * from v2;
|
||||||
@ -2908,7 +2899,6 @@ DROP FUNCTION f1;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug #16813 (WITH CHECK OPTION doesn't work with UPDATE)
|
# Bug #16813 (WITH CHECK OPTION doesn't work with UPDATE)
|
||||||
#
|
#
|
||||||
@ -2960,6 +2950,18 @@ SELECT * FROM t1;
|
|||||||
DROP VIEW v1, v2;
|
DROP VIEW v1, v2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #25580: !0 as an operand in a select expression of a view
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE VIEW v AS SELECT !0 * 5 AS x FROM DUAL;
|
||||||
|
SHOW CREATE VIEW v;
|
||||||
|
|
||||||
|
SELECT !0 * 5 AS x FROM DUAL;
|
||||||
|
SELECT * FROM v;
|
||||||
|
|
||||||
|
DROP VIEW v;
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#24293: '\Z' token is not handled correctly in views
|
# BUG#24293: '\Z' token is not handled correctly in views
|
||||||
#
|
#
|
||||||
@ -2975,6 +2977,77 @@ SHOW CREATE VIEW v1;
|
|||||||
|
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #26124: BETWEEN over a view column of the DATETIME type
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (mydate DATETIME);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('2007-01-01'), ('2007-01-02'), ('2007-01-30'), ('2007-01-31');
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS SELECT mydate from t1;
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE mydate BETWEEN '2007-01-01' AND '2007-01-31';
|
||||||
|
SELECT * FROM v1 WHERE mydate BETWEEN '2007-01-01' AND '2007-01-31';
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #25931: update of a multi-table view with check option
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int);
|
||||||
|
CREATE TABLE t2 (b int);
|
||||||
|
INSERT INTO t1 VALUES (1), (2);
|
||||||
|
INSERT INTO t2 VALUES (1), (2);
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS
|
||||||
|
SELECT t2.b FROM t1,t2 WHERE t1.a = t2.b WITH CHECK OPTION;
|
||||||
|
|
||||||
|
SELECT * FROM v1;
|
||||||
|
--error 1369
|
||||||
|
UPDATE v1 SET b=3;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#12122: Views with ORDER BY can't be resolved using MERGE algorithm.
|
||||||
|
#
|
||||||
|
create table t1(f1 int, f2 int);
|
||||||
|
insert into t1 values(1,2),(1,3),(1,1),(2,3),(2,1),(2,2);
|
||||||
|
select * from t1;
|
||||||
|
create view v1 as select * from t1 order by f2;
|
||||||
|
select * from v1;
|
||||||
|
explain extended select * from v1;
|
||||||
|
select * from v1 order by f1;
|
||||||
|
explain extended select * from v1 order by f1;
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#26209: queries with GROUP BY and ORDER BY using views
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int(11) NOT NULL PRIMARY KEY,
|
||||||
|
country varchar(32),
|
||||||
|
code int(11) default NULL
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1,'ITALY',100),(2,'ITALY',200),(3,'FRANCE',100), (4,'ITALY',100);
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
|
||||||
|
SELECT code, COUNT(DISTINCT country) FROM t1 GROUP BY code ORDER BY MAX(id);
|
||||||
|
SELECT code, COUNT(DISTINCT country) FROM v1 GROUP BY code ORDER BY MAX(id);
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#25897: Some queries are no longer possible after a CREATE VIEW
|
# BUG#25897: Some queries are no longer possible after a CREATE VIEW
|
||||||
@ -3082,7 +3155,6 @@ drop table table_24532;
|
|||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#21370 View renaming lacks tablename_to_filename encoding
|
# Bug#21370 View renaming lacks tablename_to_filename encoding
|
||||||
#
|
#
|
||||||
|
185
sql/sql_parse.cc
185
sql/sql_parse.cc
@ -56,12 +56,11 @@
|
|||||||
(LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
|
(LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
|
||||||
"FUNCTION" : "PROCEDURE")
|
"FUNCTION" : "PROCEDURE")
|
||||||
|
|
||||||
static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
|
||||||
static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
|
static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
|
||||||
static void decrease_user_connections(USER_CONN *uc);
|
static void decrease_user_connections(USER_CONN *uc);
|
||||||
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||||
static bool check_multi_update_lock(THD *thd);
|
|
||||||
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
|
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
|
||||||
|
|
||||||
const char *any_db="*any*"; // Special symbol for check_access
|
const char *any_db="*any*"; // Special symbol for check_access
|
||||||
@ -414,7 +413,11 @@ int check_user(THD *thd, enum enum_server_command command,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Why logging is performed before all checks've passed? */
|
/*
|
||||||
|
Log the command before authentication checks, so that the user can
|
||||||
|
check the log for the tried login tried and also to detect
|
||||||
|
break-in attempts.
|
||||||
|
*/
|
||||||
general_log_print(thd, command,
|
general_log_print(thd, command,
|
||||||
(thd->main_security_ctx.priv_user ==
|
(thd->main_security_ctx.priv_user ==
|
||||||
thd->main_security_ctx.user ?
|
thd->main_security_ctx.user ?
|
||||||
@ -712,6 +715,8 @@ bool is_update_query(enum enum_sql_command command)
|
|||||||
safe to test and modify members of the USER_CONN structure.
|
safe to test and modify members of the USER_CONN structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
|
||||||
static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
|
static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
|
||||||
{
|
{
|
||||||
time_t check_time = thd->start_time ? thd->start_time : time(NULL);
|
time_t check_time = thd->start_time ? thd->start_time : time(NULL);
|
||||||
@ -729,7 +734,6 @@ static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if maximum queries per hour limit has been reached
|
Check if maximum queries per hour limit has been reached
|
||||||
returns 0 if OK.
|
returns 0 if OK.
|
||||||
@ -737,7 +741,6 @@ static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
|
|||||||
|
|
||||||
static bool check_mqh(THD *thd, uint check_command)
|
static bool check_mqh(THD *thd, uint check_command)
|
||||||
{
|
{
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
||||||
bool error= 0;
|
bool error= 0;
|
||||||
USER_CONN *uc=thd->user_connect;
|
USER_CONN *uc=thd->user_connect;
|
||||||
DBUG_ENTER("check_mqh");
|
DBUG_ENTER("check_mqh");
|
||||||
@ -772,11 +775,10 @@ static bool check_mqh(THD *thd, uint check_command)
|
|||||||
end:
|
end:
|
||||||
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
#else
|
|
||||||
return (0);
|
|
||||||
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||||
|
|
||||||
|
|
||||||
static void reset_mqh(LEX_USER *lu, bool get_them= 0)
|
static void reset_mqh(LEX_USER *lu, bool get_them= 0)
|
||||||
{
|
{
|
||||||
@ -1007,7 +1009,7 @@ static int check_connection(THD *thd)
|
|||||||
return(ER_HANDSHAKE_ERROR);
|
return(ER_HANDSHAKE_ERROR);
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("IO layer change in progress..."));
|
DBUG_PRINT("info", ("IO layer change in progress..."));
|
||||||
if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout))
|
if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error", ("Failed to accept new SSL connection"));
|
DBUG_PRINT("error", ("Failed to accept new SSL connection"));
|
||||||
inc_host_errors(&thd->remote.sin_addr);
|
inc_host_errors(&thd->remote.sin_addr);
|
||||||
@ -1036,7 +1038,6 @@ static int check_connection(THD *thd)
|
|||||||
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
|
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
|
||||||
opt_using_transactions)
|
opt_using_transactions)
|
||||||
net->return_status= &thd->server_status;
|
net->return_status= &thd->server_status;
|
||||||
net->read_timeout=(uint) thd->variables.net_read_timeout;
|
|
||||||
|
|
||||||
char *user= end;
|
char *user= end;
|
||||||
char *passwd= strend(user)+1;
|
char *passwd= strend(user)+1;
|
||||||
@ -1183,6 +1184,10 @@ pthread_handler_t handle_one_connection(void *arg)
|
|||||||
Security_context *sctx= thd->security_ctx;
|
Security_context *sctx= thd->security_ctx;
|
||||||
net->no_send_error= 0;
|
net->no_send_error= 0;
|
||||||
|
|
||||||
|
/* Use "connect_timeout" value during connection phase */
|
||||||
|
net_set_read_timeout(net, connect_timeout);
|
||||||
|
net_set_write_timeout(net, connect_timeout);
|
||||||
|
|
||||||
if ((error=check_connection(thd)))
|
if ((error=check_connection(thd)))
|
||||||
{ // Wrong permissions
|
{ // Wrong permissions
|
||||||
if (error > 0)
|
if (error > 0)
|
||||||
@ -1225,6 +1230,10 @@ pthread_handler_t handle_one_connection(void *arg)
|
|||||||
thd->init_for_queries();
|
thd->init_for_queries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Connect completed, set read/write timeouts back to default */
|
||||||
|
net_set_read_timeout(net, thd->variables.net_read_timeout);
|
||||||
|
net_set_write_timeout(net, thd->variables.net_write_timeout);
|
||||||
|
|
||||||
while (!net->error && net->vio != 0 &&
|
while (!net->error && net->vio != 0 &&
|
||||||
!(thd->killed == THD::KILL_CONNECTION))
|
!(thd->killed == THD::KILL_CONNECTION))
|
||||||
{
|
{
|
||||||
@ -1556,7 +1565,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
|
|||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read one command from socket and execute it (query or simple command).
|
Read one command from connection and execute it (query or simple command).
|
||||||
This function is called in loop from thread function.
|
This function is called in loop from thread function.
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
do_command()
|
do_command()
|
||||||
@ -1567,24 +1576,26 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
|
|||||||
|
|
||||||
bool do_command(THD *thd)
|
bool do_command(THD *thd)
|
||||||
{
|
{
|
||||||
char *packet;
|
char *packet= 0;
|
||||||
uint old_timeout;
|
|
||||||
ulong packet_length;
|
ulong packet_length;
|
||||||
NET *net;
|
NET *net= &thd->net;
|
||||||
enum enum_server_command command;
|
enum enum_server_command command;
|
||||||
DBUG_ENTER("do_command");
|
DBUG_ENTER("do_command");
|
||||||
|
|
||||||
net= &thd->net;
|
|
||||||
/*
|
/*
|
||||||
indicator of uninitialized lex => normal flow of errors handling
|
indicator of uninitialized lex => normal flow of errors handling
|
||||||
(see my_message_sql)
|
(see my_message_sql)
|
||||||
*/
|
*/
|
||||||
thd->lex->current_select= 0;
|
thd->lex->current_select= 0;
|
||||||
|
|
||||||
packet=0;
|
/*
|
||||||
old_timeout=net->read_timeout;
|
This thread will do a blocking read from the client which
|
||||||
/* Wait max for 8 hours */
|
will be interrupted when the next command is received from
|
||||||
net->read_timeout=(uint) thd->variables.net_wait_timeout;
|
the client, the connection is closed or "net_wait_timeout"
|
||||||
|
number of seconds has passed
|
||||||
|
*/
|
||||||
|
net_set_read_timeout(net, thd->variables.net_wait_timeout);
|
||||||
|
|
||||||
thd->clear_error(); // Clear error message
|
thd->clear_error(); // Clear error message
|
||||||
|
|
||||||
net_new_transaction(net);
|
net_new_transaction(net);
|
||||||
@ -1613,7 +1624,10 @@ bool do_command(THD *thd)
|
|||||||
vio_description(net->vio), command,
|
vio_description(net->vio), command,
|
||||||
command_name[command].str));
|
command_name[command].str));
|
||||||
}
|
}
|
||||||
net->read_timeout=old_timeout; // restore it
|
|
||||||
|
/* Restore read timeout value */
|
||||||
|
net_set_read_timeout(net, thd->variables.net_read_timeout);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
packet_length contains length of data, as it was stored in packet
|
packet_length contains length of data, as it was stored in packet
|
||||||
header. In case of malformed header, packet_length can be zero.
|
header. In case of malformed header, packet_length can be zero.
|
||||||
@ -1664,7 +1678,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
|
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
|
||||||
thd->set_time();
|
thd->set_time();
|
||||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||||
thd->query_id=query_id;
|
thd->query_id= global_query_id;
|
||||||
if (command != COM_STATISTICS && command != COM_PING)
|
if (command != COM_STATISTICS && command != COM_PING)
|
||||||
next_query_id();
|
next_query_id();
|
||||||
thread_running++;
|
thread_running++;
|
||||||
@ -1858,7 +1872,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
|
|
||||||
while (!thd->killed && thd->lex->found_semicolon && !thd->net.report_error)
|
while (!thd->killed && thd->lex->found_semicolon && !thd->net.report_error)
|
||||||
{
|
{
|
||||||
char *packet= thd->lex->found_semicolon;
|
char *next_packet= thd->lex->found_semicolon;
|
||||||
net->no_send_error= 0;
|
net->no_send_error= 0;
|
||||||
/*
|
/*
|
||||||
Multiple queries exits, execute them individually
|
Multiple queries exits, execute them individually
|
||||||
@ -1866,24 +1880,24 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
if (thd->lock || thd->open_tables || thd->derived_tables ||
|
if (thd->lock || thd->open_tables || thd->derived_tables ||
|
||||||
thd->prelocked_mode)
|
thd->prelocked_mode)
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
ulong length= (ulong)(packet_end-packet);
|
ulong length= (ulong)(packet_end - next_packet);
|
||||||
|
|
||||||
log_slow_statement(thd);
|
log_slow_statement(thd);
|
||||||
|
|
||||||
/* Remove garbage at start of query */
|
/* Remove garbage at start of query */
|
||||||
while (my_isspace(thd->charset(), *packet) && length > 0)
|
while (my_isspace(thd->charset(), *next_packet) && length > 0)
|
||||||
{
|
{
|
||||||
packet++;
|
next_packet++;
|
||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||||
thd->query_length= length;
|
thd->query_length= length;
|
||||||
thd->query= packet;
|
thd->query= next_packet;
|
||||||
thd->query_id= next_query_id();
|
thd->query_id= next_query_id();
|
||||||
thd->set_time(); /* Reset the query start time. */
|
thd->set_time(); /* Reset the query start time. */
|
||||||
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
|
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
|
||||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||||
mysql_parse(thd, packet, length);
|
mysql_parse(thd, next_packet, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||||
@ -1900,11 +1914,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
{
|
{
|
||||||
char *fields, *packet_end= packet + packet_length - 1, *arg_end;
|
char *fields, *packet_end= packet + packet_length - 1, *arg_end;
|
||||||
/* Locked closure of all tables */
|
/* Locked closure of all tables */
|
||||||
TABLE_LIST *locked_tables= NULL;
|
|
||||||
TABLE_LIST table_list;
|
TABLE_LIST table_list;
|
||||||
LEX_STRING conv_name;
|
LEX_STRING conv_name;
|
||||||
/* Saved variable value */
|
|
||||||
my_bool old_innodb_table_locks= thd->variables.innodb_table_locks;
|
|
||||||
uint dummy;
|
uint dummy;
|
||||||
|
|
||||||
/* used as fields initializator */
|
/* used as fields initializator */
|
||||||
@ -2118,7 +2129,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
|
statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
|
||||||
&LOCK_status);
|
&LOCK_status);
|
||||||
calc_sum_of_all_status(¤t_global_status_var);
|
calc_sum_of_all_status(¤t_global_status_var);
|
||||||
uptime= (ulong) (thd->start_time - start_time);
|
uptime= (ulong) (thd->start_time - server_start_time);
|
||||||
length= my_snprintf((char*) buff, buff_len - 1,
|
length= my_snprintf((char*) buff, buff_len - 1,
|
||||||
"Uptime: %lu Threads: %d Questions: %lu "
|
"Uptime: %lu Threads: %d Questions: %lu "
|
||||||
"Slow queries: %lu Opens: %lu Flush tables: %lu "
|
"Slow queries: %lu Opens: %lu Flush tables: %lu "
|
||||||
@ -2173,13 +2184,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
{
|
{
|
||||||
statistic_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION],
|
statistic_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION],
|
||||||
&LOCK_status);
|
&LOCK_status);
|
||||||
enum_mysql_set_option command= (enum_mysql_set_option) uint2korr(packet);
|
uint opt_command= uint2korr(packet);
|
||||||
switch (command) {
|
|
||||||
case MYSQL_OPTION_MULTI_STATEMENTS_ON:
|
switch (opt_command) {
|
||||||
|
case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
|
||||||
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
|
thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
|
||||||
send_eof(thd);
|
send_eof(thd);
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPTION_MULTI_STATEMENTS_OFF:
|
case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
|
||||||
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
|
thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
|
||||||
send_eof(thd);
|
send_eof(thd);
|
||||||
break;
|
break;
|
||||||
@ -2606,7 +2618,7 @@ mysql_execute_command(THD *thd)
|
|||||||
{
|
{
|
||||||
bool res= FALSE;
|
bool res= FALSE;
|
||||||
bool need_start_waiting= FALSE; // have protection against global read lock
|
bool need_start_waiting= FALSE; // have protection against global read lock
|
||||||
int result= 0;
|
int up_result= 0;
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
|
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
|
||||||
SELECT_LEX *select_lex= &lex->select_lex;
|
SELECT_LEX *select_lex= &lex->select_lex;
|
||||||
@ -3462,7 +3474,7 @@ end_with_restore_list:
|
|||||||
break;
|
break;
|
||||||
DBUG_ASSERT(select_lex->offset_limit == 0);
|
DBUG_ASSERT(select_lex->offset_limit == 0);
|
||||||
unit->set_limit(select_lex);
|
unit->set_limit(select_lex);
|
||||||
res= (result= mysql_update(thd, all_tables,
|
res= (up_result= mysql_update(thd, all_tables,
|
||||||
select_lex->item_list,
|
select_lex->item_list,
|
||||||
lex->value_list,
|
lex->value_list,
|
||||||
select_lex->where,
|
select_lex->where,
|
||||||
@ -3471,13 +3483,14 @@ end_with_restore_list:
|
|||||||
unit->select_limit_cnt,
|
unit->select_limit_cnt,
|
||||||
lex->duplicates, lex->ignore));
|
lex->duplicates, lex->ignore));
|
||||||
/* mysql_update return 2 if we need to switch to multi-update */
|
/* mysql_update return 2 if we need to switch to multi-update */
|
||||||
if (result != 2)
|
if (up_result != 2)
|
||||||
break;
|
break;
|
||||||
|
/* Fall through */
|
||||||
case SQLCOM_UPDATE_MULTI:
|
case SQLCOM_UPDATE_MULTI:
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
/* if we switched from normal update, rights are checked */
|
/* if we switched from normal update, rights are checked */
|
||||||
if (result != 2)
|
if (up_result != 2)
|
||||||
{
|
{
|
||||||
if ((res= multi_update_precheck(thd, all_tables)))
|
if ((res= multi_update_precheck(thd, all_tables)))
|
||||||
break;
|
break;
|
||||||
@ -3562,7 +3575,7 @@ end_with_restore_list:
|
|||||||
case SQLCOM_REPLACE_SELECT:
|
case SQLCOM_REPLACE_SELECT:
|
||||||
case SQLCOM_INSERT_SELECT:
|
case SQLCOM_INSERT_SELECT:
|
||||||
{
|
{
|
||||||
select_result *result;
|
select_result *sel_result;
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
if ((res= insert_precheck(thd, all_tables)))
|
if ((res= insert_precheck(thd, all_tables)))
|
||||||
break;
|
break;
|
||||||
@ -3591,13 +3604,15 @@ end_with_restore_list:
|
|||||||
select_lex->context.table_list=
|
select_lex->context.table_list=
|
||||||
select_lex->context.first_name_resolution_table= second_table;
|
select_lex->context.first_name_resolution_table= second_table;
|
||||||
res= mysql_insert_select_prepare(thd);
|
res= mysql_insert_select_prepare(thd);
|
||||||
if (!res && (result= new select_insert(first_table, first_table->table,
|
if (!res && (sel_result= new select_insert(first_table,
|
||||||
|
first_table->table,
|
||||||
&lex->field_list,
|
&lex->field_list,
|
||||||
&lex->update_list,
|
&lex->update_list,
|
||||||
&lex->value_list,
|
&lex->value_list,
|
||||||
lex->duplicates, lex->ignore)))
|
lex->duplicates,
|
||||||
|
lex->ignore)))
|
||||||
{
|
{
|
||||||
res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
|
res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
|
||||||
/*
|
/*
|
||||||
Invalidate the table in the query cache if something changed
|
Invalidate the table in the query cache if something changed
|
||||||
after unlocking when changes become visible.
|
after unlocking when changes become visible.
|
||||||
@ -3615,7 +3630,7 @@ end_with_restore_list:
|
|||||||
first_table->next_local= save_table;
|
first_table->next_local= save_table;
|
||||||
thd->lock=0;
|
thd->lock=0;
|
||||||
}
|
}
|
||||||
delete result;
|
delete sel_result;
|
||||||
}
|
}
|
||||||
/* revert changes for SP */
|
/* revert changes for SP */
|
||||||
select_lex->table_list.first= (byte*) first_table;
|
select_lex->table_list.first= (byte*) first_table;
|
||||||
@ -3640,7 +3655,7 @@ end_with_restore_list:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
if (check_one_table_access(thd, DELETE_ACL, all_tables))
|
if (check_one_table_access(thd, DROP_ACL, all_tables))
|
||||||
goto error;
|
goto error;
|
||||||
/*
|
/*
|
||||||
Don't allow this within a transaction because we want to use
|
Don't allow this within a transaction because we want to use
|
||||||
@ -3681,7 +3696,7 @@ end_with_restore_list:
|
|||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
TABLE_LIST *aux_tables=
|
TABLE_LIST *aux_tables=
|
||||||
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
|
(TABLE_LIST *)thd->lex->auxiliary_table_list.first;
|
||||||
multi_delete *result;
|
multi_delete *del_result;
|
||||||
|
|
||||||
if (!thd->locked_tables &&
|
if (!thd->locked_tables &&
|
||||||
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
|
||||||
@ -3706,8 +3721,8 @@ end_with_restore_list:
|
|||||||
if ((res= mysql_multi_delete_prepare(thd)))
|
if ((res= mysql_multi_delete_prepare(thd)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!thd->is_fatal_error && (result= new multi_delete(aux_tables,
|
if (!thd->is_fatal_error &&
|
||||||
lex->table_count)))
|
(del_result= new multi_delete(aux_tables, lex->table_count)))
|
||||||
{
|
{
|
||||||
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
res= mysql_select(thd, &select_lex->ref_pointer_array,
|
||||||
select_lex->get_table_list(),
|
select_lex->get_table_list(),
|
||||||
@ -3719,8 +3734,8 @@ end_with_restore_list:
|
|||||||
select_lex->options | thd->options |
|
select_lex->options | thd->options |
|
||||||
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
|
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
|
||||||
OPTION_SETUP_TABLES_DONE,
|
OPTION_SETUP_TABLES_DONE,
|
||||||
result, unit, select_lex);
|
del_result, unit, select_lex);
|
||||||
delete result;
|
delete del_result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res= TRUE; // Error
|
res= TRUE; // Error
|
||||||
@ -4133,7 +4148,6 @@ end_with_restore_list:
|
|||||||
lex->spname->m_name);
|
lex->spname->m_name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint affected= 1;
|
|
||||||
if (!(res= Events::get_instance()->drop_event(thd,
|
if (!(res= Events::get_instance()->drop_event(thd,
|
||||||
lex->spname->m_db,
|
lex->spname->m_db,
|
||||||
lex->spname->m_name,
|
lex->spname->m_name,
|
||||||
@ -4531,7 +4545,7 @@ end_with_restore_list:
|
|||||||
{
|
{
|
||||||
uint namelen;
|
uint namelen;
|
||||||
char *name;
|
char *name;
|
||||||
int result= SP_INTERNAL_ERROR;
|
int sp_result= SP_INTERNAL_ERROR;
|
||||||
|
|
||||||
DBUG_ASSERT(lex->sphead != 0);
|
DBUG_ASSERT(lex->sphead != 0);
|
||||||
DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
|
DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
|
||||||
@ -4580,8 +4594,8 @@ end_with_restore_list:
|
|||||||
if (sp_process_definer(thd))
|
if (sp_process_definer(thd))
|
||||||
goto create_sp_error;
|
goto create_sp_error;
|
||||||
|
|
||||||
res= (result= lex->sphead->create(thd));
|
res= (sp_result= lex->sphead->create(thd));
|
||||||
switch (result) {
|
switch (sp_result) {
|
||||||
case SP_OK:
|
case SP_OK:
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
/* only add privileges if really neccessary */
|
/* only add privileges if really neccessary */
|
||||||
@ -4621,7 +4635,7 @@ create_sp_error:
|
|||||||
lex->unit.cleanup();
|
lex->unit.cleanup();
|
||||||
delete lex->sphead;
|
delete lex->sphead;
|
||||||
lex->sphead= 0;
|
lex->sphead= 0;
|
||||||
if (result != SP_OK )
|
if (sp_result != SP_OK )
|
||||||
goto error;
|
goto error;
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
break; /* break super switch */
|
break; /* break super switch */
|
||||||
@ -4736,7 +4750,7 @@ create_sp_error:
|
|||||||
case SQLCOM_ALTER_PROCEDURE:
|
case SQLCOM_ALTER_PROCEDURE:
|
||||||
case SQLCOM_ALTER_FUNCTION:
|
case SQLCOM_ALTER_FUNCTION:
|
||||||
{
|
{
|
||||||
int result;
|
int sp_result;
|
||||||
sp_head *sp;
|
sp_head *sp;
|
||||||
st_sp_chistics chistics;
|
st_sp_chistics chistics;
|
||||||
|
|
||||||
@ -4751,7 +4765,7 @@ create_sp_error:
|
|||||||
if (! sp)
|
if (! sp)
|
||||||
{
|
{
|
||||||
if (lex->spname->m_db.str)
|
if (lex->spname->m_db.str)
|
||||||
result= SP_KEY_NOT_FOUND;
|
sp_result= SP_KEY_NOT_FOUND;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
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));
|
||||||
@ -4776,7 +4790,7 @@ create_sp_error:
|
|||||||
{
|
{
|
||||||
my_message(ER_BINLOG_UNSAFE_ROUTINE,
|
my_message(ER_BINLOG_UNSAFE_ROUTINE,
|
||||||
ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
|
ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
|
||||||
result= SP_INTERNAL_ERROR;
|
sp_result= SP_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4786,15 +4800,15 @@ create_sp_error:
|
|||||||
follow the restrictions that log-bin-trust-function-creators=0
|
follow the restrictions that log-bin-trust-function-creators=0
|
||||||
already puts on CREATE FUNCTION.
|
already puts on CREATE FUNCTION.
|
||||||
*/
|
*/
|
||||||
|
/* Conditionally writes to binlog */
|
||||||
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
|
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
|
||||||
/* Conditionally writes to binlog */
|
sp_result= sp_update_procedure(thd, lex->spname,
|
||||||
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
|
&lex->sp_chistics);
|
||||||
else
|
else
|
||||||
/* Conditionally writes to binlog */
|
sp_result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
|
||||||
result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (result)
|
switch (sp_result)
|
||||||
{
|
{
|
||||||
case SP_OK:
|
case SP_OK:
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
@ -4813,13 +4827,13 @@ create_sp_error:
|
|||||||
case SQLCOM_DROP_PROCEDURE:
|
case SQLCOM_DROP_PROCEDURE:
|
||||||
case SQLCOM_DROP_FUNCTION:
|
case SQLCOM_DROP_FUNCTION:
|
||||||
{
|
{
|
||||||
int result;
|
int sp_result;
|
||||||
int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
|
int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
|
||||||
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
|
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
|
||||||
|
|
||||||
result= sp_routine_exists_in_table(thd, type, lex->spname);
|
sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
|
||||||
mysql_reset_errors(thd, 0);
|
mysql_reset_errors(thd, 0);
|
||||||
if (result == SP_OK)
|
if (sp_result == SP_OK)
|
||||||
{
|
{
|
||||||
char *db= lex->spname->m_db.str;
|
char *db= lex->spname->m_db.str;
|
||||||
char *name= lex->spname->m_name.str;
|
char *name= lex->spname->m_name.str;
|
||||||
@ -4840,12 +4854,11 @@ create_sp_error:
|
|||||||
ER(ER_PROC_AUTO_REVOKE_FAIL));
|
ER(ER_PROC_AUTO_REVOKE_FAIL));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* Conditionally writes to binlog */
|
||||||
if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
|
if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
|
||||||
/* Conditionally writes to binlog */
|
sp_result= sp_drop_procedure(thd, lex->spname);
|
||||||
result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */
|
|
||||||
else
|
else
|
||||||
/* Conditionally writes to binlog */
|
sp_result= sp_drop_function(thd, lex->spname);
|
||||||
result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4869,16 +4882,15 @@ create_sp_error:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (lex->spname->m_db.str)
|
if (lex->spname->m_db.str)
|
||||||
result= SP_KEY_NOT_FOUND;
|
sp_result= SP_KEY_NOT_FOUND;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
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));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res= result;
|
res= sp_result;
|
||||||
switch (result)
|
switch (sp_result) {
|
||||||
{
|
|
||||||
case SP_OK:
|
case SP_OK:
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
break;
|
break;
|
||||||
@ -5646,7 +5658,9 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||||||
{
|
{
|
||||||
uint found=0;
|
uint found=0;
|
||||||
ulong found_access=0;
|
ulong found_access=0;
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
TABLE_LIST *org_tables= tables;
|
TABLE_LIST *org_tables= tables;
|
||||||
|
#endif
|
||||||
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
|
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
|
||||||
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
|
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
|
||||||
/*
|
/*
|
||||||
@ -6680,11 +6694,8 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
|
|||||||
If this is a JOIN ... USING, move the list of joined fields to the
|
If this is a JOIN ... USING, move the list of joined fields to the
|
||||||
table reference that describes the join.
|
table reference that describes the join.
|
||||||
*/
|
*/
|
||||||
if (table->join_using_fields)
|
if (prev_join_using)
|
||||||
{
|
ptr->join_using_fields= prev_join_using;
|
||||||
ptr->join_using_fields= table->join_using_fields;
|
|
||||||
table->join_using_fields= NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
join_list->push_front(ptr);
|
join_list->push_front(ptr);
|
||||||
@ -6820,18 +6831,18 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
|
|||||||
0 on success
|
0 on success
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool st_select_lex_unit::add_fake_select_lex(THD *thd)
|
bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
|
||||||
{
|
{
|
||||||
SELECT_LEX *first_sl= first_select();
|
SELECT_LEX *first_sl= first_select();
|
||||||
DBUG_ENTER("add_fake_select_lex");
|
DBUG_ENTER("add_fake_select_lex");
|
||||||
DBUG_ASSERT(!fake_select_lex);
|
DBUG_ASSERT(!fake_select_lex);
|
||||||
|
|
||||||
if (!(fake_select_lex= new (thd->mem_root) SELECT_LEX()))
|
if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
fake_select_lex->include_standalone(this,
|
fake_select_lex->include_standalone(this,
|
||||||
(SELECT_LEX_NODE**)&fake_select_lex);
|
(SELECT_LEX_NODE**)&fake_select_lex);
|
||||||
fake_select_lex->select_number= INT_MAX;
|
fake_select_lex->select_number= INT_MAX;
|
||||||
fake_select_lex->parent_lex= thd->lex; /* Used in init_query. */
|
fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
|
||||||
fake_select_lex->make_empty_select();
|
fake_select_lex->make_empty_select();
|
||||||
fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
|
fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
|
||||||
fake_select_lex->select_limit= 0;
|
fake_select_lex->select_limit= 0;
|
||||||
@ -6851,9 +6862,9 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd)
|
|||||||
*/
|
*/
|
||||||
global_parameters= fake_select_lex;
|
global_parameters= fake_select_lex;
|
||||||
fake_select_lex->no_table_names_allowed= 1;
|
fake_select_lex->no_table_names_allowed= 1;
|
||||||
thd->lex->current_select= fake_select_lex;
|
thd_arg->lex->current_select= fake_select_lex;
|
||||||
}
|
}
|
||||||
thd->lex->pop_context();
|
thd_arg->lex->pop_context();
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6940,6 +6951,7 @@ void add_join_on(TABLE_LIST *b, Item *expr)
|
|||||||
a Left join argument
|
a Left join argument
|
||||||
b Right join argument
|
b Right join argument
|
||||||
using_fields Field names from USING clause
|
using_fields Field names from USING clause
|
||||||
|
lex The current st_select_lex
|
||||||
|
|
||||||
IMPLEMENTATION
|
IMPLEMENTATION
|
||||||
This function marks that table b should be joined with a either via
|
This function marks that table b should be joined with a either via
|
||||||
@ -6968,10 +6980,11 @@ void add_join_on(TABLE_LIST *b, Item *expr)
|
|||||||
None
|
None
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields)
|
void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
|
||||||
|
SELECT_LEX *lex)
|
||||||
{
|
{
|
||||||
b->natural_join= a;
|
b->natural_join= a;
|
||||||
b->join_using_fields= using_fields;
|
lex->prev_join_using= using_fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user