From 99b8e761432fc5b537124592eaf9044421089735 Mon Sep 17 00:00:00 2001 From: Manjot Singh Date: Thu, 26 May 2016 15:57:52 -0700 Subject: [PATCH] Completed logic for pt-osc preserve triggers Issue with some sql, currently working on. --- bin/pt-online-schema-change | 140 ++++++++++++++++++++++++++++++++---- 1 file changed, 126 insertions(+), 14 deletions(-) diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index 851ec0a9..8ac8a5dd 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -10576,6 +10576,12 @@ sub create_triggers { my $orig_insert_trigger; my $orig_update_trigger; + my %orig_triggers = ( + del => '', + ins => '', + upd => '' + ); + if ( $o->get('preserve-triggers') ) { $cxn->connect(); @@ -10590,8 +10596,6 @@ sub create_triggers { # find if trigger has begin/end - supply insertion point my $delete_trigger_ins_point = trigger_ins_point(trigger => $orig_delete_trigger->[3]); - my $insert_trigger_ins_point = trigger_ins_point(trigger => $orig_insert_trigger->[3]); - my $update_trigger_ins_point = trigger_ins_point(trigger => $orig_update_trigger->[3]); $delete_trigger = "CREATE TRIGGER `${prefix}_del` AFTER DELETE ON $orig_tbl->{name} " @@ -10604,19 +10608,19 @@ sub create_triggers { if($delete_trigger_ins_point) { $delete_trigger = "LOCK TABLES $orig_tbl->{name};\n" - . "DROP TRIGGER `$orig_tbl->{db}`.`$orig_delete_trigger->[1]`;\n" + . "DROP TRIGGER IF EXISTS `$orig_tbl->{db}`.`$orig_delete_trigger->[1]`;\n" . "DELIMITER //\n" . $delete_trigger . "\n" . substr($orig_delete_trigger->[3], 0, $delete_trigger_ins_point) . $delete_trigger_action . ";\n" - . substr($orig_delete_trigger->[3], $delete_trigger_ins_point) . "//\n" + . substr($orig_delete_trigger->[3], $delete_trigger_ins_point) . "; //\n" . "DELIMITER ;\n" . "UNLOCK TABLES;"; } else { $delete_trigger = "LOCK TABLES $orig_tbl->{name};\n" - . "DROP TRIGGER `$orig_tbl->{db}`.`$orig_delete_trigger->[1]`;\n" + . "DROP TRIGGER IF EXISTS `$orig_tbl->{db}`.`$orig_delete_trigger->[1]`;\n" . "DELIMITER //\n" . $delete_trigger . "\n" . "BEGIN\n" @@ -10626,6 +10630,18 @@ sub create_triggers { . "DELIMITER ;\n" . "UNLOCK TABLES;"; } + print $delete_trigger; + $orig_triggers{del} + = "LOCK TABLES $orig_tbl->{name};\n" + . "DROP TRIGGER IF EXISTS `${prefix}_del`;\n" + . "DELIMITER //\n" + . "CREATE DEFINER=$orig_delete_trigger->[2] TRIGGER `$orig_delete_trigger->[0]`.`$orig_delete_trigger->[1]` " + . "AFTER DELETE ON $orig_tbl->{name}\n" + . "FOR EACH ROW\n" + . $orig_delete_trigger->[3] . "\n" + . "//\n" + . "DELIMITER ;\n" + . "UNLOCK TABLES;"; } else { $delete_trigger @@ -10636,24 +10652,117 @@ sub create_triggers { } if ( $o->get('preserve-triggers') && $orig_insert_trigger) { - + + # find if trigger has begin/end - supply insertion point + my $insert_trigger_ins_point = trigger_ins_point(trigger => $orig_insert_trigger->[3]); + my $update_trigger_ins_point = trigger_ins_point(trigger => $orig_update_trigger->[3]); + + $insert_trigger + = "CREATE TRIGGER `${prefix}_ins` AFTER INSERT ON $orig_tbl->{name} " + . "FOR EACH ROW"; + + my $insert_trigger_action + = "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals)"; + + if($insert_trigger_ins_point) { + $insert_trigger + = "LOCK TABLES $orig_tbl->{name};\n" + . "DROP TRIGGER IF EXISTS `$orig_tbl->{db}`.`$orig_insert_trigger->[1]`;\n" + . "DELIMITER //\n" + . $insert_trigger . "\n" + . substr($orig_insert_trigger->[3], 0, $insert_trigger_ins_point) + . $insert_trigger_action . ";\n" + . substr($orig_insert_trigger->[3], $insert_trigger_ins_point) . "//\n" + . "DELIMITER ;\n" + . "UNLOCK TABLES;"; + } + else { + $insert_trigger + = "LOCK TABLES $orig_tbl->{name};\n" + . "DROP TRIGGER IF EXISTS `$orig_tbl->{db}`.`$orig_insert_trigger->[1]`;\n" + . "DELIMITER //\n" + . $insert_trigger . "\n" + . "BEGIN\n" + . $orig_insert_trigger->[3] . "\n" + . $insert_trigger_action . ";\n" + . "END; //\n" + . "DELIMITER ;\n" + . "UNLOCK TABLES;"; + } + + $orig_triggers{del} + = "LOCK TABLES $orig_tbl->{name};\n" + . "DROP TRIGGER IF EXISTS `${prefix}_del`;\n" + . "DELIMITER //\n" + . "CREATE DEFINER=$orig_insert_trigger->[2] TRIGGER `$orig_insert_trigger->[0]`.`$orig_insert_trigger->[1]` " + . "AFTER DELETE ON $orig_tbl->{name}\n" + . "FOR EACH ROW\n" + . $orig_insert_trigger->[3] . "\n" + . "//\n" + . "DELIMITER ;\n" + . "UNLOCK TABLES;"; + } + else { $insert_trigger = "CREATE TRIGGER `${prefix}_ins` AFTER INSERT ON $orig_tbl->{name} " - . "FOR EACH ROW " - . "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals)"; - $update_trigger - = "CREATE TRIGGER `${prefix}_upd` AFTER UPDATE ON $orig_tbl->{name} " . "FOR EACH ROW " . "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals)"; } + + if ( $o->get('preserve-triggers') && $orig_update_trigger) { + + # find if trigger has begin/end - supply insertion point + my $update_trigger_ins_point = trigger_ins_point(trigger => $orig_update_trigger->[3]); + + $update_trigger + = "CREATE TRIGGER `${prefix}_upd` AFTER UPDATE ON $orig_tbl->{name} " + . "FOR EACH ROW"; + + my $update_trigger_action + = "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals)"; + + if($update_trigger_ins_point) { + $update_trigger + = "LOCK TABLES $orig_tbl->{name};\n" + . "DROP TRIGGER IF EXISTS `$orig_tbl->{db}`.`$orig_update_trigger->[1]`;\n" + . "DELIMITER //\n" + . $update_trigger . "\n" + . substr($orig_update_trigger->[3], 0, $update_trigger_ins_point) + . $update_trigger_action . ";\n" + . substr($orig_update_trigger->[3], $update_trigger_ins_point) . "//\n" + . "DELIMITER ;\n" + . "UNLOCK TABLES;"; + } + else { + $update_trigger + = "LOCK TABLES $orig_tbl->{name};\n" + . "DROP TRIGGER IF EXISTS `$orig_tbl->{db}`.`$orig_update_trigger->[1]`;\n" + . "DELIMITER //\n" + . $update_trigger . "\n" + . "BEGIN\n" + . $orig_update_trigger->[3] . "\n" + . $update_trigger_action . ";\n" + . "END; //\n" + . "DELIMITER ;\n" + . "UNLOCK TABLES;"; + } + + $orig_triggers{del} + = "LOCK TABLES $orig_tbl->{name};\n" + . "DROP TRIGGER IF EXISTS `${prefix}_del`;\n" + . "DELIMITER //\n" + . "CREATE DEFINER=$orig_update_trigger->[2] TRIGGER `$orig_update_trigger->[0]`.`$orig_update_trigger->[1]` " + . "AFTER DELETE ON $orig_tbl->{name}\n" + . "FOR EACH ROW\n" + . $orig_update_trigger->[3] . "\n" + . "//\n" + . "DELIMITER ;\n" + . "UNLOCK TABLES;"; + } else { - $insert_trigger - = "CREATE TRIGGER `${prefix}_ins` AFTER INSERT ON $orig_tbl->{name} " - . "FOR EACH ROW " - . "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals)"; $update_trigger = "CREATE TRIGGER `${prefix}_upd` AFTER UPDATE ON $orig_tbl->{name} " . "FOR EACH ROW " @@ -10687,6 +10796,9 @@ sub create_triggers { # (or faked to be created) so if the 2nd trigger # fails to create, we know to only drop the 1st. push @trigger_names, "${prefix}_$name"; + if ( $o->get('preserve-triggers') ) { + push @drop_trigger_sqls, $orig_triggers{$name}; + } push @drop_trigger_sqls, "DROP TRIGGER IF EXISTS " . $q->quote($orig_tbl->{db}, "${prefix}_$name") . ";";