Skip Menu |

This queue is for tickets about the DBIx-Class CPAN distribution.

Report information
The Basics
Id: 63087
Status: rejected
Priority: 0/
Queue: DBIx-Class

People
Owner: Nobody in particular
Requestors: MAROS [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.08124
Fixed in: (no value)



Subject: Unique constraint with null values
Find or create on an unique constraint with nullable values does not seem to work. See attached testcase for more details Cheers Maroš
Subject: find_or_create_unique.t
use strict; use warnings; use Test::More; use Test::Exception; use lib qw(t/lib); use DBIC::SqlMakerTest; use DBICTest; my $schema = DBICTest->init_schema(); my $artist_rs = $schema->resultset ('Artist'); my $artist_ebony_bones1 = $artist_rs->create({ name => 'Ebony Bones', rank => 666, charfield => 'E', }); my $artist_ebony_bones2 = $artist_rs->find_or_create({ name => 'Ebony Bones', rank => 666, charfield => 'E', },{ key => 'u_nullable', }); is($artist_ebony_bones1->artistid,$artist_ebony_bones2->artistid,'Same artist'); my $artist_mia1 = $artist_rs->create({ name => 'M.I.A.', rank => 555, charfield => undef, }); my $artist_mia2 = $artist_rs->find_or_create({ name => 'M.I.A.', rank => 555, charfield => undef, },{ key => 'u_nullable', }); is($artist_mia1->artistid,$artist_mia2->artistid,'Same artist'); $artist_mia1->delete(); done_testing;
On Wed Nov 17 10:16:42 2010, MAROS wrote: Show quoted text
> Find or create on an unique constraint with nullable values does not > seem to work. See attached testcase for more details
I am not sure what the bugreport is about. The test case you attached throws with the correct expected error. Can you elaborate why you think this is not the desired behavior?
Show quoted text
> I am not sure what the bugreport is about. The test case you attached > throws with the correct expected error. Can you elaborate why you > think this is not the desired behavior?
I have attached an updated test case that should make my point clearer. The problem is that the test dies if i provide the key with "charfield => undef", which is a perfectly valid value and should translate to NULL (or 'IS NULL') in the database. (see 'M.I.A.' test case). According to my understanding of DBIC the 'M.I.A.' and 'Robyn' test cases should behave the same (of course the 'Robyn' find_or_create statement would produce an invalid sql in the create case) However it is also ok that an error is thrown if the key is not provided at all (see 'Santogold' test case)
Subject: find_or_create_unique_updated.t
use strict; use warnings; use Test::More; use Test::Exception; use lib qw(t/lib); use DBIC::SqlMakerTest; use DBICTest; my $schema = DBICTest->init_schema(); my $artist_rs = $schema->resultset ('Artist'); # Test with charfield NOT NULL { my ($artist_ebony_bones1,$artist_ebony_bones2); $artist_ebony_bones1 = $artist_rs->create({ name => 'Ebony Bones', rank => 666, charfield => 'E', }); $artist_ebony_bones2 = $artist_rs->find_or_create({ name => 'Ebony Bones', rank => 666, charfield => 'E', # <- Charfield provided - hence should not die },{ key => 'u_nullable', }); is($artist_ebony_bones1->artistid,$artist_ebony_bones2->artistid,'Same artist'); $artist_ebony_bones1->delete; } ## Test with charfield NOT NULL and provided as undef #{ # my ($artist_mia1,$artist_mia2); # # $artist_mia1 = $artist_rs->create({ # name => 'M.I.A.', # rank => 555, # charfield => undef, # }); # # $artist_mia2 = $artist_rs->find_or_create({ # name => 'M.I.A.', # rank => 555, # charfield => undef, # <- Charfield provided - hence should not die # },{ # key => 'u_nullable', # }); # # is($artist_mia1->artistid,$artist_mia2->artistid,'Same artist'); # # $artist_mia1->delete(); #} # Test with charfield NOT NULL and provided as NULL { my ($artist_robyn_1,$artist_robyn_2); $artist_robyn_1 = $artist_rs->create({ name => 'Robyn', rank => 999, charfield => \'IS NULL', }); $artist_robyn_2 = $artist_rs->find_or_create({ name => 'Robyn', rank => 999, charfield => \'IS NULL', # <- Charfield provided - hence should not die },{ key => 'u_nullable', }); is($artist_robyn_1->artistid,$artist_robyn_2->artistid,'Same artist'); $artist_robyn_1->delete(); } # Test with charfield NULL and not provided { my ($artist_santogold1,$artist_santogold2); $artist_santogold1 = $artist_rs->create({ name => 'Santogold', rank => 777, charfield => undef, }); throws_ok { $artist_santogold2 = $artist_rs->find_or_create({ name => 'Santogold', rank => 777, # <- Charfield not provided - hence should die },{ key => 'u_nullable', }); } qr/Unable to satisfy requested constraint/; $artist_santogold1->delete(); } done_testing;
On Thu Nov 18 06:36:54 2010, MAROS wrote: Show quoted text
> > I am not sure what the bugreport is about. The test case you attached > > throws with the correct expected error. Can you elaborate why you > > think this is not the desired behavior?
> > I have attached an updated test case that should make my point clearer. > > The problem is that the test dies if i provide the key with "charfield > => undef", which is a perfectly valid value and should translate to > NULL (or 'IS NULL') in the database. (see 'M.I.A.' test case).
It is pretty far from valid. When you ask for a specific key =>, you are essentially saying "satisfy this constraint uniquely", so DBIC does the obvious checks to make sure that it has all the values to satisfy the constraint. Considering that NULL != NULL, a null-containing constraint is not unique by definition. So DBIC tells you that what you asked does not match what you supplied. Admittedly this was not visible in earlier versions, due to a naive implementation bug. Let me know if this clears it up.
On Wed Nov 17 10:16:42 2010, MAROS wrote: Show quoted text
> Find or create on an unique constraint with nullable values does not > seem to work. See attached testcase for more details > > Cheers > Maroš
I am closing this as a non-bug. If you still feel the current behavior is incorrect - feel free to discuss it further (or better yet pop into irc.perl.org#dbix-class for a more interactive feedback)