[Dbix-class] [PATCH] Correctly propagate forced left joins through
arrayrefs and hashrefs (2nd try)
Peter Collingbourne
peter at pcc.me.uk
Sun Apr 5 21:05:14 GMT 2009
Fixes a bug in DBIC::ResultSource::resolve_join whereby forced left
joins are not propagated through an arrayref or hashref. Thus if
relationship t1 has a left join_type and t2 has inner join_type,
either of the two clauses:
join => { t1 => [ 't2' ] }
join => { t1 => { t2 => {} } }
would incorrectly use an inner join for t2. Includes test case.
---
lib/DBIx/Class.pm | 2 ++
lib/DBIx/Class/ResultSource.pm | 8 ++++++--
t/66relationship.t | 12 +++++++++++-
t/93single_accessor_object.t | 2 +-
t/96multi_create_torture.t | 18 ++++++++++++++++++
t/lib/DBICTest/Schema.pm | 1 +
t/lib/DBICTest/Schema/Demographic.pm | 21 +++++++++++++++++++++
t/lib/DBICTest/Schema/Genre.pm | 5 +++++
t/lib/sqlite.sql | 13 ++++++++++++-
9 files changed, 77 insertions(+), 5 deletions(-)
create mode 100644 t/lib/DBICTest/Schema/Demographic.pm
diff --git a/lib/DBIx/Class.pm b/lib/DBIx/Class.pm
index 6582395..e18801a 100644
--- a/lib/DBIx/Class.pm
+++ b/lib/DBIx/Class.pm
@@ -281,6 +281,8 @@ penguin: K J Cheetham
perigrin: Chris Prather <chris at prather.org>
+Peter Collingbourne <peter at pcc.me.uk>
+
phaylon: Robert Sedlacek <phaylon at dunkelheit.at>
plu: Johannes Plunien <plu at cpan.org>
diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm
index bb178fc..0094fa4 100644
--- a/lib/DBIx/Class/ResultSource.pm
+++ b/lib/DBIx/Class/ResultSource.pm
@@ -1089,12 +1089,16 @@ sub resolve_join {
$seen ||= {};
$force_left ||= { force => 0 };
if (ref $join eq 'ARRAY') {
- return map { $self->resolve_join($_, $alias, $seen) } @$join;
+ return
+ map {
+ local $force_left->{force} = $force_left->{force};
+ $self->resolve_join($_, $alias, $seen, $force_left);
+ } @$join;
} elsif (ref $join eq 'HASH') {
return
map {
my $as = ($seen->{$_} ? $_.'_'.($seen->{$_}+1) : $_);
- local $force_left->{force};
+ local $force_left->{force} = $force_left->{force};
(
$self->resolve_join($_, $alias, $seen, $force_left),
$self->related_source($_)->resolve_join(
diff --git a/t/66relationship.t b/t/66relationship.t
index aa29ade..31d28d4 100644
--- a/t/66relationship.t
+++ b/t/66relationship.t
@@ -8,7 +8,7 @@ use DBICTest;
my $schema = DBICTest->init_schema();
-plan tests => 71;
+plan tests => 74;
# has_a test
my $cd = $schema->resultset("CD")->find(4);
@@ -289,3 +289,13 @@ cmp_ok($relinfo->{attrs}{is_foreign_key_constraint}, '==', 1, "is_foreign_key_co
my $rs_overridden = $schema->source('ForceForeign');
my $relinfo_with_attr = $rs_overridden->relationship_info ('cd_3');
cmp_ok($relinfo_with_attr->{attrs}{is_foreign_key_constraint}, '==', 0, "is_foreign_key_constraint defined for belongs_to relationships with attr.");
+
+# check that relationships below left join relationships are forced to left joins
+my $cds = $schema->resultset("CD")->search({ cdid => 1 }, { join => { genre => 'demographic' } });
+is($cds->count, 1, "subjoins under left joins force_left (string)");
+
+$cds = $schema->resultset("CD")->search({ cdid => 1 }, { join => { genre => [ 'demographic' ] } });
+is($cds->count, 1, "subjoins under left joins force_left (arrayref)");
+
+$cds = $schema->resultset("CD")->search({ cdid => 1 }, { join => { genre => { demographic => {} } } });
+is($cds->count, 1, "subjoins under left joins force_left (hashref)");
diff --git a/t/93single_accessor_object.t b/t/93single_accessor_object.t
index 2303bdb..8a1281a 100644
--- a/t/93single_accessor_object.t
+++ b/t/93single_accessor_object.t
@@ -56,7 +56,7 @@ $schema = DBICTest->init_schema();
{
my $artist = $schema->resultset('Artist')->create({ artistid => 666, name => 'bad religion' });
- my $genre = $schema->resultset('Genre')->create({ genreid => 88, name => 'disco' });
+ my $genre = $schema->resultset('Genre')->create({ genreid => 88, name => 'disco', demographicid => 1 });
my $cd = $schema->resultset('CD')->create({ cdid => 187, artist => 1, title => 'how could hell be any worse?', year => 1982 });
dies_ok { $cd->genre } 'genre accessor throws without column';
diff --git a/t/96multi_create_torture.t b/t/96multi_create_torture.t
index e3a552d..dda1352 100644
--- a/t/96multi_create_torture.t
+++ b/t/96multi_create_torture.t
@@ -27,6 +27,9 @@ eval {
year => '2012',
genre => {
name => '"Greatest" collections',
+ demographic => {
+ name => '"Greatest" collections demographic',
+ },
},
tags => [
{ tag => 'A' },
@@ -47,6 +50,9 @@ eval {
year => 2012,
genre => {
name => '"Greatest" collections',
+ demographic => {
+ name => '"Greatest" collections demographic',
+ },
},
tags => [
{ tag => 'A' },
@@ -68,6 +74,9 @@ eval {
year => 2012,
genre => {
name => '"Greatest" collections',
+ demographic => {
+ name => '"Greatest" collections demographic',
+ },
},
tags => [
{ tag => 'A' },
@@ -79,6 +88,9 @@ eval {
year => 2012,
genre => {
name => '"Greatest" collections2',
+ demographic => {
+ name => '"Greatest" collections demographic',
+ },
},
tags => [
{ tag => 'A' },
@@ -91,6 +103,9 @@ eval {
year => 2013,
genre => {
name => '"Greatest" collections2',
+ demographic => {
+ name => '"Greatest" collections demographic',
+ },
},
}},
],
@@ -103,6 +118,9 @@ eval {
year => 2012,
genre => {
name => '"Greatest" collections',
+ demographic => {
+ name => '"Greatest" collections demographic',
+ },
},
tags => [
{ tag => 'A' },
diff --git a/t/lib/DBICTest/Schema.pm b/t/lib/DBICTest/Schema.pm
index b03d090..907c8cb 100644
--- a/t/lib/DBICTest/Schema.pm
+++ b/t/lib/DBICTest/Schema.pm
@@ -11,6 +11,7 @@ __PACKAGE__->load_classes(qw/
BindType
Employee
CD
+ Demographic
FileColumn
Genre
Link
diff --git a/t/lib/DBICTest/Schema/Demographic.pm b/t/lib/DBICTest/Schema/Demographic.pm
new file mode 100644
index 0000000..cff1eba
--- /dev/null
+++ b/t/lib/DBICTest/Schema/Demographic.pm
@@ -0,0 +1,21 @@
+package DBICTest::Schema::Demographic;
+
+use strict;
+
+use base 'DBIx::Class::Core';
+
+__PACKAGE__->table('demographic');
+__PACKAGE__->add_columns(
+ demographicid => {
+ data_type => 'integer',
+ is_auto_increment => 1,
+ },
+ name => {
+ data_type => 'varchar',
+ size => 100,
+ },
+);
+__PACKAGE__->set_primary_key('demographicid');
+__PACKAGE__->add_unique_constraint ( demographic_name => [qw/name/] );
+
+1;
diff --git a/t/lib/DBICTest/Schema/Genre.pm b/t/lib/DBICTest/Schema/Genre.pm
index db2ca9c..50a559c 100644
--- a/t/lib/DBICTest/Schema/Genre.pm
+++ b/t/lib/DBICTest/Schema/Genre.pm
@@ -14,10 +14,15 @@ __PACKAGE__->add_columns(
data_type => 'varchar',
size => 100,
},
+ demographicid => {
+ data_type => 'integer',
+ is_nullable => 0,
+ },
);
__PACKAGE__->set_primary_key('genreid');
__PACKAGE__->add_unique_constraint ( genre_name => [qw/name/] );
__PACKAGE__->has_many (cds => 'DBICTest::Schema::CD', 'genreid');
+__PACKAGE__->belongs_to (demographic => 'DBICTest::Schema::Demographic', 'demographicid');
1;
diff --git a/t/lib/sqlite.sql b/t/lib/sqlite.sql
index 105a490..3932c2b 100644
--- a/t/lib/sqlite.sql
+++ b/t/lib/sqlite.sql
@@ -137,6 +137,16 @@ CREATE INDEX collection_object_idx_collection_collection_obj ON collection_objec
CREATE INDEX collection_object_idx_object_c ON collection_object (object);
--
+-- Table: demographic
+--
+CREATE TABLE demographic (
+ demographicid INTEGER PRIMARY KEY NOT NULL,
+ name varchar(100) NOT NULL
+);
+
+CREATE UNIQUE INDEX demographic_name_demographic ON demographic (name);
+
+--
-- Table: employee
--
CREATE TABLE employee (
@@ -221,7 +231,8 @@ CREATE INDEX fourkeys_to_twokeys_idx_t_artist_t_cd_fourkeys_to ON fourkeys_to_tw
--
CREATE TABLE genre (
genreid INTEGER PRIMARY KEY NOT NULL,
- name varchar(100) NOT NULL
+ name varchar(100) NOT NULL,
+ demographicid INTEGER NOT NULL
);
CREATE UNIQUE INDEX genre_name_genre ON genre (name);
--
1.5.6.5
--
Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
Url : http://lists.scsys.co.uk/pipermail/dbix-class/attachments/20090405/538713f4/attachment.pgp
More information about the DBIx-Class
mailing list