X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSet.pm;h=427657a994f8d60eb52e0d05073d60a9fbc488c1;hb=0959ba52e25db43fcd4fe83c2b49ad017d978fd0;hp=0a6963b3a74faad96792ac19fbd98023bf5ecbc7;hpb=9f2baadf578157afd2130127f76ae07b17fbbdc5;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 0a6963b..427657a 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -9,13 +9,17 @@ use Data::Page; use Storable; use DBIx::Class::ResultSetColumn; use DBIx::Class::ResultSourceHandle; -use List::Util (); use Hash::Merge (); use Scalar::Util qw/blessed weaken/; use Try::Tiny; use Storable qw/nfreeze thaw/; + +# not importing first() as it will clash with our own method +use List::Util (); + use namespace::clean; + BEGIN { # De-duplication in _merge_attr() is disabled, but left in for reference *__HM_DEDUP = sub () { 0 }; @@ -267,15 +271,22 @@ sub search { my $self = shift; my $rs = $self->search_rs( @_ ); - my $want = wantarray; - if ($want) { + if (wantarray) { return $rs->all; } - elsif (defined $want) { + elsif (defined wantarray) { return $rs; } else { - $self->throw_exception ('->search is *not* a mutator, calling it in void context makes no sense'); + # we can be called by a relationship helper, which in + # turn may be called in void context due to some braindead + # overload or whatever else the user decided to be clever + # at this particular day. Thus limit the exception to + # external code calls only + $self->throw_exception ('->search is *not* a mutator, calling it in void context makes no sense') + if (caller)[0] !~ /^\QDBIx::Class::/; + + return (); } } @@ -1302,10 +1313,42 @@ sub _count_subq_rs { if (ref $sel eq 'HASH' and $sel->{-as}); } - for my $g_part (@$g) { - my $colpiece = $sel_index->{$g_part} || $g_part; + # anything from the original select mentioned on the group-by needs to make it to the inner selector + # also look for named aggregates referred in the having clause + # having often contains scalarrefs - thus parse it out entirely + my @parts = @$g; + if ($attrs->{having}) { + local $sql_maker->{having_bind}; + local $sql_maker->{quote_char} = $sql_maker->{quote_char}; + local $sql_maker->{name_sep} = $sql_maker->{name_sep}; + unless (defined $sql_maker->{quote_char} and length $sql_maker->{quote_char}) { + $sql_maker->{quote_char} = [ "\x00", "\xFF" ]; + # if we don't unset it we screw up retarded but unfortunately working + # 'MAX(foo.bar)' => { '>', 3 } + $sql_maker->{name_sep} = ''; + } + + my ($lquote, $rquote, $sep) = map { quotemeta $_ } ($sql_maker->_quote_chars, $sql_maker->name_sep); + + my $sql = $sql_maker->_parse_rs_attrs ({ having => $attrs->{having} }); + + # search for both a proper quoted qualified string, for a naive unquoted scalarref + # and if all fails for an utterly naive quoted scalar-with-function + while ($sql =~ / + $rquote $sep $lquote (.+?) $rquote + | + [\s,] \w+ \. (\w+) [\s,] + | + [\s,] $lquote (.+?) $rquote [\s,] + /gx) { + push @parts, ($1 || $2 || $3); # one of them matched if we got here + } + } + + for (@parts) { + my $colpiece = $sel_index->{$_} || $_; - # disqualify join-based group_by's. Arcane but possible query + # unqualify join-based group_by's. Arcane but possible query # also horrible horrible hack to alias a column (not a func.) # (probably need to introduce SQLA syntax) if ($colpiece =~ /\./ && $colpiece !~ /^$attrs->{alias}\./) { @@ -2709,7 +2752,7 @@ sub is_paged { sub is_ordered { my ($self) = @_; - return scalar $self->result_source->storage->_extract_order_columns($self->{attrs}{order_by}); + return scalar $self->result_source->storage->_extract_order_criteria($self->{attrs}{order_by}); } =head2 related_resultset @@ -3152,16 +3195,6 @@ sub _resolved_attrs { $_->{as} = [ map { $_ =~ /^\Q$alias.\E(.+)$/ ? $1 : $_ } @{$_->{as}} ]; } - # FIXME !!! - # Blatant bugwardness encoded into multiple tests. - # While columns behaves sensibly, +columns is expected - # to dump *any* foreign columns into the main object - # /me vomits - $selection_pieces->{'+columns'}{as} = [ map - { (split /\./, $_)[-1] } - @{$selection_pieces->{'+columns'}{as}} - ]; - # merge everything for (@sel_pairs) { $attrs->{select} = $self->_merge_attr ($attrs->{select}, $selection_pieces->{$_}{select});