restart import if last run produced errors
[pgsql-fix-value-too-long] / pgsql-fix-value-too-long.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4 use autodie;
5 use Data::Dump qw(dump);
6
7 # 1. dump errors with:
8
9
10 my ( $errors, $dump ) = @ARGV;
11 die "usage: $0 errors.log dump.sql" unless -r $errors && -r $dump;
12
13 my $fix;
14 my $type;
15
16 open(my $f, '<', $errors);
17 while(<$f>) {
18         if ( m/ERROR:  value too long for type (.+)/ ) {
19                 $type = $1;
20         } elsif ( m/CONTEXT:  COPY (\w+), line \d+, column (\w+)/ ) {
21                 $fix->{$1}->{$2} = $type;
22                 $type = undef;
23         }
24 }
25
26 warn "# fix ",dump($fix);
27
28 my $in_create_table = 0;
29
30 my $d;
31 if ( $dump =~ m/\.gz/i ) {
32         open($d, '-|', "zcat $dump");
33 } else {
34         open($d, '<', $dump);
35 }
36
37 while(<$d>) {
38         if ( m/CREATE TABLE (\w+)/ ) {
39                 $in_create_table = $1;
40         } elsif ( $in_create_table && m/;/ ) {
41                 $in_create_table = 0;
42         }
43
44         if ( $in_create_table && exists $fix->{$in_create_table} ) {
45                 my $column = $1 if /^\s+(\w+)/;
46                 if ( my $type = $fix->{$in_create_table}->{$column} ) {
47                         warn "FIX: [$_] $type\n";
48                         s/\Q$type\E/text/ || die "can't FIX $_ $type";
49                         chomp;
50                         $_ .= " -- FIXME $type\n";
51                 }
52         }
53
54         print;
55 }