X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBIHacks.pm;h=fd1bde54a096f3bcbdbc6ee0147fa0329b6de840;hb=4c2b30d6e53cd05e570ad112e87ad6f96355f695;hp=f5a03c92a7d1c2afb045dad4e01e932e0111f949;hpb=0a3441ee8e0e747cfa05eff02df0d918ed5d6acb;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBIHacks.pm b/lib/DBIx/Class/Storage/DBIHacks.pm index f5a03c9..fd1bde5 100644 --- a/lib/DBIx/Class/Storage/DBIHacks.pm +++ b/lib/DBIx/Class/Storage/DBIHacks.pm @@ -247,7 +247,9 @@ sub _resolve_aliastypes_from_select_args { # set up a botched SQLA my $sql_maker = $self->sql_maker; - local $sql_maker->{having_bind}; # these are throw away results + # these are throw away results, do not pollute the bind stack + local $sql_maker->{having_bind}; + local $sql_maker->{select_bind}; # we can't scan properly without any quoting (\b doesn't cut it # everywhere), so unless there is proper quoting set - use our @@ -259,7 +261,9 @@ sub _resolve_aliastypes_from_select_args { 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"; + $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} = ''; } @@ -274,8 +278,8 @@ sub _resolve_aliastypes_from_select_args { }), ], selecting => [ - $self->_extract_order_columns ($attrs->{order_by}, $sql_maker), $sql_maker->_recurse_fields ($select), + ( map { $_->[0] } $self->_extract_order_criteria ($attrs->{order_by}, $sql_maker) ), ], }; @@ -334,6 +338,7 @@ sub _resolve_aliastypes_from_select_args { return $aliases_by_type; } +# This is the engine behind { distinct => 1 } sub _group_over_selection { my ($self, $from, $select, $order_by) = @_; @@ -354,11 +359,12 @@ sub _group_over_selection { # add any order_by parts that are not already present in the group_by # we need to be careful not to add any named functions/aggregates - # i.e. select => [ ... { count => 'foo', -as 'foocount' } ... ] - for my $chunk ($self->_extract_order_columns($order_by)) { + # i.e. order_by => [ ... { count => 'foo' } ... ] + for ($self->_extract_order_criteria($order_by)) { # only consider real columns (for functions the user got to do an explicit group_by) - my $colinfo = $rs_column_list->{$chunk} - or next; + next if @$_ != 1; + my $chunk = $_->[0]; + my $colinfo = $rs_column_list->{$chunk} or next; $chunk = "$colinfo->{-source_alias}.$chunk" if $chunk !~ /\./; push @group_by, $chunk unless $group_index{$chunk}++; @@ -411,7 +417,7 @@ sub _resolve_column_info { my ($self, $ident, $colnames) = @_; my ($alias2src, $root_alias) = $self->_resolve_ident_sources($ident); - my (%return, %seen_cols, @auto_colnames); + my (%seen_cols, @auto_colnames); # compile a global list of column names, to be able to properly # disambiguate unqualified column names (if at all possible) @@ -428,25 +434,23 @@ sub _resolve_column_info { grep { @{$seen_cols{$_}} == 1 } (keys %seen_cols), ]; - COLUMN: + my (%return, $colinfos); foreach my $col (@$colnames) { - my ($alias, $colname) = $col =~ m/^ (?: ([^\.]+) \. )? (.+) $/x; + my ($source_alias, $colname) = $col =~ m/^ (?: ([^\.]+) \. )? (.+) $/x; - unless ($alias) { - # see if the column was seen exactly once (so we know which rsrc it came from) - if ($seen_cols{$colname} and @{$seen_cols{$colname}} == 1) { - $alias = $seen_cols{$colname}[0]; - } - else { - next COLUMN; - } - } + # if the column was seen exactly once - we know which rsrc it came from + $source_alias ||= $seen_cols{$colname}[0] + if ($seen_cols{$colname} and @{$seen_cols{$colname}} == 1); - my $rsrc = $alias2src->{$alias}; - $return{$col} = $rsrc && { - %{$rsrc->column_info($colname)}, + next unless $source_alias; + + my $rsrc = $alias2src->{$source_alias} + or next; + + $return{$col} = { + %{ ( $colinfos->{$source_alias} ||= $rsrc->columns_info )->{$colname} }, -result_source => $rsrc, - -source_alias => $alias, + -source_alias => $source_alias, }; } @@ -588,7 +592,7 @@ sub _strip_cond_qualifiers { return $cond; } -sub _extract_order_columns { +sub _extract_order_criteria { my ($self, $order_by, $sql_maker) = @_; my $parser = sub { @@ -598,8 +602,9 @@ sub _extract_order_columns { unless wantarray; my @chunks; - for my $chunk (map { ref $_ ? @$_ : $_ } ($sql_maker->_order_by_chunks ($order_by) ) ) { - $chunk =~ s/\s+ (?: ASC|DESC ) \s* $//ix; + for ($sql_maker->_order_by_chunks ($order_by) ) { + my $chunk = ref $_ ? $_ : [ $_ ]; + $chunk->[0] =~ s/\s+ (?: ASC|DESC ) \s* $//ix; push @chunks, $chunk; }