From: Ross Smith II Date: Sun, 17 Aug 2003 00:46:23 +0000 (+0000) Subject: Lots of Postgres fixes: X-Git-Tag: v0.04~315 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=50840472b86d71a07ebda8332c4b1bcd74dab01b;p=dbsrgits%2FSQL-Translator.git Lots of Postgres fixes: All the basic types (int,real,string,date,blob,text) and variants (aliases) now work. Quotes appear around field names in indexes and constraints. Creates unique index names now. ' --- diff --git a/lib/SQL/Translator/Parser/PostgreSQL.pm b/lib/SQL/Translator/Parser/PostgreSQL.pm index ab029ad..6fcd174 100644 --- a/lib/SQL/Translator/Parser/PostgreSQL.pm +++ b/lib/SQL/Translator/Parser/PostgreSQL.pm @@ -1,7 +1,7 @@ package SQL::Translator::Parser::PostgreSQL; # ------------------------------------------------------------------- -# $Id: PostgreSQL.pm,v 1.26 2003-08-15 22:29:16 kycl4rk Exp $ +# $Id: PostgreSQL.pm,v 1.27 2003-08-17 00:46:23 rossta Exp $ # ------------------------------------------------------------------- # Copyright (C) 2003 Ken Y. Clark , # Allen Day , @@ -111,7 +111,7 @@ View table: use strict; use vars qw[ $DEBUG $VERSION $GRAMMAR @EXPORT_OK ]; -$VERSION = sprintf "%d.%02d", q$Revision: 1.26 $ =~ /(\d+)\.(\d+)/; +$VERSION = sprintf "%d.%02d", q$Revision: 1.27 $ =~ /(\d+)\.(\d+)/; $DEBUG = 0 unless defined $DEBUG; use Data::Dumper; @@ -385,12 +385,11 @@ data_type : pg_data_type parens_value_list(?) } pg_data_type : - /(bigint|int8|bigserial|serial8)/i + /(bigint|int8)/i { $return = { - type => 'integer', - size => [8], - auto_increment => 1, + type => 'integer', + size => [8], }; } | @@ -402,13 +401,21 @@ pg_data_type : }; } | - /int(eger)?|int4/i + /(integer|int4?)/i # interval must come before this { $return = { type => 'integer', size => [4], }; } + | + /(real|float4)/i + { + $return = { + type => 'real', + size => [4], + }; + } | /(double precision|float8?)/i { @@ -418,11 +425,12 @@ pg_data_type : }; } | - /(real|float4)/i + /(bigserial|serial8)/i { - $return = { - type => 'real', - size => [4], + $return = { + type => 'integer', + size => [8], + auto_increment => 1, }; } | @@ -435,15 +443,6 @@ pg_data_type : }; } | - /bigserial/i - { - $return = { - type => 'integer', - size => [8], - auto_increment => 1, - }; - } - | /(bit varying|varbit)/i { $return = { type => 'varbit' }; @@ -469,12 +468,12 @@ pg_data_type : $return = { type => 'bytea' }; } | - /timestampz?/i + /(timestamptz|timestamp)/i { $return = { type => 'timestamp' }; } | - /(bit|box|cidr|circle|date|inet|interval|line|lseg|macaddr|money|numeric|decimal|path|point|polygon|text|time|varchar)/i + /(bit|box|cidr|circle|date|inet|interval|line|lseg|macaddr|money|numeric|decimal|path|point|polygon|text|timetz|time|varchar)/i { $return = { type => $item[1] }; } diff --git a/lib/SQL/Translator/Producer/PostgreSQL.pm b/lib/SQL/Translator/Producer/PostgreSQL.pm index 63e511a..1c995b9 100644 --- a/lib/SQL/Translator/Producer/PostgreSQL.pm +++ b/lib/SQL/Translator/Producer/PostgreSQL.pm @@ -1,7 +1,7 @@ package SQL::Translator::Producer::PostgreSQL; # ------------------------------------------------------------------- -# $Id: PostgreSQL.pm,v 1.12 2003-08-16 20:12:09 rossta Exp $ +# $Id: PostgreSQL.pm,v 1.13 2003-08-17 00:46:23 rossta Exp $ # ------------------------------------------------------------------- # Copyright (C) 2003 Ken Y. Clark , # darren chamberlain , @@ -30,7 +30,7 @@ SQL::Translator::Producer::PostgreSQL - PostgreSQL producer for SQL::Translator use strict; use vars qw[ $DEBUG $WARN $VERSION ]; -$VERSION = sprintf "%d.%02d", q$Revision: 1.12 $ =~ /(\d+)\.(\d+)/; +$VERSION = sprintf "%d.%02d", q$Revision: 1.13 $ =~ /(\d+)\.(\d+)/; $DEBUG = 1 unless defined $DEBUG; use SQL::Translator::Schema::Constants; @@ -168,6 +168,7 @@ sub produce { my $output; $output .= header_comment unless ($no_comments); + my %used_index_names; for my $table ( $schema->get_tables ) { my $table_name = $table->name or next; @@ -205,7 +206,7 @@ sub produce { $len = ($len < length($_)) ? length($_) : $len for (@$list); my $check_name = mk_name( $table_name.'_'.$field_name, 'chk' ); push @constraint_defs, - "CONSTRAINT $check_name CHECK ($field_name IN ($commalist))"; + "CONSTRAINT $check_name CHECK (\"$field_name\" IN ($commalist))"; $data_type = 'character varying'; } elsif ( $data_type eq 'set' ) { @@ -216,7 +217,14 @@ sub produce { $data_type = 'character varying'; } elsif ( $field->is_auto_increment ) { - $field_def .= ' serial'; + if ( defined $size[0] && $size[0] > 11 ) { + $data_type = ' bigserial'; + } + else { + $data_type = ' serial'; + } + undef @size; + # $seq_name = mk_name( $table_name.'_'.$field_name, 'sq' ); # push @sequence_defs, qq[DROP SEQUENCE "$seq_name";]; # push @sequence_defs, qq[CREATE SEQUENCE "$seq_name";]; @@ -227,6 +235,30 @@ sub produce { $data_type; } + if ( $data_type =~ /timestamp/i ) { + if ( defined $size[0] && $size[0] > 13 ) { + $size[0] = 13; + } + } + + if ( $data_type eq 'integer' ) { + if ( defined $size[0] ) { + if ( $size[0] > 10 ) { # + $data_type = ' bigint'; + } + elsif ( $size[0] < 5 ) { + $data_type = ' smallint'; + } + else { + $data_type = ' integer'; + } + } + else { + $data_type = ' integer'; + } + undef @size; + } + $field_def .= " $data_type"; if ( defined $size[0] && $size[0] > 0 ) { @@ -269,24 +301,31 @@ sub produce { if ( $type eq PRIMARY_KEY ) { $name ||= mk_name( $table_name, 'pk' ); + $name = next_unused_name($name, \%used_index_names); + # how do I get next_unused_name() to do: ? + $used_index_names{$name} = $name; push @constraint_defs, 'CONSTRAINT '.$name.' PRIMARY KEY '. - '(' . join( ', ', @fields ) . ')'; + '("' . join( '", "', @fields ) . '")'; } elsif ( $type eq UNIQUE ) { $name ||= mk_name( $table_name, $name || ++$idx_name_default ); + $name = next_unused_name($name, \%used_index_names); + $used_index_names{$name} = $name; push @constraint_defs, 'CONSTRAINT ' . $name . ' UNIQUE ' . - '(' . join( ', ', @fields ) . ')'; + '("' . join( '", "', @fields ) . '")'; } elsif ( $type eq NORMAL ) { $name ||= mk_name( $table_name, $name || ++$idx_name_default ); + $name = next_unused_name($name, \%used_index_names); + $used_index_names{$name} = $name; push @index_defs, - qq[CREATE INDEX "$name" on $table_name_ur (]. - join( ', ', @fields ). - ');'; + qq[CREATE INDEX "$name" on $table_name_ur ("]. + join( '", "', @fields ). + '");'; } else { warn "Unknown index type ($type) on table $table_name.\n" @@ -312,27 +351,31 @@ sub produce { if ( $c->type eq PRIMARY_KEY ) { $name ||= mk_name( $table_name, 'pk' ); + $name = next_unused_name($name, \%used_index_names); + $used_index_names{$name} = $name; push @constraint_defs, "CONSTRAINT $name PRIMARY KEY ". - '(' . join( ', ', @fields ) . ')'; + '("' . join( '", "', @fields ) . '")'; } elsif ( $c->type eq UNIQUE ) { $name ||= mk_name( $table_name, $name || ++$c_name_default ); + $name = next_unused_name($name, \%used_index_names); + $used_index_names{$name} = $name; push @constraint_defs, "CONSTRAINT $name UNIQUE " . - '(' . join( ', ', @fields ) . ')'; + '("' . join( '", "', @fields ) . '")'; } elsif ( $c->type eq FOREIGN_KEY ) { my $def = join(' ', map { $_ || () } 'FOREIGN KEY', $c->name ); - $def .= ' (' . join( ', ', @fields ) . ')'; + $def .= ' ("' . join( '", "', @fields ) . '")'; $def .= ' REFERENCES ' . $c->reference_table; if ( @rfields ) { - $def .= ' (' . join( ', ', @rfields ) . ')'; + $def .= ' ("' . join( '", "', @rfields ) . '")'; } if ( $c->match_type ) { @@ -444,6 +487,27 @@ sub unreserve { return $unreserve.$suffix; } +# ------------------------------------------------------------------- +sub next_unused_name { + my $name = shift || ''; + my $used_names = shift || ''; + + my %used_names = %$used_names; + + if ( !defined($used_names{$name}) ) { + $used_names{$name} = $name; + return $name; + } + + my $i = 2; + while ( defined($used_names{$name . $i}) ) { + ++$i; + } + $name .= $i; + $used_names{$name} = $name; + return $name; +} + 1; # -------------------------------------------------------------------