due to badly-written handlers (the mechanism was never meant
to be able to suppress exceptions)
- Fixed rels ending with me breaking subqueried limit realiasing
+ - Remove rogue GROUP BY on non-multiplying prefetch-induced
+ subqueries
- Oracle sequence detection now *really* works across schemas
(fixed some ommissions from 0.08123)
- dbicadmin now uses a /usr/bin/env shebang to work better with
# {multiplying} joins can go
delete $aliastypes->{multiplying} if $attrs->{group_by};
-
my @newfrom = $from->[0]; # FROM head is always present
my %need_joins = (map { %{$_||{}} } (values %$aliastypes) );
# construct the inner $from for the subquery
# we need to prune first, because this will determine if we need a group_by below
- my $inner_from = $self->_prune_unused_joins ($from, $inner_select, $where, $inner_attrs);
+ # the fake group_by is so that the pruner throws away all non-selecting, non-restricting
+ # multijoins (since we def. do not care about those inside the subquery)
+ my $inner_from = $self->_prune_unused_joins ($from, $inner_select, $where, {
+ group_by => ['dummy'], %$inner_attrs,
+ });
# if a multi-type join was needed in the subquery - add a group_by to simulate the
# collapse in the subq
# - it is part of the restrictions, in which case we need to collapse the outer
# result by tackling yet another group_by to the outside of the query
- # normalize a copy of $from, so it will be easier to work with further
- # down (i.e. promote the initial hashref to an AoH)
$from = [ @$from ];
- $from->[0] = [ $from->[0] ];
# so first generate the outer_from, up to the substitution point
my @outer_from;
while (my $j = shift @$from) {
+ $j = [ $j ] unless ref $j eq 'ARRAY'; # promote the head-from to an AoH
+
if ($j->[0]{-alias} eq $attrs->{alias}) { # time to swap
push @outer_from, [
$subq_joinspec,
$alias_list->{$al} = $j;
$aliases_by_type->{multiplying}{$al} = 1
- unless $j->{-is_single};
+ if ref($_) eq 'ARRAY' and ! $j->{-is_single}; # not array == {from} head == can't be multiplying
}
# get a column to source/alias map (including unqualified ones)
use Test::Exception;
use lib qw(t/lib);
use DBICTest;
+use DBIC::SqlMakerTest;
my $schema = DBICTest->init_schema();
my $artist2 = $use_prefetch->search({'cds.title' => { '!=' => $artist_many_cds->cds->first->title } })->slice (0,0)->next;
is($artist2->cds->count, 2, "count on search limiting prefetched has_many");
+# make sure 1:1 joins do not force a subquery (no point to exercise the optimizer, if at all available)
+# get cd's that have any tracks and their artists
+my $single_prefetch_rs = $schema->resultset ('CD')->search (
+ { 'me.year' => 2010, 'artist.name' => 'foo' },
+ { prefetch => ['tracks', 'artist'], rows => 15 },
+);
+is_same_sql_bind (
+ $single_prefetch_rs->as_query,
+ '(
+ SELECT
+ me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track,
+ tracks.trackid, tracks.cd, tracks.position, tracks.title, tracks.last_updated_on, tracks.last_updated_at, tracks.small_dt,
+ artist.artistid, artist.name, artist.rank, artist.charfield
+ FROM (
+ SELECT
+ me.cdid, me.artist, me.title, me.year, me.genreid, me.single_track
+ FROM cd me
+ JOIN artist artist ON artist.artistid = me.artist
+ WHERE ( ( artist.name = ? AND me.year = ? ) )
+ LIMIT 15
+ ) me
+ LEFT JOIN track tracks
+ ON tracks.cd = me.cdid
+ JOIN artist artist
+ ON artist.artistid = me.artist
+ WHERE ( ( artist.name = ? AND me.year = ? ) )
+ ORDER BY tracks.cd
+ )',
+ [
+ [ 'artist.name' => 'foo' ],
+ [ 'me.year' => 2010 ],
+ [ 'artist.name' => 'foo' ],
+ [ 'me.year' => 2010 ],
+ ],
+ 'No grouping of non-multiplying resultsets',
+);
+
done_testing;