use DBIx::Class::SQLMaker::Role::SQLA2Passthrough qw(on);
MySchema->source('Foo')->add_relationship(bars => 'Bar' => on {
+{ 'foreign.x' => 'self.x',
- 'self.y' => { -between => [ qw(foreign.y1 foreign.y2) ] }
+ 'foreign.y1' => { '<=', 'self.y' },
+ 'foreign.y2' => { '>=', 'self.y' },
};
});
}
warn ref($s->storage->sql_maker);
my $rs2 = $s->resultset('Foo')->search({
- -op => [ '=', { -ident => 'outer.y' }, { -ident => 'me.x' } ]
+ -op => [ '=', { -ident => 'outer.x' }, { -ident => 'me.y' } ]
}, {
'select' => [ 'me.x', { -ident => 'me.z' } ],
'!with' => [ outer => $rs->get_column('x')->as_query ],
->search({}, { prefetch => 'bars' });
::Dwarn(${$rs3->as_query}->[0]);
+
+$s->source('Foo')->result_class('DBIx::Class::Core');
+$s->source('Foo')->set_primary_key('x');
+
+my $rs4 = $s->resultset('Foo')->new_result({ x => 1, y => 2 })
+ ->search_related('bars');
+
+::Dwarn(${$rs4->as_query}->[0]);
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;