X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FSQL-Abstract.git;a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSQLMaker%2FRole%2FSQLA2Passthrough.pm;fp=lib%2FDBIx%2FClass%2FSQLMaker%2FRole%2FSQLA2Passthrough.pm;h=04a543426e44dc959fe4bcb22842464a6a179a6c;hp=d7db581c5ca1a2b268907fdaf88443e9921981a1;hb=09cfd2c811356002fcea90881d258cf4b0b22e0f;hpb=66c7632248c755e440f300a45c6d1296f503c984 diff --git a/lib/DBIx/Class/SQLMaker/Role/SQLA2Passthrough.pm b/lib/DBIx/Class/SQLMaker/Role/SQLA2Passthrough.pm index d7db581..04a5434 100644 --- a/lib/DBIx/Class/SQLMaker/Role/SQLA2Passthrough.pm +++ b/lib/DBIx/Class/SQLMaker/Role/SQLA2Passthrough.pm @@ -50,19 +50,64 @@ around select => sub { sub expand_join_condition { my ($self, $cond, $args) = @_; + my ($type, %known) = do { + if (my $obj = $args->{self_result_object}) { + (self => $obj->get_columns) + } elsif (my $val = $args->{foreign_values}) { + (foreign => %$val) + } else { + ('') + } + }; + my $maybe = $type ? 1 : 0; + my $outside; my $wrap = sub { my ($orig) = @_; + $outside = $orig; sub { my $res = $orig->(@_); - my ($name, @rest) = @{$res->{-ident}}; + my ($name, $col) = @{$res->{-ident}}; if ($name eq 'self' or $name eq 'foreign') { - $res->{-ident} = [ $args->{"${name}_alias"}, @rest ]; + if ($type eq $name) { + $maybe = 0 unless exists $known{$col}; + } + return { -ident => [ $args->{"${name}_alias"}, $col ] }; } return $res; }; }; my $sqla = $self->clone->wrap_op_expander(ident => $wrap); - $sqla->expand_expr($cond, -ident); + my $aqt = $sqla->expand_expr($cond, -ident); + return $aqt unless $maybe; + my $inner_wrap = sub { + my $res = $outside->(@_); + my ($name, $col) = @{$res->{-ident}}; + if ($name eq 'self' or $name eq 'foreign') { + if ($type eq $name) { + return { -bind => [ $args->{"${name}_alias"}.'.'.$col, $known{$col} ] }; + } + return { -ident => [ $args->{"${name}_alias"}, $col ] }; + } + return $res; + }; + $sqla->op_expander(ident => $inner_wrap); + my $inner_aqt = $self->_collapsify($sqla->expand_expr($cond, -ident)); + return ($aqt, $inner_aqt); +} + +sub _collapsify { + my ($self, $aqt) = @_; + return $aqt unless my @opargs = @{$aqt->{-op}}; + my ($logop, @args) = @opargs; + return $aqt unless $logop eq 'and'; + my %collapsed = map { + my $q = $_; + return $aqt unless my @opargs = @{$q->{-op}}; + my ($op, $lhs, @rest) = @opargs; + return $aqt unless my @ident = @{$lhs->{-ident}}; + (join('.', @ident), { $op => \@rest }); + } @args; + return \%collapsed; } 1;