[Rt-commit] [svn] r1967 - in rt/branches/3.3-TESTING: . lib/RT
jesse at pallas.eruditorum.org
jesse at pallas.eruditorum.org
Tue Dec 7 20:33:36 EST 2004
Author: jesse
Date: Tue Dec 7 20:33:35 2004
New Revision: 1967
Modified:
rt/branches/3.3-TESTING/ (props changed)
rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay.pm
Log:
r9524 at tinbook: jesse | 2004-12-07T22:51:16.647524Z
r9522 at tinbook: jesse | 2004-12-07T22:47:20.573617Z
RT-Ticket: 6286
RT-Status: resolved
RT-Update: correspond
Searching on Ticket data and Transaction content caused horribly pessimal searches.
OLD
mysql> explain SELECT DISTINCT main.* FROM Tickets main , Transactions Transactions_1, Attachments Attachments_2 WHERE ((main.EffectiveId = main.id)) AND ((main.Status != 'deleted')) AND ((main.Type = 'ticket')) AND ((main.Subject LIKE '%subject/content SQL test%')OR ( (Attachments_2.Content LIKE '%subject/content SQL test%')AND(Attachments_2.TransactionId = Transactions_1.id)AND(main.id = Transactions_1.Ticket) ) );
+----------------+-------+-----------------------+---------------+---------+------+------+------------------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+----------------+-------+-----------------------+---------------+---------+------+------+------------------------------------+
| main | ALL | PRIMARY | NULL | NULL | NULL | 30 | Using where; Using temporary |
| Attachments_2 | ALL | Attachments2 | NULL | NULL | NULL | 22 | Using where; Distinct |
| Transactions_1 | index | PRIMARY,Transactions1 | Transactions1 | 4 | NULL | 73 | Using where; Using index; Distinct |
+----------------+-------+-----------------------+---------------+---------+------+------+------------------------------------+
3 rows in set (0.00 sec)
NEW
mysql> explain SELECT DISTINCT main.* FROM ((Tickets main LEFT JOIN Transactions Transactions_1 ON ( main.id = Transactions_1.Ticket)) LEFT JOIN Attachments Attachments_2 ON ( Transactions_1.id = Attachments_2.TransactionId)) WHERE ((main.EffectiveId = main.id)) AND ((main.Status != 'deleted')) AND ((main.Type = 'ticket')) AND ((main.Subject LIKE '%subject/content SQL test%')OR ( (Attachments_2.Content LIKE '%subject/content SQL test%') ) );
+----------------+------+---------------+---------------+---------+-------------------+------+------------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+----------------+------+---------------+---------------+---------+-------------------+------+------------------------------+
| main | ALL | NULL | NULL | NULL | NULL | 30 | Using where; Using temporary |
| Transactions_1 | ref | Transactions1 | Transactions1 | 4 | main.id | 1 | Using index; Distinct |
| Attachments_2 | ref | Attachments2 | Attachments2 | 4 | Transactions_1.id | 1 | Using where; Distinct |
+----------------+------+---------------+---------------+---------+-------------------+------+------------------------------+
3 rows in set (0.03 sec)
Modified: rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay.pm
==============================================================================
--- rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay.pm (original)
+++ rt/branches/3.3-TESTING/lib/RT/Tickets_Overlay.pm Tue Dec 7 20:33:35 2004
@@ -1,4 +1,4 @@
-# BEGIN BPS TAGGED BLOCK {{{
+# {{{ BEGIN BPS TAGGED BLOCK
#
# COPYRIGHT:
#
@@ -42,7 +42,7 @@
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
-# END BPS TAGGED BLOCK }}}
+# }}} END BPS TAGGED BLOCK
# Major Changes:
# - Decimated ProcessRestrictions and broke it into multiple
@@ -77,9 +77,6 @@
=end testing
=cut
-
-package RT::Tickets;
-
use strict;
no warnings qw(redefine);
use vars qw(@SORTFIELDS);
@@ -126,7 +123,6 @@
ContentType => ['TRANSFIELD',],
Filename => ['TRANSFIELD',],
TransactionDate => ['TRANSDATE',],
- Updated => ['TRANSDATE',],
Requestor => ['WATCHERFIELD' => 'Requestor',],
Requestors => ['WATCHERFIELD' => 'Requestor',],
Cc => ['WATCHERFIELD' => 'Cc',],
@@ -135,10 +131,6 @@
LinkedTo => ['LINKFIELD',],
CustomFieldValue =>['CUSTOMFIELD',],
CF => ['CUSTOMFIELD',],
- RequestorGroup => ['MEMBERSHIPFIELD' => 'Requestor',],
- CCGroup => ['MEMBERSHIPFIELD' => 'Cc',],
- AdminCCGroup => ['MEMBERSHIPFIELD' => 'AdminCc',],
- WatcherGroup => ['MEMBERSHIPFIELD',],
);
# Mapping of Field Type to Function
@@ -151,7 +143,6 @@
TRANSFIELD => \&_TransLimit,
TRANSDATE => \&_TransDateLimit,
WATCHERFIELD => \&_WatcherLimit,
- MEMBERSHIPFIELD => \&_WatcherMembershipLimit,
LINKFIELD => \&_LinkFieldLimit,
CUSTOMFIELD => \&_CustomFieldLimit,
);
@@ -274,7 +265,7 @@
$o->Load( $value );
$value = $o->Id;
}
- $sb->_SQLLimit( FIELD => $field,
+ $sb->_SQLLimit( FIELD => $field,,
VALUE => $value,
OPERATOR => $op,
@rest,
@@ -483,20 +474,16 @@
=cut
-# This routine should really be factored into translimit.
sub _TransDateLimit {
my ($sb,$field,$op,$value, at rest) = @_;
# See the comments for TransLimit, they apply here too
+ $sb->_SetupTransactionJoins();
- $sb->{_sql_transalias} = $sb->NewAlias ('Transactions')
- unless defined $sb->{_sql_transalias};
- $sb->{_sql_trattachalias} = $sb->NewAlias ('Attachments')
- unless defined $sb->{_sql_trattachalias};
-
-
- # Join Transactions To Attachments
$sb->_OpenParen;
+ my $d = new RT::Date( $sb->CurrentUser );
+ $d->Set( Format => 'ISO', Value => $value);
+ $value = $d->ISO;
#Search for the right field
$sb->_SQLLimit(ALIAS => $sb->{_sql_trattachalias},
@@ -507,20 +494,6 @@
@rest
);
- $sb->_SQLJoin( ALIAS1 => $sb->{_sql_trattachalias}, FIELD1 => 'TransactionId',
- ALIAS2 => $sb->{_transalias}, FIELD2 => 'id');
-
- # Join Transactions to Tickets
- $sb->_SQLJoin( ALIAS1 => 'main', FIELD1 => $sb->{'primary_key'}, # UGH!
- ALIAS2 => $sb->{_sql_transalias}, FIELD2 => 'ObjectId');
-
- $sb->Limit( ALIAS => $sb->{_sql_transalias}, FIELD => 'ObjectType', VALUE => 'RT::Ticket');
-
-
- my $d = new RT::Date( $sb->CurrentUser );
- $d->Set( Format => 'ISO', Value => $value);
- $value = $d->ISO;
-
$sb->_CloseParen;
}
@@ -566,18 +539,14 @@
# them all into the same subclause when you have (A op B op C) - the
# way they get parsed in the tree they're in different subclauses.
- my ($self,$field,$op,$value, at rest) = @_;
-
- $self->{_sql_transalias} = $self->NewAlias ('Transactions')
- unless defined $self->{_sql_transalias};
- $self->{_sql_trattachalias} = $self->NewAlias ('Attachments')
- unless defined $self->{_sql_trattachalias};
+ my ($sb,$field,$op,$value, at rest) = @_;
+ $sb->_SetupTransactionJoins();
- $self->_OpenParen;
+ $sb->_OpenParen;
#Search for the right field
- $self->_SQLLimit(ALIAS => $self->{_sql_trattachalias},
+ $sb->_SQLLimit(ALIAS => $sb->{_sql_trattachalias},
FIELD => $field,
OPERATOR => $op,
VALUE => $value,
@@ -586,17 +555,7 @@
);
- $self->_SQLJoin( ALIAS1 => $self->{_sql_trattachalias}, FIELD1 => 'TransactionId',
- ALIAS2 => $self->{_sql_transalias}, FIELD2 => 'id');
-
- # Join Transactions to Tickets
- $self->_SQLJoin( ALIAS1 => 'main', FIELD1 => $self->{'primary_key'}, # Why not use "id" here?
- ALIAS2 => $self->{_sql_transalias}, FIELD2 => 'ObjectId');
-
- $self->Limit( ALIAS => $self->{_sql_transalias}, FIELD => 'ObjectType', VALUE => 'RT::Ticket', ENTRYAGGREGATOR => 'AND');
-
-
- $self->_CloseParen;
+ $sb->_CloseParen;
}
@@ -742,112 +701,6 @@
$self->_CloseParen;
}
-=head2 _WatcherMembershipLimit
-
-Handle watcher membership limits, i.e. whether the watcher belongs to a
-specific group or not.
-
-Meta Data:
- 1: Field to query on
-
-SELECT DISTINCT main.*
-FROM
- Tickets main,
- Groups Groups_1,
- CachedGroupMembers CachedGroupMembers_2,
- Users Users_3
-WHERE (
- (main.EffectiveId = main.id)
-) AND (
- (main.Status != 'deleted')
-) AND (
- (main.Type = 'ticket')
-) AND (
- (
- (Users_3.EmailAddress = '22')
- AND
- (Groups_1.Domain = 'RT::Ticket-Role')
- AND
- (Groups_1.Type = 'RequestorGroup')
- )
-) AND
- Groups_1.Instance = main.id
-AND
- Groups_1.id = CachedGroupMembers_2.GroupId
-AND
- CachedGroupMembers_2.MemberId = Users_3.id
-ORDER BY main.id ASC
-LIMIT 25
-=cut
-
-sub _WatcherMembershipLimit {
- my ($self,$field,$op,$value, at rest) = @_;
- my %rest = @rest;
-
- $self->_OpenParen;
-
- my $groups = $self->NewAlias('Groups');
- my $groupmembers = $self->NewAlias('CachedGroupMembers');
- my $users = $self->NewAlias('Users');
- my $memberships = $self->NewAlias('CachedGroupMembers');
-
- if (ref $field) { # gross hack
- my @bundle = @$field;
- $self->_OpenParen;
- for my $chunk (@bundle) {
- ($field,$op,$value, at rest) = @$chunk;
- $self->_SQLLimit(ALIAS => $memberships,
- FIELD => 'GroupId',
- VALUE => $value,
- OPERATOR => $op,
- @rest,
- );
- }
- $self->_CloseParen;
- } else {
- $self->_SQLLimit(ALIAS => $memberships,
- FIELD => 'GroupId',
- VALUE => $value,
- OPERATOR => $op,
- @rest,
- );
- }
-
- # {{{ Tie to groups for tickets we care about
- $self->_SQLLimit(ALIAS => $groups,
- FIELD => 'Domain',
- VALUE => 'RT::Ticket-Role',
- ENTRYAGGREGATOR => 'AND');
-
- $self->Join(ALIAS1 => $groups, FIELD1 => 'Instance',
- ALIAS2 => 'main', FIELD2 => 'id');
- # }}}
-
- # If we care about which sort of watcher
- my $meta = $FIELDS{$field};
- my $type = ( defined $meta->[1] ? $meta->[1] : undef );
-
- if ( $type ) {
- $self->_SQLLimit(ALIAS => $groups,
- FIELD => 'Type',
- VALUE => $type,
- ENTRYAGGREGATOR => 'AND');
- }
-
- $self->Join (ALIAS1 => $groups, FIELD1 => 'id',
- ALIAS2 => $groupmembers, FIELD2 => 'GroupId');
-
- $self->Join( ALIAS1 => $groupmembers, FIELD1 => 'MemberId',
- ALIAS2 => $users, FIELD2 => 'id');
-
- $self->Join( ALIAS1 => $memberships, FIELD1 => 'MemberId',
- ALIAS2 => $users, FIELD2 => 'id');
-
- $self->_CloseParen;
-
-}
-
-
sub _LinkFieldLimit {
my $restriction;
my $self;
@@ -916,7 +769,7 @@
=cut
sub _CustomFieldLimit {
- my ( $self, $_field, $op, $value, @rest ) = @_;
+ my ($self,$_field,$op,$value, at rest) = @_;
my %rest = @rest;
my $field = $rest{SUBKEY} || die "No field specified";
@@ -924,109 +777,107 @@
# For our sanity, we can only limit on one queue at a time
my $queue = 0;
- if ( $field =~ /^(.+?)\.{(.+)}$/ ) {
+
+ if ($field =~ /^(.+?)\.{(.+)}$/) {
$queue = $1;
$field = $2;
}
$field = $1 if $field =~ /^{(.+)}$/; # trim { }
-
-
-# If we're trying to find custom fields that don't match something, we want tickets
-# where the custom field has no value at all
-
- my $null_columns_ok;
- if ( ( $op =~ /^IS$/i ) or ( $op =~ /^NOT LIKE$/i ) or ( $op eq '!=' ) ) {
- $null_columns_ok = 1;
- }
-
- my $cfid = 0;
- if ($queue) {
-
- my $q = RT::Queue->new( $self->CurrentUser );
+ my $q = RT::Queue->new($self->CurrentUser);
$q->Load($queue) if ($queue);
my $cf;
- if ( $q->id ) {
+ if ($q->id) {
$cf = $q->CustomField($field);
}
- else {
- $cf = RT::CustomField->new( $self->CurrentUser );
- $cf->LoadByNameAndQueue( Queue => '0', Name => $field );
+ else {
+ $cf = RT::CustomField->new($self->CurrentUser);
+ $cf->LoadByNameAndQueue(Queue => '0', Name => $field);
}
- $cfid = $cf->id;
- }
- my $TicketCFs;
+ my $cfid = $cf->id;
+
+ die "No custom field named $field found\n" unless $cfid;
+
+
+
+ my $null_columns_ok;
+
+ my $TicketCFs;
# Perform one Join per CustomField
- if ( $self->{_sql_object_cf_alias}{$cfid} ) {
- $TicketCFs = $self->{_sql_object_cf_alias}{$cfid};
+ if ($self->{_sql_keywordalias}{$cfid}) {
+ $TicketCFs = $self->{_sql_keywordalias}{$cfid};
+ } else {
+ $TicketCFs = $self->{_sql_keywordalias}{$cfid} =
+ $self->_SQLJoin( TYPE => 'left',
+ ALIAS1 => 'main',
+ FIELD1 => 'id',
+ TABLE2 => 'TicketCustomFieldValues',
+ FIELD2 => 'Ticket' );
}
- else {
- $TicketCFs = $self->{_sql_object_cf_alias}{$cfid} = $self->Join(
- TYPE => 'left',
- ALIAS1 => 'main',
- FIELD1 => 'id',
- TABLE2 => 'ObjectCustomFieldValues',
- FIELD2 => 'ObjectId'
- );
- $self->Limit(
- LEFTJOIN => $TicketCFs,
- FIELD => 'ObjectType',
- VALUE => ref($self->NewItem), # we want a single item, not a collection
- ENTRYAGGREGATOR => 'AND'
- );
+ $self->_OpenParen;
- if ($cfid) {
- $self->Limit(
- LEFTJOIN => $TicketCFs,
- FIELD => 'CustomField',
- VALUE => $cfid,
- ENTRYAGGREGATOR => 'AND'
- );
- } else {
- my $cfalias = $self->Join(
- ALIAS1 => $TicketCFs,
- FIELD1 => 'CustomField',
- TABLE2 => 'CustomFields',
- FIELD2 => 'id'
- );
- $self->Limit(
- LEFTJOIN => $cfalias,
- FIELD => 'Name',
- VALUE => $field,
- );
+ $self->_SQLLimit( ALIAS => $TicketCFs,
+ FIELD => 'Content',
+ OPERATOR => $op,
+ VALUE => $value,
+ QUOTEVALUE => 1,
+ @rest );
- }
- }
+ # If we're trying to find custom fields that don't match something, we want tickets
+ # where the custom field has no value at all
- $self->_OpenParen if ($null_columns_ok);
+ if ( ($op =~ /^IS$/i) || ($op =~ /^NOT LIKE$/i) || ( $op eq '!=' ) ) {
+ $null_columns_ok = 1;
+ }
+
- $self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => 'Content',
- OPERATOR => $op,
- VALUE => $value,
- QUOTEVALUE => 1,
- @rest
- );
- if ($null_columns_ok) {
- $self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => 'Content',
- OPERATOR => 'IS',
- VALUE => 'NULL',
- QUOTEVALUE => 0,
- ENTRYAGGREGATOR => 'OR',
- );
+ if ( $null_columns_ok && $op !~ /IS/i && uc $value ne "NULL") {
+ $self->_SQLLimit( ALIAS => $TicketCFs,
+ FIELD => 'Content',
+ OPERATOR => 'IS',
+ VALUE => 'NULL',
+ QUOTEVALUE => 0,
+ ENTRYAGGREGATOR => 'OR', );
}
- $self->_CloseParen if ($null_columns_ok);
+
+ $self->_SQLLimit( LEFTJOIN => $TicketCFs,
+ FIELD => 'CustomField',
+ VALUE => $cfid,
+ ENTRYAGGREGATOR => 'OR' );
+
+
+
+ $self->_CloseParen;
+
+}
+
+sub _SetupTransactionJoins {
+ my $self = shift;
+ # Join Transactions to Tickets
+ $self->{_sql_transalias} ||= $self->Join(
+ TYPE => 'LEFT',
+ ALIAS1 => 'main',
+ FIELD1 => $self->{'primary_key'}, # UGH!
+ TABLE2 => 'Transactions',
+ FIELD2 => 'Ticket'
+ );
+
+ # Join Transactions To Attachments
+ $self->{_sql_trattachalias} ||= $self->Join(
+ TYPE => 'LEFT',
+ TABLE2 => 'Attachments',
+ FIELD2 => 'TransactionId',
+ ALIAS1 => $self->{_sql_transalias},
+ FIELD1 => 'id'
+ );
}
@@ -1100,13 +951,8 @@
sub FreezeLimits {
my $self = shift;
- require Storable;
- require MIME::Base64;
- MIME::Base64::base64_encode(
- Storable::freeze(
- \@{$self}{$self->_FreezeThawKeys}
- )
- );
+ require FreezeThaw;
+ return (FreezeThaw::freeze(@{$self}{$self->_FreezeThawKeys}));
}
# }}}
@@ -1128,14 +974,13 @@
$self->{'RecalcTicketLimits'} = 1;
- require Storable;
- require MIME::Base64;
-
+ require FreezeThaw;
+
#We don't need to die if the thaw fails.
- @{$self}{$self->_FreezeThawKeys} = eval {
- @{Storable::thaw( MIME::Base64::base64_decode($in) )};
- };
+ eval {
+ @{$self}{$self->_FreezeThawKeys} = FreezeThaw::thaw($in);
+ };
$RT::Logger->error( $@ ) if $@;
}
@@ -2208,9 +2053,9 @@
}
# Two special case
- # Handle subkey fields with a different real field
- if ($field =~ /^(\w+)\./) {
- $realfield = $1;
+ # CustomFields have a different real field
+ if ($field =~ /^CF\./) {
+ $realfield = "CF"
}
die "I don't know about $field yet"
More information about the Rt-commit
mailing list