[Rt-commit] rt branch, 4.2/use-in-operator, created. rt-4.2.7-15-ge325424

Alex Vandiver alexmv at bestpractical.com
Wed Nov 12 18:09:32 EST 2014


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

- Log -----------------------------------------------------------------
commit e325424b9062dc8040ecbe93cf352bf1b999abc0
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; this is
    advantagous because query planners can make better choices with IN than
    with long boolean queries.
    
    Unfortunately, DBIx::SearchBuilder 1.65 does not respect the
    CASESENSITIVE => 0 option when passed OPERATOR => 'IN'.  This is only an
    issue on the limits for Group.Name, which must be case-insensitive.  To
    work around this, pass FUNCTION => 'LOWER(?)', VALUE => [an lc'd list],
    and CASESENSITIVE => 1.  The former two deal with making the search
    case-insensitive, while the latter quiets the warnings which attempt ot
    detect case-sensitive searches on Group.Name.
    
    This also rewrites two queries in GetForwardAttachments into one, using
    a simple JOIN.

diff --git a/lib/RT/Action/SendEmail.pm b/lib/RT/Action/SendEmail.pm
index c200b01..e113ae9 100644
--- a/lib/RT/Action/SendEmail.pm
+++ b/lib/RT/Action/SendEmail.pm
@@ -462,11 +462,11 @@ sub AddTicket {
 
     my $attachs   = RT::Attachments->new( $self->TransactionObj->CreatorObj );
     my $txn_alias = $attachs->TransactionAlias;
-    $attachs->Limit( ALIAS => $txn_alias, FIELD => 'Type', VALUE => 'Create' );
     $attachs->Limit(
-        ALIAS => $txn_alias,
-        FIELD => 'Type',
-        VALUE => 'Correspond'
+        ALIAS    => $txn_alias,
+        FIELD    => 'Type',
+        OPERATOR => 'IN',
+        VALUE    => [qw(Create Correspond)],
     );
     $attachs->LimitByTicket($tid);
     $attachs->LimitNotEmpty;
diff --git a/lib/RT/Action/SendForward.pm b/lib/RT/Action/SendForward.pm
index 914e748..52937ff 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 97a4708..ea82827 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 14b0e8f..b3fde8a 100644
--- a/lib/RT/CustomFields.pm
+++ b/lib/RT/CustomFields.pm
@@ -130,24 +130,26 @@ 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',
+            FUNCTION      => 'LOWER(?)',
+            OPERATOR      => 'IN',
+            VALUE         => [map {lc $_} @{$list}],
+            CASESENSITIVE => 1,
+        );
     } 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',
+            FUNCTION      => 'LOWER(?)',
+            OPERATOR      => 'NOT IN',
+            VALUE         => [ map {lc $_} @list ],
+            CASESENSITIVE => 1,
+        );
     }
     return;
 }
diff --git a/lib/RT/Interface/Email.pm b/lib/RT/Interface/Email.pm
index ef939cf..d2e9bb5 100644
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@ -636,15 +636,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->LimitByTicket( $ticket->id );
+        $attachments->Limit(
+            ALIAS         => $attachments->TransactionAlias,
+            FIELD         => 'Type',
+            OPERATOR      => 'IN',
+            VALUE         => [ qw(Create Correspond) ],
+        );
     }
     return $attachments;
 }
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index a2fa00f..5529a24 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -3796,8 +3796,13 @@ 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",
+                        FUNCTION      => 'LOWER(?)',
+                        OPERATOR      => "IN",
+                        VALUE         => [ map {lc $_} $class->Roles ],
+                        CASESENSITIVE => 1,
+                    );
                 } 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 2c23833..4c1d9eb 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/SearchBuilder/AddAndSort.pm b/lib/RT/SearchBuilder/AddAndSort.pm
index db8b417..b4b3b0f 100644
--- a/lib/RT/SearchBuilder/AddAndSort.pm
+++ b/lib/RT/SearchBuilder/AddAndSort.pm
@@ -177,8 +177,7 @@ sub JoinTargetToAdded {
         ALIAS      => $alias,
         FIELD      => 'ObjectId',
         OPERATOR   => 'IN',
-        QUOTEVALUE => 0,
-        VALUE      => "(". join( ',', map $dbh->quote($_), @ids ) .")",
+        VALUE      => [ @ids ],
     );
 
     return $alias;
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index 50a2ba1..dda0ca8 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -1007,16 +1007,12 @@ 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) ],
+    );
 
     while ( my $att = $attachments->Next ) {
         foreach my $addrlist ( values %{$att->Addresses } ) {
@@ -1746,15 +1742,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 79d5e15..3f1252b 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
@@ -2511,9 +2506,13 @@ 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',
+            FUNCTION      => 'LOWER(?)',
+            OPERATOR      => 'IN',
+            VALUE         => [ @tmp ],
+            CASESENSITIVE => 1,
+        );
         my $principal_alias = $groups->Join(
             ALIAS1 => 'main',
             FIELD1 => 'id',
@@ -2564,28 +2563,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 0aec195..8517036 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -570,14 +570,12 @@ 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'},
+    );
 }
 
 =head2 SimpleSearch
@@ -645,9 +643,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