[Rt-commit] rt branch, 4.2/who-have-right-optimization, created. rt-4.2.9rc1-3-g5f03985

Alex Vandiver alexmv at bestpractical.com
Wed Oct 29 16:05:46 EDT 2014


The branch, 4.2/who-have-right-optimization has been created
        at  5f039853573bcaaf58d33a59634f289d26066898 (commit)

- Log -----------------------------------------------------------------
commit 2552c79471a1ca15d044801c6dab06d2d6ffa7d4
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Tue Oct 28 18:48:49 2014 -0400

    Only add limits for types that explicitly are rights targets
    
    This skips adding an ObjectType = 'RT::Ticket' limit, which will never
    be necessary.
    
    XXX: This causes tests to fail, but the tests are horrible and old and wrong.

diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index 0aec195..49dfea5 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -512,6 +512,7 @@ sub WhoHaveGroupRight
             my $id = 0;
             $id = $obj->id if ref($obj) && UNIVERSAL::can($obj, 'id') && $obj->id;
             next if $seen{"$type-$id"}++;
+            next unless $type->DOES("RT::Record::Role::Rights");
 
             my $object_clause = "$acl.ObjectType = '$type'";
             $object_clause   .= " AND $acl.ObjectId   = $id" if $id;
@@ -524,6 +525,7 @@ sub WhoHaveGroupRight
             $check_objects = "($acl.ObjectType != 'RT::System')";
         }
     }
+    $check_objects ||= "$acl.id = 0";
     $self->_AddSubClause( "WhichObject", "($check_objects)" );
     
     my $group_members = $self->_JoinGroupMembersForGroupRights( %args, ACLAlias => $acl );

commit 5f039853573bcaaf58d33a59634f289d26066898
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Tue Oct 28 18:50:58 2014 -0400

    Simplify WhoHaveRoleRight and WhoHaveGroupRight queries before unioning
    
    Perform a true union in SQL, via a separate 'in' query.  This
    effectively prevents duplicates in the resultset (which
    DBIx::SearchBuilder::Union makes no attempt to do), orders the set as a
    whole, and allows the individual queries to be simpler.  In particular,
    the lack of "DISTINCT" and "ORDER BY" on the WhoHaveGroupRight query on
    MySQL causes it to generate a query plan which no longer includes "with
    temporary table" (due to the DISTINCT) or "with filesort" (due to the
    ORDER BY), and makes better use of indexes (due to the limited number of
    columns returned).
    
    This does come at the assumption that duplicates within each of the two
    queries are not common -- that is, that users will not have the relevant
    right by way of a large number of membership paths.

diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index 49dfea5..7be0b98 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -386,19 +386,30 @@ sub WhoHaveRight {
         return (undef);
     }
 
+    my @ids = (0);
+
     my $from_role = $self->Clone;
     $from_role->WhoHaveRoleRight( %args );
+    $from_role->Columns( 'id' );
+    $from_role->OrderBy();
+    $from_role->{'joins_are_distinct'} = 1;
+    while (my $row = $from_role->Next) {
+        push @ids, $row->id;
+    }
 
     my $from_group = $self->Clone;
     $from_group->WhoHaveGroupRight( %args );
+    $from_group->Columns( 'id' );
+    $from_group->OrderBy();
+    $from_group->{'joins_are_distinct'} = 1;
+    while (my $row = $from_group->Next) {
+        push @ids, $row->id;
+    }
 
-    #XXX: DIRTY HACK
-    use DBIx::SearchBuilder::Union;
-    my $union = DBIx::SearchBuilder::Union->new();
-    $union->add( $from_group );
-    $union->add( $from_role );
+    my $union = RT::Users->new( $self->CurrentUser );
+    $union->Limit( FIELD => 'id', OPERATOR => 'IN', VALUE => \@ids );
+    $union->{'handled_disabled_column'} = 1;
     %$self = %$union;
-    bless $self, ref($union);
 
     return;
 }

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


More information about the rt-commit mailing list