From f57776d50ca0cc6419b87ed9a476441be91d7835 Mon Sep 17 00:00:00 2001 From: Galen Charlton Date: Fri, 20 Mar 2015 21:21:16 +0000 Subject: [PATCH] teach Clark Kent how to limit the size of a resultset A report that returns too many rows may consume memory to not good effect. This patch adds a new command-line parameter to Clark Kent, --resultset-limit, to allow report results to be truncated at the specified number of rows. Since the user cannot know how many results the report would have had without the limit, the main purpose of this patch is to reduce the chance that clark-kent.pl will trigger OOM-killer. Signed-off-by: Galen Charlton --- Open-ILS/src/perlmods/lib/OpenILS/Reporter/SQLBuilder.pm | 12 ++++++++++++ Open-ILS/src/reporter/clark-kent.pl | 3 +++ 2 files changed, 15 insertions(+) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Reporter/SQLBuilder.pm b/Open-ILS/src/perlmods/lib/OpenILS/Reporter/SQLBuilder.pm index 940972a33e..3291a4fe73 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Reporter/SQLBuilder.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Reporter/SQLBuilder.pm @@ -38,6 +38,13 @@ sub relative_time { return $self->builder->{_relative_time}; } +sub resultset_limit { + my $self = shift; + my $limit = shift; + $self->builder->{_resultset_limit} = $limit if (defined $limit); + return self->builder->{_resultset_limit}; +} + sub resolve_param { my $self = shift; my $val = shift; @@ -237,6 +244,8 @@ sub toSQL { if ($self->is_subquery) { $sql = '('; + } elsif ($self->resultset_limit) { + $sql = 'SELECT * FROM ('; } $sql .= "SELECT\t" . join(",\n\t", map { $_->toSQL } @{ $self->{_select} }) . "\n" if (@{ $self->{_select} }); @@ -251,6 +260,9 @@ sub toSQL { if ($self->is_subquery) { $sql .= ') '. $self->{_alias} . "\n"; + } elsif ($self->resultset_limit) { + $sql .= ') limited_to_' . $self->resultset_limit . + '_hits LIMIT ' . $self->resultset_limit . "\n"; } return $self->{_sql} = $sql; diff --git a/Open-ILS/src/reporter/clark-kent.pl b/Open-ILS/src/reporter/clark-kent.pl index 3821011fd8..de8d80679e 100755 --- a/Open-ILS/src/reporter/clark-kent.pl +++ b/Open-ILS/src/reporter/clark-kent.pl @@ -35,12 +35,14 @@ my ($count, $config, $sleep_interval, $lockfile, $daemon) = (1, 'SYSCONFDIR/open # before Clark refuses to try to draw a chart my $max_rows_for_charts = 1000; my $statement_timeout = 10 * 60 * 1000; +my $resultset_limit; GetOptions( "daemon" => \$daemon, "sleep=i" => \$sleep_interval, "concurrency=i" => \$count, "max-rows-for-charts=i" => \$max_rows_for_charts, + "resultset-limit=i" => \$resultset_limit, "statement-timeout=i" => \$statement_timeout, "bootstrap|boostrap=s" => \$config, "lockfile=s" => \$lockfile, @@ -174,6 +176,7 @@ while (my $r = $sth->fetchrow_hashref) { $r->{resultset}->set_pivot_label($report_data->{__pivot_label}) if $report_data->{__pivot_label}; $r->{resultset}->set_pivot_default($report_data->{__pivot_default}) if $report_data->{__pivot_default}; $r->{resultset}->relative_time($r->{run_time}); + $r->{resultset}->resultset_limit($resultset_limit) if $resultset_limit; push @reports, $r; } -- 2.11.0