Subject: | dependency solver bug in SQL::Translator::Parser prevent deployement |
Hello.
My application triggers this kind of error messages:
DBIx::Class::Schema::deploy(): Unable to produce deployment statements:
translate: Error with parser 'SQL::Translator::Parser::DBIx::Class':
Can't call method "_invoke_sqlt_deploy_hook" on an undefined value at
/usr/lib/perl5/vendor_perl/5.10.1/SQL/Translator/Parser/DBIx/Class.pm
line 258.
This happens when attempting partial deployment of a single piece of the
schema:
$schema->deploy({
add_drop_table => 1,
parser_args => {
sources => [ $moniker ]
}
});
When investigating the parse() function of
SQL::Translator::Parser::DBIx::Class, I found than the %tables hash
contains only one entry for the just added source at the end of the main
loop (line 81 -> 243), but got unfortunatly added a wrong additional
entry by _resolve_deps function call.
This last one is called recursively with the following args:
call1:
$table = 'unmaintained'
$tables = { unmaintained => { ... } }
%seen = ()
call2:
$table = 'package'
$tables = { unmaintained => { ... } }
%seen = ()
Then $tables hashref get a new entry by autovification at line 322, as
shown by this debug session
DB<11> n
...
322: for my $dep (keys %{$tables->{$table}{foreign_table_deps}} ) {
DB<12> x keys %$tables
0 'unmaintained'
DB<13> n
DB<14> x keys %$tables
0 'packages'
1 'unmaintained'
Unfortunatly, the second entry is not a valid entry, and the fatal error
occurs when attempting to access $tables{package}{source} object in the
next loop.
Here is the class corresponding to this piece of Schema:
package Youri::Check::Schema::Unmaintained;
use base qw/DBIx::Class/;
__PACKAGE__->load_components(qw/Core/);
__PACKAGE__->table('unmaintained');
__PACKAGE__->add_columns(
id => {
data_type => 'integer',
is_auto_increment => 1,
},
error => {
data_type => 'varchar',
is_auto_increment => 0,
},
package_id => {
data_type => 'integer',
is_auto_increment => 0,
},
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->belongs_to(
'package_id' => 'Youri::Check::Schema::Package'
);
There is indeed a relationship with the other table (packages), which is
already deployed at that time, and should get considered for deployement.
The same code was previously working, with previous versions of
DBIx::Class, but I can't give exact version number.