From 8063dd8763c2061713999b46d441ad0727568982 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Tue, 10 Nov 2009 15:56:05 +0100 Subject: Bug#27145 EXTRA_ACL troubles Correction of backport patch: * Fixed signature of check_access_table() for embedded build * Fixed typo for last argument in a check_access() call from UINT_MAX to 0. --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b99ff1c99c5..b5a088af539 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2268,7 +2268,7 @@ mysql_execute_command(THD *thd) privileges_requested, all_tables, FALSE, UINT_MAX, FALSE); else - res= check_access(thd, privileges_requested, any_db, 0, 0, 0, UINT_MAX); + res= check_access(thd, privileges_requested, any_db, 0, 0, 0, 0); if (res) break; -- cgit v1.2.1 From 9cfd2fce0cd72a2600b60ed182b808210cef88e5 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 10 Nov 2009 16:11:27 -0200 Subject: Backport of Bug#36649 to mysql-next-mr ------------------------------------------------------------ revno: 2630.39.3 revision-id: davi.arnaut@sun.com-20081210215359-i876m4zgc2d6rzs3 parent: kostja@sun.com-20081208222938-9es7wl61moli71ht committer: Davi Arnaut branch nick: 36649-6.0 timestamp: Wed 2008-12-10 19:53:59 -0200 message: Bug#36649: Condition area is not properly cleaned up after stored routine invocation The problem is that the diagnostics area of a trigger is not isolated from the area of the statement that caused the trigger invocation. In MySQL terms, it means that warnings generated during the execution of the trigger are not removed from the "warning area" at the end of the execution. Before this fix, the rules for MySQL message list life cycle (see manual entry for SHOW WARNINGS) did not apply to statements inside stored programs: - The manual says that the list of messages is cleared by a statement that uses a table (any table). However, such statement, if run inside a stored program did not clear the message list. - The manual says that the list is cleared by a statement that generates a new error or a warning, but this was not the case with stored program statements either and is changed to be the case as well. In other words, after this fix, a statement has the same effect on the message list regardless of whether it's executed inside a stored program/sub-statement or not. This introduces an incompatible change: - before this fix, a, e.g. statement inside a trigger could never clear the global warning list - after this fix, a trigger that generates a warning or uses a table, clears the global warning list - however, when we leave a trigger or a function, the caller's warning information is restored (see more on this below). This change is not backward compatible as it is intended to make MySQL behavior similar to the SQL standard behavior: A stored function or trigger will get its own "warning area" (or, in standard terminology, diagnostics area). At the beginning of the stored function or trigger, all messages from the caller area will be copied to the area of the trigger. During execution, the message list will be cleared according to the MySQL rules described on the manual (SHOW WARNINGS entry). At the end of the function/trigger, the "warning area" will be destroyed along with all warnings it contains, except that if the last statement of the function/trigger generated messages, these are copied into the "warning area" of the caller. Consequently, statements that use a table or generate a warning *will* clear warnings inside the trigger, but that will have no effect to the warning list of the calling (outer) statement. mysql-test/r/sp.result: Fix test case results. mysql-test/r/trigger.result: Fix test case results. mysql-test/t/sp.test: Add test case for Bug#36649 mysql-test/t/trigger.test: Add test case for Bug#36649 sql/sp_head.cc: Emulate multiple warning areas -- one per stored program instance. sql/sql_parse.cc: Message list reset rules are the same for statements inside or outside compound statements. --- sql/sql_parse.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b5a088af539..8c2f70a36a0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2065,7 +2065,6 @@ mysql_execute_command(THD *thd) A better approach would be to reset this for any commands that is not a SHOW command or a select that only access local variables, but for now this is probably good enough. - Don't reset warnings when executing a stored routine. */ if ((sql_command_flags[lex->sql_command] & CF_DIAGNOSTIC_STMT) != 0) thd->warning_info->set_read_only(TRUE); -- cgit v1.2.1 From e26de1ca16d60870184a6a30504c02bce5c4070d Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 10 Nov 2009 16:48:46 -0200 Subject: Backport of Bug#27525 to mysql-next-mr ------------------------------------------------------------ revno: 2572.2.1 revision-id: sp1r-davi@mysql.com/endora.local-20080227225948-16317 parent: sp1r-anozdrin/alik@quad.-20080226165712-10409 committer: davi@mysql.com/endora.local timestamp: Wed 2008-02-27 19:59:48 -0300 message: Bug#27525 table not found when using multi-table-deletes with aliases over several databas Bug#30234 Unexpected behavior using DELETE with AS and USING The multi-delete statement has a documented limitation that cross-database multiple-table deletes using aliases are not supported because it fails to find the tables by alias if it belongs to a different database. The problem is that when building the list of tables to delete from, if a database name is not specified (maybe an alias) it defaults to the name of the current selected database, making impossible to to properly resolve tables by alias later. Another problem is a inconsistency of the multiple table delete syntax that permits ambiguities in a delete statement (aliases that refer to multiple different tables or vice-versa). The first step for a solution and proper implementation of the cross-databse multiple table delete is to get rid of any ambiguities in a multiple table statement. Currently, the parser is accepting multiple table delete statements that have no obvious meaning, such as: DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1; DELETE a1 AS a1 FROM db1.t1 AS a1, db2.t2 AS a1; The solution is to resolve the left part of a delete statement using the right part, if the a table on right has an alias, it must be referenced in the left using the given alias. Also, each table on the left side must match unambiguously only one table in the right side. mysql-test/r/delete.result: Add test case result for Bug#27525 and Bug#21148 mysql-test/r/derived.result: Update error. mysql-test/suite/rpl/r/rpl_multi_delete2.result: Update syntax. mysql-test/suite/rpl/t/rpl_multi_delete2.test: Update syntax. mysql-test/t/delete.test: Add test case for Bug#27525 and Bug#21148 mysql-test/t/derived.test: Update statement error, alias is properly resolved now. sql/sql_parse.cc: Implement new algorithm for the resolution of alias in a multiple table delete statement. sql/sql_yacc.yy: Rework multi-delete parser rules to not accept table alias for the table source list. sql/table.h: Add flag to signal that the table has a alias set or that fully qualified table name was given. --- sql/sql_parse.cc | 74 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 12 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8c2f70a36a0..926717ef733 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6486,13 +6486,17 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, DBUG_RETURN(0); /* purecov: inspected */ if (table->db.str) { + ptr->is_fqtn= TRUE; ptr->db= table->db.str; ptr->db_length= table->db.length; } else if (lex->copy_db_to(&ptr->db, &ptr->db_length)) DBUG_RETURN(0); + else + ptr->is_fqtn= FALSE; ptr->alias= alias_str; + ptr->is_alias= alias ? TRUE : FALSE; if (lower_case_table_names && table->table.length) table->table.length= my_casedn_str(files_charset_info, table->table.str); ptr->table_name=table->table.str; @@ -7539,6 +7543,63 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables) } +/* + Given a table in the source list, find a correspondent table in the + table references list. + + @param lex Pointer to LEX representing multi-delete. + @param src Source table to match. + @param ref Table references list. + + @remark The source table list (tables listed before the FROM clause + or tables listed in the FROM clause before the USING clause) may + contain table names or aliases that must match unambiguously one, + and only one, table in the target table list (table references list, + after FROM/USING clause). + + @return Matching table, NULL otherwise. +*/ + +static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl, + TABLE_LIST *tables) +{ + TABLE_LIST *match= NULL; + DBUG_ENTER("multi_delete_table_match"); + + for (TABLE_LIST *elem= tables; elem; elem= elem->next_local) + { + int cmp; + + if (tbl->is_fqtn && elem->is_alias) + continue; /* no match */ + if (tbl->is_fqtn && elem->is_fqtn) + cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) || + strcmp(tbl->db, elem->db); + else if (elem->is_alias) + cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias); + else + cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) || + strcmp(tbl->db, elem->db); + + if (cmp) + continue; + + if (match) + { + my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias); + DBUG_RETURN(NULL); + } + + match= elem; + } + + if (!match) + my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE"); + + DBUG_RETURN(match); +} + + /** Link tables in auxilary table list of multi-delete with corresponding elements in main table list, and set proper locks for them. @@ -7564,20 +7625,9 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex) { lex->table_count++; /* All tables in aux_tables must be found in FROM PART */ - TABLE_LIST *walk; - for (walk= tables; walk; walk= walk->next_local) - { - if (!my_strcasecmp(table_alias_charset, - target_tbl->alias, walk->alias) && - !strcmp(walk->db, target_tbl->db)) - break; - } + TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables); if (!walk) - { - my_error(ER_UNKNOWN_TABLE, MYF(0), - target_tbl->table_name, "MULTI DELETE"); DBUG_RETURN(TRUE); - } if (!walk->derived) { target_tbl->table_name= walk->table_name; -- cgit v1.2.1 From e879919a9f7bb3681bc4a8522c30e335d1fc28ce Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 10 Nov 2009 18:31:28 -0200 Subject: Backport of Bug#15192 to mysql-next-mr ------------------------------------------------------------ revno: 2597.4.17 revision-id: sp1r-davi@mysql.com/endora.local-20080328174753-24337 parent: sp1r-anozdrin/alik@quad.opbmk-20080328140038-16479 committer: davi@mysql.com/endora.local timestamp: Fri 2008-03-28 14:47:53 -0300 message: Bug#15192 "fatal errors" are caught by handlers in stored procedures The problem is that fatal errors (e.g.: out of memory) were being caught by stored procedure exception handlers which could cause the execution to not be stopped due to a continue handler. The solution is to not call any exception handler if the error is fatal and send the fatal error to the client. mysql-test/r/sp-error.result: Add test case result for Bug#15192 mysql-test/t/sp-error.test: Add test case for Bug#15192 mysys/my_alloc.c: Pass flag to signal fatal error in memory root allocations. sql/event_data_objects.cc: Use init_sql_alloc to initialize memory roots, which uses the sql error handler to push errors. sql/ha_partition.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/item_func.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/item_subselect.cc: Remove redundant fatal error, memory root already pushes error. sql/opt_sum.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/sp_head.cc: Allocator already sets fatal error. sql/sql_class.h: A error must exist for it to be fatal. Pass flag to signal fatal error instead of calling fatal_error. sql/sql_insert.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/sql_list.h: Pass flag to signal fatal error instead of calling fatal_error. sql/sql_parse.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/sql_partition.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/sql_select.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/sql_servers.cc: Use init_sql_alloc to initialize memory roots, which uses the sql error handler to push errors. sql/sql_show.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/sql_trigger.cc: Use init_sql_alloc to initialize memory roots, which uses the sql error handler to push errors. sql/sql_update.cc: Pass flag to signal fatal error instead of calling fatal_error. sql/tztime.cc: Use init_sql_alloc to initialize memory roots, which uses the sql error handler to push errors. --- sql/sql_parse.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 926717ef733..a22daeabf0d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5823,7 +5823,6 @@ bool check_stack_overrun(THD *thd, long margin, my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE), stack_used, my_thread_stack_size, margin); my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR)); - thd->fatal_error(); return 1; } #ifndef DBUG_OFF -- cgit v1.2.1 From 891dffa32293a1700bb940f55825488d86915010 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 10 Nov 2009 18:51:14 -0200 Subject: Backport of Bug#45767 to mysql-next-mr ------------------------------------------------------------ revno: 3405 revision-id: davi.arnaut@sun.com-20090626124624-m4wolyo5193j4cu7 parent: luis.soares@sun.com-20090626113019-1j4mn1jos480u9f3 committer: Davi Arnaut branch nick: mysql-pe timestamp: Fri 2009-06-26 09:46:24 -0300 message: Bug#45767: deprecate/remove Field::pack_key, Field::unpack_key, Field::pack_cmp Remove unused and dead code. Parts of the patch contributed by Zardosht Kasheff --- sql/sql_parse.cc | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) (limited to 'sql/sql_parse.cc') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a22daeabf0d..4aa37d82bf0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1362,54 +1362,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->stmt_da->disable_status(); // Don't send anything back error=TRUE; // End server break; - -#ifdef REMOVED - case COM_CREATE_DB: // QQ: To be removed - { - LEX_STRING db, alias; - HA_CREATE_INFO create_info; - - status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]); - if (thd->make_lex_string(&db, packet, packet_length, FALSE) || - thd->make_lex_string(&alias, db.str, db.length, FALSE) || - check_db_name(&db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL"); - break; - } - if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0, - is_schema_db(db.str))) - break; - general_log_print(thd, command, "%.*s", db.length, db.str); - bzero(&create_info, sizeof(create_info)); - mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str), - &create_info, 0); - break; - } - case COM_DROP_DB: // QQ: To be removed - { - status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]); - LEX_STRING db; - - if (thd->make_lex_string(&db, packet, packet_length, FALSE) || - check_db_name(&db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL"); - break; - } - if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str))) - break; - if (thd->locked_tables || thd->active_transaction()) - { - my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, - ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); - break; - } - general_log_write(thd, command, "%.*s", db.length, db.str); - mysql_rm_db(thd, db.str, 0, 0); - break; - } -#endif #ifndef EMBEDDED_LIBRARY case COM_BINLOG_DUMP: { -- cgit v1.2.1