[Dbix-class] Unexpected behavior with possible NULL foreign key relationship

mike pulsation at gmail.com
Wed Apr 16 20:32:44 BST 2008


On Tue, Apr 15, 2008 at 7:59 PM, mike <pulsation at gmail.com> wrote:
> [ sorry for the CC, but my last attempt to post to the list never made it ]
>
>  On Sun, Apr 6, 2008 at 2:08 PM, Matt S Trout <dbix-class at trout.me.uk> wrote:
>  > On Fri, Mar 21, 2008 at 03:14:40PM -0700, Damon Snyder wrote:
>  >  > Hi Everyone,
>  >  > I'm new to the list so bear with me if I'm missing something. I have a
>  >  > foreign key relationship where it's possible that the belongs_to
>  >  > relationship is NULL. See the classes below. When I create a new
>  >  > Smsmessage object e.g. like so:

[snip]

>  On Wed, Apr 2, 2008 at 3:52 PM, mike <pulsation at gmail.com> wrote:
>  > attached is a patch which includes a test that shows the broken single
>  >  accessor in DBIx::Class 0.08008 and 0.08010.  DBIx::Class 0.08009 was
>  >  not tested, but DBIx::Class 0.08007 works fine.  i'm not sure exactly
>  >  what's going on here, but this behavior has appeared in DBIx::Class
>  >  before.  it breaks the holy hell out of all of our applications in a
>  >  very nasty way.  with sharp, pointy teeth.  look at the bones!

[snip]

i wish to qualify this by saying that my previous encounter with
similiar symptoms
were caused not by DBIx::Class, but by mysql's SQL_AUTO_IS_NULL behavior
as described here:

    http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html

however, this current problem is not mysql.  i have confirmed that it
only occurs
on newly created objects by adding a call to discard_changes after the creation.
following is the modified patch including the test that illustrates
this behavior.

-mike

--- snip --- snip --- snip ---

Index: t/broken_single_accessor.t
===================================================================
--- t/broken_single_accessor.t	(revision 0)
+++ t/broken_single_accessor.t	(revision 0)
@@ -0,0 +1,23 @@
+use strict;
+use warnings;
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 4;
+
+my $schema = DBICTest->init_schema();
+
+my $artist = $schema->resultset('Artist')->create({ artistid => 666,
name => 'bad religion' });
+my $genre = $schema->resultset('Genre')->create({ name => 'disco' });
+my $cd = $schema->resultset('CD')->create({ cdid => 187, artist => 1,
title => 'how could hell be any worse?', year => 1982 });
+
+ok(!defined($cd->genreid), 'genreid is NULL');
+ok(!defined($cd->genre), 'genre accessor returns undef');
+
+$cd->discard_changes;
+
+ok(!defined($cd->genreid), 'genreid is NULL');
+ok(!defined($cd->genre), 'genre accessor returns undef');
+
Index: t/lib/sqlite.sql
===================================================================
--- t/lib/sqlite.sql	(revision 4250)
+++ t/lib/sqlite.sql	(working copy)
@@ -90,10 +90,19 @@
   cdid INTEGER PRIMARY KEY NOT NULL,
   artist integer NOT NULL,
   title varchar(100) NOT NULL,
-  year varchar(100) NOT NULL
+  year varchar(100) NOT NULL,
+  genreid integer
 );

 --
+-- Table: genre
+--
+CREATE TABLE genre (
+  genreid INTEGER PRIMARY KEY NOT NULL,
+  name varchar(100) NOT NULL
+);
+
+--
 -- Table: bookmark
 --
 CREATE TABLE bookmark (
Index: t/lib/DBICTest/Schema/CD.pm
===================================================================
--- t/lib/DBICTest/Schema/CD.pm	(revision 4250)
+++ t/lib/DBICTest/Schema/CD.pm	(working copy)
@@ -20,6 +20,9 @@
     data_type => 'varchar',
     size      => 100,
   },
+  'genreid' => {
+    data_type => 'integer'
+  }
 );
 __PACKAGE__->set_primary_key('cdid');
 __PACKAGE__->add_unique_constraint([ qw/artist title/ ]);
@@ -45,4 +48,11 @@
     { order_by => 'producer.name' },
 );

+__PACKAGE__->belongs_to('genre', 'DBICTest::Schema::Genre', {
'foreign.genreid' => 'self.genreid' });
+
+#__PACKAGE__->add_relationship('genre', 'DBICTest::Schema::Genre',
+#    { 'foreign.genreid' => 'self.genreid' },
+#    { 'accessor' => 'single' }
+#);
+
 1;
Index: t/lib/DBICTest/Schema/Genre.pm
===================================================================
--- t/lib/DBICTest/Schema/Genre.pm	(revision 0)
+++ t/lib/DBICTest/Schema/Genre.pm	(revision 0)
@@ -0,0 +1,11 @@
+package DBICTest::Schema::Genre;
+
+use strict;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('genre');
+__PACKAGE__->add_columns(qw/genreid name/);
+__PACKAGE__->set_primary_key('genreid');
+
+1;
Index: t/lib/DBICTest/Schema.pm
===================================================================
--- t/lib/DBICTest/Schema.pm	(revision 4250)
+++ t/lib/DBICTest/Schema.pm	(working copy)
@@ -11,6 +11,7 @@
   Employee
   CD
   FileColumn
+  Genre
   Link
   Bookmark
   #dummy



More information about the DBIx-Class mailing list