my $result = $self->next::method(@_);
- foreach my $col (keys %$result) {
- my $data_type = $result->{$col}{data_type};
+ while (my ($col, $info) = each %$result) {
+ my $data_type = $info->{data_type};
# these types are fixed size
if ($data_type =~
-/^(?:bigint|int8|bigserial|serial8|bit|boolean|bool|box|bytea|cidr|circle|date|double precision|float8|inet|integer|int|int4|line|lseg|macaddr|money|path|point|polygon|real|float4|smallint|int2|serial|serial4|text)\z/i) {
- delete $result->{$col}{size};
+/^(?:bigint|int8|bigserial|serial8|boolean|bool|box|bytea|cidr|circle|date|double precision|float8|inet|integer|int|int4|line|lseg|macaddr|money|path|point|polygon|real|float4|smallint|int2|serial|serial4|text)\z/i) {
+ delete $info->{size};
}
# for datetime types, check if it has a precision or not
elsif ($data_type =~ /^(?:interval|time|timestamp)\b/i) {
+ if (lc($data_type) eq 'timestamp without time zone') {
+ $info->{data_type} = 'timestamp';
+ }
+
my ($precision) = $self->schema->storage->dbh
->selectrow_array(<<EOF, {}, $table, $col);
SELECT datetime_precision
if ($data_type =~ /^time\b/i) {
if ((not $precision) || $precision !~ /^\d/) {
- delete $result->{$col}{size};
+ delete $info->{size};
}
else {
my ($integer_datetimes) = $self->schema->storage->dbh
$integer_datetimes =~ /^on\z/i ? 6 : 10;
if ($precision == $max_precision) {
- delete $result->{$col}{size};
+ delete $info->{size};
}
else {
- $result->{$col}{size} = $precision;
+ $info->{size} = $precision;
}
}
}
elsif ((not $precision) || $precision !~ /^\d/ || $precision == 6) {
- delete $result->{$col}{size};
+ delete $info->{size};
}
else {
- $result->{$col}{size} = $precision;
+ $info->{size} = $precision;
}
}
- elsif ($data_type =~ /^(?:bit varying|varbit)\z/i) {
+ elsif ($data_type =~ /^(?:bit(?: varying)?|varbit)\z/i) {
+ $info->{data_type} = 'varbit' if $data_type =~ /var/i;
+
my ($precision) = $self->schema->storage->dbh
->selectrow_array(<<EOF, {}, $table, $col);
SELECT character_maximum_length
WHERE table_name = ? and column_name = ?
EOF
- $result->{$col}{size} = $precision;
+ $info->{size} = $precision if $precision;
+
+ $info->{size} = 1 if (not $precision) && lc($data_type) eq 'bit';
}
- elsif ($data_type =~ /^(?:numeric|decimal)\z/i && (my $size = $result->{$col}{size})) {
+ elsif ($data_type =~ /^(?:numeric|decimal)\z/i && (my $size = $info->{size})) {
$size =~ s/\s*//g;
my ($scale, $precision) = split /,/, $size;
- $result->{$col}{size} = [ $precision, $scale ];
+ $info->{size} = [ $precision, $scale ];
+ }
+ elsif (lc($data_type) eq 'character varying') {
+ $info->{data_type} = 'varchar';
+
+ $info->{data_type} = 'text' if not $info->{size};
+ }
+ elsif (lc($data_type) eq 'character') {
+ $info->{data_type} = 'char';
}
# process SERIAL columns
- if (ref($result->{$col}{default_value}) eq 'SCALAR' && ${ $result->{$col}{default_value} } =~ /\bnextval\(['"](\w+)/i) {
- $result->{$col}{is_auto_increment} = 1;
- $result->{$col}{sequence} = $1;
- delete $result->{$col}{default_value};
+ if (ref($info->{default_value}) eq 'SCALAR' && ${ $info->{default_value} } =~ /\bnextval\(['"](\w+)/i) {
+ $info->{is_auto_increment} = 1;
+ $info->{sequence} = $1;
+ delete $info->{default_value};
}
# alias now() to current_timestamp for deploying to other DBs
- if (eval { lc ${ $result->{$col}{default_value} }||'' eq 'now()' }) {
+ if (eval { lc ${ $info->{default_value} }||'' eq 'now()' }) {
# do not use a ref to a constant, that breaks Data::Dump output
- ${$result->{$col}{default_value}} = 'current_timestamp';
+ ${$info->{default_value}} = 'current_timestamp';
}
}
numeric => { data_type => 'numeric' },
decimal => { data_type => 'numeric' },
- 'numeric(6,3)' => { size => [6,3], data_type => 'numeric' },
- 'decimal(6,3)' => { size => [6,3], data_type => 'numeric' },
+ 'numeric(6,3)' => { data_type => 'numeric', size => [6,3] },
+ 'decimal(6,3)' => { data_type => 'numeric', size => [6,3] },
# Bit String Types
- #
- # XXX alias 'bit varying' to 'varbit'
- 'bit varying(2)' => { size => 2, data_type => 'bit varying' },
- 'varbit(2)' => { size => 2, data_type => 'bit varying' },
- 'varbit' => { size => 1, data_type => 'bit varying' },
- # XXX support bit(n)
- bit => { data_type => 'bit' },
+ 'bit varying(2)' => { data_type => 'varbit', size => 2 },
+ 'varbit(2)' => { data_type => 'varbit', size => 2 },
+ 'varbit' => { data_type => 'varbit' },
+ bit => { data_type => 'bit', size => 1 },
+ 'bit(3)' => { data_type => 'bit', size => 3 },
# Network Types
inet => { data_type => 'inet' },
circle => { data_type => 'circle' },
# Character Types
- # XXX alias 'character varying' to 'varchar'
- 'character varying(2)' => { size => 2, data_type => 'character varying' },
- 'varchar(2)' => { size => 2, data_type => 'character varying' },
-
- # XXX alias 'character' to 'char'
- 'character(2)' => { size => 2, data_type => 'character' },
- 'char(2)' => { size => 2, data_type => 'character' },
- 'character' => { size => 1, data_type => 'character' },
- 'char' => { size => 1, data_type => 'character' },
+ 'character varying(2)' => { data_type => 'varchar', size => 2 },
+ 'varchar(2)' => { data_type => 'varchar', size => 2 },
+ 'character(2)' => { data_type => 'char', size => 2 },
+ 'char(2)' => { data_type => 'char', size => 2 },
+ 'character' => { data_type => 'char', size => 1 },
+ 'char' => { data_type => 'char', size => 1 },
text => { data_type => 'text' },
+ # varchar with no size has unlimited size, we rewrite to 'text'
+ varchar => { data_type => 'text' },
# Datetime Types
date => { data_type => 'date' },
interval => { data_type => 'interval' },
- 'interval(2)' => { size => 2, data_type => 'interval' },
+ 'interval(2)' => { data_type => 'interval', size => 2 },
time => { data_type => 'time without time zone' },
- 'time(2)' => { size => 2, data_type => 'time without time zone' },
+ 'time(2)' => { data_type => 'time without time zone', size => 2 },
'time without time zone' => { data_type => 'time without time zone' },
- 'time(2) without time zone' => { size => 2, data_type => 'time without time zone' },
+ 'time(2) without time zone' => { data_type => 'time without time zone', size => 2 },
'time with time zone' => { data_type => 'time with time zone' },
- 'time(2) with time zone' => { size => 2, data_type => 'time with time zone' },
-
- # XXX alias 'timestamp without time zone' to 'timestamp'
- timestamp => { data_type => 'timestamp without time zone' },
+ 'time(2) with time zone' => { data_type => 'time with time zone', size => 2 },
+ timestamp => { data_type => 'timestamp' },
'timestamp default current_timestamp'
- => { data_type => 'timestamp without time zone', default_value => \'current_timestamp' },
- 'timestamp(2)' => { size => 2, data_type => 'timestamp without time zone' },
- 'timestamp without time zone' => { data_type => 'timestamp without time zone' },
- 'timestamp(2) without time zone' => { size => 2, data_type => 'timestamp without time zone' },
+ => { data_type => 'timestamp', default_value => \'current_timestamp' },
+ 'timestamp(2)' => { data_type => 'timestamp', size => 2 },
+ 'timestamp without time zone' => { data_type => 'timestamp' },
+ 'timestamp(2) without time zone' => { data_type => 'timestamp', size => 2 },
'timestamp with time zone' => { data_type => 'timestamp with time zone' },
- 'timestamp(2) with time zone' => { size => 2, data_type => 'timestamp with time zone' },
+ 'timestamp(2) with time zone' => { data_type => 'timestamp with time zone', size => 2 },
# Blob Types
bytea => { data_type => 'bytea' },