#
# This code will remove non-selecting/non-restricting joins from
-# {from} specs, aiding the RDBMS query optimizer.
+# {from} specs, aiding the RDBMS query optimizer
#
sub _prune_unused_joins {
- my $self = shift;
+ my ($self) = shift;
+
+ my ($from, $select, $where, $attrs) = @_;
- my $from = shift;
if (ref $from ne 'ARRAY' || ref $from->[0] ne 'HASH' || ref $from->[1] ne 'ARRAY') {
return $from; # only standard {from} specs are supported
}
- my $aliastypes = $self->_resolve_aliastypes_from_select_args($from, @_);
+ my $aliastypes = $self->_resolve_aliastypes_from_select_args(@_);
+
+ # a grouped set will not be affected by amount of rows. Thus any
+ # {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) );
for my $j (@{$from}[1..$#$from]) {
push @newfrom, $j if (
- ! $j->[0]{-alias} # legacy crap
+ (! $j->[0]{-alias}) # legacy crap
||
$need_joins{$j->[0]{-alias}}
);
SELECT genre.genreid
FROM (
SELECT me.artistid, me.name, me.rank, me.charfield
- FROM artist me GROUP BY me.artistid, me.name, me.rank, me.charfield
+ FROM artist me
+ GROUP BY me.artistid, me.name, me.rank, me.charfield
) me
JOIN cd cds ON cds.artist = me.artistid
JOIN genre genre ON genre.genreid = cds.genreid
- LEFT JOIN cd cds_2 ON cds_2.genreid = genre.genreid
- WHERE ( genre.name = ? ) GROUP BY genre.genreid
+ WHERE ( genre.name = ? )
+ GROUP BY genre.genreid
)
count_subq
)',
FROM (
SELECT me.cdid
FROM cd me
- LEFT JOIN track tracks ON tracks.cd = me.cdid
WHERE ( me.cdid IS NOT NULL )
GROUP BY me.cdid
LIMIT 2
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
- LEFT JOIN track tracks ON tracks.cd = me.cdid
+ LEFT JOIN track tracks ON tracks.cd = me.cdid
WHERE ( tracks.id != ? )
LIMIT 2
) me
JOIN artist artist ON artist.artistid = me.artist
- LEFT JOIN track tracks ON tracks.cd = me.cdid
JOIN tags tags ON tags.cd = me.cdid
WHERE ( tags.tag IS NOT NULL )
GROUP BY tags.tagid, tags.cd, tags.tag