diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 36c79a77f93..4d3b20ffcbc 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -834,14 +834,14 @@ show create view v1; View Create View v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1` drop view v1; -create table tü (cü char); -create view vü as select cü from tü; -insert into vü values ('ü'); -select * from vü; -cü -ü -drop view vü; -drop table tü; +create table t (c char); +create view v as select c from t; +insert into v values (''); +select * from v; +c + +drop view v; +drop table t; create table t1 (a int, b int); 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; @@ -2060,17 +2060,6 @@ CALL p1(); DROP PROCEDURE p1; DROP VIEW v1; 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); 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; @@ -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 .f1 and ta.f2=tb.f2; 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; a b 2 2 @@ -3016,6 +3005,17 @@ i j 6 3 DROP VIEW v1, v2; 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; CREATE VIEW v1 AS SELECT 'The\ZEnd'; SELECT * FROM v1; @@ -3025,6 +3025,107 @@ SHOW CREATE VIEW v1; View Create View v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd` 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; SELECT * FROM (SELECT 1) AS t; 1 diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index f1eb1b5dd68..7f523c52c87 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -748,12 +748,12 @@ drop view v1; # # VIEWs with national characters # -create table tü (cü char); -create view vü as select cü from tü; -insert into vü values ('ü'); -select * from vü; -drop view vü; -drop table tü; +create table t (c char); +create view v as select c from t; +insert into v values (''); +select * from v; +drop view v; +drop table t; # # problem with used_tables() of outer reference resolved in VIEW @@ -1878,15 +1878,6 @@ DROP PROCEDURE p1; DROP VIEW v1; 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 # 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 .f1 and ta.f2=tb.f2; 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; update v2 set b=3 where a=2; select * from v2; @@ -2908,7 +2899,6 @@ DROP FUNCTION f1; DROP VIEW v1; DROP TABLE t1; - # # Bug #16813 (WITH CHECK OPTION doesn't work with UPDATE) # @@ -2960,6 +2950,18 @@ SELECT * FROM t1; DROP VIEW v1, v2; 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 # @@ -2975,6 +2977,77 @@ SHOW CREATE 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 @@ -3082,7 +3155,6 @@ drop table table_24532; --echo End of 5.0 tests. - # # Bug#21370 View renaming lacks tablename_to_filename encoding # diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 580be4d5c1f..6cd8db421ea 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -56,12 +56,11 @@ (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \ "FUNCTION" : "PROCEDURE") -static void time_out_user_resource_limits(THD *thd, USER_CONN *uc); #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 void decrease_user_connections(USER_CONN *uc); #endif /* NO_EMBEDDED_ACCESS_CHECKS */ -static bool check_multi_update_lock(THD *thd); static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables); 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, (thd->main_security_ctx.priv_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. */ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + static void time_out_user_resource_limits(THD *thd, USER_CONN *uc) { 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; } - /* Check if maximum queries per hour limit has been reached 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) { -#ifndef NO_EMBEDDED_ACCESS_CHECKS bool error= 0; USER_CONN *uc=thd->user_connect; DBUG_ENTER("check_mqh"); @@ -772,11 +775,10 @@ static bool check_mqh(THD *thd, uint check_command) end: (void) pthread_mutex_unlock(&LOCK_user_conn); 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) { @@ -1007,7 +1009,7 @@ static int check_connection(THD *thd) return(ER_HANDSHAKE_ERROR); } 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")); inc_host_errors(&thd->remote.sin_addr); @@ -1036,7 +1038,6 @@ static int check_connection(THD *thd) if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && opt_using_transactions) net->return_status= &thd->server_status; - net->read_timeout=(uint) thd->variables.net_read_timeout; char *user= end; char *passwd= strend(user)+1; @@ -1183,6 +1184,10 @@ pthread_handler_t handle_one_connection(void *arg) Security_context *sctx= thd->security_ctx; 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))) { // Wrong permissions if (error > 0) @@ -1225,6 +1230,10 @@ pthread_handler_t handle_one_connection(void *arg) 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 && !(thd->killed == THD::KILL_CONNECTION)) { @@ -1556,7 +1565,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion) #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. SYNOPSIS do_command() @@ -1567,24 +1576,26 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion) bool do_command(THD *thd) { - char *packet; - uint old_timeout; + char *packet= 0; ulong packet_length; - NET *net; + NET *net= &thd->net; enum enum_server_command command; DBUG_ENTER("do_command"); - net= &thd->net; /* indicator of uninitialized lex => normal flow of errors handling (see my_message_sql) */ thd->lex->current_select= 0; - packet=0; - old_timeout=net->read_timeout; - /* Wait max for 8 hours */ - net->read_timeout=(uint) thd->variables.net_wait_timeout; + /* + This thread will do a blocking read from the client which + will be interrupted when the next command is received from + 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 net_new_transaction(net); @@ -1613,7 +1624,10 @@ bool do_command(THD *thd) vio_description(net->vio), command, 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 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->set_time(); 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) next_query_id(); 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) { - char *packet= thd->lex->found_semicolon; + char *next_packet= thd->lex->found_semicolon; net->no_send_error= 0; /* 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 || thd->prelocked_mode) close_thread_tables(thd); - ulong length= (ulong)(packet_end-packet); + ulong length= (ulong)(packet_end - next_packet); log_slow_statement(thd); /* 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--; } VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_length= length; - thd->query= packet; + thd->query= next_packet; thd->query_id= next_query_id(); thd->set_time(); /* Reset the query start time. */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */ VOID(pthread_mutex_unlock(&LOCK_thread_count)); - mysql_parse(thd, packet, length); + mysql_parse(thd, next_packet, length); } 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; /* Locked closure of all tables */ - TABLE_LIST *locked_tables= NULL; TABLE_LIST table_list; LEX_STRING conv_name; - /* Saved variable value */ - my_bool old_innodb_table_locks= thd->variables.innodb_table_locks; uint dummy; /* 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], &LOCK_status); 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, "Uptime: %lu Threads: %d Questions: %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], &LOCK_status); - enum_mysql_set_option command= (enum_mysql_set_option) uint2korr(packet); - switch (command) { - case MYSQL_OPTION_MULTI_STATEMENTS_ON: + uint opt_command= uint2korr(packet); + + switch (opt_command) { + case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON: thd->client_capabilities|= CLIENT_MULTI_STATEMENTS; send_eof(thd); break; - case MYSQL_OPTION_MULTI_STATEMENTS_OFF: + case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF: thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS; send_eof(thd); break; @@ -2606,7 +2618,7 @@ mysql_execute_command(THD *thd) { bool res= FALSE; bool need_start_waiting= FALSE; // have protection against global read lock - int result= 0; + int up_result= 0; LEX *lex= thd->lex; /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ SELECT_LEX *select_lex= &lex->select_lex; @@ -3462,22 +3474,23 @@ end_with_restore_list: break; DBUG_ASSERT(select_lex->offset_limit == 0); unit->set_limit(select_lex); - res= (result= mysql_update(thd, all_tables, - select_lex->item_list, - lex->value_list, - select_lex->where, - select_lex->order_list.elements, - (ORDER *) select_lex->order_list.first, - unit->select_limit_cnt, - lex->duplicates, lex->ignore)); + res= (up_result= mysql_update(thd, all_tables, + select_lex->item_list, + lex->value_list, + select_lex->where, + select_lex->order_list.elements, + (ORDER *) select_lex->order_list.first, + unit->select_limit_cnt, + lex->duplicates, lex->ignore)); /* mysql_update return 2 if we need to switch to multi-update */ - if (result != 2) + if (up_result != 2) break; + /* Fall through */ case SQLCOM_UPDATE_MULTI: { DBUG_ASSERT(first_table == all_tables && first_table != 0); /* if we switched from normal update, rights are checked */ - if (result != 2) + if (up_result != 2) { if ((res= multi_update_precheck(thd, all_tables))) break; @@ -3562,7 +3575,7 @@ end_with_restore_list: case SQLCOM_REPLACE_SELECT: case SQLCOM_INSERT_SELECT: { - select_result *result; + select_result *sel_result; DBUG_ASSERT(first_table == all_tables && first_table != 0); if ((res= insert_precheck(thd, all_tables))) break; @@ -3591,13 +3604,15 @@ end_with_restore_list: select_lex->context.table_list= select_lex->context.first_name_resolution_table= second_table; res= mysql_insert_select_prepare(thd); - if (!res && (result= new select_insert(first_table, first_table->table, - &lex->field_list, - &lex->update_list, - &lex->value_list, - lex->duplicates, lex->ignore))) + if (!res && (sel_result= new select_insert(first_table, + first_table->table, + &lex->field_list, + &lex->update_list, + &lex->value_list, + 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 after unlocking when changes become visible. @@ -3615,7 +3630,7 @@ end_with_restore_list: first_table->next_local= save_table; thd->lock=0; } - delete result; + delete sel_result; } /* revert changes for SP */ select_lex->table_list.first= (byte*) first_table; @@ -3640,7 +3655,7 @@ end_with_restore_list: break; } 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; /* 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); TABLE_LIST *aux_tables= (TABLE_LIST *)thd->lex->auxiliary_table_list.first; - multi_delete *result; + multi_delete *del_result; if (!thd->locked_tables && !(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))) goto error; - if (!thd->is_fatal_error && (result= new multi_delete(aux_tables, - lex->table_count))) + if (!thd->is_fatal_error && + (del_result= new multi_delete(aux_tables, lex->table_count))) { res= mysql_select(thd, &select_lex->ref_pointer_array, select_lex->get_table_list(), @@ -3719,8 +3734,8 @@ end_with_restore_list: select_lex->options | thd->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | OPTION_SETUP_TABLES_DONE, - result, unit, select_lex); - delete result; + del_result, unit, select_lex); + delete del_result; } else res= TRUE; // Error @@ -4133,7 +4148,6 @@ end_with_restore_list: lex->spname->m_name); else { - uint affected= 1; if (!(res= Events::get_instance()->drop_event(thd, lex->spname->m_db, lex->spname->m_name, @@ -4531,7 +4545,7 @@ end_with_restore_list: { uint namelen; char *name; - int result= SP_INTERNAL_ERROR; + int sp_result= SP_INTERNAL_ERROR; DBUG_ASSERT(lex->sphead != 0); 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)) goto create_sp_error; - res= (result= lex->sphead->create(thd)); - switch (result) { + res= (sp_result= lex->sphead->create(thd)); + switch (sp_result) { case SP_OK: #ifndef NO_EMBEDDED_ACCESS_CHECKS /* only add privileges if really neccessary */ @@ -4621,7 +4635,7 @@ create_sp_error: lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; - if (result != SP_OK ) + if (sp_result != SP_OK ) goto error; send_ok(thd); break; /* break super switch */ @@ -4736,7 +4750,7 @@ create_sp_error: case SQLCOM_ALTER_PROCEDURE: case SQLCOM_ALTER_FUNCTION: { - int result; + int sp_result; sp_head *sp; st_sp_chistics chistics; @@ -4751,7 +4765,7 @@ create_sp_error: if (! sp) { if (lex->spname->m_db.str) - result= SP_KEY_NOT_FOUND; + sp_result= SP_KEY_NOT_FOUND; else { 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, ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0)); - result= SP_INTERNAL_ERROR; + sp_result= SP_INTERNAL_ERROR; } else { @@ -4786,15 +4800,15 @@ create_sp_error: follow the restrictions that log-bin-trust-function-creators=0 already puts on CREATE FUNCTION. */ + /* Conditionally writes to binlog */ if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) - /* Conditionally writes to binlog */ - result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); + sp_result= sp_update_procedure(thd, lex->spname, + &lex->sp_chistics); else - /* Conditionally writes to binlog */ - result= sp_update_function(thd, lex->spname, &lex->sp_chistics); + sp_result= sp_update_function(thd, lex->spname, &lex->sp_chistics); } } - switch (result) + switch (sp_result) { case SP_OK: send_ok(thd); @@ -4813,13 +4827,13 @@ create_sp_error: case SQLCOM_DROP_PROCEDURE: case SQLCOM_DROP_FUNCTION: { - int result; + int sp_result; int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ? 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); - if (result == SP_OK) + if (sp_result == SP_OK) { char *db= lex->spname->m_db.str; char *name= lex->spname->m_name.str; @@ -4840,12 +4854,11 @@ create_sp_error: ER(ER_PROC_AUTO_REVOKE_FAIL)); } #endif + /* Conditionally writes to binlog */ if (lex->sql_command == SQLCOM_DROP_PROCEDURE) - /* Conditionally writes to binlog */ - result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */ + sp_result= sp_drop_procedure(thd, lex->spname); else - /* Conditionally writes to binlog */ - result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */ + sp_result= sp_drop_function(thd, lex->spname); } else { @@ -4869,16 +4882,15 @@ create_sp_error: } #endif if (lex->spname->m_db.str) - result= SP_KEY_NOT_FOUND; + sp_result= SP_KEY_NOT_FOUND; else { my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); goto error; } } - res= result; - switch (result) - { + res= sp_result; + switch (sp_result) { case SP_OK: send_ok(thd); break; @@ -5646,7 +5658,9 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, { uint found=0; ulong found_access=0; +#ifndef EMBEDDED_LIBRARY TABLE_LIST *org_tables= tables; +#endif TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); 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 table reference that describes the join. */ - if (table->join_using_fields) - { - ptr->join_using_fields= table->join_using_fields; - table->join_using_fields= NULL; - } + if (prev_join_using) + ptr->join_using_fields= prev_join_using; } } 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 */ -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(); DBUG_ENTER("add_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); fake_select_lex->include_standalone(this, (SELECT_LEX_NODE**)&fake_select_lex); 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->linkage= GLOBAL_OPTIONS_TYPE; 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; 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); } @@ -6940,6 +6951,7 @@ void add_join_on(TABLE_LIST *b, Item *expr) a Left join argument b Right join argument using_fields Field names from USING clause + lex The current st_select_lex IMPLEMENTATION 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 */ -void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List *using_fields) +void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List *using_fields, + SELECT_LEX *lex) { b->natural_join= a; - b->join_using_fields= using_fields; + lex->prev_join_using= using_fields; }