my $alias = $attrs->{alias};
my $sql_maker = $self->sql_maker;
- # create subquery select list - loop only over primary columns
+ # create subquery select list - consider only stuff *not* brought in by the prefetch
my $sub_select = [];
for my $i (0 .. @{$attrs->{select}} - @{$attrs->{prefetch_select}} - 1) {
my $sel = $attrs->{select}[$i];
# adjust the outer select accordingly
if (ref $sel eq 'HASH' && !$sel->{-select}) {
$sel = { -select => $sel, -as => $attrs->{as}[$i] };
- $select->[$i] = join ('.', $attrs->{alias}, $attrs->{as}[$i]);
+ $select->[$i] = join ('.', $attrs->{alias}, ($attrs->{as}[$i] || "select_$i") );
}
push @$sub_select, $sel;
{
# produce stuff unquoted, so it can be scanned
local $sql_maker->{quote_char};
+ my $sep = $self->_sql_maker_opts->{name_sep} || '.';
+ $sep = "\Q$sep\E";
my @order_by = (map
{ ref $_ ? $_->[0] : $_ }
);
my $where_sql = $sql_maker->where ($where);
+ my $select_sql = $sql_maker->_recurse_fields ($sub_select);
# sort needed joins
for my $alias (keys %join_info) {
# any table alias found on a column name in where or order_by
# gets included in %inner_joins
# Also any parent joins that are needed to reach this particular alias
- for my $piece ($where_sql, @order_by ) {
- if ($piece =~ /\b$alias\./) {
+ for my $piece ($select_sql, $where_sql, @order_by ) {
+ if ($piece =~ /\b $alias $sep/x) {
$inner_joins{$alias} = 1;
}
}
my $track_rs = $schema->resultset ('Track')->search (
{ 'me.cd' => { -in => [ $cd_rs->get_column ('cdid')->all ] } },
{
- # the select/as is deliberately silly to test both funcs and refs below
select => [
'me.cd',
{ count => 'me.trackid' },
# Test sql by hand, as the sqlite db will simply paper over
# improper group/select combinations
#
- # the exploded IN needs fixing below, coming in another branch
- #
is_same_sql_bind (
$track_rs->count_rs->as_query,
'(
# test a has_many/might_have prefetch at the same level
# Note that one of the CDs now has 4 tracks instead of 3
{
- my $most_tracks_rs = $cd_rs->search ({}, {
- prefetch => 'liner_notes', # tracks are alredy prefetched
- select => ['me.cdid', { count => 'tracks.trackid' } ],
- as => [qw/cdid track_count/],
- group_by => 'me.cdid',
- order_by => { -desc => 'track_count' },
- rows => 2,
- });
+ my $most_tracks_rs = $schema->resultset ('CD')->search (
+ {
+ 'me.cdid' => { '!=' => undef }, # duh - this is just to test WHERE
+ },
+ {
+ prefetch => [qw/tracks liner_notes/],
+ select => ['me.cdid', { count => 'tracks.trackid' } ],
+ as => [qw/cdid track_count/],
+ group_by => 'me.cdid',
+ order_by => { -desc => 'track_count' },
+ rows => 2,
+ }
+ );
is_same_sql_bind (
$most_tracks_rs->count_rs->as_query,
FROM cd me
LEFT JOIN track tracks ON tracks.cd = me.cdid
LEFT JOIN liner_notes liner_notes ON liner_notes.liner_id = me.cdid
- WHERE ( tracks.cd IS NOT NULL )
+ WHERE ( me.cdid IS NOT NULL )
GROUP BY me.cdid
LIMIT 2
) count_subq
SELECT me.cdid, COUNT( tracks.trackid ) AS track_count
FROM cd me
LEFT JOIN track tracks ON tracks.cd = me.cdid
- WHERE ( tracks.cd IS NOT NULL )
+ WHERE ( me.cdid IS NOT NULL )
GROUP BY me.cdid
ORDER BY track_count DESC
LIMIT 2
) me
LEFT JOIN track tracks ON tracks.cd = me.cdid
LEFT JOIN liner_notes liner_notes ON liner_notes.liner_id = me.cdid
- WHERE ( tracks.cd IS NOT NULL )
+ WHERE ( me.cdid IS NOT NULL )
ORDER BY track_count DESC, tracks.cd
)',
[],