Manual merge

parent 5c8216ba
...@@ -834,14 +834,14 @@ show create view v1; ...@@ -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 (c char); create table t (c char);
create view v as select c from t; create view v as select c from t;
insert into v values (''); insert into v values ('');
select * from v; select * from v;
c c
drop view v; drop view v;
drop table t; 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(); ...@@ -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); ...@@ -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 ...@@ -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; ...@@ -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; ...@@ -748,12 +748,12 @@ drop view v1;
# #
# VIEWs with national characters # VIEWs with national characters
# #
create table t (c char); create table t (c char);
create view v as select c from t; create view v as select c from t;
insert into v values (''); insert into v values ('');
select * from v; select * from v;
drop view v; drop view v;
drop table t; 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; ...@@ -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); ...@@ -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; ...@@ -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; ...@@ -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; ...@@ -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; ...@@ -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
# #
......
...@@ -56,12 +56,11 @@ ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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(&current_global_status_var); calc_sum_of_all_status(&current_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, ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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.
*/ */
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
/* Conditionally writes to binlog */ /* Conditionally writes to binlog */
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
sp_result= sp_update_procedure(thd, lex->spname,
&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: ...@@ -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: ...@@ -4840,12 +4854,11 @@ create_sp_error:
ER(ER_PROC_AUTO_REVOKE_FAIL)); ER(ER_PROC_AUTO_REVOKE_FAIL));
} }
#endif #endif
if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
/* Conditionally writes to binlog */ /* Conditionally writes to binlog */
result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */ if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
sp_result= sp_drop_procedure(thd, lex->spname);
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: ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment