From: Dmitry Lenev Date: December 22 2010 3:23pm Subject: bzr commit into mysql-trunk-bugfixing branch (Dmitry.Lenev:3402) Bug#27480 List-Archive: http://lists.mysql.com/commits/127513 X-Bug: 27480 Message-Id: <20101222152349.9F7762F95B6@mockturtle> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1672410697==" --===============1672410697== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/dlenev/src/bzr/mysql-trunk-bugfixing-bug27480/ based on revid:dmitry.lenev@stripped 3402 Dmitry Lenev 2010-12-22 Prerequisite patch for Bug#27480 (Extend CREATE TEMPORARY TABLES privilege to allow temp table operations). Review fixes in progress. Final (almost) batch of fixes. modified: mysql-test/r/alter_table.result mysql-test/r/handler_myisam.result mysql-test/r/temp_table.result mysql-test/suite/innodb/r/innodb_mysql.result mysql-test/suite/innodb/t/innodb_mysql.test mysql-test/suite/rpl/r/rpl_create_if_not_exists.result mysql-test/suite/rpl/t/rpl_create_if_not_exists.test mysql-test/t/alter_table.test mysql-test/t/handler_myisam.test mysql-test/t/temp_table.test sql/log_event.cc sql/sql_admin.cc sql/sql_base.cc sql/sql_base.h sql/sql_class.h sql/sql_handler.cc sql/sql_parse.cc sql/sql_partition_admin.cc sql/sql_show.cc sql/sql_table.cc sql/sql_truncate.cc === modified file 'mysql-test/r/alter_table.result' --- a/mysql-test/r/alter_table.result 2010-08-30 06:38:09 +0000 +++ b/mysql-test/r/alter_table.result 2010-12-22 15:23:28 +0000 @@ -1383,3 +1383,14 @@ ALTER TABLE t1 CHANGE a id INT; affected rows: 0 info: Records: 0 Duplicates: 0 Warnings: 0 DROP TABLE t1; +# +# Additional coverage for refactoring which is made as part +# of fix for bug #27480 "Extend CREATE TEMPORARY TABLES privilege +# to allow temp table operations". +# +# At some point the below test case failed on assertion. +DROP TABLE IF EXISTS t1; +CREATE TEMPORARY TABLE t1 (i int) ENGINE=MyISAM; +ALTER TABLE t1 DISCARD TABLESPACE; +ERROR HY000: Table storage engine for 't1' doesn't have this option +DROP TABLE t1; === modified file 'mysql-test/r/handler_myisam.result' --- a/mysql-test/r/handler_myisam.result 2010-11-29 14:13:07 +0000 +++ b/mysql-test/r/handler_myisam.result 2010-12-22 15:23:28 +0000 @@ -1859,15 +1859,20 @@ a b HANDLER t1 CLOSE; DROP TABLE t1; # -# Bug#27480 +# Additional coverage for refactoring which is made as part +# of fix for bug #27480 "Extend CREATE TEMPORARY TABLES privilege +# to allow temp table operations". # +# Check that DDL on temporary table properly closes HANDLER cursors +# for this table belonging to the same connection. CREATE TEMPORARY TABLE t1 AS SELECT 1 AS f1; # -- CREATE TABLE HANDLER t1 OPEN; -CREATE TABLE t2 SELECT * FROM t1; +CREATE TEMPORARY TABLE IF NOT EXISTS t1 SELECT 1 AS f1; +Warnings: +Note 1050 Table 't1' already exists HANDLER t1 READ FIRST; ERROR 42S02: Unknown table 't1' in HANDLER -DROP TABLE t2; # -- REPAIR TABLE HANDLER t1 OPEN; REPAIR TABLE t1; @@ -1901,6 +1906,21 @@ HANDLER t1 OPEN; ALTER TABLE t1 ADD COLUMN b INT; HANDLER t1 READ FIRST; ERROR 42S02: Unknown table 't1' in HANDLER +# -- CREATE INDEX +HANDLER t1 OPEN; +CREATE INDEX b ON t1 (b); +HANDLER t1 READ FIRST; +ERROR 42S02: Unknown table 't1' in HANDLER +# -- DROP INDEX +HANDLER t1 OPEN; +DROP INDEX b ON t1; +HANDLER t1 READ FIRST; +ERROR 42S02: Unknown table 't1' in HANDLER +# -- TRUNCATE TABLE +HANDLER t1 OPEN; +TRUNCATE TABLE t1; +HANDLER t1 READ FIRST; +ERROR 42S02: Unknown table 't1' in HANDLER # -- DROP TABLE HANDLER t1 OPEN; DROP TABLE t1; === modified file 'mysql-test/r/temp_table.result' --- a/mysql-test/r/temp_table.result 2010-11-29 14:13:07 +0000 +++ b/mysql-test/r/temp_table.result 2010-12-22 15:23:28 +0000 @@ -223,6 +223,10 @@ CREATE TEMPORARY TABLE bug48067.t1 (c1 i DROP DATABASE bug48067; DROP TEMPORARY table bug48067.t1; End of 5.1 tests +# +# Test that admin statements work for temporary tables. +# +DROP TABLE IF EXISTS t1,t2; CREATE TEMPORARY TABLE t1(a INT); CREATE TEMPORARY TABLE t2(b INT); CREATE TEMPORARY TABLE t3(c INT); @@ -266,3 +270,4 @@ Table Op Msg_type Msg_text test.t1 repair status OK test.t2 repair status OK test.t3 repair status OK +DROP TABLES t1, t2, t3; === modified file 'mysql-test/suite/innodb/r/innodb_mysql.result' --- a/mysql-test/suite/innodb/r/innodb_mysql.result 2010-11-26 13:46:21 +0000 +++ b/mysql-test/suite/innodb/r/innodb_mysql.result 2010-12-22 15:23:28 +0000 @@ -2830,4 +2830,17 @@ PACK_KEYS=0; CREATE INDEX a ON t1 (a); CREATE INDEX c on t1 (c); DROP TABLE t1; +# +# Additional coverage for refactoring which is made as part +# of fix for bug #27480 "Extend CREATE TEMPORARY TABLES privilege +# to allow temp table operations". +# +# Check that OPTIMIZE table works for temporary InnoDB tables. +DROP TABLE IF EXISTS t1; +CREATE TEMPORARY TABLE t1 (a INT) ENGINE=InnoDB; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +DROP TABLE t1; End of 6.0 tests === modified file 'mysql-test/suite/innodb/t/innodb_mysql.test' --- a/mysql-test/suite/innodb/t/innodb_mysql.test 2010-11-23 11:04:47 +0000 +++ b/mysql-test/suite/innodb/t/innodb_mysql.test 2010-12-22 15:23:28 +0000 @@ -992,4 +992,19 @@ CREATE INDEX c on t1 (c); DROP TABLE t1; + +--echo # +--echo # Additional coverage for refactoring which is made as part +--echo # of fix for bug #27480 "Extend CREATE TEMPORARY TABLES privilege +--echo # to allow temp table operations". +--echo # +--echo # Check that OPTIMIZE table works for temporary InnoDB tables. +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TEMPORARY TABLE t1 (a INT) ENGINE=InnoDB; +OPTIMIZE TABLE t1; +DROP TABLE t1; + + --echo End of 6.0 tests === modified file 'mysql-test/suite/rpl/r/rpl_create_if_not_exists.result' --- a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result 2010-08-30 08:40:42 +0000 +++ b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result 2010-12-22 15:23:28 +0000 @@ -126,3 +126,17 @@ show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info DROP VIEW v1; DROP TABLE t1, t2; +# +# Test case which has failed on assertion after refactoring which was +# made as part of fix for bug #27480 "Extend CREATE TEMPORARY TABLES +# privilege to allow temp table operations". +# +CREATE TEMPORARY TABLE t1 (id int); +CREATE TABLE IF NOT EXISTS t2 LIKE t1; +# The below statement should succeed with warning and +# should not crash due to failing assertion. +CREATE TABLE IF NOT EXISTS t2 LIKE t1; +Warnings: +Note 1050 Table 't2' already exists +# Clean-up. +DROP TABLE t1, t2; === modified file 'mysql-test/suite/rpl/t/rpl_create_if_not_exists.test' --- a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test 2010-08-30 08:40:42 +0000 +++ b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test 2010-12-22 15:23:28 +0000 @@ -173,4 +173,21 @@ DROP VIEW v1; DROP TABLE t1, t2; + +--echo # +--echo # Test case which has failed on assertion after refactoring which was +--echo # made as part of fix for bug #27480 "Extend CREATE TEMPORARY TABLES +--echo # privilege to allow temp table operations". +--echo # +CREATE TEMPORARY TABLE t1 (id int); +CREATE TABLE IF NOT EXISTS t2 LIKE t1; +--echo # The below statement should succeed with warning and +--echo # should not crash due to failing assertion. +CREATE TABLE IF NOT EXISTS t2 LIKE t1; +--echo # Clean-up. +DROP TABLE t1, t2; +sync_slave_with_master; +connection master; + + source include/master-slave-end.inc; === modified file 'mysql-test/t/alter_table.test' --- a/mysql-test/t/alter_table.test 2010-07-26 09:22:38 +0000 +++ b/mysql-test/t/alter_table.test 2010-12-22 15:23:28 +0000 @@ -1144,3 +1144,18 @@ INSERT INTO t1 VALUES (1, 1), (2, 2); ALTER TABLE t1 CHANGE a id INT; --disable_info DROP TABLE t1; + + +--echo # +--echo # Additional coverage for refactoring which is made as part +--echo # of fix for bug #27480 "Extend CREATE TEMPORARY TABLES privilege +--echo # to allow temp table operations". +--echo # +--echo # At some point the below test case failed on assertion. +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TEMPORARY TABLE t1 (i int) ENGINE=MyISAM; +--error ER_ILLEGAL_HA +ALTER TABLE t1 DISCARD TABLESPACE; +DROP TABLE t1; === modified file 'mysql-test/t/handler_myisam.test' --- a/mysql-test/t/handler_myisam.test 2010-11-29 14:13:07 +0000 +++ b/mysql-test/t/handler_myisam.test 2010-12-22 15:23:28 +0000 @@ -98,19 +98,21 @@ DROP TABLE t1; --echo # ---echo # Bug#27480 +--echo # Additional coverage for refactoring which is made as part +--echo # of fix for bug #27480 "Extend CREATE TEMPORARY TABLES privilege +--echo # to allow temp table operations". --echo # +--echo # Check that DDL on temporary table properly closes HANDLER cursors +--echo # for this table belonging to the same connection. CREATE TEMPORARY TABLE t1 AS SELECT 1 AS f1; --echo # -- CREATE TABLE HANDLER t1 OPEN; -CREATE TABLE t2 SELECT * FROM t1; +CREATE TEMPORARY TABLE IF NOT EXISTS t1 SELECT 1 AS f1; --error ER_UNKNOWN_TABLE HANDLER t1 READ FIRST; -DROP TABLE t2; - --echo # -- REPAIR TABLE HANDLER t1 OPEN; REPAIR TABLE t1; @@ -141,6 +143,24 @@ ALTER TABLE t1 ADD COLUMN b INT; --error ER_UNKNOWN_TABLE HANDLER t1 READ FIRST; +--echo # -- CREATE INDEX +HANDLER t1 OPEN; +CREATE INDEX b ON t1 (b); +--error ER_UNKNOWN_TABLE +HANDLER t1 READ FIRST; + +--echo # -- DROP INDEX +HANDLER t1 OPEN; +DROP INDEX b ON t1; +--error ER_UNKNOWN_TABLE +HANDLER t1 READ FIRST; + +--echo # -- TRUNCATE TABLE +HANDLER t1 OPEN; +TRUNCATE TABLE t1; +--error ER_UNKNOWN_TABLE +HANDLER t1 READ FIRST; + --echo # -- DROP TABLE HANDLER t1 OPEN; DROP TABLE t1; === modified file 'mysql-test/t/temp_table.test' --- a/mysql-test/t/temp_table.test 2010-11-29 14:13:07 +0000 +++ b/mysql-test/t/temp_table.test 2010-12-22 15:23:28 +0000 @@ -252,8 +252,12 @@ DROP TEMPORARY table bug48067.t1; --echo End of 5.1 tests -# Check admin statements. - +--echo # +--echo # Test that admin statements work for temporary tables. +--echo # +--disable_warnings +DROP TABLE IF EXISTS t1,t2; +--enable_warnings CREATE TEMPORARY TABLE t1(a INT); CREATE TEMPORARY TABLE t2(b INT); CREATE TEMPORARY TABLE t3(c INT); @@ -288,3 +292,5 @@ INSERT INTO t2 VALUES (11), (12), (13); INSERT INTO t3 VALUES (101), (102), (103); REPAIR TABLE t1, t2, t3; + +DROP TABLES t1, t2, t3; === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2010-11-29 16:55:45 +0000 +++ b/sql/log_event.cc 2010-12-22 15:23:28 +0000 @@ -5302,7 +5302,8 @@ int Load_log_event::do_apply_event(NET* update it inside mysql_load(). */ List tmp_list; - if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list, + if (open_temporary_table_list(thd, &tables) || + mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list, handle_dup, ignore, net != 0)) thd->is_slave_error= 1; if (thd->cuted_fields) === modified file 'sql/sql_admin.cc' --- a/sql/sql_admin.cc 2010-12-14 09:15:37 +0000 +++ b/sql/sql_admin.cc 2010-12-22 15:23:28 +0000 @@ -17,7 +17,6 @@ #include "keycaches.h" // get_key_cache #include "sql_base.h" // Open_table_context #include "lock.h" // MYSQL_OPEN_* -#include "sql_handler.h" // mysql_ha_rm_tables #include "partition_element.h" // PART_ADMIN #include "sql_partition.h" // set_part_state #include "transaction.h" // trans_rollback_stmt @@ -565,6 +564,13 @@ static bool mysql_admin_table(THD* thd, HA_ADMIN_NEEDS_ALTER)) { DBUG_PRINT("admin", ("recreating table")); + /* + Temporary table are always created by current server so they never + require upgrade. So we don't need to pre-open them before calling + mysql_recreate_table(). + */ + DBUG_ASSERT(! table->table->s->tmp_table); + trans_rollback_stmt(thd); trans_rollback(thd); close_thread_tables(thd); @@ -723,7 +729,9 @@ send_result_message: *save_next_global= table->next_global; table->next_local= table->next_global= 0; tmp_disable_binlog(thd); // binlogging is done by caller if wanted - result_code= mysql_recreate_table(thd, table); + /* Don't forget to pre-open temporary tables. */ + result_code= (open_temporary_table_list(thd, table) || + mysql_recreate_table(thd, table)); reenable_binlog(thd); /* mysql_recreate_table() can push OK or ERROR. @@ -737,14 +745,15 @@ send_result_message: trans_commit(thd); close_thread_tables(thd); thd->mdl_context.release_transactional_locks(); - if (!result_code && // recreation went ok - !table->table) // not a temporary table opened above + /* Clear references to TABLE and MDL_ticket after releasing them. */ + table->table= NULL; + table->mdl_request.ticket= NULL; + if (!result_code) // recreation went ok { - /* Clear the ticket released above. */ - table->mdl_request.ticket= NULL; DEBUG_SYNC(thd, "ha_admin_open_ltable"); table->mdl_request.set_type(MDL_SHARED_WRITE); - if ((table->table= open_ltable(thd, table, lock_type, 0))) + if (!open_temporary_table_list(thd, table) && + (table->table= open_n_lock_single_table(thd, table, lock_type, 0))) { result_code= table->table->file->ha_analyze(thd, check_opt); if (result_code == HA_ADMIN_ALREADY_DONE) === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2010-12-14 15:31:57 +0000 +++ b/sql/sql_base.cc 2010-12-22 15:23:28 +0000 @@ -2621,8 +2621,7 @@ bool open_table(THD *thd, TABLE_LIST *ta if (thd->killed) DBUG_RETURN(TRUE); - key_length= (create_table_def_key(thd, key, table_list, 1) - - TMP_TABLE_KEY_EXTRA); + key_length= create_table_def_key(thd, key, table_list, 0); /* If we're in pre-locked or LOCK TABLES mode, let's try to find the @@ -4303,7 +4302,7 @@ open_and_process_table(THD *thd, LEX *le (TABLE_LIST::table is not NULL), that TABLE object must be a pre-opened temporary table. */ - DBUG_ASSERT(is_temporary_table(tables->table)); + DBUG_ASSERT(is_temporary_table(tables)); } else if (tables->open_type == OT_TEMPORARY_ONLY) { @@ -5973,6 +5972,9 @@ static void update_field_dependencies(TH of this thread. Temporary tables are thread-local and "shadow" base tables with the same name. + @note In most cases one should use open_temporary_tables() instead + of this call. + @note One should finalize process of opening temporary table for table list element by calling open_and_process_table(). This function is responsible for table version checking and handling of merge @@ -5998,16 +6000,21 @@ bool open_temporary_table(THD *thd, TABL */ DBUG_ASSERT(tl->table == NULL); + /* + This function should not be called for cases when derived or I_S + tables can be met since table list elements for such tables can + have invalid db or table name. + Instead open_temporary_table_list() should be used. + */ + DBUG_ASSERT(!tl->derived && !tl->schema_table); + if (tl->open_type == OT_BASE_ONLY) { DBUG_PRINT("info", ("skip_temporary is set")); DBUG_RETURN(FALSE); } - char table_key[MAX_DBKEY_LENGTH]; - uint table_key_length= create_table_def_key(thd, table_key, tl, 1); - - TABLE *table= find_temporary_table(thd, table_key, table_key_length); + TABLE *table= find_temporary_table(thd, tl); if (!table) { @@ -6050,12 +6057,33 @@ bool open_temporary_table(THD *thd, TABL } +/** + Pre-open temporary tables corresponding to table list elements. + + @note One should finalize process of opening temporary tables + by calling open_tables(). This function is responsible + for table version checking and handling of merge tables. + + @return Error status. + @retval FALSE On success. If a temporary tables exists for the + given element, tl->table is set. + @retval TRUE On error. my_error() has been called. +*/ + bool open_temporary_table_list(THD *thd, TABLE_LIST *tl_list) { DBUG_ENTER("open_temporary_table_list"); for (TABLE_LIST *tl= tl_list; tl; tl= tl->next_global) { + if (tl->derived || tl->schema_table) + { + /* + Derived and I_S tables will be handled by a later call to open_tables(). + */ + continue; + } + if (open_temporary_table(thd, tl)) DBUG_RETURN(TRUE); } === modified file 'sql/sql_base.h' --- a/sql/sql_base.h 2010-12-14 09:15:37 +0000 +++ b/sql/sql_base.h 2010-12-22 15:23:28 +0000 @@ -572,27 +572,12 @@ private: /** - Indicate if a TABLE instance represents a temporary table. -*/ - -inline bool is_temporary_table(TABLE *table) -{ - /* - NOTE: 'table->s' might be NULL for specially constructed TABLE_LIST - instances, like for SHOW TRIGGERS LIKE ... - */ - - return table->s && table->s->tmp_table != NO_TMP_TABLE; -} - - -/** - Indicate if a TABLE_LIST instance represents a temporary table. + Check if a TABLE_LIST instance represents a pre-opened temporary table. */ inline bool is_temporary_table(TABLE_LIST *tl) { - return tl->table ? is_temporary_table(tl->table) : FALSE; + return tl->table ? (tl->table->s->tmp_table != NO_TMP_TABLE) : FALSE; } === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2010-12-06 10:36:38 +0000 +++ b/sql/sql_class.h 2010-12-22 15:23:28 +0000 @@ -3703,7 +3703,7 @@ public: #define CF_PREOPEN_TMP_TABLES (1U << 10) /** - Identfies statements for which open handlers should be closed in the + Identifies statements for which open handlers should be closed in the beginning of the statement. */ #define CF_HA_CLOSE (1U << 11) === modified file 'sql/sql_handler.cc' --- a/sql/sql_handler.cc 2010-12-14 09:15:37 +0000 +++ b/sql/sql_handler.cc 2010-12-22 15:23:28 +0000 @@ -287,7 +287,11 @@ bool mysql_ha_open(THD *thd, TABLE_LIST */ DBUG_ASSERT(! hash_tables->table); - error= open_temporary_table(thd, hash_tables); + /* + TODO/FIXME: In the upcoming patch we somehow should handle + situation with privilege check for temporary table. + */ + error= open_temporary_table_list(thd, hash_tables); if (!error) error= open_tables(thd, &hash_tables, &counter, 0); === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2010-12-14 09:15:37 +0000 +++ b/sql/sql_parse.cc 2010-12-22 15:23:28 +0000 @@ -369,7 +369,7 @@ void init_update_queries(void) sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_GRANTS]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND; - sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND; + sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND; sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND; @@ -455,7 +455,6 @@ void init_update_queries(void) them, but which are not listed here. The thing is that the order of pre-opening temporary tables for those statements is somewhat custom. */ - sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_CREATE_INDEX]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_PREOPEN_TMP_TABLES; @@ -484,9 +483,11 @@ void init_update_queries(void) sql_command_flags[SQLCOM_ASSIGN_TO_KEYCACHE]|= CF_PREOPEN_TMP_TABLES; /* - DDL statements should start with closing opened handlers. - */ + DDL statements that should start with closing opened handlers. + We use this flag only for statements for which open HANDLERs + have to be closed before emporary tables are pre-opened. + */ sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_HA_CLOSE; sql_command_flags[SQLCOM_ALTER_TABLE]|= CF_HA_CLOSE; sql_command_flags[SQLCOM_TRUNCATE]|= CF_HA_CLOSE; @@ -1252,7 +1253,7 @@ bool dispatch_command(enum enum_server_c thd->set_query(fields, query_length); general_log_print(thd, command, "%s %s", table_list.table_name, fields); - if (open_temporary_table(thd, &table_list)) + if (open_temporary_table_list(thd, &table_list)) break; if (check_table_access(thd, SELECT_ACL, &table_list, @@ -2072,9 +2073,25 @@ mysql_execute_command(THD *thd) DEBUG_SYNC(thd,"before_execute_sql_command"); #endif + /* + Close tables open by HANDLERs before executing DDL statement + which is going to affect those tables. + + This should happen before temporary tables are pre-opened as + otherwise we will get errors about attempt to re-open tables + if table to be changed is open through HANDLER. + + Note that even although this is done before any privilege + checks there is no security problem here as closing open + HANDLER doesn't require any privileges anyway. + */ if (sql_command_flags[lex->sql_command] & CF_HA_CLOSE) mysql_ha_rm_tables(thd, all_tables); + /* + Pre-open temporary tables to simplify privilege checking + for statements which need this. + */ if (sql_command_flags[lex->sql_command] & CF_PREOPEN_TMP_TABLES) { if (open_temporary_table_list(thd, all_tables)) @@ -2382,6 +2399,10 @@ case SQLCOM_PREPARE: goto end_with_restore_list; } + /* + Pre-open temporary tables from UNION clause to simplify privilege + checking for them. + */ if (lex->create_info.merge_list.elements) { if (open_temporary_table_list( @@ -3218,12 +3239,10 @@ end_with_restore_list: Here we have to pre-open temporary tables for LOCK TABLES. CF_PREOPEN_TMP_TABLES is not set for this SQL statement simply - because LOCK TABLES calls close_thread_tables() firstly (it's called - from release_transactional_locks() above). - - close_thread_tables() closes all open tables, so even if - CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened in a - usual way, they would be closed by close_thread_tables(). + because LOCK TABLES calls close_thread_tables() as a first thing + (it's called from unlock_locked_tables() above). So even if + CF_PREOPEN_TMP_TABLES was set and the tables would be pre-opened + in a usual way, they would have been closed. */ if (open_temporary_table_list(thd, all_tables)) @@ -4630,6 +4649,7 @@ bool check_single_table_access(THD *thd, &all_tables->grant.m_internal, 0, no_errors)) goto deny; + /* Show only 1 table for check_grant */ if (!(all_tables->belong_to_view && (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) && @@ -4953,6 +4973,12 @@ static bool check_show_access(THD *thd, DBUG_ASSERT(dst_table); + /* + TODO/FIXME: In the upcoming patch we somehow should handle + situation when table in question is a temporary + table. + */ + if (check_access(thd, SELECT_ACL, dst_table->db, &dst_table->grant.privilege, &dst_table->grant.m_internal, === modified file 'sql/sql_partition_admin.cc' --- a/sql/sql_partition_admin.cc 2010-11-16 00:55:42 +0000 +++ b/sql/sql_partition_admin.cc 2010-12-22 15:23:28 +0000 @@ -20,7 +20,6 @@ #include "sql_cmd.h" // Sql_cmd #include "sql_alter.h" // Sql_cmd_alter_table #include "sql_partition.h" // struct partition_info, etc. -#include "sql_handler.h" // mysql_ha_rm_tables #include "sql_base.h" // open_and_lock_tables, etc #include "debug_sync.h" // DEBUG_SYNC #include "sql_truncate.h" // mysql_truncate_table, @@ -492,9 +491,6 @@ bool Sql_cmd_alter_table_exchange_partit partition_name= alter_info->partition_names.head(); - /* Clear open tables from the threads table handler cache */ - mysql_ha_rm_tables(thd, table_list); - /* Don't allow to exchange with log table */ swap_table_list= table_list->next_local; if (check_if_log_table(swap_table_list->db_length, swap_table_list->db, === modified file 'sql/sql_show.cc' --- a/sql/sql_show.cc 2010-12-14 09:15:37 +0000 +++ b/sql/sql_show.cc 2010-12-22 15:23:28 +0000 @@ -3635,8 +3635,6 @@ int get_all_tables(THD *thd, TABLE_LIST show_table_list->i_s_requested_object= schema_table->i_s_requested_object; DEBUG_SYNC(thd, "before_open_in_get_all_tables"); - if (open_temporary_table_list(thd, show_table_list)) - goto err; res= open_normal_and_derived_tables(thd, show_table_list, (MYSQL_OPEN_IGNORE_FLUSH | MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL | === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2010-12-14 09:15:37 +0000 +++ b/sql/sql_table.cc 2010-12-22 15:23:28 +0000 @@ -4800,6 +4800,7 @@ bool mysql_create_like_table(THD* thd, T String query(buf, sizeof(buf), system_charset_info); query.length(0); // Have to zero it since constructor doesn't Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); + bool new_table= FALSE; // Whether newly created table is open. /* The condition avoids a crash as described in BUG#48506. Other @@ -4808,14 +4809,20 @@ bool mysql_create_like_table(THD* thd, T */ if (!table->view) { - /* - Here we open the destination table, on which we already have - exclusive metadata lock. This is needed for store_create_info() - to work. The table will be closed by close_thread_table() at - the end of this branch. - */ - if (open_table(thd, table, thd->mem_root, &ot_ctx)) - goto err; + if (!table->table) + { + /* + In order for store_create_info() to work we need to open + destination table if it is not already open (i.e. if it + has not existed before). We don't need acquire metadata + lock in order to do this as we already hold exclusive + lock on this table. The table will be closed by + close_thread_table() at the end of this branch. + */ + if (open_table(thd, table, thd->mem_root, &ot_ctx)) + goto err; + new_table= TRUE; + } int result __attribute__((unused))= store_create_info(thd, table, &query, @@ -4825,13 +4832,16 @@ bool mysql_create_like_table(THD* thd, T if (write_bin_log(thd, TRUE, query.ptr(), query.length())) goto err; - DBUG_ASSERT(thd->open_tables == table->table); - /* - When opening the table, we ignored the locked tables - (MYSQL_OPEN_GET_NEW_TABLE). Now we can close the table without - risking to close some locked table. - */ - close_thread_table(thd, &thd->open_tables); + if (new_table) + { + DBUG_ASSERT(thd->open_tables == table->table); + /* + When opening the table, we ignored the locked tables + (MYSQL_OPEN_GET_NEW_TABLE). Now we can close the table + without risking to close some locked table. + */ + close_thread_table(thd, &thd->open_tables); + } } } else // Case 1 @@ -4854,9 +4864,9 @@ err: static int mysql_discard_or_import_tablespace(THD *thd, TABLE_LIST *table_list, - enum tablespace_op_type tablespace_op) + Alter_info *alter_info) { - TABLE *table; + Alter_table_prelocking_strategy alter_prelocking_strategy(alter_info); my_bool discard; int error; DBUG_ENTER("mysql_discard_or_import_tablespace"); @@ -4868,21 +4878,30 @@ mysql_discard_or_import_tablespace(THD * thd_proc_info(thd, "discard_or_import_tablespace"); - discard= test(tablespace_op == DISCARD_TABLESPACE); + discard= test(alter_info->tablespace_op == DISCARD_TABLESPACE); /* We set this flag so that ha_innobase::open and ::external_lock() do not complain when we lock the table */ thd->tablespace_op= TRUE; + /* + Adjust values of table-level and metadata which was set in parser + for the case general ALTER TABLE. + */ table_list->mdl_request.set_type(MDL_SHARED_WRITE); - if (!(table=open_ltable(thd, table_list, TL_WRITE, 0))) + table_list->lock_type= TL_WRITE; + /* Do not open views. */ + table_list->required_type= FRMTYPE_TABLE; + + if (open_and_lock_tables(thd, table_list, FALSE, 0, + &alter_prelocking_strategy)) { thd->tablespace_op=FALSE; DBUG_RETURN(-1); } - error= table->file->ha_discard_or_import_tablespace(discard); + error= table_list->table->file->ha_discard_or_import_tablespace(discard); thd_proc_info(thd, "end"); @@ -4913,7 +4932,7 @@ err: DBUG_RETURN(0); } - table->file->print_error(error, MYF(0)); + table_list->table->file->print_error(error, MYF(0)); DBUG_RETURN(-1); } @@ -5939,7 +5958,7 @@ bool mysql_alter_table(THD *thd,char *ne if (alter_info->tablespace_op != NO_TABLESPACE_OP) /* Conditionally writes to binlog. */ DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, - alter_info->tablespace_op)); + alter_info)); /* Code below can handle only base tables so ensure that we won't open a view. @@ -7328,7 +7347,7 @@ bool mysql_checksum_table(THD *thd, TABL /* Allow to open real tables only. */ table->required_type= FRMTYPE_TABLE; - if (open_temporary_table(thd, table) || + if (open_temporary_table_list(thd, table) || open_and_lock_tables(thd, table, FALSE, 0)) { t= NULL; === modified file 'sql/sql_truncate.cc' --- a/sql/sql_truncate.cc 2010-11-29 14:13:07 +0000 +++ b/sql/sql_truncate.cc 2010-12-22 15:23:28 +0000 @@ -18,7 +18,6 @@ #include "sql_class.h" // THD #include "sql_base.h" // open_and_lock_tables #include "sql_table.h" // write_bin_log -#include "sql_handler.h" // mysql_ha_rm_tables #include "datadict.h" // dd_recreate_table() #include "lock.h" // MYSQL_OPEN_* flags #include "sql_acl.h" // DROP_ACL --===============1672410697== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/dmitry.lenev@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: dmitry.lenev@stripped # target_branch: file:///home/dlenev/src/bzr/mysql-trunk-bugfixing-\ # bug27480/ # testament_sha1: 0ee20767e8b5d1907cacf24142f579ffd3dc211a # timestamp: 2010-12-22 18:23:49 +0300 # source_branch: file:///home/dlenev/src/bzr/mysql-trunk-bugfixing/ # base_revision_id: dmitry.lenev@stripped\ # 4g1febb7doxy9g8o # # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWVvcDIwAFE9/gFV1QID5//// /+/++r////5gI403xrk8Yc6z3TbVl3eee4nMg7d1pSdtVIV69Hd7uq3sd2M7Drqcvvt7265aK96u 97awaJDrON8gAA7tVemuhWgKdGg0ADTJsb21AD0FeEkhNRkZJmgyJ6NU8qe0nqRpsJo1MIBgmNEa aZNMyj1BKIACEwSYQmU8mqeoMhoNNAGg0yepppoAABpoBESGVPBT2kmgzJPUAAAAANAAAAEmpBCa UxI8mSnptGqB+VDyNCYI2oNMgBoAMQxBtUSeUzKjQADIAAAANGgANGgAGgASKBBMBBMRoAAQ1TMl NiZJoTaEPUGgAD9S+ILgyQl+y9/xdYMaRoi7JsaFrrWd1vQ+Mdr0tkd3r6+siL170rKxkKqv5ORo vdOwuN3ubRRZUeNzKafESySQa7BxGTc6MBwzEB3X/L7jCPjQX/ZRhPn/X8fDpPdX07093qk+V51u Ya1xzEsPnDPImMny6Y5ZTW49vVZqln68GH6YR+XuT7u5rVp62Sz4TnN9PZ5Zb5mJ8ORo1chmNj/v ZPfw0Qfj6bTBGva/bny49BWa3oyDi1yjAnqLRlvqS/NXvcy+BsXVy2r53VtZjHnDXEvmr3ex3l6v vvU0q80FjS9mH+qeu9yeUY41kpSi+uJLs6HYtbdV+km9YxwUweWdF67APiHpQ5VfqOI/25EHoFOw GJuVilnsLNo5MFexsAbBV2QAUKG7buIVyuFIc3CgbSXkLm1llt2qqcE6hnXVioq10VmU2JGcTOGE 5F2ViswuAcUtYqZMZ0Da9O9wgAQCEREQ2kNh/NrRgujxzA+9JL0A5W94qvRh6qvafcw6WpCxf+Ga 6xjx01dopi25/2oRH7IRkhDbBRVUUFUEYqqooqwUAUUhF9Sc3ohA6/L47Fufr8nkt18a/ya6X0Tb PC2eHY2N812Zo1aNq0c3MWqNtC+ca5KdBDZ0eCZS3oIZcYIxa5LSosuWeJLh4WS5FFLQLDi5pXFS sMMHJBIciGXOUSs9iTdO2Gs4BBLHJUiZUCSxLDDBrUNmnqFIilohimCtotOoQ3bRctgiGUEgthnK FVkaWxMFLIkFszSSPhIU83Puryq3CZxPY7DvObEDoC7jqzgunBdImAJg0HQJgso09qboE22KxnU7 u7OES+Awx3jerqvZ8BMdoRhTPYLNV//Q4C5y7LVCQFCRHIXwRD3gLWSFAHPORhQKjJFAUVtYZdQq D/Xp3f49Odh1jrd+sywFVAO+OhsQ31dwXxrx3I1JE6sgDYSgXn0wFXYMYMqLwNzM6uEbxQAzkKzl 14PWcNkEpKpP6aLLoyQ3zcMsJM5Ngd5efqrTaHk0nclYckmzHDaPbUryGSKFsEIqv5bwP5OumH8Q K4iu2UX8k+HUQM5UbJSW7GjdWJyuZtpypHe3dUlyR07vf7MG/aHDKwxRGyex67GWHFw1SYmhGLiT cm/dQQrZrM9d7FEXmsC4mOZxMED8xyvAvS3Js74nDbG27WQC7rsgcO1AgWYFVgzUM2PA5CxhoRgS sY6q+64RPG7mwEiMiTHhyd3Da4EEfEZRrBSme9CFGsoLFYDWS8TwFF2AtYQGNJjjAgQZAOgVla2X EDVLG75oKjk19SgjOfzQjRbRNCK3fBTkqUXFiM+hVXZA6ZEzC77eCHBka9AQIO0Bzi9u28QCdeUV saUlrm7XwBjcbGM0t+8qpnTeBgggLhRjt5UtUp2u46SRx0uuAcVrXbPLSBOcVYYiNyGF3OW8MBxV 4zfgj/n5KDcfNz87+XwO53xf4YO8ESEbj8H6+TxZ/vul6psmnHJLNf4uXQg0zobCGlFTiwmOLTcH t60I8MMzh+uybldTSlIz5pnh8AHcQDj6wFEkh8RKkVVVBBERVVEWMUViQ+z8RR/JJtuh0/bhcnus dRwdSz1K592uAp00om1CY+ZUTvxyUFNlFTQ3Q8fYQ6HnUefIsdiEgPgtm/G7cnSmsZZSkPUzsYdR ivVsL8CIfEofJvoMXZT5dxgk+GLFNFu3gvFuTxnMOg0XM5QhUozP5CuFmgR9L8Bs9T1PYYHT0F4i IxaOsKEj9D6wGhAdJ9zSHXeLb6exgJIiVG1YPcnBkQZAhBZbz2D0/dtLjicRAfMaVyrDAyPZmPeF CcxhjUeREecAOyAhobEEO2CISANphgSYWN04GWI+X4Nw9Pgsq4KuZzhVsRdc3+EscJezwbSin8ZW 7OBoI9/J5efji76OWi2lFhLiWE77gZAC3tb63qI1AkxiGcHHNBcuWsHOZJgyBL1SXqeKPU9fX1IS frBJH/ceOWCEaIR3nf39nN2yfCKDUIFRoqY2LvdbSDtdKQQS7JdDZ1aSFsUTVJf7TXnT3N1q+2vA D5MklBcDB2iZuUCCcjyDChliZv7F7GTASgiQAsEoEgAgUVO8mQMaG1rtFWSx8E5ijgJe1VSEx653 ziXiZMGbhublYNwyYuXOBnUR0KtcPOaY11adQmx3uBoCPgC6CO85BkQOMOj1ItcAMMAFLIC4o7BI tKSYrBVVVgrycwCaGlK1T/A9DAqMyqRq8Cg0yIHs+JxmVHOaY416YFCZ9ceR971nPI1cjQCySFkN ktVG7oA46a2caeDe2NsXt0Y46m4BV52TS7YIhAZEmS0a0KgoFRowREDRoNFFcQTTC/+hL9X7+xlC JeX2c8t5EgxaUrlUDOa+C2GQhbaDntXKqsYIALqaxRoqiadCsb1g5gzjByvfvVeGnOEqOkQujpoT Ny40cSHa8HDcCYUGGItUjU7LhUSRdUiIWRGgozE2EC5ooP57ak8WBAREMCYUEuQUC4YjdXmJmPJD mFuAZWKOhuaNHQViLdcIsJFR5BxQ99WJkGW7UDtoazQlW2mFZjvBby851BiTe5CIFZrNpcXnA1jJ GJwSDmMhki9lONBJby0mWHA6Qpr+pu4uKuSYClNX3Nuob3bhuIm6uppcticPB3ANxktrgqukUilQ ukREBLEWnFUq7C4x74FrRGiG5EQLEoVK4qJiSGFQkiczmoWFtAJspVSUXJUREOboUY/EGOkopBsR jHjmS7E7yuFbRW2T24G0SRSpu4kXyobMoyI1RLByyrIH7FhmtR+qDfItiRuWuTERBwFzbkSLkk2F 3HmZS5WMVuLBxsJEVdguiIC4BsWJE1GJUWkDIzkZjLyWPLmO9S4owJH1Lzcai87CZ0mJkbShE+4X BI6CZYx1w38PV2dRyiqcwGsZBjlc7V127Oa8bu5HUpmmbGjCwljigybXWVVm26EDnYE+54uxplIc SlUKMLnjEYURSBBKTGUIiiIg/sIPeRJEaGCjwfsRgsHRIYGQypYZjApBhNhSheQ80Kkh0MSwWGLT JmMC46ztLSxlgrAGsrTwNKaNyOFOvZBORmSspt4HibmxQm0ocEQgNHkjIyGhwGmBdJxxEjntOUvp E5IeOY7BWbC1IctdJIYzALOjZMCoiIdDyIP5gxRV35QzIP0m/uWLXOdKMuyUILfhp6t6LiYLVoOd ASSeU7NOF9zQ2tDY8mhYEgMwhg9bGZUiMaYdpNHgKopV2DRhUd33K3JmDXEMXDxl+R3Exx2EDQWT tOHM9w0SJcyLk7wJ7EdTvFvSbZTToZF0Iog9MhjA0UA0lBG6i4jRk9w+cpgPKoSImrm7SJ+0CBzw NCIzcM4jwqJlNNeIkhYdutUJFAYh5wb5abxWZDWZS7mdv8vRHPKmOlhPTzLUQMKKmNrrI4LwHBI3 hxmDUh+vYVIEyxgVJ0a/AiIiDBkzsLhpAeihYymdBAkLNfqkQOwiJIqecCzdAlXibCyFzLDQsSOs Shq1UfXVdSwDjbGFTW8QmUIyUcSl1GymuNUqTnmCmLEzKhkhxBQwMBlvkqiBzG4NBjg0ChAcToPe UCJEonQf5C9TtOI1PPcvmaJxSeHk4YVlE0UqDyXY2kSyvMrD+EKFQThikAuNAoNdMOs6TTjxNQ4n A7LUchumpc0MNnvnMeEdFDmSJLCVSQpAUoCitVLHUlNxEeROhSRS5RHCwp1aOL1G+tIJG5qPzPZO 7lOJkLTMrjCJI37oKIgvaaGZUxNTNTYt7uBuQDNMyY41HYQND07u0iYmh3G03dE0j0MzQZUeZQ26 8t3KVmFaX5ZNc56Ga8O0TNKzlpMhFAFoI2jIsBDzIQoKaHU1LOo45ECRcfC642bVxmiEY5Xkly3Q 3SRaEirAiCXKx4PTvhIY15mUOJAa2U2EMxg8sYGQ1SuZoOaQSmOOQ8LBI4UREMHGIpkUMiqZYRJm rQkYKJoGZRVWhvOJ3EJnccBJHEkjlQ1lfSdnG/LTePHNHGe6dI3OtuBJzcZc8zdEkhsVje0DTYvk C5Y3PCW6S4XLFGBDarJa8wvdh6lCMR01OvpamMsjoUOHrujgcWBsczCZ1GmkAg0lllOONSURQnoc B7BUzewXgQGK1jmDCaxXErRqYC4YSb3aV7sDY4EiJmZnRCqWkVKCmIT1GCvFsYykQkcfYHcd5d5k vDTYau77Ky3NIsMGszEiTMgJSrhJtYCEXPGEKBwmBDDQZJxoQq6mxnALE6tGanEUq99lx5GJ3jcu wtQFmXWEuNcjQZRzcAUiJoYZxqJmZWUNg8woYmZzFMjAyI2LGgwaTLk0qYkDxUaHENj6RrNVnobP 3muSY6QBX3QSiPWzGcwUQyi6NwxiJEiCSHVCExIrAVK3V6V/l+JdAr3k1CcH/NiynV8ZaxtWZonz uGvkLFihxvGrvWYKmuuef3iQ+rvfoT9PdU86cMP3OJnBTIoKKIgkRn4UIlAIogmMQDTabTbGai4P b+KEex9mCHZ7FLCRiMNqEE7eWqq96hB0lBHGldqWvUWBMCP8XlQETrCYIDAwwgvwFR8nLgK6BmST MDQDYOB/mISYVzwXcE1/fL+/DziWibAYDZjALyEyKfkD44Q+NiMeAxMQYghtgOLgFNvT8+Dmh/5h PAHOyfUrALST+0QbFHhxXINaVTI4heAG+pSKIDkK4GUmpJgGQUCgPEG/LSBAFcklf6uEDqBeuAjc NvDWaZwpB0Ec+gKC0aFiE8giBoDLO0X8TYq/+QLdM3hWi6h7xj36bhglwuf8+2gIbjXIINQCoa7k 2+QE95O9rzNuxIMsEAmbQ6v+Y2GIRExC1AFQQYZSCQWC7E5jJf/095vlrN2ZjvLaBoIGLC9eHkAt QFaDtNBTUiDSmAtrQF94OI7qdt0xVQNIGgN6qFoIWO7q5hBrCwNomG4VqAgG5mjURpSGMRGH71RG 8MDIKUX7brQruFSALnsNDWLVUHAgKZWmADG2gyZAafMhKZ6AoT8YPiZczwlJQVyrFCtR6WAlMBrD IgEr1zQWii9WolZCEQRoVoDowtcg+KeAacsbmL4SUoKLZ5dTStpWrokNJVWJglsJgZjWdGXJWGI1 3mltBkBkBSfiFD99ATVA+VHWg11t79z0zJVkPgh0+VDXpsRhRqQenCE4i0QqtkNFOoR05ao5Lc3y 5rSctkRUS5pmTBjTUvRx71b8ubATzLFeT5YtIl5JeU2JOfjk85dHP+7lyGFJERkI9OY/QcPP2FD5 UgQIFj5+KfIdRx7SQfCPJmB7RpoMOHWWGJWMmYaj35htNg2IGwBHSs1BIDgUFBiVoICDwIrIvKx6 xlAlMQF3RojMd0HB1OHYMNzoYDzAeczwE5kywTHYomigJuNoJmbCEnoHC/erIiDEPZiSoQNscHu8 zx/v0dAzD7zTUiYkcugSRzXqBSZPQilu28v80eABNVngR8jquvVS4ISO33A+pEFm1mCVJj1NpgQH z1liPmJlRVq1qsWtSAh4x7S+1ldqYK1YINVeufWUQbxJF9Kzerbb8Qh5khRNRrJD/TUFfUP1LC7z PM2+xT0N5Ql7lodR3+fsRXzO5RMjkYHE9zA6zX3jyMz6DQ1Jlx6IUNhGikh5YgSNhPQTltmEjQ6S vlYaDNReDMzMvQaj+yAlWbjQ7DsOBv8WhCXi0gO0+ZgjyLajgTP6Vk6vY7c7TZAD3OwwIrU5GBw/ iJL+tiQDh3IPZMSuInQdBgQIHeeXDwNRrfVEckCZ3nkdh5EjmdSZ3CmQVMyZkRLDCBgOGlTA8DAl memsiw8KlLnNEN0VEkmtRZlC4kf60kXm0zKzEyMiJ7rpPkbsAxGdozmGaj2NZjvPqYR0MdC0r8IW GB2nOX9ohstagWEOOg159vI6AA0eQwrgAyCgryHsrKAgGd/+6CD91ptRUdaSA+ZDxsrMsCCXoWXx PmY2pMinrOcpVMyHjM9l9J3V446ajVSDPNGHVRQjaiBEcYpwCTimiLUGp9XZGluCA8UgkGR3lD1D d152racSg4eeYpUcZHmeh5nmRHET0KnoT20JEd0RB5QnU1REH5HjY4zRBB5dW3NFayBmQLxMYB5m rq3iQ0icVEDKTkTcZjWJ4brhYeQWACdloHTmr8aipFz542soKy5w4hIl3LkmnpFqLTHr5Cxcl9fW wKgyCekd44xIZCHQMAGgJyw2mWCPGHv1WHuYh8F9sLTy2qX3si4iYpt/J/LqUnzgL53GAPImmbIK dAn0pqqXUSgQYcI2Ho7NLYDTNO9WqAbKEyMQOXA1GMiHghydb0YaulL6AehWF9U09TLPeBcxGTV1 sFnlAAiIZmyj7s4XgxkCAICCaAPoXH0e+Bj5H0PdUPod/d0HrUfGwiS3lZ5GjqlCC3wzpOuko76S zWhkZZROczMjxC08DacSYzUSOuPDa21mhHQhFCpgHOwhwoJEktYCgAbXEG+CgLlgeBNYFi7GGIki sICVReDNtx7JJViKBTuWHlDHNwli74MjqlnIKU6CrVYifZZN1xqqgvgfYXHadvdqCR1dzNxqLkjq OMQOo3QwKhZiW1cDkY2Ld37+x8/zgdePmmsReZ15sxZmojE2IP3sVbEHcGTLiqMXAgg7e2CS2qow aCySKfjcIScoSL9lcE7k0I4QV0gJJI9hi5yU76sYKMdSaGPxkBEGgkLjegqN+q/yVxd+jKzPYH0P iIZGNLEsJBA3QS6+7CcuXfCLBFNJuokQKN6bToBgFrAjrjRJd117pCEYmEw794JK/WbVH86ALSIP 8phUioUDIEi0uMH1mOMjUC+u1BAY2vLdy9BJfI9iBM9HSkzQgeo/nM9TNIyJnOFC8iTLTUXnywPj 4iYlh6FDUTiWFxUXaxWBQiBcM0F2Go+DMzMCZWUFcZ51ePMieBQURB4K6GREvEeaERpE4CIR4EvN IpKY+1COI5kIgIDRuGOF+vYZRL7TGbUoiD8WfkxQaNomue8gWm5Sid5E3GOw8r1EBgTYSHNmMIP+ w2HCqDUG1SqgsNW0qL9eYRhS7Tk+MUwFbDdNwNpVuLiBsN5Yv/28xPqS+1EatEjDrzNhxqyq8BJ2 zYPyJDGgYqTyFOgxiTme4cikTLjA/E9OIVFLEJHjsXith6jIqjDc6wH4t3GD1DEA8yeyICh3Y/ZB C0T3ffbbpZPEdpiJXEkWjGwxPA4nwVHQeZgklhYb0J+uwiuJ4Jkw7j2RceRkXrnBIPsQrSIXQNx5 HtYewz4IkGwqo0JKHZkO3OYS4vqSESmt8xQS5ivueHzj/HwwYineK4SLMjtKQNd6AD6BgJM0VaND VYF7DtFUKIfnrKXgAjcO6ojtspdg5oqzVbHqeNY/SpgB98lSoD24jZorRhXtOfGX199klcwGxMSG m0kzr8uw8A4W702m2IbGiN25UBro5AKefFIN4rSzChWLFWi4gkplo2HFiXmZAbxrL6VmTsQiE6x/ ge6kbT8ImBzl+hUdJMgep1mhAiMPf7uhE982PqpbE4mpsd548/dcKArNmz8A6jPsSR0GJlaKSqSG ePafmuMQFJdbWZivmojKil14hOJIwc2E1FJrKFs1hoiOE1bOgWm+kOSaTSoG4zLF2DQilVyq2tWJ HETENkmoMC0W0w2Lg7ok02Cyt1HwrhpG1CGkkNtgFgIBgoIQxNCGgNGL6qqmZQGxKclLuQJdEEiS QGy5GhE1kWMttKoaFiAmaEi05FamejREYjW65GuBb9mQzXvqNIm3YwUDFAzcXhH0N5kkv1mCe8Ck azbzDj58chYcDnVMFwOwz4e51FVy25jSQDIh6Gh/UTmugDoMIQwWzMWXyVMJDDpQV2Opya0rGRmF dPEOQJURWU5kio5G4sPUgkXctxkg05wgLQSMCAJPakQ1nQeVyxOk9egvSSMucMP2gL7H7WAY1vc9 NGoOJSF6lVU+NLT004CyX8UtgRC+CrOjQdCN1jIsKBoRjr9jcjn7z8juKhIrtRBQeyCA3kpCd+8S JlxK0sKHTioTqgeBIgRQMG5AJptFrSThth4qaLgjBCSh9X+LqBIrnQigdwGUz1EBgOUo9S4sY+8G +F8VGERS5KoXq7B3lxI9SpI6DMiYmiRikYLHWiAmhtCGOLUGAD6hh2njI4ncPJXYJJPzAP8mfJo3 tHLpnGgaDyPkMyNDaaE0i4Plf4GoihVkxeZL94ZLqQv0rU+0ny+hVqq7jfmWl6SAyQw5KwGJprhe QQlNiLoz+lxCtUQU2xWBzYl5gd9ovETXm36KFof70VcUZDSdxR6vWXC1QCkphKDqZb5ggIoFoCVC go8tcYgdaILZqNVhtHUtxxYLyOwvS4f2QF/gNP+uXeuzDUaNDaXSx6CgYIVsFqVp1hgZFxYaVI+d dSDrHtQCztEkdxl5mlQj8ys58ftBCGkjpUEDTXqYFSOiwSNh0n7jczASRsCpoSNiRAtzKGnOBMuP EuLjI2EwSo392ricTAgRIUSKxbV8/OKQb/4FSq2huPUxOo78kjzGbjrXMVLxNpWdRamYm9CFkMDU YF5WdK6r0jpCZv5n1tYjLTqOaI0k2zogKBBkEA2j8uQQim0vsM1nEg0eJ3Gol3OtMQMEBscBMBO8 gCWJyUkGhxzVD9IQ76QThEjB7f8VvFqJcy0CIlTcOdfAiIrWrS5CRKt/j4UwpXXVs/BC+P5fSbPT 9YiRcGg+l5+IpAYU8SgREu+aSK1iYkGWlIuGMRIkbiUtbcUDlmBavNtZqZhdhAP8mlBMwByOuIEm 5JQUFeEfmayHhRTpBJOAhJwEYnaWz6vp/O2tk9cW6IkoSwnJQlmj6LnbivNirFa8oy9osC9ewy0s Ao8GzMZsYbKPHxAUAs7R1xXLtUPRuUzhnDJ980PWNCtzp2prpVsA7DMSRzKKyMDVfBPeDJxM2xo7 Zq1hS2urvLhVVFhBfHaf7CSqSPhpHahFSEyrqMxBXi7GfEAsw3o68cUIhvqIllZBDSTmgOkscvnY dXVzH3ZA7VVVVVVVVVV1DqkOwCxQ3SjWqL1Reiw2FLULYDE6IpOrpLA85Rw6KhZSXSUAghMbkPga kqyZLiAnsU0WRCJNJe5Gn3mh8vO7ViL64JXZPFcoCCGdu8GtRYxCtb0RXwisBxC+JPU2d6BUGqBq IjslJcEEEOlDol3apaeI6AJzIYCwYQa/9DXyXZ5W1XmFzE0IuW0Qhozob8rO5IsgVApoEqonsp7V i3w0feZkAy/0hAD9JCgmm1+jSgKNUCEUoTzLxLl9jANE2c7gtGlEaoDErUHP5DZAAuEe24sQVfuU rDeJVnShsDuIgWyEIh5rAPdyA3CTe6CA2vWxKulij7JGVPuMqY9Oz0PBbOMozJeKuBkQxQRQQWRl 2bIQZD8NFE6RpKDQsbhCuAwWouEkRUlLNdGKQlIkNpM+wq/zJJIso2exwIjPcuX1Raiq8LzaHMkc xblwIkF6NmWpV4H547wP6PJ7ys6SsLHcRIEcBioku6iS0MCBvUh8e0vKiKoQ3q8z+/AgmcxOsbx/ qhkVHekfIobABaHoWc7+3SXyuYhLE5saHCoKnAKhsKJ75iqxKCmKbnRJQoIjAEUgXMU2Go02O0cR uAMEhpoR/DgSWo6hNHRlsPg2H8ygGpo+bBciZuIqDDV785h0mizO4rSs2iSOkr6ys+XQA+M7xh1F ZvWCxOBOsRwFWLfiXkdUCY4i6T/E8iZaXFWBUVgkfwQeBrB7W063UnzEJQqduA85pKd1kG75NwYh LliajpPE3h+ZSusRmeRwLzWbTmLzoaimRQuHLQed+4QOB1ISRAyxFLbF1PiKE/MvulqkXHHAmjid LPJiRguBjcqHwZHtovMrOBw/gfQNoPef+LuSKcKEgt7gZGA= --===============1672410697==--