[Rt-commit] rt branch, 4.2/use-in-operator, created. rt-4.2.3-87-gdebe5de

Alex Vandiver alexmv at bestpractical.com
Fri Apr 18 13:04:04 EDT 2014


The branch, 4.2/use-in-operator has been created
        at  debe5de8aa72914c440b60fc17ec283749b44c8c (commit)

- Log -----------------------------------------------------------------
commit debe5de8aa72914c440b60fc17ec283749b44c8c
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Apr 18 13:00:09 2014 -0400

    When possible, switch to IN or NOT IN rather than multiple OR'd clauses
    
    DBIx::SearchBuilder 1.63 began allowing the IN and NOT IN operators; RT
    4.0 could not immediately make use of them because it did depend on a
    high enough version of DBIx::SearchBuilder.  RT 4.2, however, depends on
    DBIx::SearchBuilder 1.65, and thus can use IN freely.  Do so, as query
    optimizers are likely to be able to make better plans based on IN
    queries, rather than multiple OR's.
    
    This also rewrites two queries in GetForwardAttachments into one, using
    a simple JOIN.

diff --git a/lib/RT/Action/SendForward.pm b/lib/RT/Action/SendForward.pm
index 0a7949c..4c39c22 100644
--- a/lib/RT/Action/SendForward.pm
+++ b/lib/RT/Action/SendForward.pm
@@ -92,9 +92,10 @@ sub Prepare {
     else {
         my $txns = $self->TicketObj->Transactions;
         $txns->Limit(
-            FIELD => 'Type',
-            VALUE => $_,
-        ) for qw(Create Correspond);
+            FIELD    => 'Type',
+            OPERATOR => 'IN',
+            VALUE    => [qw(Create Correspond)],
+        );
 
         $entity = MIME::Entity->build(
             Type        => 'multipart/mixed',
diff --git a/lib/RT/Articles.pm b/lib/RT/Articles.pm
index 410578a..dea3583 100644
--- a/lib/RT/Articles.pm
+++ b/lib/RT/Articles.pm
@@ -406,12 +406,11 @@ sub LimitTopics {
 
     my $topics = $self->NewAlias('ObjectTopics');
     $self->Limit(
-        ALIAS           => $topics,
-        FIELD           => 'Topic',
-        VALUE           => $_,
-        ENTRYAGGREGATOR => 'OR'
-      )
-      for @topics;
+        ALIAS    => $topics,
+        FIELD    => 'Topic',
+        OPERATOR => 'IN',
+        VALUE    => [ @topics ],
+    );
 
     $self->Limit(
         ALIAS => $topics,
diff --git a/lib/RT/CustomFields.pm b/lib/RT/CustomFields.pm
index eab9a10..b8a1ee1 100644
--- a/lib/RT/CustomFields.pm
+++ b/lib/RT/CustomFields.pm
@@ -128,24 +128,24 @@ sub LimitToGrouping {
         unless ( $list and ref($list) eq 'ARRAY' and @$list ) {
             return $self->Limit( FIELD => 'id', VALUE => 0, ENTRYAGGREGATOR => 'AND' );
         }
-        foreach ( @$list ) {
-            $self->Limit( FIELD => 'Name', VALUE => $_, CASESENSITIVE => 0 );
-        }
+        $self->Limit(
+            FIELD         => 'Name',
+            OPERATOR      => 'IN',
+            VALUE         => $list,
+            CASESENSITIVE => 0,
+        );
     } else {
         my @list = map {@$_} grep defined && ref($_) eq 'ARRAY',
             values %h;
 
         return unless @list;
-        foreach ( @list ) {
-            $self->Limit(
-                FIELD => 'Name',
-                OPERATOR => '!=',
-                VALUE => $_,
-                ENTRYAGGREGATOR => 'AND',
-                CASESENSITIVE => 0,
-            );
-        }
 
+        $self->Limit(
+            FIELD         => 'Name',
+            OPERATOR      => 'NOT IN',
+            VALUE         => [ @list ],
+            CASESENSITIVE => 0,
+        );
     }
     return;
 }
diff --git a/lib/RT/Interface/Email.pm b/lib/RT/Interface/Email.pm
index facdb38..e603262 100644
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@ -632,15 +632,13 @@ sub GetForwardAttachments {
         $attachments->Limit( FIELD => 'TransactionId', VALUE => $txn->id );
     }
     else {
-        my $txns = $ticket->Transactions;
-        $txns->Limit(
-            FIELD => 'Type',
-            VALUE => $_,
-        ) for qw(Create Correspond);
-
-        while ( my $txn = $txns->Next ) {
-            $attachments->Limit( FIELD => 'TransactionId', VALUE => $txn->id );
-        }
+        $attachments->Limit(
+            ALIAS         => $attachments->TransactionAlias,
+            FIELD         => 'Type',
+            OPERATOR      => 'IN',
+            VALUE         => [ qw(Create Correspond) ],
+            CASESENSITIVE => 1,
+        );
     }
     return $attachments;
 }
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index f2cb21b..e866795 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -3806,8 +3806,12 @@ sub GetPrincipalsMap {
                 my $class = $object->RecordClassFromLookupType;
                 if ($class and $class->DOES("RT::Record::Role::Roles")) {
                     $roles->LimitToRolesForObject(RT->System);
-                    $roles->Limit( FIELD => "Name", VALUE => $_, CASESENSITIVE => 0 )
-                        for $class->Roles;
+                    $roles->Limit(
+                        FIELD         => "Name",
+                        OPERATOR      => "IN",
+                        VALUE         => [ $class->Roles ],
+                        CASESENSITIVE => 0
+                    );
                 } else {
                     # No roles to show; so show nothing
                     undef $roles;
diff --git a/lib/RT/Migrate/Serializer.pm b/lib/RT/Migrate/Serializer.pm
index 2afb7fe..bf8d486 100644
--- a/lib/RT/Migrate/Serializer.pm
+++ b/lib/RT/Migrate/Serializer.pm
@@ -248,8 +248,9 @@ sub PushBasics {
     my $cfs = RT::CustomFields->new( RT->SystemUser );
     $cfs->Limit(
         FIELD => 'LookupType',
-        VALUE => $_
-    ) for qw/RT::User RT::Group RT::Queue/;
+        OPERATOR => 'IN',
+        VALUE => [ qw/RT::User RT::Group RT::Queue/ ],
+    );
     $self->PushObj( $cfs );
 
     # Global attributes
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index 46c8f68..3d81d28 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -1007,16 +1007,13 @@ sub TransactionAddresses {
     $attachments->LimitByTicket( $self->id );
     $attachments->Columns( qw( id Headers TransactionId));
 
-
-    foreach my $type (qw(Create Comment Correspond)) {
-        $attachments->Limit( ALIAS    => $attachments->TransactionAlias,
-                             FIELD    => 'Type',
-                             OPERATOR => '=',
-                             VALUE    => $type,
-                             ENTRYAGGREGATOR => 'OR',
-                             CASESENSITIVE   => 1
-                           );
-    }
+    $attachments->Limit(
+        ALIAS         => $attachments->TransactionAlias,
+        FIELD         => 'Type',
+        OPERATOR      => 'IN',
+        VALUE         => [ qw(Create Comment Correspond) ],
+        CASESENSITIVE => 1,
+    );
 
     while ( my $att = $attachments->Next ) {
         foreach my $addrlist ( values %{$att->Addresses } ) {
@@ -1738,15 +1735,10 @@ sub _Links {
     # at least to myself
     $links->Limit(
         FIELD           => $limit_on,
-        VALUE           => $self->id,
-        ENTRYAGGREGATOR => 'OR',
+        OPERATOR        => 'IN',
+        VALUE           => [ $self->id, $self->Merged ],
     );
     $links->Limit(
-        FIELD           => $limit_on,
-        VALUE           => $_,
-        ENTRYAGGREGATOR => 'OR',
-    ) foreach $self->Merged;
-    $links->Limit(
         FIELD => 'Type',
         VALUE => $type,
     ) if $type;
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index a898e17..7342a93 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -329,20 +329,15 @@ sub _BookmarkLimit {
         TABLE2 => 'Tickets',
         FIELD2 => 'EffectiveId',
     );
-    $sb->_OpenParen;
-    my $first = 1;
-    my $ea = $op eq '='? 'OR': 'AND';
-    foreach my $id ( sort @bookmarks ) {
-        $sb->Limit(
-            ALIAS    => $tickets_alias,
-            FIELD    => 'id',
-            OPERATOR => $op,
-            VALUE    => $id,
-            $first? (@rest): ( ENTRYAGGREGATOR => $ea )
-        );
-        $first = 0 if $first;
-    }
-    $sb->_CloseParen;
+
+    $op = $op eq '='? 'IN': 'NOT IN';
+    $sb->Limit(
+        ALIAS    => $tickets_alias,
+        FIELD    => 'id',
+        OPERATOR => $op,
+        VALUE    => [ @bookmarks ],
+        @rest,
+    );
 }
 
 =head2 _EnumLimit
@@ -2510,9 +2505,12 @@ sub CurrentUserCanSee {
 
         my $groups = RT::Groups->new( RT->SystemUser );
         $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
-        foreach ( @tmp ) {
-            $groups->Limit( FIELD => 'Name', VALUE => $_, CASESENSITIVE => 0 );
-        }
+        $groups->Limit(
+            FIELD         => 'Name',
+            OPERATOR      => 'IN',
+            VALUE         => [ @tmp ],
+            CASESENSITIVE => 0
+        );
         my $principal_alias = $groups->Join(
             ALIAS1 => 'main',
             FIELD1 => 'id',
@@ -2563,28 +2561,14 @@ sub CurrentUserCanSee {
             my @queues = @_;
 
             return unless @queues;
-            if ( @queues == 1 ) {
-                $self->Limit(
-                    SUBCLAUSE => 'ACL',
-                    ALIAS => 'main',
-                    FIELD => 'Queue',
-                    VALUE => $_[0],
-                    ENTRYAGGREGATOR => $ea,
-                );
-            } else {
-                $self->SUPER::_OpenParen('ACL');
-                foreach my $q ( @queues ) {
-                    $self->Limit(
-                        SUBCLAUSE => 'ACL',
-                        ALIAS => 'main',
-                        FIELD => 'Queue',
-                        VALUE => $q,
-                        ENTRYAGGREGATOR => $ea,
-                    );
-                    $ea = 'OR';
-                }
-                $self->SUPER::_CloseParen('ACL');
-            }
+            $self->Limit(
+                SUBCLAUSE       => 'ACL',
+                ALIAS           => 'main',
+                FIELD           => 'Queue',
+                OPERATOR        => 'IN',
+                VALUE           => [ @queues ],
+                ENTRYAGGREGATOR => $ea,
+            );
             return 1;
         };
 
diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index f53ca80..a07b7b4 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -560,14 +560,13 @@ sub WhoBelongToGroups {
 
     my $group_members = $self->_JoinGroupMembers( %args );
 
-    foreach my $groupid (@{$args{'Groups'}}) {
-        $self->Limit( ALIAS           => $group_members,
-                      FIELD           => 'GroupId',
-                      VALUE           => $groupid,
-                      QUOTEVALUE      => 0,
-                      ENTRYAGGREGATOR => 'OR',
-                    );
-    }
+    $self->Limit(
+        ALIAS      => $group_members,
+        FIELD      => 'GroupId',
+        OPERATOR   => 'IN',
+        VALUE      => $args{'Groups'},
+        QUOTEVALUE => 0,
+    );
 }
 
 =head2 SimpleSearch
@@ -635,9 +634,8 @@ sub SimpleSearch {
     }
 
     # Exclude users we don't want
-    foreach (@{$args{Exclude}}) {
-        $self->Limit(FIELD => 'id', VALUE => $_, OPERATOR => '!=', ENTRYAGGREGATOR => 'AND');
-    }
+    $self->Limit(FIELD => 'id', OPERATOR => 'NOT IN', VALUE => $args{Exclude} )
+        if @{$args{Exclude}};
 
     if ( RT->Config->Get('DatabaseType') eq 'Oracle' ) {
         $self->Limit(

-----------------------------------------------------------------------


More information about the rt-commit mailing list