【发布时间】:2018-05-15 20:36:40
【问题描述】:
我正在使用 DBIX::Class 并为这样的搜索生成条件:
my @array;
push @array, { condition1 => 'value1' };
push @array, [ { condition2 => 'value2' }, { condition3 => 'value3' } ];
必须使用 AND 运算符检查所有这些条件,这就是我写这个的原因:
@array = ( -and => @array );
在我的虚拟机上运行具有此类条件的代码后,进程开始使用多达 8 Gb 内存。我认为这是递归问题,我没有弄错。我查看了日志并查看了关于深度递归的记录,但我在互联网上找不到任何关于我的案例的信息。
将包含数组的列表分配给数组本身有问题吗? 或者可能是 DBIX::Class (SQL::Abstract) 的问题?为什么会导致深度递归?
更新。这是项目的真实代码:
sub faq {
my ( $self ) = @_;
my @cond;
if ( $self->param('faq_type') ) {
push @cond,
{
'me.faq_type' => $self->param('faq_type'),
};
}
if ( my $search = $self->param('search') ) {
push @cond,
[
'me.title' => { ilike => "%$search%" },
'me.text' => { ilike => "%$search%" },
];
}
@cond = ( -and => @cond );
my %attr = (
join => 'page_category',
rows => $self->param('limit'),
offset => $self->param('offset'),
order_by => { -desc => 'id' },
result_class => 'BUX::Util::HashRefInflator',
'+select' => [ qw( page_category.name ) ],
'+as' => [ qw( category_name ) ],
);
my @pages = BUX::DB->rs('Page')->search( \@cond, \%attr )->all;
my $total_count = BUX::DB->rs('Page')->count( \@cond );
return $self->render(json => {
pages => \@pages,
count => $total_count
});
}
以及日志记录:
在 /opt/perlbrew/perls/perl-5.14.4/lib/site_perl/5.14.4/SQL/Abstract.pm 第 719 行对子例程“SQL::Abstract::_SWITCH_refkind”进行深度递归。 在 /opt/perlbrew/perls/perl-5.14.4/lib/site_perl/5.14.4/SQL/Abstract.pm 第 546 行对子例程“SQL::Abstract::_recurse_where”进行深度递归。 在 /opt/perlbrew/perls/perl-5.14.4/lib/site_perl/5.14.4/SQL/Abstract.pm 第 687 行对子例程“SQL::Abstract::_where_ARRAYREF”进行深度递归。 在 /opt/perlbrew/perls/perl-5.14.4/lib/site_perl/5.14.4/SQL/Abstract.pm 第 493 行对子例程“SQL::Abstract::_where_HASHREF”进行深度递归。 在 /opt/perlbrew/perls/perl-5.14.4/lib/site_perl/5.14.4/SQL/Abstract.pm 第 596 行对子例程“SQL::Abstract::_where_unary_op”进行深度递归。 在 /opt/perlbrew/perls/perl-5.14.4/lib/site_perl/5.14.4/SQL/Abstract.pm 第 645 行对子例程“SQL::Abstract::_where_op_ANDOR”进行深度递归。
附: BUX::DB 是 DBIx::Class 的子类,rs 是 resultset 的快捷方式。
【问题讨论】:
-
请显示更多您的代码。
@array = (-and => @array);与@array = ('-and', @array);相同,只是将字符串-and前置到@array;它不是递归的。 (我不知道这对您对 operatorand987654333@ 的需求有何帮助) -
我的意思是你需要展示更多的代码。正如我所说,
@array = (-and => @array);itself 将'-and'添加到数组中,没有递归。如您所说,该数组确实被展平为列表。如果您分配\@array,那么这就是它添加的内容。但我们看不到其余代码的作用。 -
在我看来,您想要推送
{ condition2 => 'value2' }, ...,而不是[{condition2 => ...}, {...}]来获取hashrefs 数组。然后,您应该指定search({ -and => \@array })并且一切顺利。 -
您可能在循环中使用了该代码,因此您的数组越来越多。请edit 向我们展示更多信息,否则我们无法为您提供帮助。
-
'me.faq_type' => $self->param('faq_type')看起来可能容易被注入。param来自哪里?
标签: arrays list perl recursion