From: Peter Rabbitson Date: Sat, 20 Jun 2009 22:42:18 +0000 (+0000) Subject: That should be all X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=64c7c000587e6e6dccb9fc6330a66dcebd1f3695;p=dbsrgits%2FDBIx-Class-Historic.git That should be all --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 72b0c79..bb5ebef 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -1259,6 +1259,9 @@ sub _count_subq_rs { $sub_attrs->{select} = $rsrc->storage->_subq_count_select ($rsrc, $sub_attrs); + # this is so that ordering can be thrown away in things like Top limit + $sub_attrs->{-for_count_only} = 1; + $attrs->{from} = [{ count_subq => $rsrc->resultset_class->new ($rsrc, $sub_attrs )->as_query }]; diff --git a/lib/DBIx/Class/SQLAHacks.pm b/lib/DBIx/Class/SQLAHacks.pm index f99e0f7..ba89264 100644 --- a/lib/DBIx/Class/SQLAHacks.pm +++ b/lib/DBIx/Class/SQLAHacks.pm @@ -216,6 +216,16 @@ sub _Top { my ( $order_by_inner, $order_by_outer ) = $self->_order_directions($limit_order); my $order_by_requested = $self->_order_by ($req_order); + # generate the rest + delete $order->{$_} for qw/order_by _virtual_order_by/; + my $grpby_having = $self->_order_by ($order); + + # short circuit for counts - the ordering complexity is needless + if ($self->{_dbic_rs_attrs}{-for_count_only}) { + return "SELECT TOP $rows $inner_select $sql $grpby_having $order_by_outer"; + } + + # we can't really adjust the order_by columns, as introspection is lacking # resort to simple substitution for my $col (keys %outer_col_aliases) { @@ -227,12 +237,6 @@ sub _Top { $order_by_inner =~ s/\s+$col\s+/$col_aliases{$col}/g; } - - # generate the rest - delete $order->{$_} for qw/order_by _virtual_order_by/; - my $grpby_having = $self->_order_by ($order); - - my $inner_lim = $rows + $offset; $sql = "SELECT TOP $inner_lim $inner_select $sql $grpby_having $order_by_inner"; diff --git a/t/746mssql.t b/t/746mssql.t index a23898f..a958986 100644 --- a/t/746mssql.t +++ b/t/746mssql.t @@ -11,7 +11,7 @@ my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MSSQL_ODBC_${_}" } qw/DSN USER PA plan skip_all => 'Set $ENV{DBICTEST_MSSQL_ODBC_DSN}, _USER and _PASS to run this test' unless ($dsn && $user); -plan tests => 23; +plan tests => 25; my $schema = DBICTest::Schema->connect($dsn, $user, $pass); @@ -154,29 +154,26 @@ $schema->populate ('BooksInLibrary', [ local $TODO = 'limit past end of resultset problem'; is ($owners->page(3)->all, 2, 'has_many prefetch returns correct number of rows'); is ($owners->page(3)->count, 2, 'has-many prefetch returns correct count'); + is ($owners->page(3)->count_rs->next, 2, 'has-many prefetch returns correct count_rs'); + + # make sure count does not become overly complex FIXME + is_same_sql_bind ( + $owners->page(3)->count_rs->as_query, + '( + SELECT COUNT( * ) + FROM ( + SELECT TOP 3 me.id + FROM owners me + LEFT JOIN books books ON books.owner = me.id + WHERE ( books.id IS NOT NULL ) + GROUP BY me.id + ORDER BY me.id DESC + ) count_subq + )', + [], + ); } - # make sure count does not become overly complex FIXME - is_same_sql_bind ( - $owners->page(2)->count_rs->as_query, - '( - SELECT COUNT( * ) - FROM ( - SELECT TOP 3 id - FROM ( - SELECT TOP 6 me.id - FROM owners me - LEFT JOIN books books ON books.owner = me.id - WHERE ( books.id IS NOT NULL ) - GROUP BY me.id - ORDER BY me.id ASC - ) AS inner_sel - ORDER BY id DESC - ) count_subq - )', - [], - ); - # try a ->belongs_to direction (no select collapse, group_by should work) my $books = $schema->resultset ('BooksInLibrary')->search ({ 'owner.name' => [qw/wiggle woggle/], @@ -195,33 +192,30 @@ $schema->populate ('BooksInLibrary', [ local $TODO = 'limit past end of resultset problem'; is ($books->page(2)->all, 1, 'Prefetched grouped search returns correct number of rows'); is ($books->page(2)->count, 1, 'Prefetched grouped search returns correct count'); + is ($books->page(2)->count_rs->next, 1, 'Prefetched grouped search returns correct count_rs'); + + # make sure count does not become overly complex FIXME + is_same_sql_bind ( + $books->page(2)->count_rs->as_query, + '( + SELECT COUNT( * ) + FROM ( + SELECT TOP 2 me.id + FROM books me + JOIN owners owner ON owner.id = me.owner + WHERE ( ( ( owner.name = ? OR owner.name = ? ) AND source = ? ) ) + GROUP BY me.id, me.source, me.owner, me.title, me.price, owner.id, owner.name + ORDER BY me.id DESC + ) count_subq + )', + [ + [ 'owner.name' => 'wiggle' ], + [ 'owner.name' => 'woggle' ], + [ 'source' => 'Library' ], + ], + ); } - # make sure count does not become overly complex FIXME - is_same_sql_bind ( - $books->page(2)->count_rs->as_query, - '( - SELECT COUNT( * ) - FROM ( - SELECT TOP 2 id - FROM ( - SELECT TOP 4 me.id - FROM books me - JOIN owners owner ON owner.id = me.owner - WHERE ( ( ( owner.name = ? OR owner.name = ? ) AND source = ? ) ) - GROUP BY me.id, me.source, me.owner, me.title, me.price, owner.id, owner.name - ORDER BY me.id ASC - ) AS inner_sel - ORDER BY id DESC - ) count_subq - )', - [ - [ 'owner.name' => 'wiggle' ], - [ 'owner.name' => 'woggle' ], - [ 'source' => 'Library' ], - ], - ); - } # clean up our mess