From: Date: March 27 2009 5:08pm Subject: bzr commit into mysql-5.1-bugteam branch (kristofer.pettersson:2842) Bug#40127 List-Archive: http://lists.mysql.com/commits/70728 X-Bug: 40127 Message-Id: <0KH6006UGA2EVKC0@fe-emea-09.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_jGAkf7Pmdvve8lcM5NuWTA)" --Boundary_(ID_jGAkf7Pmdvve8lcM5NuWTA) MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: inline #At file:///home/thek/Development/cpp/mysqlbzr/51-bug40127/ based on revid:gni@stripped 2842 Kristofer Pettersson 2009-03-27 Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 The server crashes on an assert in net_end_statement indicating that the Diagnostics area wasn't set properly during execution. This happened on a multi table DELETE operation using the IGNORE keyword. The keyword is suppose to allow for execution to continue on a best effort despite some non-fatal errors. Instead execution stopped and no client response was sent which would have led to a protocol error if it hadn't been for the assert. This patch corrects this issue by checking for the existence of an IGNORE option before setting an error state during row-by-row delete iteration. @ mysql-test/r/innodb_mysql.result * Added test case for bug40127 @ mysql-test/t/innodb_mysql.test * Added test case for bug40127 @ sql/sql_delete.cc * IGNORE option wasn't implemented in multi_delete::send_data and multi_delete::do_deletes modified: mysql-test/r/innodb_mysql.result mysql-test/t/innodb_mysql.test sql/sql_delete.cc === modified file 'mysql-test/r/innodb_mysql.result' --- a/mysql-test/r/innodb_mysql.result 2009-02-20 09:50:50 +0000 +++ b/mysql-test/r/innodb_mysql.result 2009-03-27 16:08:14 +0000 @@ -1846,4 +1846,149 @@ id TRUNCATE TABLE t2; DROP TABLE t2; DROP TABLE t1; +# +# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 +# +CREATE TABLE t1 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +PRIMARY KEY (id) +) ENGINE=InnoDB; +CREATE TABLE t2 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +aid INT UNSIGNED NOT NULL, +PRIMARY KEY (id), +FOREIGN KEY (aid) REFERENCES t1 (id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( +bid INT UNSIGNED NOT NULL, +FOREIGN KEY (bid) REFERENCES t2 (id) +) ENGINE=InnoDB; +CREATE TABLE t4 ( +a INT +) ENGINE=InnoDB; +CREATE TABLE t5 ( +a INT +) ENGINE=InnoDB; +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t2 (id, aid) VALUES (1, 1),(2,1),(3,1),(4,1); +INSERT INTO t3 (bid) VALUES (1); +INSERT INTO t4 VALUES (1),(2),(3),(4),(5); +INSERT INTO t5 VALUES (1); +DELETE t5 FROM t4 LEFT JOIN t5 ON t4.a= t5.a; +DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `t2` (`id`)) +DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `t2` (`id`)) +DELETE IGNORE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; +DROP TABLES t4,t5; +# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 +# Testing for any side effects of IGNORE on AFTER DELETE triggers used with +# transactional tables. +# +CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a VARCHAR(100)) ENGINE=InnoDB; +CREATE TABLE t3 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t4 (i INT NOT NULL PRIMARY KEY, t1i INT, +FOREIGN KEY (t1i) REFERENCES t1(i)) +ENGINE=InnoDB; +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN +SET @b:='EXECUTED TRIGGER'; +INSERT INTO t2 VALUES (@b); +SET @a:= error_happens_here; +END|| +SET @b:=""; +SET @a:=""; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 SELECT * FROM t1; +** An error in a trigger causes rollback of the statement. +DELETE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +ERROR 42S22: Unknown column 'error_happens_here' in 'field list' +SELECT @a,@b; +@a @b + EXECUTED TRIGGER +SELECT * FROM t2; +a +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +i i +1 1 +2 2 +3 3 +4 4 +** Same happens with the IGNORE option +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +ERROR 42S22: Unknown column 'error_happens_here' in 'field list' +SELECT * FROM t2; +a +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +i i +1 1 +2 2 +3 3 +4 4 +** +** The following is an attempt to demonstrate +** error handling inside a row iteration. +** +DROP TRIGGER trg; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 VALUES (1),(2),(3),(4); +INSERT INTO t4 VALUES (3,3),(4,4); +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN +SET @b:= CONCAT('EXECUTED TRIGGER FOR ROW ',CAST(OLD.i AS CHAR)); +INSERT INTO t2 VALUES (@b); +END|| +** DELETE is prevented by foreign key constrains but errors are silenced. +** The AFTER trigger isn't fired. +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +** Tables are modified by best effort: +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +i i +3 3 +4 4 +** The AFTER trigger was only executed on successful rows: +SELECT * FROM t2; +a +EXECUTED TRIGGER FOR ROW 1 +EXECUTED TRIGGER FOR ROW 2 +DROP TRIGGER trg; +** +** Induce an error midway through an AFTER-trigger +** +TRUNCATE TABLE t4; +TRUNCATE TABLE t1; +TRUNCATE TABLE t3; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 VALUES (1),(2),(3),(4); +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN +SET @a:= @a+1; +IF @a > 2 THEN +INSERT INTO t4 VALUES (5,5); +END IF; +END|| +SET @a:=0; +** Errors in the trigger causes the statement to abort. +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`t1i`) REFERENCES `t1` (`i`)) +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +i i +1 1 +2 2 +3 3 +4 4 +SELECT * FROM t4; +i t1i +DROP TRIGGER trg; +DROP TABLE t4; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; End of 5.1 tests === modified file 'mysql-test/t/innodb_mysql.test' --- a/mysql-test/t/innodb_mysql.test 2009-02-20 09:50:50 +0000 +++ b/mysql-test/t/innodb_mysql.test 2009-03-27 16:08:14 +0000 @@ -185,4 +185,151 @@ TRUNCATE TABLE t2; DROP TABLE t2; DROP TABLE t1; +--echo # +--echo # Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 +--echo # +CREATE TABLE t1 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + aid INT UNSIGNED NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (aid) REFERENCES t1 (id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( + bid INT UNSIGNED NOT NULL, + FOREIGN KEY (bid) REFERENCES t2 (id) +) ENGINE=InnoDB; + +CREATE TABLE t4 ( + a INT +) ENGINE=InnoDB; + +CREATE TABLE t5 ( + a INT +) ENGINE=InnoDB; + +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t2 (id, aid) VALUES (1, 1),(2,1),(3,1),(4,1); +INSERT INTO t3 (bid) VALUES (1); + +INSERT INTO t4 VALUES (1),(2),(3),(4),(5); +INSERT INTO t5 VALUES (1); + +DELETE t5 FROM t4 LEFT JOIN t5 ON t4.a= t5.a; + +--error ER_ROW_IS_REFERENCED_2 +DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; +--error ER_ROW_IS_REFERENCED_2 +DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; + +DELETE IGNORE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; + +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; +DROP TABLES t4,t5; + +--echo # Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 +--echo # Testing for any side effects of IGNORE on AFTER DELETE triggers used with +--echo # transactional tables. +--echo # +CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a VARCHAR(100)) ENGINE=InnoDB; +CREATE TABLE t3 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t4 (i INT NOT NULL PRIMARY KEY, t1i INT, + FOREIGN KEY (t1i) REFERENCES t1(i)) + ENGINE=InnoDB; +delimiter ||; +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN + SET @b:='EXECUTED TRIGGER'; + INSERT INTO t2 VALUES (@b); + SET @a:= error_happens_here; +END|| +delimiter ;|| + +SET @b:=""; +SET @a:=""; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 SELECT * FROM t1; +--echo ** An error in a trigger causes rollback of the statement. +--error ER_BAD_FIELD_ERROR +DELETE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +SELECT @a,@b; +SELECT * FROM t2; +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; + +--echo ** Same happens with the IGNORE option +--error ER_BAD_FIELD_ERROR +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +SELECT * FROM t2; +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; + +--echo ** +--echo ** The following is an attempt to demonstrate +--echo ** error handling inside a row iteration. +--echo ** +DROP TRIGGER trg; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 VALUES (1),(2),(3),(4); +INSERT INTO t4 VALUES (3,3),(4,4); + +delimiter ||; +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN + SET @b:= CONCAT('EXECUTED TRIGGER FOR ROW ',CAST(OLD.i AS CHAR)); + INSERT INTO t2 VALUES (@b); +END|| +delimiter ;|| + +--echo ** DELETE is prevented by foreign key constrains but errors are silenced. +--echo ** The AFTER trigger isn't fired. +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +--echo ** Tables are modified by best effort: +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +--echo ** The AFTER trigger was only executed on successful rows: +SELECT * FROM t2; + +DROP TRIGGER trg; + +--echo ** +--echo ** Induce an error midway through an AFTER-trigger +--echo ** +TRUNCATE TABLE t4; +TRUNCATE TABLE t1; +TRUNCATE TABLE t3; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 VALUES (1),(2),(3),(4); +delimiter ||; +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN + SET @a:= @a+1; + IF @a > 2 THEN + INSERT INTO t4 VALUES (5,5); + END IF; +END|| +delimiter ;|| + +SET @a:=0; +--echo ** Errors in the trigger causes the statement to abort. +--error ER_NO_REFERENCED_ROW_2 +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +SELECT * FROM t4; + +DROP TRIGGER trg; +DROP TABLE t4; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + --echo End of 5.1 tests === modified file 'sql/sql_delete.cc' --- a/sql/sql_delete.cc 2009-02-09 22:51:59 +0000 +++ b/sql/sql_delete.cc 2009-03-27 16:08:14 +0000 @@ -709,6 +709,8 @@ bool multi_delete::send_data(List TABLE_LIST *del_table; DBUG_ENTER("multi_delete::send_data"); + bool ignore= thd->lex->current_select->no_error; + for (del_table= delete_tables; del_table; del_table= del_table->next_local, secure_counter++) @@ -741,8 +743,12 @@ bool multi_delete::send_data(List TRG_ACTION_AFTER, FALSE)) DBUG_RETURN(1); } - else + else if (!ignore) { + /* + If the IGNORE option is used errors caused by ha_delete_row don't + have to stop the iteration. + */ table->file->print_error(error,MYF(0)); DBUG_RETURN(1); } @@ -834,6 +840,11 @@ int multi_delete::do_deletes() { int local_error= 0, counter= 0, tmp_error; bool will_batch; + /* + If the IGNORE option is used all non fatal errors will be translated + to warnings and we should not break the row-by-row iteration + */ + bool ignore= thd->lex->current_select->no_error; DBUG_ENTER("do_deletes"); DBUG_ASSERT(do_delete); @@ -872,18 +883,29 @@ int multi_delete::do_deletes() local_error= 1; break; } - if ((local_error=table->file->ha_delete_row(table->record[0]))) + + local_error= table->file->ha_delete_row(table->record[0]); + if (local_error && !ignore) { - table->file->print_error(local_error,MYF(0)); - break; + table->file->print_error(local_error,MYF(0)); + break; } - deleted++; - if (table->triggers && - table->triggers->process_triggers(thd, TRG_EVENT_DELETE, - TRG_ACTION_AFTER, FALSE)) + + /* + Increase the reported number of deleted rows only if no error occurred + during ha_delete_row. + Also, don't execute the AFTER trigger if the row operation failed. + */ + if (!local_error) { - local_error= 1; - break; + deleted++; + if (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_AFTER, FALSE)) + { + local_error= 1; + break; + } } } if (will_batch && (tmp_error= table->file->end_bulk_delete())) --Boundary_(ID_jGAkf7Pmdvve8lcM5NuWTA) MIME-version: 1.0 Content-type: text/bzr-bundle; name="bzr/kristofer.pettersson@stripped"; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/kristofer.pettersson@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kristofer.pettersson@stripped\ # orn2jj66rx0gpgci # target_branch: file:///home/thek/Development/cpp/mysqlbzr/51-\ # bug40127/ # testament_sha1: 6c34e4144fb375c1d15427a2340cba6dd7864ffe # timestamp: 2009-03-27 17:08:25 +0100 # base_revision_id: gni@stripped # # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWUztvW0ACgVfgFVwef///3// 3+r////+YBMkd9077V694Pe89g7doFeKAUWey2orbANweXEVDeeudKPXQG9i2KurK9hJJE1T8BEe p6TE08in6RpinpNNMmRppoaBpoAZNDIJJATRoak8kDIniE0JqD0gM09UA/UjJkaADyg40NA0aZGm jTIDEwQAA0BoDTIDAmQJNSJImJk9R6jT1NPSAAAGmIGgNAAAABFImUZVP9Jp6qP9BTI/Uoep+o9U yeaRDIaaDIAaNDQaPUCKIgCACNECbKeVP1T2lH6hp6SYTRpkMmQyGjQKYUILq11eC+Hqm6Ec9hir cu1ixgTiyabKWpHDbNj53ff6dnVqkGpybXTnn1J4XrZbgvNmI2W53SuI3onQN2P9WeJ2GV3By5mY wPRu0u47PZR/9arzGTENs9z+Lc8XRc/7t+Ea7n4uIYXvajnQZ9NsCEexdi0HN4BLkogwSadoGnd9 QuYLppmTMmZKixr9MaRfAfKLJDMhntlYtnJKbDLqZjNfQQUkWZkuJsOcZ9iw9jUtwbVns1tC0zNB NRt/RBR9Bpi5EvazHVweNEnkei2fPXiUjEgw+eThvoQWxhCCVIDGw5mYAyZ0uyyiwYJte3p2RFa1 /A+sF+4+9jNsJC4uIMClKzMwSSTfQ8wz3CGoXa/EH4PBgiIhiB2dyaNO7n5X6+RElyYN/kk+6HrP xeK3Yx4l0R8nlkTgqsWe6zDp0l2PUD3jzGB2AD9x4jpSDjPwD3g6g3FpyPBtTYNxMgefwAI2pYXb htDtbbBKjAwBzElPqMO8l+4gKzA3jmNoah7AEG0VzHDjGYhvXuCCB9IG0D0nnTcFwwEC1HWNpJEI qGQzE4eWB6CaYYjIGM0A9wICCRWMYICDidOpKjUZLDzkDrA8puMtow7dcQlQmC+PCrUSuGzhlTnG hhw4zaxU9wGKDSQmSSF/CMiUmP8Vds+JQhcXFCjKA+ASnjRPEOxj8LjKI/OdVJdRngFzeJEziOuH 12X3STSenjEBiroGakj6PcQjdQ4I0wKtCbYk/zkoDPmNQvYvI1Jk9M8WGiIabTJjjN8cjBOfTKby 7Ae7MmGBCUhMMqwE+BOpgprJ8YKrESBDJpFxiShBjIZXsGzJroDaeg3jrGwD0ATFsGhIA1jYUAqQ GBiLkQsEpBEYlCUBiAsSwSxQ1KlKhEBJUtMU9U6jWbh21Nt1ORwNx+VlOfcSbyeJmaMy+2SesjtB 5EkpwNLkF96cql1b8bbnDFzvLjqazRvQ+V/Lza8cxx56ncMLy4R501aS2AetSXrSQd3IKxFXjw7p R+nfHFKNcym8LBmkQnUNughiOiElCQElxkh2BJMqB03kaV3rnHJ3qDITaGhoTuTA4gknOqwutMZg ahJsBE5IRE5ZRpV+OVbyXML2KLpcily9eKbIG0JNUgVRJvy0REREVERXd3aNTrHq09zXXh2nOIcD Y67XfsHkLRUkbTUQQbDSeMysNQj0uVLcAOKsgWNbvaZFrEQ7aZXtsoUK4ukQtE0cVoUh42CfEUq7 DynGuOnXNJmcyZJImack35+ZoSdI60zhoYE+YxANQBUYHSpUTuO7t9yQUw9bXoftSsetypu+hMQN UB5JlDomx9/iWU9u8m3g/G1oKTBUaPOBjXpIzbHuMyWiO4wzcy0loNSy+qMhUApHaQXMMGYRho9h /qTE4dYnb7TufzcftYXONvQBLThQQeQNTxCUghrUUkt3uph5bDf/UyfktAyi8jovuDo2CdAZmR0F WpkF4lGyLi/1T5tTaHVgcIe9rWH2cSYIggmQ0hH5O4xPoRwMSoxytbuVtZcYRmFggOQGBggHc61S HaYW5FHjUjo+ktbNjPR+Zx6XFjnIb01iMsF84+Y92MRWBTGMDcsCZ/1x6shF/JdIdIXYCyycJFug FxGDRQANF6iy0NLPWC2uENDEg/lqrY74VPUp5PJ91gVMixKS7O/tWnSGPStGxCm9wF3RznKIhGpu dmInPU+hNbUN5a8OLsNNpYcmXwHjtTxUevIz0Ov3xHo+W83hqBxN4/Iw+DJthfldQzIYvFmdR1BR EDUvC31adKtiZAY/GpgvVbt2mZne5YFjae3aegoFSo45S8FrHDPB7rLVWEOQyjHYRUz0ZktnpEVn TSSNGMXlTmIzPystU8R42XtXFcFrjHMZr0UyUs8jqUhECHd93frNTGnqYmIy6hxgv3eer0XX8OPQ ZFSq0IG5cBjd0c2M6UZ+Kh0iHplFajzW2Z24E5EuogXBpGmm8kVVWkWHhhAAy3KpODLGLD1Kw47R l+HoLlqS0rC45ub3m46T1GTkcmSYxh2HMayAgIMuZ3cTm3tWQyxolW6khB0YvFPXdT18Su8LeTX5 Qvi17l8vPc9vJxjjDZk5zh2lRH2q4dZ2ZYsXDhsBiJ587nOrAYa/cUU1ZkK8mZMPkYFS8mzMyjfM I9ZwXuWXS4D2soHSwdIwO8pcVD4ZNWJMxBZJ1weplCbg/cIagDH6g8fPPNKcW6Sk6dtJwhhQX4fA Eh98vbruokJ5hU0j8fKWoyg8rz/6C+cIPyEofyFoQEAiCCCIFE8icIyKMTdIGkUT7kkLvTcHA/mI 2DrKrcA1C4EshatCVfsOAhVLQIQgCDGRSwsLiaXDfvVGEghWGIEKRoI0qJKCSg8rcgbwmAErUE61 oBVcGoNBDWMkPUXAmCATDiQDlnAwrEHAOP5aAIDSMAykEN484PsFqXitydYLghgWCwgFcuozkHWo Wm4/pBPMDeSj5b4iYgQKiHIA2qFyhQdwhKocTWJvP8DvMcoLVDBDcBQUoJkP9wHUEiFRuEiIhH6o ZENTAAZ2lPVhQ/MQgFN+0W80mQKQCUEJEkA5BdCLYIHASoe5ck0YhqOxCBkWABAREzglwlgQEgXA 1SWIFiWJCovHMVqBmZIlQgAIoLPAV6wHeahAsFeSX0RecTQKQhAso3hOApv5ojBaGcJAEDAkBChs CG5koKUHIB1NqFUKBUG1E/yJmIHpFNC3iYNyIXA4iSgEEKe046ALiBNQrMkQEQxEgWkOsqSGkEvF yFdAhUdQsKXnSSN4qXKFQQgXetwBUwtFahc/2sBMwbJEkNALQXMGoF65BIAZZiSMMglgkD1+HzfO +5xOnRgcalYMgtLNpStDH7E6xtzp7V1KE2Q7Ibh3u1NiZ8ohuEKti+OEvDbZk0ff4DK0QapWa9aO 1mD+AzOXxh3pxEcQHIWUA8ywfSMFrI8yQFQiv/YpHAYqVPrP29JioOIupzEUdQtuIvdt2l59gTEY GZuMlZFbjkRRJ6C5lYD5E9PHpcHI0BfWGBjN5E/jcx22KTHqvFkQWD4jAyJ0N0UXmB+bej7D+nLk ULEgGEZHQY1Kp8gxcZYFsKqqoOswpK/COPquV7mY6GAZESSw7TLNCslJQSlhYaETFLIyo/A/kTiT GSkg++ZzYicCx6cZ6pze1ZmxCP5CPQs1OEXfeM3miAYGyDK2h3l7Ls/kSMsFgJAFeuT1SXkUDsmQ pB2XAM6pIOlol/E81DyEPJzKFhQwyTQSXGjBLKiYySHz+l9RxExzPjLg85uNhzOQkds5ieXu6zPM Mh7yP2zHkXUbE7F3rgdYucTIcrG4fyhAfFMSPYM6LeHWRpSRII+DD3hRDqFPZEfIJASQy1KrlU7y 8rJpQ4kj5hx4jyhGJgVOTHm5Qb0uMi26TWtRo39RO6jpO1EpS4vJ/Abp2+jrIDzRxsZal8R7olx9 8rwJEdvVP5+1D9VARrY0moU/HW6EihJzRQs69638siCyCU8xMMgdBg8pCsOuCrVTR00MiA5g8+dd PkTghK/YSuaYA3FwxtMZCSu0t0bOW5ILTawpSPEsTE8uQB9OlStgNTUt69IOOoPdCDl9JND1id5u KyshZ8lRgukIbI4YUYJiQIh8ZUPGA614Tf0vQ8Q9p9055ORYtY0Qjpd7kXQ7nVzDcjuXKGY6hN5K EPcAK7ACpbITG8kGbi3iaLR/vhoGvyzTM1CLEeABwdZCyB0AwrtXmWXh0AYwREMQONndzhds6KZ8 8TZolNNE53g2PMlTzh2UB9h4jQwLUkoS0vextADoal3j83VufXwpf1YYj1D8JsO6kRtGCWSJLBoG aNTSbw8DsD3szF4ydyoFqgGIR3D5u3ZACicrcpicUIjSJrv57NMFk2l5NcOXfe/hMs5mZAF/LDw0 29aVTOACEIXWVNjCWCQ6zxyBp4dAym4J8M2/5PxE/UI0mHMrS315Hlec5uQepU9wFXtihrOD+1mN DKmnenIJ98obkCyWE7KJRKWpaW8CO/2d4y+ZJJIYUsN81CCoVALDbI6C4zujIiDHs7o9nfqb3L5b w9sbi2QMju13vl7Ol9tyBaVerDcWQmA1ejv2HOMLjlS8/IvCZgVqF+MCUl8i7Jnku8R+AyCjWKsr oYJIljvI6SjKHESwlYID0R1BA7xY6XETtM0TFPDpb/lhvGZEiZWytFaRCaHDH7C9wELhLm88wh2E CSYpMwfAeWsOV5oHAyoTlQGtWEhIYgCYZhYxhsPI44bET3A0QxBTf7xyeTGsuEOeDqTVXGolpSo1 B73r3G1LTSVUNMVCbw7YSjlKSsEOgpIlikD67H1XiaSOoz1WkrMnwQ0HSkIQSypUdpdZoCEfKJ75 W5a4kGZgxem30XOXNJxhSC0lt3I7NY93d2pSG/rbQ0gYIeKmr0iZ8kvbn8aFOKUiWJ3DWsmHRiTF n7OfbJZALsWzO5P6lPGaLGCgwQURjjolQtU59pDfJ2ZhgFIE0iXw+SCq1cCIJJIIJsLN/I4mdwly VIXh5+SbTnpV2Q01A6jKQDi3/f7qlul4wJp9kl2GZlRdaARwPTWLGYIgbtLmi/WQ0SCIFCKixFh1 ZlIWmjyJqnFzi5xOAVgjjMMUNDlFQHucRcSUxiAzSGiM0Abt4PO96OfvWBlGq7cnA6+MYk1CNMUO dsC0MLLm8kJ2iWPb8e1LrC804Zg+wPRGiZmZnUeTsVpWjZUsHAg5wcpGCFMdcBopXdJINTMbAZNF ieAtlf143ZYwagwy1HxTGDTfgw+5x0DC5qKTk5bzONBm2RNIinx/LJ4lJAZGBCSAX+gBAEhAowwj +Z3fQsTA7s+Y2WDNi4Tghgl5ZnweQIpMnO69klthpS50VKFL6pkTtGUJANLjoDIzmKfAT5hRPzYS PSmI+PY4xzImTylmN6Zhg2DSgJay1LrQP1laCWtZCUYIB9chDhBlKtWDLTKSbeCPvtgasz4GL/H6 k+k+F2mfrJIvT9L9yY8xUXg+DJu6XW8G2sMBVnSVHq0OD4DecxodfgdJj4uJMwnM4vwa1Jcsmo6i 9l5SMWKEBBR94pR0u90GAlPRRepheLzsiWNtGdhwOJUsqM5Vq0sAsFKAjHUqOhZVUFMFuF5US+kz /sFzr2CwNKf+LuSKcKEgmdt62g== --Boundary_(ID_jGAkf7Pmdvve8lcM5NuWTA)--