my $class = ref($self) || $self;
my %opt = (ref $_[0] eq 'HASH') ? %{$_[0]} : @_;
+ # Work around bug in DBIx::Class t/52leaks.t
+ #
+ # Newer perls cache anon subs with no closed over values since the result
+ # is constant, but only on first evaluation, so when the perl5 VM creates
+ # them on-demand during new() the DBIx::Class leak test code sees them as
+ # created and not freed, therefore leaked.
+ #
+ # So to make this work for users pinned to v0.082841 of DBIx::Class
+ # (the last version before the hostile fork of this module) we need to
+ # create an ersatz closed over value that defeats the perl5 VM's
+ # improvement.
+ #
+ # We do this by creating a faux scalar that's never used for anything, and
+ # then in subroutines that need to -not- be cached to pass, add
+ #
+ # $fake_out_dbic_leak_test_bug if 0;
+ #
+ # which the peephole optimiser will turn into an OP_NULL because it can
+ # spot that it's an if with a false condition, so any performance overhead
+ # should be minimal.
+
+ my $fake_out_dbic_leak_test_bug;
+
# choose our case by keeping an option around
delete $opt{case} if $opt{case} && $opt{case} ne 'lower';
}
if (__PACKAGE__->can('_table') ne $class->can('_table')) {
$opt{expand_clause}{'select.from'} = sub {
+ $fake_out_dbic_leak_test_bug if 0;
return +{ -literal => [ $_[0]->_table($_[2]) ] };
};
}
if (__PACKAGE__->can('_order_by') ne $class->can('_order_by')) {
- $opt{expand_clause}{'select.order_by'} = sub { $_[2] };
+ $opt{expand_clause}{'select.order_by'} = sub {
+ $fake_out_dbic_leak_test_bug if 0;
+ $_[2]
+ };
$opt{render_clause}{'select.order_by'} = sub {
+ $fake_out_dbic_leak_test_bug if 0;
[ $_[0]->_order_by($_[2]) ];
};
}
$opt{warn_once_on_nest} = 1;
$opt{disable_old_special_ops} = 1;
$opt{render_clause}{'select.where'} = sub {
+ $fake_out_dbic_leak_test_bug if 0;
my ($sql, @bind) = $_[0]->where($_[2]);
s/\A\s+//, s/\s+\Z// for $sql;
return [ $sql, @bind ];
};
$opt{expand_op}{ident} = $class->make_unop_expander(sub {
+ $fake_out_dbic_leak_test_bug if 0;
my ($self, undef, $body) = @_;
$body = $body->from if Scalar::Util::blessed($body);
$self->_expand_ident(ident => $body);
$opt{join_sql_parts} ||= sub { SQL::Abstract::Parts->new(@_) };
}
- $opt{join_sql_parts} ||= sub { join $_[0], @_[1..$#_] };
+ $opt{join_sql_parts} ||= sub {
+ $fake_out_dbic_leak_test_bug if 0;
+ join $_[0], @_[1..$#_];
+ };
return bless \%opt, $class;
}