}
if (blessed($call_cond) and $call_cond->isa('Data::Query::ExprBuilder')) {
- $call_cond = \$call_cond->{expr};
+ my ($mapped_expr, $extra_join)
+ = $self->_remap_identifiers($call_cond->{expr});
+ $call_cond = \$mapped_expr;
+ if (@$extra_join) {
+ $self->throw_exception("Can't handle join-requiring DQ expr when join attribute specified")
+ if $call_attrs->{join};
+ $call_attrs->{join} = $extra_join;
+ }
}
# see if we can keep the cache (no $rs changes)
return $rs;
}
+sub _remap_identifiers {
+ my ($self, $dq) = @_;
+ my $map = {};
+ my $attrs = $self->_resolved_attrs;
+ foreach my $j ( @{$attrs->{from}}[1 .. $#{$attrs->{from}} ] ) {
+ next unless $j->[0]{-alias};
+ next unless $j->[0]{-join_path};
+ my $p = $map;
+ $p = $p->{$_} ||= {} for map { keys %$_ } @{$j->[0]{-join_path}};
+ $p->{''} = $j->[0]{-alias};
+ }
+
+ my $seen_join = { %{$attrs->{seen_join}||{}} };
+ my $storage = $self->result_source->storage;
+ my @need_join;
+ my $mapped = map_dq_tree {
+ return $_ unless is_Identifier;
+ my @el = @{$_->{elements}};
+ my $last = pop @el;
+ unless (@el) {
+ return Identifier($attrs->{alias}, $last);
+ }
+ my $p = $map;
+ $p = $p->{$_} ||= {} for @el;
+ if (my $alias = $p->{''}) {
+ return Identifier($alias, $last);
+ }
+ my $need = my $j = {};
+ $j = $j->{$_} = {} for @el;
+ push @need_join, $need;
+ my $alias = $storage->relname_to_table_alias(
+ $el[-1], ++$seen_join->{$el[-1]}
+ );
+ return Identifier($alias, $last);
+ } $dq;
+ return ($mapped, \@need_join);
+}
+
my $dark_sel_dumper;
sub _normalize_selection {
my ($self, $attrs) = @_;
$source->_resolve_join(
$join,
$alias,
- { %{ $attrs->{seen_join} || {} } },
+ ($attrs->{seen_join} = { %{ $attrs->{seen_join} || {} } }),
( $attrs->{seen_join} && keys %{$attrs->{seen_join}})
? $attrs->{from}[-1][0]{-join_path}
: []
is($mccrae->cds2_pre2k->count, 2, 'CDs returned from expr w/cond');
+my $cds = $schema->resultset('CD')
+ ->search(expr { $_->artist->name eq 'Caterwauler McCrae' });
+
+is($cds->count, 3, 'CDs via join injection');
+
+my $tags = $schema->resultset('Tag')
+ ->search(expr { $_->cd->artist->name eq 'Caterwauler McCrae' });
+
+is($tags->count, 5, 'Tags via two step join injection');
+
done_testing;