Subject: | Pg should call __PACKAGE__->sequence() for tables with sequences. [Patch] |
Patch adds the line '__PACKAGE__->sequence("foo_seq");' for any
sequences in the table.
All tests pass (including 12pg_common.t)
Rationale: This is useful when dealing with databases with multiple
schemas (in
the Pg sense of the word). It seems that there is an issue when a
column with a
sequence is called and there is no sequence defined. When there is no
sequence
defined in the table class, the function _dbh_get_autoinc_seq in
Storage::DBI::Pg calls current_info() which doesn't seem to respect
schemas, and
instead just grabs the first one it finds.
To demonstrate this, create a Pg database with two schemas, say a and b,
then
create a table (with the same name) in each that has a serial column (again,
pointing to a sequence with the same name). Try to do something with the
DBIx::Class schema created for b and watch how it uses the sequence from a.
Adding the sequence to the table class avoids this lookup and Pg knows
to stay
in its schema.
Note: I'm not actually sure if/how DBI/DBIC supports tables that have
multiple
columns with sequences.
Subject: | dbic-schema-loader-pg-sequence.patch |
--- ./lib/DBIx/Class/Schema/Loader/DBI/Pg.pm 2009-04-18 07:28:35.000000000 -0400
+++ ./lib/DBIx/Class/Schema/Loader/DBI/Pg.pm 2009-07-02 15:01:29.000000000 -0400
@@ -35,6 +35,14 @@
$self->{db_schema} ||= 'public';
}
+sub _setup_src_meta {
+ my ( $self, $table, @args ) = @_;
+
+ $self->next::method( $table, @args );
+ my $seq = delete $self->{_cache}{sequence};
+ $self->_dbic_stmt( $self->classes->{$table}, 'sequence', $_ ) for @{$seq};
+}
+
sub _table_uniq_info {
my ($self, $table) = @_;
@@ -99,7 +107,10 @@
my ($self, $info) = @_;
my %extra_info;
- if ($info->{COLUMN_DEF} && $info->{COLUMN_DEF} =~ /\bnextval\(/i) {
+ my $sequence = qr/^nextval\(+'([^']+)'::(?:text|regclass)\)/;
+ if ( $info->{COLUMN_DEF} and $info->{COLUMN_DEF} =~ $sequence ) {
+ my $seq_name = $1;
+ push @{$self->{_cache}{sequence}}, $seq_name;
$extra_info{is_auto_increment} = 1;
}