From c0bf69411ac5f7af2b39053ff41bb653199dbca0 Mon Sep 17 00:00:00 2001 From: Dobrica Pavlinusic Date: Thu, 17 Jan 2013 16:20:06 +0100 Subject: [PATCH 1/1] parse postgresql error log for value too long and rewrite schema --- pgsql-fix-value-too-long.pl | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 pgsql-fix-value-too-long.pl diff --git a/pgsql-fix-value-too-long.pl b/pgsql-fix-value-too-long.pl new file mode 100755 index 0000000..ffe2e7f --- /dev/null +++ b/pgsql-fix-value-too-long.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl +use warnings; +use strict; +use autodie; +use Data::Dump qw(dump); + +# 1. dump errors with: +# + +my ( $errors, $dump ) = @ARGV; +die "usage: $0 errors.log dump.sql" unless -r $errors && -r $dump; + +my $fix; +my $type; + +open(my $f, '<', $errors); +while(<$f>) { + if ( m/ERROR: value too long for type (.+)/ ) { + $type = $1; + } elsif ( m/CONTEXT: COPY (\w+), line \d+, column (\w+)/ ) { + $fix->{$1}->{$2} = $type; + $type = undef; + } +} + +warn "# fix ",dump($fix); + +my $in_create_table = 0; + +my $d; +if ( $dump =~ m/\.gz/i ) { + open($d, '-|', "zcat $dump"); +} else { + open($d, '<', $dump); +} + +while(<$d>) { + if ( m/CREATE TABLE (\w+)/ ) { + $in_create_table = $1; + } elsif ( $in_create_table && m/;/ ) { + $in_create_table = 0; + } + + if ( $in_create_table && exists $fix->{$in_create_table} ) { + my $column = $1 if /^\s+(\w+)/; + if ( my $type = $fix->{$in_create_table}->{$column} ) { + warn "FIX: [$_] $type\n"; + s/\Q$type\E/text/ || die "can't FIX $_ $type"; + chomp; + $_ .= " -- FIXME $type\n"; + } + } + + print; +} -- 2.20.1