[Rt-commit] rt branch 5.0/optimize-from-sql-searches created. rt-5.0.3-125-g4b6fdee3e8
BPS Git Server
git at git.bestpractical.com
Fri Oct 7 20:00:06 UTC 2022
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".
The branch, 5.0/optimize-from-sql-searches has been created
at 4b6fdee3e8b77e2ef87db56f04377d21ae129522 (commit)
- Log -----------------------------------------------------------------
commit 4b6fdee3e8b77e2ef87db56f04377d21ae129522
Author: sunnavy <sunnavy at bestpractical.com>
Date: Tue Sep 27 19:08:29 2022 +0800
Test more about optimized ticket/transactions/asset searches
This is to make sure the following optimizations work:
* OR => IN for transaction/asset searches
* Active/Inactive status searches with queue/catalog/lifecycle limited
diff --git a/t/api/sql.t b/t/api/sql.t
index 7a39cd65f9..262a6c2d8b 100644
--- a/t/api/sql.t
+++ b/t/api/sql.t
@@ -17,21 +17,89 @@ my $alice_id = RT::Test->load_or_create_user( Name => 'alice' )->id;
my $general_id = RT::Test->load_or_create_queue( Name => 'General' )->id;
my $support_id = RT::Test->load_or_create_queue( Name => 'Support' )->id;
-my %ticketsql = (
- q{Status = 'new' OR Status = 'open'} => qr{Status IN \('new', 'open'\)},
- q{Status = '__Active__'} => qr{Status IN \('new', 'open', 'stalled'\)},
- q{id = 2 OR id = 3} => qr{id IN \('2', '3'\)},
- q{Creator = 'root' OR Creator = 'alice'} => qr{Creator IN \('$alice_id', '$root_id'\)},
- q{Queue = 'General' OR Queue = 'Support'} => qr{Queue IN \('$general_id', '$support_id'\)},
- q{Lifecycle = 'default' or Lifecycle = 'approvals'} => qr{Lifecycle IN \('approvals', 'default'\)},
- q{(Queue = 'General' OR Queue = 'Support') AND (Status = 'new' OR Status = 'open')} =>
- qr{Queue IN \('$general_id', '$support_id'\).+Status IN \('new', 'open'\)},
+my $lifecycles = RT->Config->Get('Lifecycles');
+RT->Config->Set(
+ Lifecycles => %{$lifecycles},
+ hardware => {
+ type => 'asset',
+ initial => ['new'],
+ active => ['tracked'],
+ inactive => ['retired'],
+ defaults => { on_create => 'new', },
+ },
);
-my $tickets = RT::Tickets->new( RT->SystemUser );
-for my $query ( sort keys %ticketsql ) {
- $tickets->FromSQL($query);
- like( $tickets->BuildSelectQuery(PreferBind => 0), $ticketsql{$query}, qq{TicketSQL "$query" uses IN} );
+RT::Lifecycle->FillCache();
+
+require RT::Test::Assets;
+my $general_catalog_id = RT::Test::Assets->load_or_create_catalog( Name => 'General assets' )->Id;
+my $hardware_catalog_id = RT::Test::Assets->load_or_create_catalog( Name => 'Hardware', Lifecycle => 'hardware' )->Id;
+
+my %sql = (
+ 'RT::Tickets' => {
+ like => {
+ q{Status = 'new' OR Status = 'open'} => qr{Status IN \('new', 'open'\)},
+ q{Status = '__Active__'} => qr{Status IN \('new', 'open', 'stalled'\)},
+ q{id = 2 OR id = 3} => qr{id IN \('2', '3'\)},
+ q{Creator = 'root' OR Creator = 'alice'} => qr{Creator IN \('$alice_id', '$root_id'\)},
+ q{Queue = 'General' OR Queue = 'Support'} => qr{Queue IN \('$general_id', '$support_id'\)},
+ q{Lifecycle = 'default' or Lifecycle = 'approvals'} => qr{Lifecycle IN \('approvals', 'default'\)},
+ q{(Queue = 'General' OR Queue = 'Support') AND (Status = 'new' OR Status = 'open')} =>
+ qr{Queue IN \('$general_id', '$support_id'\).+Status IN \('new', 'open'\)},
+ },
+ unlike => {
+ q{Status = '__Active__' and Queue = 'General'} => qr{approvals},
+ q{Status = '__Inactive__' and Lifecycle = 'default'} => qr{approvals},
+ },
+ },
+ 'RT::Transactions' => {
+ like => {
+ q{TicketStatus = 'new' OR TicketStatus = 'open'} => qr{Status IN \('new', 'open'\)},
+ q{TicketStatus = '__Active__'} => qr{Status IN \('new', 'open', 'stalled'\)},
+ q{id = 2 OR id = 3} => qr{id IN \('2', '3'\)},
+ q{Creator = 'root' OR Creator = 'alice'} => qr{Creator IN \('$alice_id', '$root_id'\)},
+ q{TicketCreator = 'root' OR TicketCreator = 'alice'} => qr{Creator IN \('$alice_id', '$root_id'\)},
+ q{TicketLastUpdatedBy = 'root' OR TicketLastUpdatedBy = 'alice'} => qr{LastUpdatedBy IN \('$alice_id', '$root_id'\)},
+ q{TicketQueue = 'General' OR TicketQueue = 'Support'} => qr{Queue IN \('$general_id', '$support_id'\)},
+ q{TicketQueueLifecycle = 'default' or TicketQueueLifecycle = 'approvals'} =>
+ qr{Lifecycle IN \('approvals', 'default'\)},
+ q{(TicketQueue = 'General' OR TicketQueue = 'Support') AND (TicketStatus = 'new' OR TicketStatus = 'open')}
+ => qr{Queue IN \('$general_id', '$support_id'\).+Status IN \('new', 'open'\)},
+ },
+ unlike => {
+ q{TicketStatus = '__Active__' and TicketQueue = 'General'} => qr{approvals},
+ },
+ },
+ 'RT::Assets' => {
+ like => {
+ q{Status = 'new' OR Status = 'allocated'} => qr{Status IN \('allocated', 'new'\)},
+ q{Status = '__Active__'} => qr{Status IN \('allocated', 'in-use', 'new'\)},
+ q{id = 2 OR id = 3} => qr{id IN \('2', '3'\)},
+ q{Catalog = 'General assets' OR Catalog = 'Hardware'} =>
+ qr{Catalog IN \('$general_catalog_id', '$hardware_catalog_id'\)},
+ q{(Catalog = 'General assets' OR Catalog = 'Hardware') AND (Status = 'allocated' OR Status = 'new')} =>
+ qr{Catalog IN \('$general_catalog_id', '$hardware_catalog_id'\).+Status IN \('allocated', 'new'\)},
+ },
+ unlike => {
+ q{Status = '__Active__' and Catalog = 'General assets'} => qr{hardware},
+ },
+ },
+);
+
+for my $type ( sort keys %sql ) {
+ my $collection = $type->new( RT->SystemUser );
+ for my $op ( sort keys %{ $sql{$type} } ) {
+ for my $query ( sort keys %{ $sql{$type}{$op} } ) {
+ $collection->FromSQL($query);
+ no strict 'refs';
+ $op->(
+ $collection->BuildSelectQuery( PreferBind => 0 ),
+ $sql{$type}{$op}{$query},
+ qq{SQL "$query" is simplified}
+ );
+ }
+ }
+
}
done_testing;
commit afa2e9598c7a0fda5f76e97532bf53b22176ad86
Author: sunnavy <sunnavy at bestpractical.com>
Date: Tue Sep 27 16:30:26 2022 +0800
Convert "OR" clauses in transactions/assets searches to "IN" for perforamnce
This is generally to mirror the behavior in ticket searches. See also
2745b9ff05
diff --git a/lib/RT/Assets.pm b/lib/RT/Assets.pm
index 262f566f7b..72a3a35e96 100644
--- a/lib/RT/Assets.pm
+++ b/lib/RT/Assets.pm
@@ -865,16 +865,30 @@ sub _EnumLimit {
# SQL::Statement changes != to <>. (Can we remove this now?)
$op = "!=" if $op eq "<>";
- die "Invalid Operation: $op for $field"
- unless $op eq "="
- or $op eq "!=";
+ die "Invalid Operation: $op for $field" unless $op =~ /^(?:=|!=|IN|NOT IN)$/i;
my $meta = $FIELD_METADATA{$field};
if ( defined $meta->[1] && defined $value && $value !~ /^\d+$/ ) {
my $class = "RT::" . $meta->[1];
- my $o = $class->new( $sb->CurrentUser );
- $o->Load($value);
- $value = $o->Id || 0;
+ if ( ref $value eq 'ARRAY' ) {
+ my @values;
+ for my $i (@$value) {
+ if ( $i !~ /^\d+$/ ) {
+ my $o = $class->new( $sb->CurrentUser );
+ $o->Load($i);
+ push @values, $o->Id || 0;
+ }
+ else {
+ push @values, $i;
+ }
+ }
+ $value = \@values;
+ }
+ else {
+ my $o = $class->new( $sb->CurrentUser );
+ $o->Load($value);
+ $value = $o->Id || 0;
+ }
}
$sb->Limit(
FIELD => $field,
@@ -1205,7 +1219,12 @@ sub _StringLimit {
}
if ($field eq "Status") {
- $value = lc $value;
+ if ( ref $value eq 'ARRAY' ) {
+ $value = [ map lc, @$value ];
+ }
+ else {
+ $value = lc $value;
+ }
}
$sb->Limit(
@@ -1617,6 +1636,8 @@ sub _parser {
}
);
+ RT::SQL::_Optimize($tree);
+
my $ea = '';
$tree->traverse(
sub {
diff --git a/lib/RT/SQL.pm b/lib/RT/SQL.pm
index 2d1f047cde..e5dfd6a85c 100644
--- a/lib/RT/SQL.pm
+++ b/lib/RT/SQL.pm
@@ -239,6 +239,85 @@ sub _BitmaskToString {
return join ' or ', @res;
}
+sub _Optimize {
+ my $tree = shift;
+
+ # Convert simple OR'd clauses to IN for better performance, e.g.
+ # (Status = 'new' OR Status = 'open' OR Status = 'stalled')
+ # to
+ # Status IN ('new', 'open', 'stalled')
+
+ $tree->traverse(
+ sub {
+ my $node = shift;
+ my $parent = $node->getParent;
+ return if $parent eq 'root'; # Skip root's root
+
+ # For simple searches like "Status = 'new' OR Status = 'open'",
+ # the OR node is also the root node, go up one level.
+ $node = $parent if $node->isLeaf && $parent->isRoot;
+
+ return if $node->isLeaf;
+
+ if ( ( $node->getNodeValue // '' ) =~ /^or$/i && $node->getChildCount > 1 ) {
+ my @children = $node->getAllChildren;
+ my %info;
+ for my $child (@children) {
+
+ # Only handle innermost ORs
+ return unless $child->isLeaf;
+ my $entry = $child->getNodeValue;
+ return unless $entry->{Op} =~ /^!?=$/;
+
+ # Handle String/Int/Id/Enum/Queue/Lifecycle only for
+ # now. Others have more complicated logic inside, which
+ # can't be easily converted.
+
+ # TICKETQUEUEFIELD only supports Lifecycle right now, which is fine
+ return
+ unless ( $entry->{Meta}[0] // '' )
+ =~ /^(?:STRING|INT|ID|ENUM|QUEUE|LIFECYCLE|TICKETFIELD|TICKETQUEUEFIELD)$/;
+
+ # TICKETFIELD contains more than what we want, need to filter a bit more deeply.
+ if ( $entry->{Meta}[0] eq 'TICKETFIELD' ) {
+ my ($field) = $entry->{Key} =~ /Ticket(\w+)/;
+ require RT::Tickets;
+ return
+ unless $RT::Tickets::FIELD_METADATA{$field}[0]
+ =~ /^(?:STRING|INT|ID|ENUM|QUEUE|LIFECYCLE)$/;
+ }
+
+ for my $field (qw/Key SubKey Op Value/) {
+ $info{$field}{ $entry->{$field} // '' } ||= 1;
+
+ if ( $field eq 'Value' ) {
+
+ # In case it's meta value like __Bookmarked__
+ return if $entry->{Meta}[0] eq 'ID' && $entry->{$field} !~ /^\d+$/;
+ }
+ elsif ( keys %{ $info{$field} } > 1 ) {
+ return; # Skip if Key/SubKey/Op are different
+ }
+ }
+ }
+
+ my $first_child = shift @children;
+ my $entry = $first_child->getNodeValue;
+ $entry->{Op} = $info{Op}{'='} ? 'IN' : 'NOT IN';
+ $entry->{Value} = [ sort keys %{ $info{Value} } ];
+ if ( $node->isRoot ) {
+ $parent->removeChild($_) for @children;
+ }
+ else {
+ $parent->removeChild($node);
+ $parent->addChild($first_child);
+ }
+ }
+ }
+ );
+ return $tree;
+}
+
RT::Base->_ImportOverlays();
1;
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index e355c4dd10..1d98b97f50 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -3340,67 +3340,7 @@ sub _parser {
}
);
- # Convert simple OR'd clauses to IN for better performance, e.g.
- # (Status = 'new' OR Status = 'open' OR Status = 'stalled')
- # to
- # Status IN ('new', 'open', 'stalled')
-
- $tree->traverse(
- sub {
- my $node = shift;
- my $parent = $node->getParent;
- return if $parent eq 'root'; # Skip root's root
-
- # For simple searches like "Status = 'new' OR Status = 'open'",
- # the OR node is also the root node, go up one level.
- $node = $parent if $node->isLeaf && $parent->isRoot;
-
- return if $node->isLeaf;
-
- if ( ( $node->getNodeValue // '' ) =~ /^or$/i && $node->getChildCount > 1 ) {
- my @children = $node->getAllChildren;
- my %info;
- for my $child (@children) {
-
- # Only handle innermost ORs
- return unless $child->isLeaf;
- my $entry = $child->getNodeValue;
- return unless $entry->{Op} =~ /^!?=$/;
-
- # Handle String/Int/Id/Enum/Queue/Lifecycle only for
- # now. Others have more complicated logic inside, which
- # can't be easily converted.
-
- return unless ( $entry->{Meta}[0] // '' ) =~ /^(?:STRING|INT|ID|ENUM|QUEUE|LIFECYCLE)$/;
-
- for my $field (qw/Key SubKey Op Value/) {
- $info{$field}{ $entry->{$field} // '' } ||= 1;
-
- if ( $field eq 'Value' ) {
-
- # In case it's meta value like __Bookmarked__
- return if $entry->{Meta}[0] eq 'ID' && $entry->{$field} !~ /^\d+$/;
- }
- elsif ( keys %{ $info{$field} } > 1 ) {
- return; # Skip if Key/SubKey/Op are different
- }
- }
- }
-
- my $first_child = shift @children;
- my $entry = $first_child->getNodeValue;
- $entry->{Op} = $info{Op}{'='} ? 'IN' : 'NOT IN';
- $entry->{Value} = [ sort keys %{ $info{Value} } ];
- if ( $node->isRoot ) {
- $parent->removeChild($_) for @children;
- }
- else {
- $parent->removeChild($node);
- $parent->addChild($first_child);
- }
- }
- }
- );
+ RT::SQL::_Optimize($tree);
my $ea = '';
$tree->traverse(
diff --git a/lib/RT/Transactions.pm b/lib/RT/Transactions.pm
index b465f3d8ff..54dc0f9e6d 100644
--- a/lib/RT/Transactions.pm
+++ b/lib/RT/Transactions.pm
@@ -284,16 +284,30 @@ sub _EnumLimit {
# SQL::Statement changes != to <>. (Can we remove this now?)
$op = "!=" if $op eq "<>";
- die "Invalid Operation: $op for $field"
- unless $op eq "="
- or $op eq "!=";
+ die "Invalid Operation: $op for $field" unless $op =~ /^(?:=|!=|IN|NOT IN)$/i;
my $meta = $FIELD_METADATA{$field};
if ( defined $meta->[1] && defined $value && $value !~ /^\d+$/ ) {
my $class = "RT::" . $meta->[1];
- my $o = $class->new( $sb->CurrentUser );
- $o->Load($value);
- $value = $o->Id || 0;
+ if ( ref $value eq 'ARRAY' ) {
+ my @values;
+ for my $i (@$value) {
+ if ( $i !~ /^\d+$/ ) {
+ my $o = $class->new( $sb->CurrentUser );
+ $o->Load($i);
+ push @values, $o->Id || 0;
+ }
+ else {
+ push @values, $i;
+ }
+ }
+ $value = \@values;
+ }
+ else {
+ my $o = $class->new( $sb->CurrentUser );
+ $o->Load($value);
+ $value = $o->Id || 0;
+ }
}
$sb->Limit(
FIELD => $field,
@@ -807,15 +821,37 @@ sub _TicketLimit {
$field =~ s!^Ticket!!;
if ( $field eq 'Queue' && $value =~ /\D/ ) {
- my $queue = RT::Queue->new($self->CurrentUser);
- $queue->Load($value);
- $value = $queue->id if $queue->id;
+ if ( ref $value eq 'ARRAY' ) {
+ my @values;
+ for my $v ( @$value ) {
+ my $o = RT::Queue->new( $self->CurrentUser );
+ $o->Load($v);
+ push @values, $o->Id || 0;
+ }
+ $value = \@values;
+ }
+ else {
+ my $queue = RT::Queue->new($self->CurrentUser);
+ $queue->Load($value);
+ $value = $queue->id if $queue->id;
+ }
}
- if ( $field =~ /^(?:Owner|Creator)$/ && $value =~ /\D/ ) {
- my $user = RT::User->new( $self->CurrentUser );
- $user->Load($value);
- $value = $user->id if $user->id;
+ if ( $field =~ /^(?:Owner|Creator|LastUpdatedBy)$/ && $value =~ /\D/ ) {
+ if ( ref $value eq 'ARRAY' ) {
+ my @values;
+ for my $v ( @$value ) {
+ my $o = RT::User->new( $self->CurrentUser );
+ $o->Load($v);
+ push @values, $o->Id || 0;
+ }
+ $value = \@values;
+ }
+ else {
+ my $user = RT::User->new( $self->CurrentUser );
+ $user->Load($value);
+ $value = $user->id if $user->id;
+ }
}
$self->Limit(
@@ -1038,6 +1074,8 @@ sub _parser {
}
);
+ RT::SQL::_Optimize($tree);
+
my $ea = '';
$tree->traverse(
sub {
@@ -1073,6 +1111,7 @@ sub _parser {
return $self->_CloseParen unless $node->isLeaf;
}
);
+
}
sub FromSQL {
commit b9a7691fdb6fb048ae69e9874d6d3e5d9eb38c82
Author: sunnavy <sunnavy at bestpractical.com>
Date: Sat Sep 24 11:09:06 2022 +0800
Include referenced queues/catalogs only for active/inactive status searches
Previously we included active/inactive statuses in all ticket/asset
lifecycles, which isn't quite necessary if queue or lifecycle is
limited. This commit filters statuses to only include ones referenced.
E.g.
Queue = 'General' AND Status = '__Active__'
will be translated to something like
Queue = '1' AND Status IN ('new', 'open', 'stalled')
instead of
Queue = '1' AND
( ( Queues.Lifecycle = 'default' AND Status IN ('new', 'open', 'stalled') )
OR ( Queues.Lifecycle = 'approvals' AND Status IN ('new', 'open', 'stalled')
)
diff --git a/lib/RT/Assets.pm b/lib/RT/Assets.pm
index 046a834e9e..262f566f7b 100644
--- a/lib/RT/Assets.pm
+++ b/lib/RT/Assets.pm
@@ -1497,6 +1497,9 @@ sub _parser {
return $text;
};
+ my $catalogs = $tree->GetReferencedCatalogs( CurrentUser => $self->CurrentUser );
+ my %referenced_lifecycle = map { $_->{Lifecycle} => 1 } values %$catalogs;
+
my ( $active_status_node, $inactive_status_node );
$tree->traverse(
@@ -1516,6 +1519,7 @@ sub _parser {
map { $_ => $RT::Lifecycle::LIFECYCLES{ $_ }{ inactive } }
grep { @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ inactive } || [] } }
grep { $_ ne '__maps__' && $RT::Lifecycle::LIFECYCLES_CACHE{ $_ }{ type } eq 'asset' }
+ grep { %referenced_lifecycle ? $referenced_lifecycle{$_} : 1 }
keys %RT::Lifecycle::LIFECYCLES;
return unless %lifecycle;
@@ -1559,6 +1563,7 @@ sub _parser {
|| @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ active } || [] }
}
grep { $_ ne '__maps__' && $RT::Lifecycle::LIFECYCLES_CACHE{ $_ }{ type } eq 'asset' }
+ grep { %referenced_lifecycle ? $referenced_lifecycle{$_} : 1 }
keys %RT::Lifecycle::LIFECYCLES;
return unless %lifecycle;
diff --git a/lib/RT/Interface/Web/QueryBuilder/Tree.pm b/lib/RT/Interface/Web/QueryBuilder/Tree.pm
index e566d7f472..2c8d662b17 100644
--- a/lib/RT/Interface/Web/QueryBuilder/Tree.pm
+++ b/lib/RT/Interface/Web/QueryBuilder/Tree.pm
@@ -116,14 +116,20 @@ sub GetReferencedQueues {
my $clause = $node->getNodeValue();
if ( $clause->{Key} =~ /^(?:Ticket)?Queue$/ ) {
if ( $clause->{Op} eq '=' ) {
- $queues->{ $clause->{Value} } ||= 1;
+ my $q = RT::Queue->new( $args{CurrentUser} || $HTML::Mason::Commands::session{CurrentUser} );
+ $q->Load( $clause->{Value} );
+ if ( $q->id ) {
+ # Skip ACL check
+ $queues->{ $q->id } ||= { map { $_ => $q->__Value($_) } qw/Name Lifecycle/ };
+ }
}
elsif ( $clause->{Op} =~ /^LIKE$/i ) {
my $qs = RT::Queues->new( $args{CurrentUser} || $HTML::Mason::Commands::session{CurrentUser} );
$qs->Limit( FIELD => 'Name', VALUE => $clause->{Value}, OPERATOR => 'LIKE', CASESENSITIVE => 0 );
while ( my $q = $qs->Next ) {
next unless $q->id;
- $queues->{ $q->id } ||= 1;
+ # Skip ACL check
+ $queues->{ $q->id } ||= { map { $_ => $q->__Value($_) } qw/Name Lifecycle/ };
}
}
}
@@ -133,7 +139,8 @@ sub GetReferencedQueues {
$qs->Limit( FIELD => 'Lifecycle', VALUE => $clause->{Value} );
while ( my $q = $qs->Next ) {
next unless $q->id;
- $queues->{ $q->id } ||= 1;
+ # Skip ACL check
+ $queues->{ $q->id } ||= { map { $_ => $q->__Value($_) } qw/Name Lifecycle/ };
}
}
}
@@ -153,6 +160,10 @@ will appear as a key whose value is 1.
sub GetReferencedCatalogs {
my $self = shift;
+ my %args = (
+ CurrentUser => '',
+ @_,
+ );
my $catalogs = {};
@@ -167,7 +178,12 @@ sub GetReferencedCatalogs {
return unless $clause->{ Key } eq 'Catalog';
return unless $clause->{ Op } eq '=';
- $catalogs->{ $clause->{ Value } } = 1;
+ my $catalog = RT::Catalog->new( $args{CurrentUser} || $HTML::Mason::Commands::session{CurrentUser} );
+ $catalog->Load( $clause->{Value} );
+ if ( $catalog->Id ) {
+ # Skip ACL check
+ $catalogs->{ $catalog->Id } ||= { map { $_ => $catalog->__Value($_) } qw/Name Lifecycle/ };
+ }
}
);
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 1278f3b000..e355c4dd10 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -3183,18 +3183,14 @@ sub _parser {
);
die join "; ", map { ref $_ eq 'ARRAY' ? $_->[ 0 ] : $_ } @results if @results;
+ my $queues = $tree->GetReferencedQueues( CurrentUser => $self->CurrentUser );
+ my %referenced_lifecycle = map { $_->{Lifecycle} => 1 } values %$queues;
+
if ( RT->Config->Get('EnablePriorityAsString') ) {
- my $queues = $tree->GetReferencedQueues( CurrentUser => $self->CurrentUser );
my %config = RT->Config->Get('PriorityAsString');
my @names;
if (%$queues) {
- for my $id ( keys %$queues ) {
- my $queue = RT::Queue->new( $self->CurrentUser );
- $queue->Load($id);
- if ( $queue->Id ) {
- push @names, $queue->__Value('Name'); # Skip ACL check
- }
- }
+ @names = map { $_->{Name} } values %$queues;
}
else {
@names = keys %config;
@@ -3248,6 +3244,7 @@ sub _parser {
map { $_ => $RT::Lifecycle::LIFECYCLES{ $_ }{ inactive } }
grep { @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ inactive } || [] } }
grep { $_ ne '__maps__' && $RT::Lifecycle::LIFECYCLES_CACHE{ $_ }{ type } eq 'ticket' }
+ grep { %referenced_lifecycle ? $referenced_lifecycle{$_} : 1 }
keys %RT::Lifecycle::LIFECYCLES;
return unless %lifecycle;
@@ -3290,6 +3287,7 @@ sub _parser {
|| @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ active } || [] }
}
grep { $_ ne '__maps__' && $RT::Lifecycle::LIFECYCLES_CACHE{ $_ }{ type } eq 'ticket' }
+ grep { %referenced_lifecycle ? $referenced_lifecycle{$_} : 1 }
keys %RT::Lifecycle::LIFECYCLES;
return unless %lifecycle;
diff --git a/lib/RT/Transactions.pm b/lib/RT/Transactions.pm
index 6ee5697bb4..b465f3d8ff 100644
--- a/lib/RT/Transactions.pm
+++ b/lib/RT/Transactions.pm
@@ -896,18 +896,14 @@ sub _parser {
);
die join "; ", map { ref $_ eq 'ARRAY' ? $_->[ 0 ] : $_ } @results if @results;
+ my $queues = $tree->GetReferencedQueues( CurrentUser => $self->CurrentUser );
+ my %referenced_lifecycle = map { $_->{Lifecycle} => 1 } values %$queues;
+
if ( RT->Config->Get('EnablePriorityAsString') ) {
- my $queues = $tree->GetReferencedQueues( CurrentUser => $self->CurrentUser );
my %config = RT->Config->Get('PriorityAsString');
my @names;
if (%$queues) {
- for my $id ( keys %$queues ) {
- my $queue = RT::Queue->new( $self->CurrentUser );
- $queue->Load($id);
- if ( $queue->Id ) {
- push @names, $queue->__Value('Name'); # Skip ACL check
- }
- }
+ @names = map { $_->{Name} } values %$queues;
}
else {
@names = keys %config;
@@ -965,6 +961,7 @@ sub _parser {
map { $_ => $RT::Lifecycle::LIFECYCLES{ $_ }{ inactive } }
grep { @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ inactive } || [] } }
grep { $RT::Lifecycle::LIFECYCLES_CACHE{ $_ }{ type } eq 'ticket' }
+ grep { %referenced_lifecycle ? $referenced_lifecycle{$_} : 1 }
keys %RT::Lifecycle::LIFECYCLES;
return unless %lifecycle;
@@ -1008,6 +1005,7 @@ sub _parser {
|| @{ $RT::Lifecycle::LIFECYCLES{ $_ }{ active } || [] }
}
grep { $RT::Lifecycle::LIFECYCLES_CACHE{ $_ }{ type } eq 'ticket' }
+ grep { %referenced_lifecycle ? $referenced_lifecycle{$_} : 1 }
keys %RT::Lifecycle::LIFECYCLES;
return unless %lifecycle;
-----------------------------------------------------------------------
hooks/post-receive
--
rt
More information about the rt-commit
mailing list