From: Peter Rabbitson Date: Tue, 4 Aug 2009 21:05:03 +0000 (+0000) Subject: Merge 'prefetch_bug-related_resultset_order_by_plus_limit' into 'prefetch_redux' X-Git-Tag: v0.08109~48^2~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e711f3168414b165f83499758dc669753cdf5be5;hp=23b67299bf3b2c3979f5193475088e780909109a;p=dbsrgits%2FDBIx-Class.git Merge 'prefetch_bug-related_resultset_order_by_plus_limit' into 'prefetch_redux' Move norbi's test to prefetch_redux - it's the same idea --- diff --git a/Changes b/Changes index 8145785..3a07811 100644 --- a/Changes +++ b/Changes @@ -6,11 +6,14 @@ Revision history for DBIx::Class 'force_pool' attribute. Lots of documentation updates, including a new Introduction.pod file. Fixed the way we detect transaction to make this more reliable and forward looking. Fixed some trouble with - the way Moose Types are used. + the way Moose Types are used. + - Added new MySQL specific on_connect_call macro 'set_strict_mode' + (also known as make_mysql_not_suck_as_much) - Added call to Pod::Inherit in Makefile.PL - currently at author-time only, so we need to add the produced .pod files to the MANIFEST + 0.08108 2009-07-05 23:15:00 (UTC) - Fixed the has_many prefetch with limit/group deficiency - it is now possible to select "top 5 commenters" while diff --git a/Makefile.PL b/Makefile.PL index 2c65cfe..d21951b 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -60,8 +60,8 @@ resources 'MailingList' => 'http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/db # re-build README and require extra modules for testing if we're in a checkout my %force_requires_if_author = ( +# 'Module::Install::Pod::Inherit' => 0.01, 'Test::Pod::Coverage' => 1.04, - 'Module::Install::Pod::Inherit' => 0.01, 'SQL::Translator' => 0.09007, # CDBI-compat related @@ -137,8 +137,8 @@ EOW unlink 'MANIFEST'; } - eval { require Module::Install::Pod::Inherit }; - PodInherit() if !$@; +# eval { require Module::Install::Pod::Inherit }; +# PodInherit() if !$@; } auto_install(); diff --git a/lib/DBIx/Class.pm b/lib/DBIx/Class.pm index 4db8939..34ab70d 100644 --- a/lib/DBIx/Class.pm +++ b/lib/DBIx/Class.pm @@ -73,9 +73,11 @@ Create a schema class called MyDB/Schema.pm: 1; -Create a table class to represent artists, who have many CDs, in +Create a result class to represent artists, who have many CDs, in MyDB/Schema/Result/Artist.pm: +See L for docs on defining result classes. + package MyDB::Schema::Result::Artist; use base qw/DBIx::Class/; @@ -87,7 +89,7 @@ MyDB/Schema/Result/Artist.pm: 1; -A table class to represent a CD, which belongs to an artist, in +A result class to represent a CD, which belongs to an artist, in MyDB/Schema/Result/CD.pm: package MyDB::Schema::Result::CD; @@ -109,9 +111,17 @@ Then you can use these classes in your application's code: # Query for all artists and put them in an array, # or retrieve them as a result set object. + # $schema->resultset returns a DBIx::Class::ResultSet my @all_artists = $schema->resultset('Artist')->all; my $all_artists_rs = $schema->resultset('Artist'); + # Output all artists names + # $artist here is a DBIx::Class::Row, which has accessors + # for all its columns. Rows are also subclasses of your Result class. + foreach $artist (@artists) { + print $artist->name, "\n"; + } + # Create a result set to search for artists. # This does not query the DB. my $johns_rs = $schema->resultset('Artist')->search( diff --git a/lib/DBIx/Class/InflateColumn/DateTime.pm b/lib/DBIx/Class/InflateColumn/DateTime.pm index 1d19012..7e50807 100644 --- a/lib/DBIx/Class/InflateColumn/DateTime.pm +++ b/lib/DBIx/Class/InflateColumn/DateTime.pm @@ -119,6 +119,9 @@ sub register_column { if ($type eq "timestamp with time zone" || $type eq "timestamptz") { $type = "timestamp"; $info->{_ic_dt_method} ||= "timestamp_with_timezone"; + } elsif ($type eq "timestamp without time zone") { + $type = "timestamp"; + $info->{_ic_dt_method} ||= "timestamp_without_timezone"; } elsif ($type eq "smalldatetime") { $type = "datetime"; $info->{_ic_dt_method} ||= "datetime"; diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index ed1cdc0..e24dafe 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -1264,7 +1264,7 @@ sub _count_subq_rs { my $sub_attrs = { %$attrs }; # extra selectors do not go in the subquery and there is no point of ordering it - delete $sub_attrs->{$_} for qw/collapse prefetch_select select as order_by/; + delete $sub_attrs->{$_} for qw/collapse select _prefetch_select as order_by/; # if we prefetch, we group_by primary keys only as this is what we would get out of the rs via ->next/->all # clobber old group_by regardless @@ -2875,6 +2875,12 @@ sub _resolved_attrs { $attrs->{group_by} = [ $attrs->{group_by} ]; } + # generate the distinct induced group_by early, as prefetch will be carried via a + # subquery (since a group_by is present) + if (delete $attrs->{distinct}) { + $attrs->{group_by} ||= [ grep { !ref($_) || (ref($_) ne 'HASH') } @{$attrs->{select}} ]; + } + $attrs->{collapse} ||= {}; if ( my $prefetch = delete $attrs->{prefetch} ) { $prefetch = $self->_merge_attr( {}, $prefetch ); @@ -2886,19 +2892,16 @@ sub _resolved_attrs { my @prefetch = $source->_resolve_prefetch( $prefetch, $alias, $join_map, $prefetch_ordering, $attrs->{collapse} ); - $attrs->{prefetch_select} = [ map { $_->[0] } @prefetch ]; - push @{ $attrs->{select} }, @{$attrs->{prefetch_select}}; + # we need to somehow mark which columns came from prefetch + $attrs->{_prefetch_select} = [ map { $_->[0] } @prefetch ]; + + push @{ $attrs->{select} }, @{$attrs->{_prefetch_select}}; push @{ $attrs->{as} }, (map { $_->[1] } @prefetch); push( @{$attrs->{order_by}}, @$prefetch_ordering ); $attrs->{_collapse_order_by} = \@$prefetch_ordering; } - - if (delete $attrs->{distinct}) { - $attrs->{group_by} ||= [ grep { !ref($_) || (ref($_) ne 'HASH') } @{$attrs->{select}} ]; - } - # if both page and offset are specified, produce a combined offset # even though it doesn't make much sense, this is what pre 081xx has # been doing @@ -2928,7 +2931,7 @@ sub _joinpath_aliases { for my $j (@$fromspec) { next if ref $j ne 'ARRAY'; - next if $j->[0]{-relation_chain_depth} < $cur_depth; + next if ($j->[0]{-relation_chain_depth} || 0) < $cur_depth; my $jpath = $j->[0]{-join_path}; @@ -3377,6 +3380,42 @@ with that artist is given below (assuming many-to-many from artists to tags): B If you specify a C attribute, the C and C